Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: unytelogo_animation
Fork of Adafruit_GFX by
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 Adafruit invests time and resources providing this open source code, 00007 please support Adafruit and open-source hardware by purchasing 00008 products from Adafruit! 00009 Written by Limor Fried/Ladyada for Adafruit Industries. 00010 BSD license, check license.txt for more information 00011 All text above must be included in any redistribution 00012 ****************************************/ 00013 00014 /* 00015 * Modified by Neal Horman 7/14/2012 for use in mbed 00016 */ 00017 00018 #include "mbed.h" 00019 00020 #include "Adafruit_GFX.h" 00021 #include "glcdfont.h" 00022 00023 #if defined(GFX_WANT_ABSTRACTS) 00024 // draw a circle outline 00025 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) 00026 { 00027 int16_t f = 1 - r; 00028 int16_t ddF_x = 1; 00029 int16_t ddF_y = -2 * r; 00030 int16_t x = 0; 00031 int16_t y = r; 00032 00033 drawPixel(x0, y0+r, color); 00034 drawPixel(x0, y0-r, color); 00035 drawPixel(x0+r, y0, color); 00036 drawPixel(x0-r, y0, color); 00037 00038 while (x<y) 00039 { 00040 if (f >= 0) 00041 { 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 { 00071 if (f >= 0) 00072 { 00073 y--; 00074 ddF_y += 2; 00075 f += ddF_y; 00076 } 00077 x++; 00078 ddF_x += 2; 00079 f += ddF_x; 00080 00081 if (cornername & 0x4) 00082 { 00083 drawPixel(x0 + x, y0 + y, color); 00084 drawPixel(x0 + y, y0 + x, color); 00085 } 00086 00087 if (cornername & 0x2) 00088 { 00089 drawPixel(x0 + x, y0 - y, color); 00090 drawPixel(x0 + y, y0 - x, color); 00091 } 00092 00093 if (cornername & 0x8) 00094 { 00095 drawPixel(x0 - y, y0 + x, color); 00096 drawPixel(x0 - x, y0 + y, color); 00097 } 00098 00099 if (cornername & 0x1) 00100 { 00101 drawPixel(x0 - y, y0 - x, color); 00102 drawPixel(x0 - x, y0 - y, color); 00103 } 00104 } 00105 } 00106 00107 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) 00108 { 00109 drawFastVLine(x0, y0-r, 2*r+1, color); 00110 fillCircleHelper(x0, y0, r, 3, 0, color); 00111 } 00112 00113 // used to do circles and roundrects! 00114 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color) 00115 { 00116 int16_t f = 1 - r; 00117 int16_t ddF_x = 1; 00118 int16_t ddF_y = -2 * r; 00119 int16_t x = 0; 00120 int16_t y = r; 00121 00122 while (x<y) 00123 { 00124 if (f >= 0) 00125 { 00126 y--; 00127 ddF_y += 2; 00128 f += ddF_y; 00129 } 00130 x++; 00131 ddF_x += 2; 00132 f += ddF_x; 00133 00134 if (cornername & 0x1) 00135 { 00136 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 00137 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 00138 } 00139 00140 if (cornername & 0x2) 00141 { 00142 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); 00143 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); 00144 } 00145 } 00146 } 00147 #endif 00148 00149 #if defined(GFX_WANT_ABSTRACTS) || defined(GFX_SIZEABLE_TEXT) 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 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) 00196 { 00197 // stupidest version - update in subclasses if desired! 00198 drawLine(x, y, x, y+h-1, color); 00199 } 00200 00201 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 00202 { 00203 // stupidest version - update in subclasses if desired! 00204 for (int16_t i=x; i<x+w; i++) 00205 drawFastVLine(i, y, h, color); 00206 } 00207 #endif 00208 00209 #if defined(GFX_WANT_ABSTRACTS) 00210 // draw a rectangle 00211 void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 00212 { 00213 drawFastHLine(x, y, w, color); 00214 drawFastHLine(x, y+h-1, w, color); 00215 drawFastVLine(x, y, h, color); 00216 drawFastVLine(x+w-1, y, h, color); 00217 } 00218 00219 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) 00220 { 00221 // stupidest version - update in subclasses if desired! 00222 drawLine(x, y, x+w-1, y, color); 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 00351 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) 00352 { 00353 for (int16_t j=0; j<h; j++) 00354 { 00355 for (int16_t i=0; i<w; i++ ) 00356 { 00357 if (bitmap[i + (j/8)*w] & _BV(j%8)) 00358 drawPixel(x+i, y+j, color); 00359 } 00360 } 00361 } 00362 #endif 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 defined(GFX_WANT_ABSTRACTS) || defined(GFX_SIZEABLE_TEXT) 00411 if (size == 1) // default size 00412 drawPixel(x+i, y+j, color); 00413 else // big size 00414 fillRect(x+(i*size), y+(j*size), size, size, color); 00415 #else 00416 drawPixel(x+i, y+j, color); 00417 #endif 00418 } 00419 else if (bg != color) 00420 { 00421 #if defined(GFX_WANT_ABSTRACTS) || defined(GFX_SIZEABLE_TEXT) 00422 if (size == 1) // default size 00423 drawPixel(x+i, y+j, bg); 00424 else // big size 00425 fillRect(x+i*size, y+j*size, size, size, bg); 00426 #else 00427 drawPixel(x+i, y+j, bg); 00428 #endif 00429 } 00430 line >>= 1; 00431 } 00432 } 00433 } 00434 00435 void Adafruit_GFX::setRotation(uint8_t x) 00436 { 00437 x %= 4; // cant be higher than 3 00438 rotation = x; 00439 switch (x) 00440 { 00441 case 0: 00442 case 2: 00443 _width = _rawWidth; 00444 _height = _rawHeight; 00445 break; 00446 case 1: 00447 case 3: 00448 _width = _rawHeight; 00449 _height = _rawWidth; 00450 break; 00451 } 00452 }
Generated on Fri Jul 15 2022 23:19:51 by
1.7.2
