Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Fri Jul 15 2022 01:41:58 by
1.7.2