Utility library for HSP SPo2 HR demo including user interface, board support adn accelerometer.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GraphicsDisplay.cpp Source File

GraphicsDisplay.cpp

00001 /* mbed GraphicsDisplay Display Library Base Class
00002  * Copyright (c) 2007-2009 sford
00003  * Released under the MIT License: http://mbed.org/license/mit
00004  */
00005  
00006 #include "../screen/GraphicsDisplay.h"
00007 
00008 #define incx() x++, dxt += d2xt, t += dxt
00009 #define incy() y--, dyt += d2yt, t += dyt
00010 
00011 const unsigned char FONT8x8[97][8] = {
00012 {0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, num_bytes_per_char
00013 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space 0x20
00014 {0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
00015 {0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
00016 {0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
00017 {0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
00018 {0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
00019 {0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
00020 {0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
00021 {0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
00022 {0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
00023 {0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
00024 {0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
00025 {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
00026 {0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
00027 {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
00028 {0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // / (forward slash)
00029 {0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0 0x30
00030 {0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
00031 {0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
00032 {0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
00033 {0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
00034 {0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
00035 {0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
00036 {0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
00037 {0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
00038 {0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
00039 {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
00040 {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
00041 {0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
00042 {0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
00043 {0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
00044 {0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
00045 {0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @ 0x40
00046 {0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
00047 {0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
00048 {0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
00049 {0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
00050 {0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
00051 {0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
00052 {0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
00053 {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
00054 {0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
00055 {0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
00056 {0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
00057 {0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
00058 {0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
00059 {0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
00060 {0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
00061 {0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P 0x50
00062 {0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
00063 {0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
00064 {0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
00065 {0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
00066 {0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
00067 {0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
00068 {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
00069 {0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
00070 {0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
00071 {0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
00072 {0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
00073 {0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // \ (back slash)
00074 {0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
00075 {0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
00076 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
00077 {0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // ` 0x60
00078 {0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
00079 {0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
00080 {0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
00081 {0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
00082 {0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
00083 {0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
00084 {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
00085 {0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
00086 {0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
00087 {0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
00088 {0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
00089 {0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
00090 {0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
00091 {0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
00092 {0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
00093 {0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
00094 {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
00095 {0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
00096 {0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
00097 {0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
00098 {0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
00099 {0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
00100 {0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
00101 {0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
00102 {0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
00103 {0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
00104 {0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
00105 {0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
00106 {0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
00107 {0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
00108 {0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00}}; // DEL
00109     
00110 GraphicsDisplay::GraphicsDisplay(const char *name):TextDisplay(name) {
00111     foreground((uint16_t)Black);
00112     background((uint16_t)White);
00113     // current pixel location
00114     _x = 0;
00115     _y = 0;
00116     // window settings
00117     _x1 = 0;
00118     _x2 = 0;
00119     _y1 = 0;
00120     _y2 = 0;
00121 }
00122     
00123 void GraphicsDisplay::character(int column, int row, int value) { 
00124     if(externalfont){ // send external font
00125         unsigned int hor,vert,offset,bpl,j,i,b;
00126         const unsigned char* sign;
00127         unsigned char z,w;
00128         if ((value < 31) || (value > 127)) return;   // test char range
00129         // read font parameter from start of array
00130         offset = font[0];                    // bytes / char
00131         hor = font[1];                       // get hor size of font
00132         vert = font[2];                      // get vert size of font
00133         bpl = font[3];                       // bytes per line
00134         if (char_x + hor > width()) {
00135             char_x = 0;
00136             char_y = char_y + vert;
00137             if (char_y >= height() - font[2]) {
00138                 char_y = 0;
00139             }
00140         }     
00141         window(char_x, char_y,hor,vert); // char box
00142         sign = &font[((value -32) * offset) + 4]; // start of char bitmap
00143         w = sign[0];                          // width of actual char
00144         for (j=0; j<vert; j++) {  //  vert line
00145             for (i=0; i<hor; i++) {   //  horz line
00146                 z =  sign[bpl * i + ((j & 0xF8) >> 3)+1];
00147                 b = 1 << (j & 0x07);
00148                 if (( z & b ) == 0x00) {               
00149                     putp(_foreground);              
00150                 } 
00151                 else {                     
00152                     putp(_background);                                
00153                 }
00154             }
00155         }
00156         if ((w + 2) < hor) {                   // x offset to next char
00157             char_x += w + 2;
00158             }
00159             else char_x += hor;
00160     }   
00161     // send default font            
00162     else {
00163         blitbit(column * 8, row * 8, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
00164     }
00165 }
00166 
00167 void GraphicsDisplay::window(int x, int y, int w, int h) {
00168     // current pixel location
00169     _x = x;
00170     _y = y;
00171     // window settings
00172     _x1 = x;
00173     _x2 = x + w - 1;
00174     _y1 = y;
00175     _y2 = y + h - 1;
00176 }
00177     
00178 void GraphicsDisplay::putp(int colour) {
00179     // put pixel at current pixel location
00180     pixel(_x, _y, colour);
00181     // update pixel location based on window settings
00182     _x++;
00183     if(_x > _x2) {
00184         _x = _x1;
00185         _y++;
00186         if(_y > _y2) {
00187             _y = _y1;
00188         }
00189     }
00190 }
00191 
00192 void GraphicsDisplay::rect(int x0, int y0, int x1, int y1, int color) {
00193     if (x1 > x0) hline(x0,x1,y0,color);
00194     else  hline(x1,x0,y0,color);
00195     if (y1 > y0) vline(x0,y0,y1,color);
00196     else vline(x0,y1,y0,color);
00197     if (x1 > x0) hline(x0,x1,y1,color);
00198     else  hline(x1,x0,y1,color);
00199     if (y1 > y0) vline(x1,y0,y1,color);
00200     else vline(x1,y1,y0,color);
00201     return;
00202 }
00203  
00204 void GraphicsDisplay::fillrect(int x0, int y0, int w, int h, int colour) {
00205     unsigned long int index=0;
00206     if (w < 0) {
00207         x0 = x0 + w;
00208         w = -w;
00209     }
00210     if (h < 0) {
00211         y0 = y0 + h;
00212         h = -h;
00213     }
00214     window(x0,y0,w,h);
00215     int num = h*w;
00216     for( index = 0; index<num; index++ ) {
00217        putp(colour); 
00218     }
00219     return;
00220 }
00221 
00222 void GraphicsDisplay::fill(int x, int y, int w, int h, int colour) { 
00223     fillrect(x, y, w, h, colour);
00224 }
00225 
00226 void GraphicsDisplay::circle(int x, int y, int r,int colour){
00227     int ce = -r;
00228     int cx = r;
00229     int cy = 0;
00230     while(cx >= cy){
00231         pixel(x+cx,y+cy,colour);
00232         pixel(x-cx,y-cy,colour);
00233         pixel(x-cx,y+cy,colour);
00234         pixel(x+cx,y-cy,colour);
00235         pixel(x+cy,y+cx,colour);
00236         pixel(x-cy,y+cx,colour);
00237         pixel(x-cy,y-cx,colour);
00238         pixel(x+cy,y-cx,colour);
00239         ce += 2*cy++ + 1;
00240         if(ce >= 0){
00241             ce -= 2*cx---1; 
00242         }
00243         
00244     }
00245 
00246 }
00247 
00248 // To draw circle set a and b to the same values
00249 void GraphicsDisplay::ellipse(int xc, int yc, int a, int b, unsigned int colour)
00250 {
00251     /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
00252     int x = 0, y = b;
00253     long a2 = (long)a*a, b2 = (long)b*b;
00254     long crit1 = -(a2/4 + a%2 + b2);
00255     long crit2 = -(b2/4 + b%2 + a2);
00256     long crit3 = -(b2/4 + b%2);
00257     long t = -a2*y;                         // e(x+1/2,y-1/2) - (a^2+b^2)/4
00258     long dxt = 2*b2*x, dyt = -2*a2*y;
00259     long d2xt = 2*b2, d2yt = 2*a2;
00260  
00261     while (y>=0 && x<=a) {
00262         pixel(xc+x, yc+y, colour);
00263         if (x!=0 || y!=0)
00264             pixel(xc-x, yc-y, colour);
00265         if (x!=0 && y!=0) {
00266             pixel(xc+x, yc-y, colour);
00267             pixel(xc-x, yc+y, colour);
00268         }
00269         if (t + b2*x <= crit1 ||            // e(x+1,y-1/2) <= 0
00270                 t + a2*y <= crit3)          // e(x+1/2,y) <= 0
00271             incx();
00272         else if (t - a2*y > crit2)          // e(x+1/2,y-1) > 0
00273             incy();
00274         else {
00275             incx();
00276             incy();
00277         }
00278     }
00279 }
00280 // To draw circle set a and b to the same values
00281 void GraphicsDisplay::fillellipse(int xc, int yc, int a, int b, unsigned int colour)
00282 {
00283     /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
00284     int x = 0, y = b;
00285     int rx = x, ry = y;
00286     unsigned int width = 1;
00287     unsigned int height = 1;
00288     long a2 = (long)a*a, b2 = (long)b*b;
00289     long crit1 = -(a2/4 + a%2 + b2);
00290     long crit2 = -(b2/4 + b%2 + a2);
00291     long crit3 = -(b2/4 + b%2);
00292     long t = -a2*y;                         // e(x+1/2,y-1/2) - (a^2+b^2)/4
00293     long dxt = 2*b2*x, dyt = -2*a2*y;
00294     long d2xt = 2*b2, d2yt = 2*a2;
00295     if (b == 0) {
00296         fillrect(xc-a, yc, 2*a+1, 1, colour);
00297         return;
00298     }
00299     while (y>=0 && x<=a) {
00300         if (t + b2*x <= crit1 ||            // e(x+1,y-1/2) <= 0
00301                 t + a2*y <= crit3) {        // e(x+1/2,y) <= 0
00302             if (height == 1)
00303                 ;                           // draw nothing
00304             else if (ry*2+1 > (height-1)*2) {
00305                 fillrect(xc-rx, yc-ry, width, height-1, colour);
00306                 fillrect(xc-rx, yc+ry+1, width, 1-height, colour);
00307                 ry -= height-1;
00308                 height = 1;
00309             } else {
00310                 fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
00311                 ry -= ry;
00312                 height = 1;
00313             }
00314             incx();
00315             rx++;
00316             width += 2;
00317         } else if (t - a2*y > crit2) {      // e(x+1/2,y-1) > 0
00318             incy();
00319             height++;
00320         } else {
00321             if (ry*2+1 > height*2) {
00322                 fillrect(xc-rx, yc-ry, width, height, colour);
00323                 fillrect(xc-rx, yc+ry+1, width, -height, colour);
00324             } else {
00325                 fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
00326             }
00327             incx();
00328             incy();
00329             rx++;
00330             width += 2;
00331             ry -= height;
00332             height = 1;
00333         }
00334     }
00335     if (ry > height) {
00336         fillrect(xc-rx, yc-ry, width, height, colour);
00337         fillrect(xc-rx, yc+ry+1, width, -height, colour);
00338     } else {
00339         fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
00340     }
00341 }
00342  
00343  
00344 void GraphicsDisplay::line(int x0, int y0, int x1, int y1, int colour) {
00345     //window(x0, y, w, h);
00346     int   dx = 0, dy = 0;
00347     int   dx_sym = 0, dy_sym = 0;
00348     int   dx_x2 = 0, dy_x2 = 0;
00349     int   di = 0;
00350     dx = x1-x0;
00351     dy = y1-y0;
00352  
00353     if (dx == 0) {        /* vertical line */
00354         if (y1 > y0) vline(x0,y0,y1,colour);
00355         else vline(x0,y1,y0,colour);
00356         return;
00357     }
00358     if (dx > 0) {
00359         dx_sym = 1;
00360     } else {
00361         dx_sym = -1;
00362     }
00363     if (dy == 0) {        /* horizontal line */
00364         if (x1 > x0) hline(x0,x1,y0,colour);
00365         else  hline(x1,x0,y0,colour);
00366         return;
00367     }
00368     if (dy > 0) {
00369         dy_sym = 1;
00370     } else {
00371         dy_sym = -1;
00372     }
00373     dx = dx_sym*dx;
00374     dy = dy_sym*dy;
00375     dx_x2 = dx*2;
00376     dy_x2 = dy*2;
00377     if (dx >= dy) {
00378         di = dy_x2 - dx;
00379         while (x0 != x1) {
00380  
00381             pixel(x0, y0, colour);
00382             x0 += dx_sym;
00383             if (di<0) {
00384                 di += dy_x2;
00385             } else {
00386                 di += dy_x2 - dx_x2;
00387                 y0 += dy_sym;
00388             }
00389         }
00390         pixel(x0, y0, colour);
00391     } else {
00392         di = dx_x2 - dy;
00393         while (y0 != y1) {
00394             pixel(x0, y0, colour);
00395             y0 += dy_sym;
00396             if (di < 0) {
00397                 di += dx_x2;
00398             } else {
00399                 di += dx_x2 - dy_x2;
00400                 x0 += dx_sym;
00401             }
00402         }
00403         pixel(x0, y0, colour);
00404     }
00405     return;
00406 }
00407  
00408 void GraphicsDisplay::hline(int x0, int x1, int y, int colour) {
00409     int w;
00410     w = x1 - x0 + 1;
00411     window(x0,y,w,1);
00412     for (int x=0; x<w; x++) {
00413         putp(colour);
00414     }
00415     return;
00416 }
00417  
00418 void GraphicsDisplay::vline(int x, int y0, int y1, int colour) {
00419     int h;
00420     h = y1 - y0 + 1;
00421     window(x,y0,1,h);
00422     for (int y=0; y<h; y++) {
00423         putp(colour);
00424     }
00425     return;
00426 }
00427 
00428 void GraphicsDisplay::cls() {
00429     fill(0, 0, width(), height(), _background);
00430 }
00431     
00432 void GraphicsDisplay::blit(int x, int y, int w, int h, const int *colour) { 
00433     window(x, y, w, h);
00434     for(int i=0; i<w*h; i++) {
00435         putp(colour[i]);
00436     }
00437 }
00438     
00439 void GraphicsDisplay::blitbit(int x, int y, int w, int h, const char* colour) {
00440     window(x, y, w, h);
00441     for(int i = 0; i < w*h; i++) {
00442         char byte = colour[i >> 3];
00443         int offset = i & 0x7;
00444         int c = ((byte << (offset)) & 0x80) ? _foreground : _background;
00445         putp(c);
00446     }
00447 }
00448     
00449 int GraphicsDisplay::columns() { 
00450     return width() / 8; 
00451 }
00452 
00453 int GraphicsDisplay::rows() { 
00454     return height() / 8; 
00455 }
00456