Mac Lobdell / Adafruit_LEDBackpack

Dependents:   Adafruit_LEDBackpack_16x8_App Adafruit_32x8matrix

Fork of Adafruit_LEDBackpack by Luiz Hespanha

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_GFX.cpp Source File

Adafruit_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 #include "mbed.h"
00021 
00022 #include "Adafruit_GFX.h"
00023 #include "glcdfont.h"
00024 
00025 #ifdef WANT_ABSTRACTS
00026 // draw a circle outline
00027 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
00028 {
00029     int16_t f = 1 - r;
00030     int16_t ddF_x = 1;
00031     int16_t ddF_y = -2 * r;
00032     int16_t x = 0;
00033     int16_t y = r;
00034     
00035     drawPixel(x0, y0+r, color);
00036     drawPixel(x0, y0-r, color);
00037     drawPixel(x0+r, y0, color);
00038     drawPixel(x0-r, y0, color);
00039     
00040     while (x<y)
00041     {
00042         if (f >= 0)
00043         {
00044             y--;
00045             ddF_y += 2;
00046             f += ddF_y;
00047         }
00048         x++;
00049         ddF_x += 2;
00050         f += ddF_x;
00051         
00052         drawPixel(x0 + x, y0 + y, color);
00053         drawPixel(x0 - x, y0 + y, color);
00054         drawPixel(x0 + x, y0 - y, color);
00055         drawPixel(x0 - x, y0 - y, color);
00056         drawPixel(x0 + y, y0 + x, color);
00057         drawPixel(x0 - y, y0 + x, color);
00058         drawPixel(x0 + y, y0 - x, color);
00059         drawPixel(x0 - y, y0 - x, color);
00060     }
00061 }
00062 
00063 void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color)
00064 {
00065     int16_t f     = 1 - r;
00066     int16_t ddF_x = 1;
00067     int16_t ddF_y = -2 * r;
00068     int16_t x     = 0;
00069     int16_t y     = r;
00070     
00071     while (x<y)
00072     {
00073         if (f >= 0)
00074         {
00075             y--;
00076             ddF_y += 2;
00077             f += ddF_y;
00078         }
00079         x++;
00080         ddF_x += 2;
00081         f += ddF_x;
00082         
00083         if (cornername & 0x4)
00084         {
00085             drawPixel(x0 + x, y0 + y, color);
00086             drawPixel(x0 + y, y0 + x, color);
00087         } 
00088 
00089         if (cornername & 0x2)
00090         {
00091             drawPixel(x0 + x, y0 - y, color);
00092             drawPixel(x0 + y, y0 - x, color);
00093         }
00094 
00095         if (cornername & 0x8)
00096         {
00097             drawPixel(x0 - y, y0 + x, color);
00098             drawPixel(x0 - x, y0 + y, color);
00099         }
00100         
00101         if (cornername & 0x1)
00102         {
00103             drawPixel(x0 - y, y0 - x, color);
00104             drawPixel(x0 - x, y0 - y, color);
00105         }
00106     }
00107 }
00108 
00109 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
00110 {
00111     drawFastVLine(x0, y0-r, 2*r+1, color);
00112     fillCircleHelper(x0, y0, r, 3, 0, color);
00113 }
00114 
00115 // used to do circles and roundrects!
00116 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color)
00117 {
00118     int16_t f     = 1 - r;
00119     int16_t ddF_x = 1;
00120     int16_t ddF_y = -2 * r;
00121     int16_t x     = 0;
00122     int16_t y     = r;
00123     
00124     while (x<y)
00125     {
00126         if (f >= 0)
00127         {
00128             y--;
00129             ddF_y += 2;
00130             f += ddF_y;
00131         }
00132         x++;
00133         ddF_x += 2;
00134         f += ddF_x;
00135         
00136         if (cornername & 0x1)
00137         {
00138             drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
00139             drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
00140         }
00141 
00142         if (cornername & 0x2)
00143         {
00144             drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
00145             drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
00146         }
00147     }
00148 }
00149 
00150 // bresenham's algorithm - thx wikpedia
00151 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,  int16_t x1, int16_t y1, uint16_t color)
00152 {
00153     int16_t steep = abs(y1 - y0) > abs(x1 - x0);
00154     
00155     if (steep)
00156     {
00157         swap(x0, y0);
00158         swap(x1, y1);
00159     }
00160     
00161     if (x0 > x1)
00162     {
00163         swap(x0, x1);
00164         swap(y0, y1);
00165     }
00166     
00167     int16_t dx, dy;
00168     dx = x1 - x0;
00169     dy = abs(y1 - y0);
00170     
00171     int16_t err = dx / 2;
00172     int16_t ystep;
00173     
00174     if (y0 < y1)
00175         ystep = 1;
00176     else
00177         ystep = -1;
00178     
00179     for (; x0<=x1; x0++)
00180     {
00181         if (steep)
00182             drawPixel(y0, x0, color);
00183         else
00184             drawPixel(x0, y0, color);
00185 
00186         err -= dy;
00187         if (err < 0)
00188         {
00189             y0 += ystep;
00190             err += dx;
00191         }
00192     }
00193 }
00194 
00195 
00196 // draw a rectangle
00197 void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
00198 {
00199     drawFastHLine(x, y, w, color);
00200     drawFastHLine(x, y+h-1, w, color);
00201     drawFastVLine(x, y, h, color);
00202     drawFastVLine(x+w-1, y, h, color);
00203 }
00204 
00205 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
00206 {
00207     // stupidest version - update in subclasses if desired!
00208     drawLine(x, y, x, y+h-1, color);
00209 }
00210 
00211 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
00212 {
00213     // stupidest version - update in subclasses if desired!
00214     drawLine(x, y, x+w-1, y, color);
00215 }
00216 
00217 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
00218 {
00219     // stupidest version - update in subclasses if desired!
00220     for (int16_t i=x; i<x+w; i++)
00221         drawFastVLine(i, y, h, color); 
00222 }
00223 
00224 
00225 void Adafruit_GFX::fillScreen(uint16_t color)
00226 {
00227     fillRect(0, 0, _width, _height, color);
00228 }
00229 
00230 // draw a rounded rectangle!
00231 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)
00232 {
00233     // smarter version
00234     drawFastHLine(x+r  , y    , w-2*r, color); // Top
00235     drawFastHLine(x+r  , y+h-1, w-2*r, color); // Bottom
00236     drawFastVLine(  x    , y+r  , h-2*r, color); // Left
00237     drawFastVLine(  x+w-1, y+r  , h-2*r, color); // Right
00238     // draw four corners
00239     drawCircleHelper(x+r    , y+r    , r, 1, color);
00240     drawCircleHelper(x+w-r-1, y+r    , r, 2, color);
00241     drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
00242     drawCircleHelper(x+r    , y+h-r-1, r, 8, color);
00243 }
00244 
00245 // fill a rounded rectangle!
00246 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)
00247 {
00248     // smarter version
00249     fillRect(x+r, y, w-2*r, h, color);
00250     
00251     // draw four corners
00252     fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
00253     fillCircleHelper(x+r    , y+r, r, 2, h-2*r-1, color);
00254 }
00255 
00256 // draw a triangle!
00257 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
00258 {
00259     drawLine(x0, y0, x1, y1, color);
00260     drawLine(x1, y1, x2, y2, color);
00261     drawLine(x2, y2, x0, y0, color);
00262 }
00263 
00264 // fill a triangle!
00265 void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
00266 {
00267     int16_t a, b, y, last;
00268     
00269     // Sort coordinates by Y order (y2 >= y1 >= y0)
00270     if (y0 > y1)
00271         swap(y0, y1); swap(x0, x1);
00272 
00273     if (y1 > y2)
00274         swap(y2, y1); swap(x2, x1);
00275 
00276     if (y0 > y1)
00277         swap(y0, y1); swap(x0, x1);
00278 
00279     
00280     if(y0 == y2)
00281     { // Handle awkward all-on-same-line case as its own thing
00282         a = b = x0;
00283         if(x1 < a)
00284             a = x1;
00285         else if(x1 > b)
00286             b = x1;
00287             
00288         if(x2 < a)
00289             a = x2;
00290         else if(x2 > b) b = x2;
00291             drawFastHLine(a, y0, b-a+1, color);
00292         return;
00293     }
00294 
00295     int16_t
00296         dx01 = x1 - x0,
00297         dy01 = y1 - y0,
00298         dx02 = x2 - x0,
00299         dy02 = y2 - y0,
00300         dx12 = x2 - x1,
00301         dy12 = y2 - y1,
00302         sa   = 0,
00303         sb   = 0;
00304 
00305     // For upper part of triangle, find scanline crossings for segments
00306     // 0-1 and 0-2.  If y1=y2 (flat-bottomed triangle), the scanline y1
00307     // is included here (and second loop will be skipped, avoiding a /0
00308     // error there), otherwise scanline y1 is skipped here and handled
00309     // in the second loop...which also avoids a /0 error here if y0=y1
00310     // (flat-topped triangle).
00311     if(y1 == y2)
00312         last = y1;   // Include y1 scanline
00313     else
00314         last = y1-1; // Skip it
00315 
00316     for(y=y0; y<=last; y++)
00317     {
00318         a   = x0 + sa / dy01;
00319         b   = x0 + sb / dy02;
00320         sa += dx01;
00321         sb += dx02;
00322         /* longhand:
00323         a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
00324         b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
00325         */
00326         if(a > b)
00327             swap(a,b);
00328         drawFastHLine(a, y, b-a+1, color);
00329     }
00330 
00331     // For lower part of triangle, find scanline crossings for segments
00332     // 0-2 and 1-2.  This loop is skipped if y1=y2.
00333     sa = dx12 * (y - y1);
00334     sb = dx02 * (y - y0);
00335     for(; y<=y2; y++)
00336     {
00337         a   = x1 + sa / dy12;
00338         b   = x0 + sb / dy02;
00339         sa += dx12;
00340         sb += dx02;
00341         /* longhand:
00342         a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
00343         b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
00344         */
00345         if(a > b)
00346             swap(a,b);
00347         drawFastHLine(a, y, b-a+1, color);
00348     }
00349 }
00350 #endif
00351 
00352 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color)
00353 {
00354     for (int16_t j=0; j<h; j++)
00355     {
00356         for (int16_t i=0; i<w; i++ )
00357         {
00358             if (bitmap[i + (j/8)*w] & _BV(j%8))
00359                 drawPixel(x+i, y+j, color);
00360         }
00361     }
00362 }
00363 
00364 size_t Adafruit_GFX::writeChar(uint8_t c)
00365 {
00366         
00367     if (c == '\n')
00368     {
00369         cursor_y += textsize*8;
00370         cursor_x = 0;
00371     }
00372     else if (c == '\r')
00373         cursor_x = 0;
00374     else
00375     {
00376         drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
00377         cursor_x += textsize*6;
00378         if (wrap && (cursor_x > (_width - textsize*6)))
00379         {
00380             cursor_y += textsize*8;
00381             cursor_x = 0;
00382         }
00383     }
00384     return 1;
00385 }
00386 
00387 // draw a character
00388 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
00389 {
00390    
00391     if(
00392         (x >= _width) || // Clip right
00393         (y >= _height) || // Clip bottom
00394         ((x + 5 * size - 1) < 0) || // Clip left
00395         ((y + 8 * size - 1) < 0) // Clip top
00396         )
00397         return;
00398     
00399     for (int8_t i=0; i<6; i++ )
00400     {
00401         uint8_t line = 0;
00402 
00403         if (i == 5) 
00404             line = 0x0;
00405         else 
00406             line = font[(c*5)+i];
00407             
00408         for (int8_t j = 0; j<8; j++)
00409         {
00410             if (line & 0x1)
00411             {
00412                 if (size == 1) // default size
00413                     drawPixel(x+i, y+j, color);
00414 #ifdef WANT_ABSTRACTS
00415                 else // big size
00416                     fillRect(x+(i*size), y+(j*size), size, size, color);
00417 #endif
00418             }
00419             else if (bg != color)
00420             {
00421                 if (size == 1) // default size
00422                     drawPixel(x+i, y+j, bg);
00423 #ifdef WANT_ABSTRACTS
00424                 else // big size
00425                     fillRect(x+i*size, y+j*size, size, size, bg);
00426 #endif
00427             }
00428             line >>= 1;
00429         }
00430     }
00431 }
00432 void Adafruit_GFX::setRotation(uint8_t x)
00433 {
00434     x %= 4;  // cant be higher than 3
00435     rotation = x;
00436     switch (x)
00437     {
00438         case 0:
00439         case 2:
00440             _width = _rawWidth;
00441             _height = _rawHeight;
00442             break;
00443         case 1:
00444         case 3:
00445             _width = _rawHeight;
00446             _height = _rawWidth;
00447             break;
00448     }
00449 }