.
Fork of Adafruit_GFX by
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 { 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 #endif 00150 00151 #if defined(GFX_WANT_ABSTRACTS) || defined(GFX_SIZEABLE_TEXT) 00152 // bresenham's algorithm - thx wikpedia 00153 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) 00154 { 00155 int16_t steep = abs(y1 - y0) > abs(x1 - x0); 00156 00157 if (steep) 00158 { 00159 swap(x0, y0); 00160 swap(x1, y1); 00161 } 00162 00163 if (x0 > x1) 00164 { 00165 swap(x0, x1); 00166 swap(y0, y1); 00167 } 00168 00169 int16_t dx, dy; 00170 dx = x1 - x0; 00171 dy = abs(y1 - y0); 00172 00173 int16_t err = dx / 2; 00174 int16_t ystep; 00175 00176 if (y0 < y1) 00177 ystep = 1; 00178 else 00179 ystep = -1; 00180 00181 for (; x0<=x1; x0++) 00182 { 00183 if (steep) 00184 drawPixel(y0, x0, color); 00185 else 00186 drawPixel(x0, y0, color); 00187 00188 err -= dy; 00189 if (err < 0) 00190 { 00191 y0 += ystep; 00192 err += dx; 00193 } 00194 } 00195 } 00196 00197 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) 00198 { 00199 // stupidest version - update in subclasses if desired! 00200 drawLine(x, y, x, y+h-1, color); 00201 } 00202 00203 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 00204 { 00205 // stupidest version - update in subclasses if desired! 00206 for (int16_t i=x; i<x+w; i++) 00207 drawFastVLine(i, y, h, color); 00208 } 00209 #endif 00210 00211 #if defined(GFX_WANT_ABSTRACTS) 00212 // draw a rectangle 00213 void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 00214 { 00215 drawFastHLine(x, y, w, color); 00216 drawFastHLine(x, y+h-1, w, color); 00217 drawFastVLine(x, y, h, color); 00218 drawFastVLine(x+w-1, y, h, color); 00219 } 00220 00221 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) 00222 { 00223 // stupidest version - update in subclasses if desired! 00224 drawLine(x, y, x+w-1, y, color); 00225 } 00226 00227 void Adafruit_GFX::fillScreen(uint16_t color) 00228 { 00229 fillRect(0, 0, _width, _height, color); 00230 } 00231 00232 // draw a rounded rectangle! 00233 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) 00234 { 00235 // smarter version 00236 drawFastHLine(x+r , y , w-2*r, color); // Top 00237 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom 00238 drawFastVLine( x , y+r , h-2*r, color); // Left 00239 drawFastVLine( x+w-1, y+r , h-2*r, color); // Right 00240 // draw four corners 00241 drawCircleHelper(x+r , y+r , r, 1, color); 00242 drawCircleHelper(x+w-r-1, y+r , r, 2, color); 00243 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); 00244 drawCircleHelper(x+r , y+h-r-1, r, 8, color); 00245 } 00246 00247 // fill a rounded rectangle! 00248 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) 00249 { 00250 // smarter version 00251 fillRect(x+r, y, w-2*r, h, color); 00252 00253 // draw four corners 00254 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); 00255 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); 00256 } 00257 00258 // draw a triangle! 00259 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) 00260 { 00261 drawLine(x0, y0, x1, y1, color); 00262 drawLine(x1, y1, x2, y2, color); 00263 drawLine(x2, y2, x0, y0, color); 00264 } 00265 00266 // fill a triangle! 00267 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) 00268 { 00269 int16_t a, b, y, last; 00270 00271 // Sort coordinates by Y order (y2 >= y1 >= y0) 00272 if (y0 > y1) 00273 swap(y0, y1); swap(x0, x1); 00274 00275 if (y1 > y2) 00276 swap(y2, y1); swap(x2, x1); 00277 00278 if (y0 > y1) 00279 swap(y0, y1); swap(x0, x1); 00280 00281 00282 if(y0 == y2) 00283 { // Handle awkward all-on-same-line case as its own thing 00284 a = b = x0; 00285 if(x1 < a) 00286 a = x1; 00287 else if(x1 > b) 00288 b = x1; 00289 00290 if(x2 < a) 00291 a = x2; 00292 else if(x2 > b) b = x2; 00293 drawFastHLine(a, y0, b-a+1, color); 00294 return; 00295 } 00296 00297 int16_t 00298 dx01 = x1 - x0, 00299 dy01 = y1 - y0, 00300 dx02 = x2 - x0, 00301 dy02 = y2 - y0, 00302 dx12 = x2 - x1, 00303 dy12 = y2 - y1, 00304 sa = 0, 00305 sb = 0; 00306 00307 // For upper part of triangle, find scanline crossings for segments 00308 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 00309 // is included here (and second loop will be skipped, avoiding a /0 00310 // error there), otherwise scanline y1 is skipped here and handled 00311 // in the second loop...which also avoids a /0 error here if y0=y1 00312 // (flat-topped triangle). 00313 if(y1 == y2) 00314 last = y1; // Include y1 scanline 00315 else 00316 last = y1-1; // Skip it 00317 00318 for(y=y0; y<=last; y++) 00319 { 00320 a = x0 + sa / dy01; 00321 b = x0 + sb / dy02; 00322 sa += dx01; 00323 sb += dx02; 00324 /* longhand: 00325 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); 00326 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00327 */ 00328 if(a > b) 00329 swap(a,b); 00330 drawFastHLine(a, y, b-a+1, color); 00331 } 00332 00333 // For lower part of triangle, find scanline crossings for segments 00334 // 0-2 and 1-2. This loop is skipped if y1=y2. 00335 sa = dx12 * (y - y1); 00336 sb = dx02 * (y - y0); 00337 for(; y<=y2; y++) 00338 { 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) 00348 swap(a,b); 00349 drawFastHLine(a, y, b-a+1, color); 00350 } 00351 } 00352 00353 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) 00354 { 00355 for (int16_t j=0; j<h; j++) 00356 { 00357 for (int16_t i=0; i<w; i++ ) 00358 { 00359 if (bitmap[i + (j/8)*w] & _BV(j%8)) 00360 drawPixel(x+i, y+j, color); 00361 } 00362 } 00363 } 00364 #endif 00365 00366 size_t Adafruit_GFX::writeChar(uint8_t c) 00367 { 00368 if (c == '\n') 00369 { 00370 cursor_y += textsize*8; 00371 cursor_x = 0; 00372 } 00373 else if (c == '\r') 00374 cursor_x = 0; 00375 else 00376 { 00377 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); 00378 cursor_x += textsize*6; 00379 if (wrap && (cursor_x > (_width - textsize*6))) 00380 { 00381 cursor_y += textsize*8; 00382 cursor_x = 0; 00383 } 00384 } 00385 return 1; 00386 } 00387 00388 // draw a character 00389 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size) 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 defined(GFX_WANT_ABSTRACTS) || defined(GFX_SIZEABLE_TEXT) 00413 if (size == 1) // default size 00414 drawPixel(x+i, y+j, color); 00415 else // big size 00416 fillRect(x+(i*size), y+(j*size), size, size, color); 00417 #else 00418 drawPixel(x+i, y+j, color); 00419 #endif 00420 } 00421 else if (bg != color) 00422 { 00423 #if defined(GFX_WANT_ABSTRACTS) || defined(GFX_SIZEABLE_TEXT) 00424 if (size == 1) // default size 00425 drawPixel(x+i, y+j, bg); 00426 else // big size 00427 fillRect(x+i*size, y+j*size, size, size, bg); 00428 #else 00429 drawPixel(x+i, y+j, bg); 00430 #endif 00431 } 00432 line >>= 1; 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 }
Generated on Fri Jul 15 2022 20:36:29 by 1.7.2