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