The wait in mci_WaitForEvent will delay all card transactions.

Dependencies:   FATFileSystem

Fork of EALib by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_GFX.cpp Source File

Adafruit_GFX.cpp

00001 /*
00002 This is the core graphics library for all our displays, providing a common
00003 set of graphics primitives (points, lines, circles, etc.).  It needs to be
00004 paired with a hardware-specific library for each display device we carry
00005 (to handle the lower-level functions).
00006 
00007 Adafruit invests time and resources providing this open source code, please
00008 support Adafruit & open-source hardware by purchasing products from Adafruit!
00009 
00010 Copyright (c) 2013 Adafruit Industries.  All rights reserved.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014 
00015 - Redistributions of source code must retain the above copyright notice,
00016   this list of conditions and the following disclaimer.
00017 - Redistributions in binary form must reproduce the above copyright notice,
00018   this list of conditions and the following disclaimer in the documentation
00019   and/or other materials provided with the distribution.
00020 
00021 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00022 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00025 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00026 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00027 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00028 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00029 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00030 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 POSSIBILITY OF SUCH DAMAGE.
00032  */
00033 
00034 #include "mbed.h"
00035 #include "Adafruit_GFX.h"
00036 #include "glcdfont.c"
00037 #ifdef __AVR__
00038 #include <avr/pgmspace.h>
00039 #else
00040 #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
00041 #endif
00042 
00043 Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h):
00044 WIDTH(w), HEIGHT(h)
00045 {
00046     _width    = WIDTH;
00047     _height   = HEIGHT;
00048     rotation  = 0;
00049     cursor_y  = cursor_x    = 0;
00050     textsize  = 1;
00051     textcolor = textbgcolor = 0xFFFF;
00052     wrap      = true;
00053 }
00054 
00055 // Draw a circle outline
00056 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
00057         uint16_t color) {
00058     int16_t f = 1 - r;
00059     int16_t ddF_x = 1;
00060     int16_t ddF_y = -2 * r;
00061     int16_t x = 0;
00062     int16_t y = r;
00063 
00064     drawPixel(x0  , y0+r, color);
00065     drawPixel(x0  , y0-r, color);
00066     drawPixel(x0+r, y0  , color);
00067     drawPixel(x0-r, y0  , color);
00068 
00069     while (x<y) {
00070         if (f >= 0) {
00071             y--;
00072             ddF_y += 2;
00073             f += ddF_y;
00074         }
00075         x++;
00076         ddF_x += 2;
00077         f += ddF_x;
00078 
00079         drawPixel(x0 + x, y0 + y, color);
00080         drawPixel(x0 - x, y0 + y, color);
00081         drawPixel(x0 + x, y0 - y, color);
00082         drawPixel(x0 - x, y0 - y, color);
00083         drawPixel(x0 + y, y0 + x, color);
00084         drawPixel(x0 - y, y0 + x, color);
00085         drawPixel(x0 + y, y0 - x, color);
00086         drawPixel(x0 - y, y0 - x, color);
00087     }
00088 }
00089 
00090 void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0,
00091         int16_t r, uint8_t cornername, uint16_t color) {
00092     int16_t f     = 1 - r;
00093     int16_t ddF_x = 1;
00094     int16_t ddF_y = -2 * r;
00095     int16_t x     = 0;
00096     int16_t y     = r;
00097 
00098     while (x<y) {
00099         if (f >= 0) {
00100             y--;
00101             ddF_y += 2;
00102             f     += ddF_y;
00103         }
00104         x++;
00105         ddF_x += 2;
00106         f     += ddF_x;
00107         if (cornername & 0x4) {
00108             drawPixel(x0 + x, y0 + y, color);
00109             drawPixel(x0 + y, y0 + x, color);
00110         }
00111         if (cornername & 0x2) {
00112             drawPixel(x0 + x, y0 - y, color);
00113             drawPixel(x0 + y, y0 - x, color);
00114         }
00115         if (cornername & 0x8) {
00116             drawPixel(x0 - y, y0 + x, color);
00117             drawPixel(x0 - x, y0 + y, color);
00118         }
00119         if (cornername & 0x1) {
00120             drawPixel(x0 - y, y0 - x, color);
00121             drawPixel(x0 - x, y0 - y, color);
00122         }
00123     }
00124 }
00125 
00126 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r,
00127         uint16_t color) {
00128     drawFastVLine(x0, y0-r, 2*r+1, color);
00129     fillCircleHelper(x0, y0, r, 3, 0, color);
00130 }
00131 
00132 // Used to do circles and roundrects
00133 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
00134         uint8_t cornername, int16_t delta, uint16_t color) {
00135 
00136     int16_t f     = 1 - r;
00137     int16_t ddF_x = 1;
00138     int16_t ddF_y = -2 * r;
00139     int16_t x     = 0;
00140     int16_t y     = r;
00141 
00142     while (x<y) {
00143         if (f >= 0) {
00144             y--;
00145             ddF_y += 2;
00146             f     += ddF_y;
00147         }
00148         x++;
00149         ddF_x += 2;
00150         f     += ddF_x;
00151 
00152         if (cornername & 0x1) {
00153             drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
00154             drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
00155         }
00156         if (cornername & 0x2) {
00157             drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
00158             drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
00159         }
00160     }
00161 }
00162 
00163 // Bresenham's algorithm - thx wikpedia
00164 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,
00165         int16_t x1, int16_t y1,
00166         uint16_t color) {
00167     int16_t steep = abs(y1 - y0) > abs(x1 - x0);
00168     if (steep) {
00169         swap(x0, y0);
00170         swap(x1, y1);
00171     }
00172 
00173     if (x0 > x1) {
00174         swap(x0, x1);
00175         swap(y0, y1);
00176     }
00177 
00178     int16_t dx, dy;
00179     dx = x1 - x0;
00180     dy = abs(y1 - y0);
00181 
00182     int16_t err = dx / 2;
00183     int16_t ystep;
00184 
00185     if (y0 < y1) {
00186         ystep = 1;
00187     } else {
00188         ystep = -1;
00189     }
00190 
00191     for (; x0<=x1; x0++) {
00192         if (steep) {
00193             drawPixel(y0, x0, color);
00194         } else {
00195             drawPixel(x0, y0, color);
00196         }
00197         err -= dy;
00198         if (err < 0) {
00199             y0 += ystep;
00200             err += dx;
00201         }
00202     }
00203 }
00204 
00205 // Draw a rectangle
00206 void Adafruit_GFX::drawRect(int16_t x, int16_t y,
00207         int16_t w, int16_t h,
00208         uint16_t color) {
00209     drawFastHLine(x, y, w, color);
00210     drawFastHLine(x, y+h-1, w, color);
00211     drawFastVLine(x, y, h, color);
00212     drawFastVLine(x+w-1, y, h, color);
00213 }
00214 
00215 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y,
00216         int16_t h, uint16_t color) {
00217     // Update in subclasses if desired!
00218     drawLine(x, y, x, y+h-1, color);
00219 }
00220 
00221 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y,
00222         int16_t w, uint16_t color) {
00223     // Update in subclasses if desired!
00224     drawLine(x, y, x+w-1, y, color);
00225 }
00226 
00227 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
00228         uint16_t color) {
00229     // Update in subclasses if desired!
00230     for (int16_t i=x; i<x+w; i++) {
00231         drawFastVLine(i, y, h, color);
00232     }
00233 }
00234 
00235 void Adafruit_GFX::fillScreen(uint16_t color) {
00236     fillRect(0, 0, _width, _height, color);
00237 }
00238 
00239 // Draw a rounded rectangle
00240 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w,
00241         int16_t h, int16_t r, uint16_t color) {
00242     // smarter version
00243     drawFastHLine(x+r  , y    , w-2*r, color); // Top
00244     drawFastHLine(x+r  , y+h-1, w-2*r, color); // Bottom
00245     drawFastVLine(x    , y+r  , h-2*r, color); // Left
00246     drawFastVLine(x+w-1, y+r  , h-2*r, color); // Right
00247     // draw four corners
00248     drawCircleHelper(x+r    , y+r    , r, 1, color);
00249     drawCircleHelper(x+w-r-1, y+r    , r, 2, color);
00250     drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
00251     drawCircleHelper(x+r    , y+h-r-1, r, 8, color);
00252 }
00253 
00254 // Fill a rounded rectangle
00255 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w,
00256         int16_t h, int16_t r, uint16_t color) {
00257     // smarter version
00258     fillRect(x+r, y, w-2*r, h, color);
00259 
00260     // draw four corners
00261     fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
00262     fillCircleHelper(x+r    , y+r, r, 2, h-2*r-1, color);
00263 }
00264 
00265 // Draw a triangle
00266 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0,
00267         int16_t x1, int16_t y1,
00268         int16_t x2, int16_t y2, uint16_t color) {
00269     drawLine(x0, y0, x1, y1, color);
00270     drawLine(x1, y1, x2, y2, color);
00271     drawLine(x2, y2, x0, y0, color);
00272 }
00273 
00274 // Fill a triangle
00275 void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0,
00276         int16_t x1, int16_t y1,
00277         int16_t x2, int16_t y2, uint16_t color) {
00278 
00279     int16_t a, b, y, last;
00280 
00281     // Sort coordinates by Y order (y2 >= y1 >= y0)
00282     if (y0 > y1) {
00283         swap(y0, y1); swap(x0, x1);
00284     }
00285     if (y1 > y2) {
00286         swap(y2, y1); swap(x2, x1);
00287     }
00288     if (y0 > y1) {
00289         swap(y0, y1); swap(x0, x1);
00290     }
00291 
00292     if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
00293         a = b = x0;
00294         if(x1 < a)      a = x1;
00295         else if(x1 > b) b = x1;
00296         if(x2 < a)      a = x2;
00297         else if(x2 > b) b = x2;
00298         drawFastHLine(a, y0, b-a+1, color);
00299         return;
00300     }
00301 
00302     int16_t
00303     dx01 = x1 - x0,
00304     dy01 = y1 - y0,
00305     dx02 = x2 - x0,
00306     dy02 = y2 - y0,
00307     dx12 = x2 - x1,
00308     dy12 = y2 - y1,
00309     sa   = 0,
00310     sb   = 0;
00311 
00312     // For upper part of triangle, find scanline crossings for segments
00313     // 0-1 and 0-2.  If y1=y2 (flat-bottomed triangle), the scanline y1
00314     // is included here (and second loop will be skipped, avoiding a /0
00315     // error there), otherwise scanline y1 is skipped here and handled
00316     // in the second loop...which also avoids a /0 error here if y0=y1
00317     // (flat-topped triangle).
00318     if(y1 == y2) last = y1;   // Include y1 scanline
00319     else         last = y1-1; // Skip it
00320 
00321     for(y=y0; y<=last; y++) {
00322         a   = x0 + sa / dy01;
00323         b   = x0 + sb / dy02;
00324         sa += dx01;
00325         sb += dx02;
00326         /* longhand:
00327     a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
00328     b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
00329          */
00330         if(a > b) swap(a,b);
00331         drawFastHLine(a, y, b-a+1, color);
00332     }
00333 
00334     // For lower part of triangle, find scanline crossings for segments
00335     // 0-2 and 1-2.  This loop is skipped if y1=y2.
00336     sa = dx12 * (y - y1);
00337     sb = dx02 * (y - y0);
00338     for(; y<=y2; y++) {
00339         a   = x1 + sa / dy12;
00340         b   = x0 + sb / dy02;
00341         sa += dx12;
00342         sb += dx02;
00343         /* longhand:
00344     a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
00345     b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
00346          */
00347         if(a > b) swap(a,b);
00348         drawFastHLine(a, y, b-a+1, color);
00349     }
00350 }
00351 
00352 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
00353         const uint8_t *bitmap, int16_t w, int16_t h,
00354         uint16_t color) {
00355 
00356     int16_t i, j, byteWidth = (w + 7) / 8;
00357 
00358     for(j=0; j<h; j++) {
00359         for(i=0; i<w; i++ ) {
00360             if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) {
00361                 drawPixel(x+i, y+j, color);
00362             }
00363         }
00364     }
00365 }
00366 
00367 
00368 size_t Adafruit_GFX::write(uint8_t c) {
00369     if (c == '\n') {
00370         cursor_y += textsize*8;
00371         cursor_x  = 0;
00372     } else if (c == '\r') {
00373         // skip em
00374     } else {
00375         drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
00376         cursor_x += textsize*6;
00377         if (wrap && (cursor_x > (_width - textsize*6))) {
00378             cursor_y += textsize*8;
00379             cursor_x = 0;
00380         }
00381     }
00382 
00383     return 1;
00384 
00385 }
00386 
00387 // Draw a character
00388 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
00389         uint16_t color, uint16_t bg, uint8_t size) {
00390 
00391     if((x >= _width)            || // Clip right
00392             (y >= _height)           || // Clip bottom
00393             ((x + 6 * size - 1) < 0) || // Clip left
00394             ((y + 8 * size - 1) < 0))   // Clip top
00395         return;
00396 
00397     for (int8_t i=0; i<6; i++ ) {
00398         uint8_t line;
00399         if (i == 5)
00400             line = 0x0;
00401         else
00402             line = pgm_read_byte(font+(c*5)+i);
00403         for (int8_t j = 0; j<8; j++) {
00404             if (line & 0x1) {
00405                 if (size == 1) // default size
00406                     drawPixel(x+i, y+j, color);
00407                 else {  // big size
00408                     fillRect(x+(i*size), y+(j*size), size, size, color);
00409                 }
00410             } else if (bg != color) {
00411                 if (size == 1) // default size
00412                     drawPixel(x+i, y+j, bg);
00413                 else {  // big size
00414                     fillRect(x+i*size, y+j*size, size, size, bg);
00415                 }
00416             }
00417             line >>= 1;
00418         }
00419     }
00420 }
00421 
00422 void Adafruit_GFX::setCursor(int16_t x, int16_t y) {
00423     cursor_x = x;
00424     cursor_y = y;
00425 }
00426 
00427 void Adafruit_GFX::setTextSize(uint8_t s) {
00428     textsize = (s > 0) ? s : 1;
00429 }
00430 
00431 void Adafruit_GFX::setTextColor(uint16_t c) {
00432     // For 'transparent' background, we'll set the bg
00433     // to the same as fg instead of using a flag
00434     textcolor = textbgcolor = c;
00435 }
00436 
00437 void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
00438     textcolor   = c;
00439     textbgcolor = b;
00440 }
00441 
00442 void Adafruit_GFX::setTextWrap(bool w) {
00443     wrap = w;
00444 }
00445 
00446 uint8_t Adafruit_GFX::getRotation(void) {
00447     return rotation;
00448 }
00449 
00450 void Adafruit_GFX::setRotation(uint8_t x) {
00451     rotation = (x & 3);
00452     switch(rotation) {
00453     case 0:
00454     case 2:
00455         _width  = WIDTH;
00456         _height = HEIGHT;
00457         break;
00458     case 1:
00459     case 3:
00460         _width  = HEIGHT;
00461         _height = WIDTH;
00462         break;
00463     }
00464 }
00465 
00466 // Return the size of the display (per current rotation)
00467 int16_t Adafruit_GFX::width(void) {
00468     return _width;
00469 }
00470 
00471 int16_t Adafruit_GFX::height(void) {
00472     return _height;
00473 }
00474 
00475 void Adafruit_GFX::invertDisplay(bool i) {
00476     // Do nothing, must be subclassed if supported
00477 }
00478 
00479