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