added the WANT_ABSTRACTS define so the library works with text sizes greater than 1

Dependents:   car_stereo

Fork of Adafruit_GFX by Neal Horman

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     if (c == '\n')
00367     {
00368         cursor_y += textsize*8;
00369         cursor_x = 0;
00370     }
00371     else if (c == '\r') {
00372         // cursor_x = 0;
00373     }
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 
00388 
00389 // draw a character
00390 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
00391 {
00392     if(
00393         (x >= _width) || // Clip right
00394         (y >= _height) || // Clip bottom
00395         ((x + 5 * size - 1) < 0) || // Clip left
00396         ((y + 8 * size - 1) < 0) // Clip top
00397         )
00398     return;
00399     
00400     for (int8_t i=0; i<6; i++ )
00401     {
00402         uint8_t line = 0;
00403 
00404         if (i == 5) 
00405             line = 0x0;
00406         else 
00407             line = font[(c*5)+i];
00408             
00409         for (int8_t j = 0; j<8; j++)
00410         {
00411             if (line & 0x1)
00412             {
00413                 if (size == 1) // default size
00414                     drawPixel(x+i, y+j, color);
00415 #ifdef WANT_ABSTRACTS
00416                 else { // big size 
00417                     fillRect(x+(i*size), y+(j*size), size, size, color);
00418 #endif
00419                 }
00420             }
00421             else if (bg != color)
00422             {
00423                 if (size == 1) // default size
00424                     drawPixel(x+i, y+j, bg);
00425 #ifdef WANT_ABSTRACTS
00426                 else {// big size 
00427                     fillRect(x+i*size, y+j*size, size, size, bg);
00428 #endif     
00429                 }
00430             }
00431             line >>= 1;
00432         }
00433     }
00434 }
00435 
00436 
00437 void Adafruit_GFX::setRotation(uint8_t x)
00438 {
00439     x %= 4;  // cant be higher than 3
00440     rotation = x;
00441     switch (x)
00442     {
00443         case 0:
00444         case 2:
00445             _width = _rawWidth;
00446             _height = _rawHeight;
00447             break;
00448         case 1:
00449         case 3:
00450             _width = _rawHeight;
00451             _height = _rawWidth;
00452             break;
00453     }
00454 }