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.
Dependencies: EthernetInterface NTPClient mbed-rtos mbed
LedPanel_GFX.cpp
00001 /*********************************** 00002 This is a our graphics core library, for all our displays. 00003 We'll be adapting all the 00004 existing libaries to use this core to make updating, support 00005 and upgrading easier! 00006 00007 Adafruit invests time and resources providing this open source code, 00008 please support Adafruit and open-source hardware by purchasing 00009 products from Adafruit! 00010 00011 Written by Limor Fried/Ladyada for Adafruit Industries. 00012 BSD license, check license.txt for more information 00013 All text above must be included in any redistribution 00014 ****************************************/ 00015 00016 /* 00017 * Modified by Neal Horman 7/14/2012 for use in LPC1768 00018 */ 00019 00020 /** 00021 * Matrix16x16 LEDPanel Grafix library 00022 * 00023 * @author Junichi Katsu 00024 * @version 1.0 00025 * @date 15-April-2015 00026 * 00027 */ 00028 00029 #include "mbed.h" 00030 00031 #include "LedPanel_GFX.h" 00032 #include "font.h" 00033 00034 Serial pc(USBTX, USBRX); 00035 00036 00037 LedPanel_GFX::LedPanel_GFX(int16_t w, int16_t h) 00038 { 00039 _rawWidth = w; 00040 _rawHeight = h; 00041 _width = w; 00042 _height = h; 00043 cursor_x = 0; 00044 cursor_y = 0; 00045 textcolor = WHITE; 00046 textbgcolor = BLACK; 00047 textsize = 1; 00048 rotation = 0; 00049 wrap = true; 00050 00051 memcpy( &fnt_head , &font[0] , 18); 00052 font_head_size = 18 + fnt_head.Tnum * 4; 00053 for (uint32_t i=0;i<fnt_head.Tnum;i++) 00054 { 00055 fnt_head.Block[i].Start = font[19 + i*4]; 00056 fnt_head.Block[i].Start <<= 8; 00057 fnt_head.Block[i].Start |= font[18 + i*4]; 00058 fnt_head.Block[i].End = font[21 + i*4]; 00059 fnt_head.Block[i].End <<= 8; 00060 fnt_head.Block[i].End |= font[20 + i*4]; 00061 } 00062 font_search_tbl[0] = 0; 00063 00064 for (uint32_t i=1;i<fnt_head.Tnum;i++) 00065 { 00066 font_search_tbl[i] = (fnt_head.Block[i-1].End - fnt_head.Block[i-1].Start + 1) + font_search_tbl[i-1]; 00067 } 00068 }; 00069 00070 #ifdef WANT_ABSTRACTS 00071 // draw a circle outline 00072 void LedPanel_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) 00073 { 00074 int16_t f = 1 - r; 00075 int16_t ddF_x = 1; 00076 int16_t ddF_y = -2 * r; 00077 int16_t x = 0; 00078 int16_t y = r; 00079 00080 drawPixel(x0, y0+r, color); 00081 drawPixel(x0, y0-r, color); 00082 drawPixel(x0+r, y0, color); 00083 drawPixel(x0-r, y0, color); 00084 00085 while (x<y) 00086 { 00087 if (f >= 0) 00088 { 00089 y--; 00090 ddF_y += 2; 00091 f += ddF_y; 00092 } 00093 x++; 00094 ddF_x += 2; 00095 f += ddF_x; 00096 00097 drawPixel(x0 + x, y0 + y, color); 00098 drawPixel(x0 - x, y0 + y, color); 00099 drawPixel(x0 + x, y0 - y, color); 00100 drawPixel(x0 - x, y0 - y, color); 00101 drawPixel(x0 + y, y0 + x, color); 00102 drawPixel(x0 - y, y0 + x, color); 00103 drawPixel(x0 + y, y0 - x, color); 00104 drawPixel(x0 - y, y0 - x, color); 00105 } 00106 } 00107 00108 void LedPanel_GFX::drawCircleHelper( int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color) 00109 { 00110 int16_t f = 1 - r; 00111 int16_t ddF_x = 1; 00112 int16_t ddF_y = -2 * r; 00113 int16_t x = 0; 00114 int16_t y = r; 00115 00116 while (x<y) 00117 { 00118 if (f >= 0) 00119 { 00120 y--; 00121 ddF_y += 2; 00122 f += ddF_y; 00123 } 00124 x++; 00125 ddF_x += 2; 00126 f += ddF_x; 00127 00128 if (cornername & 0x4) 00129 { 00130 drawPixel(x0 + x, y0 + y, color); 00131 drawPixel(x0 + y, y0 + x, color); 00132 } 00133 00134 if (cornername & 0x2) 00135 { 00136 drawPixel(x0 + x, y0 - y, color); 00137 drawPixel(x0 + y, y0 - x, color); 00138 } 00139 00140 if (cornername & 0x8) 00141 { 00142 drawPixel(x0 - y, y0 + x, color); 00143 drawPixel(x0 - x, y0 + y, color); 00144 } 00145 00146 if (cornername & 0x1) 00147 { 00148 drawPixel(x0 - y, y0 - x, color); 00149 drawPixel(x0 - x, y0 - y, color); 00150 } 00151 } 00152 } 00153 00154 void LedPanel_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) 00155 { 00156 drawFastVLine(x0, y0-r, 2*r+1, color); 00157 fillCircleHelper(x0, y0, r, 3, 0, color); 00158 } 00159 00160 // used to do circles and roundrects! 00161 void LedPanel_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color) 00162 { 00163 int16_t f = 1 - r; 00164 int16_t ddF_x = 1; 00165 int16_t ddF_y = -2 * r; 00166 int16_t x = 0; 00167 int16_t y = r; 00168 00169 while (x<y) 00170 { 00171 if (f >= 0) 00172 { 00173 y--; 00174 ddF_y += 2; 00175 f += ddF_y; 00176 } 00177 x++; 00178 ddF_x += 2; 00179 f += ddF_x; 00180 00181 if (cornername & 0x1) 00182 { 00183 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 00184 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 00185 } 00186 00187 if (cornername & 0x2) 00188 { 00189 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); 00190 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); 00191 } 00192 } 00193 } 00194 00195 // bresenham's algorithm - thx wikpedia 00196 void LedPanel_GFX::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) 00197 { 00198 int16_t steep = abs(y1 - y0) > abs(x1 - x0); 00199 00200 if (steep) 00201 { 00202 swap(x0, y0); 00203 swap(x1, y1); 00204 } 00205 00206 if (x0 > x1) 00207 { 00208 swap(x0, x1); 00209 swap(y0, y1); 00210 } 00211 00212 int16_t dx, dy; 00213 dx = x1 - x0; 00214 dy = abs(y1 - y0); 00215 00216 int16_t err = dx / 2; 00217 int16_t ystep; 00218 00219 if (y0 < y1) 00220 ystep = 1; 00221 else 00222 ystep = -1; 00223 00224 for (; x0<=x1; x0++) 00225 { 00226 if (steep) 00227 drawPixel(y0, x0, color); 00228 else 00229 drawPixel(x0, y0, color); 00230 00231 err -= dy; 00232 if (err < 0) 00233 { 00234 y0 += ystep; 00235 err += dx; 00236 } 00237 } 00238 } 00239 00240 00241 // draw a rectangle 00242 void LedPanel_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 00243 { 00244 drawFastHLine(x, y, w, color); 00245 drawFastHLine(x, y+h-1, w, color); 00246 drawFastVLine(x, y, h, color); 00247 drawFastVLine(x+w-1, y, h, color); 00248 } 00249 00250 void LedPanel_GFX::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) 00251 { 00252 // stupidest version - update in subclasses if desired! 00253 drawLine(x, y, x, y+h-1, color); 00254 } 00255 00256 void LedPanel_GFX::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) 00257 { 00258 // stupidest version - update in subclasses if desired! 00259 drawLine(x, y, x+w-1, y, color); 00260 } 00261 00262 void LedPanel_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 00263 { 00264 // stupidest version - update in subclasses if desired! 00265 for (int16_t i=x; i<x+w; i++) 00266 drawFastVLine(i, y, h, color); 00267 } 00268 00269 00270 void LedPanel_GFX::fillScreen(uint16_t color) 00271 { 00272 fillRect(0, 0, _width, _height, color); 00273 } 00274 00275 // draw a rounded rectangle! 00276 void LedPanel_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) 00277 { 00278 // smarter version 00279 drawFastHLine(x+r , y , w-2*r, color); // Top 00280 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom 00281 drawFastVLine( x , y+r , h-2*r, color); // Left 00282 drawFastVLine( x+w-1, y+r , h-2*r, color); // Right 00283 // draw four corners 00284 drawCircleHelper(x+r , y+r , r, 1, color); 00285 drawCircleHelper(x+w-r-1, y+r , r, 2, color); 00286 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); 00287 drawCircleHelper(x+r , y+h-r-1, r, 8, color); 00288 } 00289 00290 // fill a rounded rectangle! 00291 void LedPanel_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) 00292 { 00293 // smarter version 00294 fillRect(x+r, y, w-2*r, h, color); 00295 00296 // draw four corners 00297 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); 00298 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); 00299 } 00300 00301 // draw a triangle! 00302 void LedPanel_GFX::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) 00303 { 00304 drawLine(x0, y0, x1, y1, color); 00305 drawLine(x1, y1, x2, y2, color); 00306 drawLine(x2, y2, x0, y0, color); 00307 } 00308 00309 // fill a triangle! 00310 void LedPanel_GFX::fillTriangle ( int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) 00311 { 00312 int16_t a, b, y, last; 00313 00314 // Sort coordinates by Y order (y2 >= y1 >= y0) 00315 if (y0 > y1) 00316 swap(y0, y1); swap(x0, x1); 00317 00318 if (y1 > y2) 00319 swap(y2, y1); swap(x2, x1); 00320 00321 if (y0 > y1) 00322 swap(y0, y1); swap(x0, x1); 00323 00324 00325 if(y0 == y2) 00326 { // Handle awkward all-on-same-line case as its own thing 00327 a = b = x0; 00328 if(x1 < a) 00329 a = x1; 00330 else if(x1 > b) 00331 b = x1; 00332 00333 if(x2 < a) 00334 a = x2; 00335 else if(x2 > b) b = x2; 00336 drawFastHLine(a, y0, b-a+1, color); 00337 return; 00338 } 00339 00340 int16_t 00341 dx01 = x1 - x0, 00342 dy01 = y1 - y0, 00343 dx02 = x2 - x0, 00344 dy02 = y2 - y0, 00345 dx12 = x2 - x1, 00346 dy12 = y2 - y1, 00347 sa = 0, 00348 sb = 0; 00349 00350 // For upper part of triangle, find scanline crossings for segments 00351 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 00352 // is included here (and second loop will be skipped, avoiding a /0 00353 // error there), otherwise scanline y1 is skipped here and handled 00354 // in the second loop...which also avoids a /0 error here if y0=y1 00355 // (flat-topped triangle). 00356 if(y1 == y2) 00357 last = y1; // Include y1 scanline 00358 else 00359 last = y1-1; // Skip it 00360 00361 for(y=y0; y<=last; y++) 00362 { 00363 a = x0 + sa / dy01; 00364 b = x0 + sb / dy02; 00365 sa += dx01; 00366 sb += dx02; 00367 /* longhand: 00368 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); 00369 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00370 */ 00371 if(a > b) 00372 swap(a,b); 00373 drawFastHLine(a, y, b-a+1, color); 00374 } 00375 00376 // For lower part of triangle, find scanline crossings for segments 00377 // 0-2 and 1-2. This loop is skipped if y1=y2. 00378 sa = dx12 * (y - y1); 00379 sb = dx02 * (y - y0); 00380 for(; y<=y2; y++) 00381 { 00382 a = x1 + sa / dy12; 00383 b = x0 + sb / dy02; 00384 sa += dx12; 00385 sb += dx02; 00386 /* longhand: 00387 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); 00388 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00389 */ 00390 if(a > b) 00391 swap(a,b); 00392 drawFastHLine(a, y, b-a+1, color); 00393 } 00394 } 00395 #endif 00396 00397 void LedPanel_GFX::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) 00398 { 00399 for (int16_t j=0; j<h; j++) 00400 { 00401 for (int16_t i=0; i<w; i++ ) 00402 { 00403 if (bitmap[i + (j/8)*w] & _BV(j%8)) 00404 drawPixel(x+i, y+j, color); 00405 } 00406 } 00407 } 00408 00409 size_t LedPanel_GFX::writeChar(uint8_t c) 00410 { 00411 static unsigned char tmp[2] = { 0 , 0 }; 00412 static int flag = 0; 00413 00414 if (c == '\n') 00415 { 00416 cursor_y += textsize*8; 00417 cursor_x = 0; 00418 } 00419 else if (c == '\r') 00420 { 00421 cursor_x = 0; 00422 } 00423 else if(flag == 1) 00424 { 00425 flag = 0; 00426 tmp[1] = c; 00427 draw2Char(cursor_x, cursor_y, tmp, textcolor, textbgcolor, textsize); 00428 cursor_x += textsize*8; 00429 if (wrap && (cursor_x > (_width - textsize*8))) 00430 { 00431 cursor_y += textsize*8; 00432 cursor_x = 0; 00433 } 00434 } 00435 else if((c >= 0x81) && (c <= 0xea)) 00436 { 00437 tmp[0] = c; 00438 flag = 1; 00439 } 00440 else 00441 { 00442 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); 00443 cursor_x += textsize*6; 00444 if (wrap && (cursor_x > (_width - textsize*6))) 00445 { 00446 cursor_y += textsize*8; 00447 cursor_x = 0; 00448 } 00449 } 00450 return 1; 00451 } 00452 00453 // draw a character 00454 void LedPanel_GFX::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size) 00455 { 00456 if( 00457 (x >= _width) || // Clip right 00458 (y >= _height) || // Clip bottom 00459 ((x + 5 * size - 1) < 0) || // Clip left 00460 ((y + 8 * size - 1) < 0) // Clip top 00461 ) 00462 return; 00463 00464 for (int8_t i=0; i<6; i++ ) 00465 { 00466 uint8_t line = 0; 00467 00468 if (i == 5) 00469 line = 0x0; 00470 else 00471 line = s_apxFont5x8[(c*5)+i]; 00472 00473 for (int8_t j = 0; j<8; j++) 00474 { 00475 if (line & 0x1) 00476 { 00477 if (size == 1) // default size 00478 drawPixel(x+i, y+j, color); 00479 #ifdef WANT_ABSTRACTS 00480 else // big size 00481 fillRect(x+(i*size), y+(j*size), size, size, color); 00482 #endif 00483 } 00484 else if (bg != color) 00485 { 00486 if (size == 1) // default size 00487 drawPixel(x+i, y+j, bg); 00488 #ifdef WANT_ABSTRACTS 00489 else // big size 00490 fillRect(x+i*size, y+j*size, size, size, bg); 00491 #endif 00492 } 00493 line >>= 1; 00494 } 00495 } 00496 } 00497 00498 int32_t LedPanel_GFX::search_font_area( uint16_t code ) 00499 { 00500 00501 for(uint16_t i=0;i<fnt_head.Tnum;i++) 00502 { 00503 if( (fnt_head.Block[i].Start<=code) && (fnt_head.Block[i].End>=code) ) 00504 { 00505 return(i); 00506 } 00507 } 00508 00509 return(-1); 00510 } 00511 00512 int32_t LedPanel_GFX::get_font_pt( uint16_t code ,uint8_t *chr ) 00513 { 00514 int32_t font_area; 00515 int32_t offset; 00516 uint32_t addr; 00517 00518 font_area = search_font_area(code); 00519 00520 if(font_area == -1) 00521 { 00522 code = 0x81a0; 00523 font_area = search_font_area(code); 00524 } 00525 00526 offset = (uint32_t)code - (uint32_t)fnt_head.Block[font_area].Start; 00527 00528 addr = ((uint32_t)font_search_tbl[font_area] + offset) * ((fnt_head.XSize >> 3) * fnt_head.YSize); 00529 00530 addr += font_head_size; 00531 00532 memcpy( chr ,&font[addr] ,8 ); 00533 00534 return( 0 ); 00535 } 00536 00537 // draw a character 00538 void LedPanel_GFX::draw2Char(int16_t x, int16_t y, unsigned char *c, uint16_t color, uint16_t bg, uint8_t size) 00539 { 00540 if( 00541 (x >= _width) || // Clip right 00542 (y >= _height) || // Clip bottom 00543 ((x + 5 * size - 1) < 0) || // Clip left 00544 ((y + 8 * size - 1) < 0) // Clip top 00545 ) 00546 return; 00547 00548 unsigned short tmp; 00549 unsigned char chr[8]; 00550 00551 tmp = c[0]; 00552 tmp <<= 8; 00553 tmp |= c[1]; 00554 00555 get_font_pt(tmp,&chr[0]); 00556 00557 for (int8_t i=0; i<8; i++ ) 00558 { 00559 uint8_t line = chr[i]; 00560 00561 for (int8_t j = 0; j<8; j++) 00562 { 00563 if (line & 0x1) 00564 { 00565 drawPixel(x+(7-i), y+(7-j), color); 00566 } 00567 else if (bg != color) 00568 { 00569 drawPixel(x+(7-i), y+(7-j), bg); 00570 } 00571 line >>= 1; 00572 } 00573 } 00574 }
Generated on Thu Jul 14 2022 17:34:26 by
1.7.2