Sharp Memory LCD library

Dependencies:   Fonts Images BurstSPI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SharpLCD.cpp Source File

SharpLCD.cpp

00001 
00002 #include "mbed.h"
00003 #include "SharpLCD.h"
00004 
00005 const unsigned char FONT8x8[97][8] = {
00006 {0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, num_bytes_per_char
00007 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space 0x20
00008 {0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
00009 {0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
00010 {0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
00011 {0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
00012 {0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
00013 {0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
00014 {0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
00015 {0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
00016 {0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
00017 {0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
00018 {0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
00019 {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
00020 {0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
00021 {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
00022 {0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // / (forward slash)
00023 {0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0 0x30
00024 {0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
00025 {0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
00026 {0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
00027 {0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
00028 {0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
00029 {0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
00030 {0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
00031 {0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
00032 {0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
00033 {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
00034 {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
00035 {0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
00036 {0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
00037 {0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
00038 {0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
00039 {0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @ 0x40
00040 {0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
00041 {0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
00042 {0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
00043 {0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
00044 {0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
00045 {0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
00046 {0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
00047 {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
00048 {0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
00049 {0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
00050 {0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
00051 {0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
00052 {0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
00053 {0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
00054 {0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
00055 {0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P 0x50
00056 {0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
00057 {0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
00058 {0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
00059 {0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
00060 {0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
00061 {0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
00062 {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
00063 {0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
00064 {0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
00065 {0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
00066 {0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
00067 {0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // \ (back slash)
00068 {0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
00069 {0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
00070 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
00071 {0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // ` 0x60
00072 {0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
00073 {0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
00074 {0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
00075 {0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
00076 {0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
00077 {0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
00078 {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
00079 {0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
00080 {0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
00081 {0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
00082 {0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
00083 {0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
00084 {0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
00085 {0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
00086 {0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
00087 {0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
00088 {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
00089 {0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
00090 {0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
00091 {0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
00092 {0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
00093 {0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
00094 {0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
00095 {0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
00096 {0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
00097 {0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
00098 {0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
00099 {0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
00100 {0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
00101 {0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
00102 {0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00}}; // DEL
00103 
00104 // SharpLCD commands
00105 #define SharpLCD_CMD_UPDATE     (0x01)
00106 #define SharpLCD_CMD_ALL_CLEAR  (0x04)
00107 
00108 // Macro to switch endianness on char value
00109 #define SWAP8(a) ((((a) & 0x80) >> 7) | (((a) & 0x40) >> 5) | (((a) & 0x20) >> 3) | (((a) & 0x10) >> 1) | (((a) & 0x08) << 1) | (((a) & 0x04) << 3) | (((a) & 0x02) << 5) | (((a) & 0x01) << 7))
00110 
00111 SharpLCD::SharpLCD(PinName mosi, PinName miso, PinName sclk, PinName chipSelect, PinName enable, PinName extcom)
00112          :  spi(mosi, miso, sclk), chipSelect(chipSelect), Enable(enable), ExtCom(extcom)
00113 {
00114     //Initialize
00115     spi.frequency(3500000);// Nominal speed is 1MHz, tested working at 3MHz
00116     lcdPolarity = 0;    
00117     rowCount = 0;
00118     memset((uint8_t*)pixelBuffer, White, sizeof(pixelBuffer));  // init full pixel buffer to White
00119     memset((void*)RowState, 0, sizeof(RowState));   // init row status
00120     // current pixel location
00121     _x = 0;
00122     _y = 0;
00123     // window settings
00124     _x1 = 0;
00125     _x2 = 0;
00126     _y1 = 0;
00127     _y2 = 0;
00128      _row = 0;
00129     _column = 0;
00130 }
00131 // Call this function at 55 ~ 65 Hz to keep the display up-to-date.
00132 void SharpLCD::toggle() {
00133     ExtCom=!ExtCom;
00134 }
00135 
00136 void SharpLCD::enableDisplay(void) {
00137     Enable = 1;
00138 }
00139 
00140 void SharpLCD::disableDisplay(void) {
00141     Enable = 0;
00142 }
00143 
00144 void SharpLCD::clearImmediate() {
00145     // Clear out the pixel buffer
00146     memset((void*)pixelBuffer, foreground, sizeof(pixelBuffer));
00147     memset((void*)RowState, 0, sizeof(RowState));
00148     chipSelect = 1;
00149     // send clear command to display
00150     cmd[0] = (uint8_t)(SWAP8(SharpLCD_CMD_ALL_CLEAR | lcdPolarity));
00151     cmd[1] = 0; 
00152     spi.fastWrite(cmd[0]);
00153     spi.fastWrite(cmd[1]);
00154     spi.clearRX();  
00155     chipSelect = 0;
00156 }
00157 
00158 void SharpLCD::update() {
00159     //Initialize the command vector
00160     cmd[0] = (uint8_t)SWAP8(SharpLCD_CMD_UPDATE);
00161     cmd[1] = SWAP8(1);
00162     chipSelect=1;
00163     rowCount = 0;
00164     display_write();
00165 }
00166 
00167 void SharpLCD::display_write() {    
00168     while(rowCount < DISPLAY_HEIGHT) {      
00169         // Determine the next line to send
00170         if((RowState[rowCount / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (rowCount % DISPLAY_BUFFER_TYPE_SIZE))) != 0) {
00171             // Row has pixel changes, send this row to the display
00172             cmd[1] = (uint8_t)SWAP8(rowCount+1);
00173             
00174             memcpy(&(cmd[2]), (const void*)&(pixelBuffer[rowCount*(DISPLAY_WIDTH/DISPLAY_BUFFER_TYPE_SIZE)]), DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE));
00175                         
00176             int len=sizeof(cmd);            
00177             for(int i=0; i<len; i++) {      
00178                 spi.fastWrite(cmd[i]);      
00179                 }
00180             // update pixel change status of this line as sent
00181             RowState[rowCount / DISPLAY_BUFFER_TYPE_SIZE] &= ~(1 << (rowCount % DISPLAY_BUFFER_TYPE_SIZE));             
00182         }               
00183         rowCount++;
00184     }
00185     // send end of transfer bytes 
00186     spi.fastWrite(cmd[0]);
00187     spi.fastWrite(0xFF);
00188     // clear SPI RX buffer
00189     spi.clearRX();                  
00190     chipSelect = 0;     
00191 }
00192 
00193 void SharpLCD::pixel(int x, int y, int colour) {
00194     uint8_t swapx = 7 - ((unsigned int)x & 0x07);
00195         x = ((unsigned int)x & 0xFFFFFFF8) | swapx;
00196         // determine if row has pixel changes
00197         bool change = ((pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (x % DISPLAY_BUFFER_TYPE_SIZE))) != ((colour & 0x01) << (x % DISPLAY_BUFFER_TYPE_SIZE)));
00198         if(change) {
00199             // xor operation
00200             pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] ^= (1 << (x % DISPLAY_BUFFER_TYPE_SIZE));
00201             // update pixel change status of this line
00202             RowState[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE));
00203         }
00204     }
00205     
00206 int SharpLCD::_putc(int value) {
00207     if(value == '\n') {
00208         _column = 0;
00209         _row++;
00210         if(_row >= rows()) {
00211             _row = 0;
00212         }
00213     } else {
00214         character(_column, _row, value);
00215         _column++;
00216         if(_column >= columns()) {
00217             _column = 0;
00218             _row++;
00219             if(_row >= rows()) {
00220                 _row = 0;
00221             }
00222         }
00223     }
00224     return value;
00225 }
00226 
00227 void SharpLCD::set_font(const unsigned char * f) {
00228     font = f;
00229     if (font==NULL){externalfont=0;}    // set display.font
00230         else{externalfont=1;}
00231 }
00232 
00233 void SharpLCD::locate(int column, int row) {
00234     _column = column;
00235     _row = row;
00236     char_x = column;
00237     char_y = row;
00238 }
00239 
00240 int SharpLCD::_getc() {
00241     return -1;
00242 }
00243 
00244 void SharpLCD::printf(const char* format, ...) {
00245     char buffer[MAX_PRINTF_CHARS + 1] = { 0 };
00246     uint32_t iterator = 0;
00247     va_list args;
00248     va_start(args, format);
00249     vsprintf(buffer, format, args);
00250     va_end(args);
00251 
00252     while((buffer[iterator] != 0) && (iterator < MAX_PRINTF_CHARS)) {
00253         _putc(buffer[iterator++]);
00254     }
00255 }
00256    
00257 void SharpLCD::character(int column, int row, int value) {    
00258     if(externalfont){ // send external font
00259         unsigned int hor,vert,offset,bpl,j,i,b;
00260         const unsigned char* sign;
00261         unsigned char z,w;
00262         if ((value < 31) || (value > 127)) return;   // test char range
00263         // read font parameter from start of array
00264         offset = font[0];                    // bytes / char
00265         hor = font[1];                       // get hor size of font
00266         vert = font[2];                      // get vert size of font
00267         bpl = font[3];                       // bytes per line
00268         if (char_x + hor > width()) {
00269             char_x = 0;
00270             char_y = char_y + vert;
00271             if (char_y >= height() - font[2]) {
00272                 char_y = 0;
00273             }
00274         }     
00275         window(char_x, char_y,hor,vert); 
00276         sign = &font[((value -32) * offset) + 4]; 
00277         w = sign[0];                         
00278         for (j=0; j<vert; j++) {  
00279             for (i=0; i<hor; i++) {  
00280                 z =  sign[bpl * i + ((j & 0xF8) >> 3)+1];
00281                 b = 1 << (j & 0x07);
00282                 if (( z & b ) == 0x00) {               
00283                     putp(foreground);              
00284                 } 
00285                 else {                     
00286                     putp(background);                                
00287                 }
00288             }
00289         }
00290         if ((w + 2) < hor) {                   // x offset to next char
00291             char_x += w + 2;
00292             }
00293             else char_x += hor;
00294     }   
00295     // send default font using blitbit function             
00296     else{
00297         blitbit(column * 8, row * 8, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
00298         }
00299 }
00300 
00301 void SharpLCD::window(int x, int y, int w, int h) {
00302     // current pixel location
00303     _x = x;
00304     _y = y;
00305     // window settings
00306     _x1 = x;
00307     _x2 = x + w - 1;
00308     _y1 = y;
00309     _y2 = y + h - 1;
00310 }
00311     
00312 void SharpLCD::putp(int colour) {
00313     pixel(_x, _y, colour);
00314     _x++;
00315     if(_x > _x2) {
00316         _x = _x1;
00317         _y++;
00318         if(_y > _y2) {
00319             _y = _y1;
00320         }
00321     }
00322 }
00323 
00324 void SharpLCD::rect(int x0, int y0, int x1, int y1, int color) {
00325     if (x1 > x0) hline(x0,x1,y0,color);
00326     else  hline(x1,x0,y0,color);
00327     if (y1 > y0) vline(x0,y0,y1,color);
00328     else vline(x0,y1,y0,color);
00329     if (x1 > x0) hline(x0,x1,y1,color);
00330     else  hline(x1,x0,y1,color);
00331     if (y1 > y0) vline(x1,y0,y1,color);
00332     else vline(x1,y1,y0,color);
00333     return;
00334 }
00335 
00336 void SharpLCD::fillrect(int x0, int y0, int w, int h, int colour) {
00337     unsigned long int index=0;
00338     if (w < 0) {
00339         x0 = x0 + w;
00340         w = -w;
00341     }
00342     if (h < 0) {
00343         y0 = y0 + h;
00344         h = -h;
00345     }
00346     window(x0,y0,w,h);
00347     int num = h*w;
00348     for( index = 0; index<num; index++ ) {
00349        putp(colour); 
00350     }
00351     return;
00352 }
00353 
00354 void SharpLCD::circle(int x, int y, int r,int colour){
00355     int ce = -r;
00356     int cx = r;
00357     int cy = 0;
00358     while(cx >= cy){
00359         pixel(x+cx,y+cy,colour);
00360         pixel(x-cx,y-cy,colour);
00361         pixel(x-cx,y+cy,colour);
00362         pixel(x+cx,y-cy,colour);
00363         pixel(x+cy,y+cx,colour);
00364         pixel(x-cy,y+cx,colour);
00365         pixel(x-cy,y-cx,colour);
00366         pixel(x+cy,y-cx,colour);
00367         ce += 2*cy++ + 1;
00368         if(ce >= 0){
00369             ce -= 2*cx---1; 
00370         }       
00371     }
00372 }
00373 
00374 void SharpLCD::ellipse(int xc, int yc, int a, int b, unsigned int colour)
00375 {
00376     int x = 0, y = b;
00377     long a2 = (long)a*a, b2 = (long)b*b;
00378     long crit1 = -(a2/4 + a%2 + b2);
00379     long crit2 = -(b2/4 + b%2 + a2);
00380     long crit3 = -(b2/4 + b%2);
00381     long t = -a2*y;
00382     long dxt = 2*b2*x, dyt = -2*a2*y;
00383     long d2xt = 2*b2, d2yt = 2*a2;
00384     while (y>=0 && x<=a) {
00385         pixel(xc+x, yc+y, colour);
00386         if (x!=0 || y!=0)
00387             pixel(xc-x, yc-y, colour);
00388         if (x!=0 && y!=0) {
00389             pixel(xc+x, yc-y, colour);
00390             pixel(xc-x, yc+y, colour);
00391         }
00392         if (t + b2*x <= crit1 ||            
00393                 t + a2*y <= crit3)          
00394             incx();
00395         else if (t - a2*y > crit2)          
00396             incy();
00397         else {
00398             incx();
00399             incy();
00400         }
00401     }
00402 }
00403 
00404 void SharpLCD::fillellipse(int xc, int yc, int a, int b, unsigned int colour)
00405 {
00406     int x = 0, y = b;
00407     int rx = x, ry = y;
00408     unsigned int width = 1;
00409     unsigned int height = 1;
00410     long a2 = (long)a*a, b2 = (long)b*b;
00411     long crit1 = -(a2/4 + a%2 + b2);
00412     long crit2 = -(b2/4 + b%2 + a2);
00413     long crit3 = -(b2/4 + b%2);
00414     long t = -a2*y;                         
00415     long dxt = 2*b2*x, dyt = -2*a2*y;
00416     long d2xt = 2*b2, d2yt = 2*a2;
00417     if (b == 0) {
00418         fillrect(xc-a, yc, 2*a+1, 1, colour);
00419         return;
00420     }
00421     while (y>=0 && x<=a) {
00422         if (t + b2*x <= crit1 ||            
00423                 t + a2*y <= crit3) {        
00424             if (height == 1)
00425                 ;                           
00426             else if (ry*2+1 > (height-1)*2) {
00427                 fillrect(xc-rx, yc-ry, width, height-1, colour);
00428                 fillrect(xc-rx, yc+ry+1, width, 1-height, colour);
00429                 ry -= height-1;
00430                 height = 1;
00431             } else {
00432                 fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
00433                 ry -= ry;
00434                 height = 1;
00435             }
00436             incx();
00437             rx++;
00438             width += 2;
00439         } else if (t - a2*y > crit2) {      
00440             incy();
00441             height++;
00442         } else {
00443             if (ry*2+1 > height*2) {
00444                 fillrect(xc-rx, yc-ry, width, height, colour);
00445                 fillrect(xc-rx, yc+ry+1, width, -height, colour);
00446             } else {
00447                 fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
00448             }
00449             incx();
00450             incy();
00451             rx++;
00452             width += 2;
00453             ry -= height;
00454             height = 1;
00455         }
00456     }
00457     if (ry > height) {
00458         fillrect(xc-rx, yc-ry, width, height, colour);
00459         fillrect(xc-rx, yc+ry+1, width, -height, colour);
00460     } else {
00461         fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
00462     }
00463 }
00464 
00465 void SharpLCD::line(int x0, int y0, int x1, int y1, int colour) {
00466     int   dx = 0, dy = 0;
00467     int   dx_sym = 0, dy_sym = 0;
00468     int   dx_x2 = 0, dy_x2 = 0;
00469     int   di = 0;
00470     dx = x1-x0;
00471     dy = y1-y0;
00472 
00473     if (dx == 0) {        
00474         if (y1 > y0) vline(x0,y0,y1,colour);
00475         else vline(x0,y1,y0,colour);
00476         return;
00477     }
00478     if (dx > 0) {
00479         dx_sym = 1;
00480     } else {
00481         dx_sym = -1;
00482     }
00483     if (dy == 0) {        
00484         if (x1 > x0) hline(x0,x1,y0,colour);
00485         else  hline(x1,x0,y0,colour);
00486         return;
00487     }
00488     if (dy > 0) {
00489         dy_sym = 1;
00490     } else {
00491         dy_sym = -1;
00492     }
00493     dx = dx_sym*dx;
00494     dy = dy_sym*dy;
00495     dx_x2 = dx*2;
00496     dy_x2 = dy*2;
00497     if (dx >= dy) {
00498         di = dy_x2 - dx;
00499         while (x0 != x1) {
00500 
00501             pixel(x0, y0, colour);
00502             x0 += dx_sym;
00503             if (di<0) {
00504                 di += dy_x2;
00505             } else {
00506                 di += dy_x2 - dx_x2;
00507                 y0 += dy_sym;
00508             }
00509         }
00510         pixel(x0, y0, colour);
00511     } else {
00512         di = dx_x2 - dy;
00513         while (y0 != y1) {
00514             pixel(x0, y0, colour);
00515             y0 += dy_sym;
00516             if (di < 0) {
00517                 di += dx_x2;
00518             } else {
00519                 di += dx_x2 - dy_x2;
00520                 x0 += dx_sym;
00521             }
00522         }
00523         pixel(x0, y0, colour);
00524     }
00525     return;
00526 }
00527 
00528 void SharpLCD::hline(int x0, int x1, int y, int colour) {
00529     int w;
00530     w = x1 - x0 + 1;
00531     window(x0,y,w,1);
00532     for (int x=0; x<w; x++) {
00533         putp(colour);
00534     }
00535     return;
00536 }
00537 
00538 void SharpLCD::vline(int x, int y0, int y1, int colour) {
00539     int h;
00540     h = y1 - y0 + 1;
00541     window(x,y0,1,h);
00542     for (int y=0; y<h; y++) {
00543         putp(colour);
00544     }
00545     return;
00546 }
00547     
00548 void SharpLCD::blit(int x, int y, int w, int h, const int *colour) { 
00549     window(x, y, w, h);
00550     for(int i=0; i<w*h; i++) {
00551         putp(colour[i]);
00552     }
00553 }
00554     
00555 void SharpLCD::blitbit(int x, int y, int w, int h, const char* colour) {
00556     window(x, y, w, h);
00557     for(int i = 0; i < w*h; i++) {
00558         char byte = colour[i >> 3];
00559         int offset = i & 0x7;
00560         int c = ((byte << (offset)) & 0x80) ? background : foreground;
00561         putp(c);
00562     }
00563 }
00564     
00565 int SharpLCD::columns() { 
00566     return width() / 8; 
00567 }
00568 
00569 int SharpLCD::rows() { 
00570     return height() / 8; 
00571 }
00572 
00573 int SharpLCD::width() {
00574     return DISPLAY_WIDTH;
00575 }
00576 
00577 int SharpLCD::height() {
00578     return DISPLAY_HEIGHT;
00579 }
00580 
00581 void SharpLCD::showBMP(const uint8_t* bitmap, const uint32_t bmpWidth, const uint32_t bmpHeight, const uint32_t startX, const uint32_t startY) {
00582     uint32_t bitmapLine = 0, y = startY, bytesPerLine = ((bmpWidth >= (DISPLAY_WIDTH - startX)) ? (DISPLAY_WIDTH - startX) : bmpWidth) / 8;
00583 
00584     // Apply constraints
00585     if((bmpWidth & 0x07) != 0) return;
00586     if(startX >= DISPLAY_WIDTH) return;
00587     
00588     // Copy over bytes to pixel buffer
00589     for(; y < startY + bmpHeight; y++) {
00590         memcpy( (void*) &(((uint8_t*)pixelBuffer)[((y * DISPLAY_WIDTH) + startX) / 8]),
00591                 (const void*) &(bitmap[bitmapLine * (bmpWidth / 8)]),
00592                 bytesPerLine);
00593         RowState[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE));
00594         bitmapLine++;
00595     }
00596     return;
00597 }
00598