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.
Fork of Adafruit_GFX by
Adafruit_GFX.cpp
00001 /****************************************************************** 00002 This is the core graphics library for all our displays, providing 00003 basic graphics primitives (points, lines, circles, etc.). It needs 00004 to be paired with a hardware-specific library for each display 00005 device we carry (handling the lower-level functions). 00006 00007 Adafruit invests time and resources providing this open 00008 source code, please support Adafruit and open-source hardware 00009 by purchasing 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 #include "mbed.h" 00017 #include "Adafruit_GFX.h" 00018 #include "glcdfont.h" 00019 00020 Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): WIDTH(w), HEIGHT(h) { 00021 00022 _width = WIDTH; 00023 _height = HEIGHT; 00024 00025 rotation = 0; 00026 cursor_y = cursor_x = 0; 00027 textsize = 1; 00028 textcolor = textbgcolor = 0xFFFF; 00029 wrap = true; 00030 } 00031 00032 00033 // draw a circle outline 00034 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, 00035 uint16_t color) { 00036 int16_t f = 1 - r; 00037 int16_t ddF_x = 1; 00038 int16_t ddF_y = -2 * r; 00039 int16_t x = 0; 00040 int16_t y = r; 00041 00042 drawPixel(x0, y0+r, color); 00043 drawPixel(x0, y0-r, color); 00044 drawPixel(x0+r, y0, color); 00045 drawPixel(x0-r, y0, color); 00046 00047 while (x<y) { 00048 if (f >= 0) { 00049 y--; 00050 ddF_y += 2; 00051 f += ddF_y; 00052 } 00053 x++; 00054 ddF_x += 2; 00055 f += ddF_x; 00056 00057 drawPixel(x0 + x, y0 + y, color); 00058 drawPixel(x0 - x, y0 + y, color); 00059 drawPixel(x0 + x, y0 - y, color); 00060 drawPixel(x0 - x, y0 - y, color); 00061 drawPixel(x0 + y, y0 + x, color); 00062 drawPixel(x0 - y, y0 + x, color); 00063 drawPixel(x0 + y, y0 - x, color); 00064 drawPixel(x0 - y, y0 - x, color); 00065 00066 } 00067 } 00068 00069 void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, 00070 int16_t r, uint8_t cornername, uint16_t color) { 00071 int16_t f = 1 - r; 00072 int16_t ddF_x = 1; 00073 int16_t ddF_y = -2 * r; 00074 int16_t x = 0; 00075 int16_t y = r; 00076 00077 while (x<y) { 00078 if (f >= 0) { 00079 y--; 00080 ddF_y += 2; 00081 f += ddF_y; 00082 } 00083 x++; 00084 ddF_x += 2; 00085 f += ddF_x; 00086 if (cornername & 0x4) { 00087 drawPixel(x0 + x, y0 + y, color); 00088 drawPixel(x0 + y, y0 + x, color); 00089 } 00090 if (cornername & 0x2) { 00091 drawPixel(x0 + x, y0 - y, color); 00092 drawPixel(x0 + y, y0 - x, color); 00093 } 00094 if (cornername & 0x8) { 00095 drawPixel(x0 - y, y0 + x, color); 00096 drawPixel(x0 - x, y0 + y, color); 00097 } 00098 if (cornername & 0x1) { 00099 drawPixel(x0 - y, y0 - x, color); 00100 drawPixel(x0 - x, y0 - y, color); 00101 } 00102 } 00103 } 00104 00105 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, 00106 uint16_t color) { 00107 drawFastVLine(x0, y0-r, 2*r+1, color); 00108 fillCircleHelper(x0, y0, r, 3, 0, color); 00109 } 00110 00111 // used to do circles and roundrects! 00112 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, 00113 uint8_t cornername, int16_t delta, uint16_t color) { 00114 00115 int16_t f = 1 - r; 00116 int16_t ddF_x = 1; 00117 int16_t ddF_y = -2 * r; 00118 int16_t x = 0; 00119 int16_t y = r; 00120 00121 while (x<y) { 00122 if (f >= 0) { 00123 y--; 00124 ddF_y += 2; 00125 f += ddF_y; 00126 } 00127 x++; 00128 ddF_x += 2; 00129 f += ddF_x; 00130 00131 if (cornername & 0x1) { 00132 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 00133 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 00134 } 00135 if (cornername & 0x2) { 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 } 00141 00142 // bresenham's algorithm - thx wikpedia 00143 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, 00144 int16_t x1, int16_t y1, 00145 uint16_t color) { 00146 int16_t steep = abs(y1 - y0) > abs(x1 - x0); 00147 if (steep) { 00148 swap(x0, y0); 00149 swap(x1, y1); 00150 } 00151 00152 if (x0 > x1) { 00153 swap(x0, x1); 00154 swap(y0, y1); 00155 } 00156 00157 int16_t dx, dy; 00158 dx = x1 - x0; 00159 dy = abs(y1 - y0); 00160 00161 int16_t err = dx / 2; 00162 int16_t ystep; 00163 00164 if (y0 < y1) { 00165 ystep = 1; 00166 } else { 00167 ystep = -1; 00168 } 00169 00170 for (; x0<=x1; x0++) { 00171 if (steep) { 00172 drawPixel(y0, x0, color); 00173 } else { 00174 drawPixel(x0, y0, color); 00175 } 00176 err -= dy; 00177 if (err < 0) { 00178 y0 += ystep; 00179 err += dx; 00180 } 00181 } 00182 } 00183 00184 00185 // draw a rectangle 00186 void Adafruit_GFX::drawRect(int16_t x, int16_t y, 00187 int16_t w, int16_t h, 00188 uint16_t color) { 00189 drawFastHLine(x, y, w, color); 00190 drawFastHLine(x, y+h-1, w, color); 00191 drawFastVLine(x, y, h, color); 00192 drawFastVLine(x+w-1, y, h, color); 00193 } 00194 00195 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, 00196 int16_t h, uint16_t color) { 00197 // stupidest version - update in subclasses if desired! 00198 drawLine(x, y, x, y+h-1, color); 00199 } 00200 00201 00202 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, 00203 int16_t w, uint16_t color) { 00204 // stupidest version - update in subclasses if desired! 00205 drawLine(x, y, x+w-1, y, color); 00206 } 00207 00208 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 00209 uint16_t color) { 00210 // stupidest version - update in subclasses if desired! 00211 for (int16_t i=x; i<x+w; i++) { 00212 drawFastVLine(i, y, h, color); 00213 } 00214 } 00215 00216 00217 void Adafruit_GFX::fillScreen(uint16_t color) { 00218 fillRect(0, 0, _width, _height, color); 00219 } 00220 00221 // draw a rounded rectangle! 00222 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, 00223 int16_t h, int16_t r, uint16_t color) { 00224 // smarter version 00225 drawFastHLine(x+r , y , w-2*r, color); // Top 00226 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom 00227 drawFastVLine( x , y+r , h-2*r, color); // Left 00228 drawFastVLine( x+w-1, y+r , h-2*r, color); // Right 00229 // draw four corners 00230 drawCircleHelper(x+r , y+r , r, 1, color); 00231 drawCircleHelper(x+w-r-1, y+r , r, 2, color); 00232 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); 00233 drawCircleHelper(x+r , y+h-r-1, r, 8, color); 00234 } 00235 00236 // fill a rounded rectangle! 00237 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, 00238 int16_t h, int16_t r, uint16_t color) { 00239 // smarter version 00240 fillRect(x+r, y, w-2*r, h, color); 00241 00242 // draw four corners 00243 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); 00244 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); 00245 } 00246 00247 // draw a triangle! 00248 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0, 00249 int16_t x1, int16_t y1, 00250 int16_t x2, int16_t y2, uint16_t color) { 00251 drawLine(x0, y0, x1, y1, color); 00252 drawLine(x1, y1, x2, y2, color); 00253 drawLine(x2, y2, x0, y0, color); 00254 } 00255 00256 // fill a triangle! 00257 void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0, 00258 int16_t x1, int16_t y1, 00259 int16_t x2, int16_t y2, uint16_t color) { 00260 00261 int16_t a, b, y, last; 00262 00263 // Sort coordinates by Y order (y2 >= y1 >= y0) 00264 if (y0 > y1) { 00265 swap(y0, y1); swap(x0, x1); 00266 } 00267 if (y1 > y2) { 00268 swap(y2, y1); swap(x2, x1); 00269 } 00270 if (y0 > y1) { 00271 swap(y0, y1); swap(x0, x1); 00272 } 00273 00274 if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing 00275 a = b = x0; 00276 if(x1 < a) a = x1; 00277 else if(x1 > b) b = x1; 00278 if(x2 < a) 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) last = y1; // Include y1 scanline 00301 else last = y1-1; // Skip it 00302 00303 for(y=y0; y<=last; y++) { 00304 a = x0 + sa / dy01; 00305 b = x0 + sb / dy02; 00306 sa += dx01; 00307 sb += dx02; 00308 /* longhand: 00309 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); 00310 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00311 */ 00312 if(a > b) swap(a,b); 00313 drawFastHLine(a, y, b-a+1, color); 00314 } 00315 00316 // For lower part of triangle, find scanline crossings for segments 00317 // 0-2 and 1-2. This loop is skipped if y1=y2. 00318 sa = dx12 * (y - y1); 00319 sb = dx02 * (y - y0); 00320 for(; y<=y2; y++) { 00321 a = x1 + sa / dy12; 00322 b = x0 + sb / dy02; 00323 sa += dx12; 00324 sb += dx02; 00325 /* longhand: 00326 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); 00327 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00328 */ 00329 if(a > b) swap(a,b); 00330 drawFastHLine(a, y, b-a+1, color); 00331 } 00332 } 00333 00334 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, 00335 const uint8_t *bitmap, int16_t w, int16_t h, 00336 uint16_t color) { 00337 00338 int16_t i, j, byteWidth = (w + 7) / 8; 00339 00340 for(j=0; j<h; j++) { 00341 for(i=0; i<w; i++ ) { 00342 // if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { 00343 if(bitmap[ j * byteWidth + i / 8] & (128 >> (i & 7))) { 00344 drawPixel(x+i, y+j, color); 00345 } 00346 } 00347 } 00348 } 00349 00350 int Adafruit_GFX::_putc(int c) { 00351 if (c == '\n') { 00352 cursor_y += textsize*8; 00353 cursor_x = 0; 00354 } else if (c == '\r') { 00355 // skip em 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 00365 return c; 00366 } 00367 int Adafruit_GFX::_getc() { 00368 return -1; 00369 } 00370 00371 // draw a character 00372 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, 00373 uint16_t color, uint16_t bg, uint8_t size) { 00374 00375 if((x >= _width) || // Clip right 00376 (y >= _height) || // Clip bottom 00377 ((x + 6 * size - 1) < 0) || // Clip left 00378 ((y + 8 * size - 1) < 0)) // Clip top 00379 return; 00380 00381 for (int8_t i=0; i<6; i++ ) { 00382 uint8_t line; 00383 if (i == 5) 00384 line = 0x0; 00385 else 00386 line = font[(c*5)+i]; 00387 for (int8_t j = 0; j<8; j++) { 00388 if (line & 0x1) { 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 } 00394 } else if (bg != color) { 00395 if (size == 1) // default size 00396 drawPixel(x+i, y+j, bg); 00397 else { // big size 00398 fillRect(x+i*size, y+j*size, size, size, bg); 00399 } 00400 } 00401 line >>= 1; 00402 } 00403 } 00404 } 00405 00406 void Adafruit_GFX::setCursor(int16_t x, int16_t y) { 00407 cursor_x = x; 00408 cursor_y = y; 00409 } 00410 00411 00412 void Adafruit_GFX::setTextSize(uint8_t s) { 00413 textsize = (s > 0) ? s : 1; 00414 } 00415 00416 00417 void Adafruit_GFX::setTextColor(uint16_t c) { 00418 textcolor = c; 00419 textbgcolor = c; 00420 // for 'transparent' background, we'll set the bg 00421 // to the same as fg instead of using a flag 00422 } 00423 00424 void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) { 00425 textcolor = c; 00426 textbgcolor = b; 00427 } 00428 00429 void Adafruit_GFX::setTextWrap(boolean w) { 00430 wrap = w; 00431 } 00432 00433 uint8_t Adafruit_GFX::getRotation(void) { 00434 rotation %= 4; 00435 return rotation; 00436 } 00437 00438 void Adafruit_GFX::setRotation(uint8_t x) { 00439 x %= 4; // cant be higher than 3 00440 rotation = x; 00441 switch (x) { 00442 case 0: 00443 case 2: 00444 _width = WIDTH; 00445 _height = HEIGHT; 00446 break; 00447 case 1: 00448 case 3: 00449 _width = HEIGHT; 00450 _height = WIDTH; 00451 break; 00452 } 00453 } 00454 00455 00456 void Adafruit_GFX::invertDisplay(boolean i) { 00457 // do nothing, can be subclassed 00458 } 00459 00460 00461 // return the size of the display which depends on the rotation! 00462 int16_t Adafruit_GFX::width(void) { 00463 return _width; 00464 } 00465 00466 int16_t Adafruit_GFX::height(void) { 00467 return _height; 00468 }
Generated on Tue Jul 12 2022 20:45:22 by
1.7.2
