Animation demo with MIP8F_SPI_Ver60

Dependencies:   mbed MIP8F_SPI_Ver60 MIP8f_FRDM_LineBuffer_sample MIP8f_FRDM_TransferMode_sample

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