Junichi Katsu / Mbed 2 deprecated LedPanel_ClockSpeaker

Dependencies:   EthernetInterface NTPClient mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LedPanel_GFX.cpp Source File

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 }