ILI9340 Library based on the Arduino version from Adafruit. It has been tested with a custom STM32F103C8 board.
Adafruit_GFX.cpp
00001 /* 00002 This is the core graphics library for all our displays, providing a common 00003 set of graphics primitives (points, lines, circles, etc.). It needs to be 00004 paired with a hardware-specific library for each display device we carry 00005 (to handle the lower-level functions). 00006 00007 Adafruit invests time and resources providing this open source code, please 00008 support Adafruit & open-source hardware by purchasing products from Adafruit! 00009 00010 Copyright (c) 2013 Adafruit Industries. All rights reserved. 00011 00012 Redistribution and use in source and binary forms, with or without 00013 modification, are permitted provided that the following conditions are met: 00014 00015 - Redistributions of source code must retain the above copyright notice, 00016 this list of conditions and the following disclaimer. 00017 - Redistributions in binary form must reproduce the above copyright notice, 00018 this list of conditions and the following disclaimer in the documentation 00019 and/or other materials provided with the distribution. 00020 00021 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00022 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00023 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00024 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00025 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00026 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00027 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00028 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00029 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00030 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00031 POSSIBILITY OF SUCH DAMAGE. 00032 */ 00033 00034 // Modified for mbed 00035 // by Georgios Moralis 00036 00037 #include "Adafruit_GFX.h" 00038 #include "glcdfont.c" 00039 //#include "stm32f10x.h" 00040 //#include "stm32f10x_conf.h" 00041 //#include "stm32f10x_spi.h" 00042 00043 //#include "core_cm3.h" 00044 #include "stdint.h" 00045 00046 #define COMPILE_FOR_STM32 00047 #ifdef COMPILE_FOR_STM32 00048 #include "stm32f10x_flash.h" 00049 #endif 00050 00051 uint8_t pgm_read_byte(const uint8_t *whatever) 00052 { 00053 uint8_t rd; 00054 #ifdef COMPILE_FOR_STM32 00055 FLASH_Unlock(); 00056 #endif 00057 rd = *((uint8_t *) whatever); 00058 #ifdef COMPILE_FOR_STM32 00059 FLASH_Lock(); 00060 #endif 00061 return rd; 00062 } 00063 00064 int16_t abs(int16_t num) 00065 { 00066 if(num>=0) 00067 return num; 00068 else 00069 return -num; 00070 } 00071 00072 00073 00074 Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): 00075 WIDTH(w), HEIGHT(h) 00076 { 00077 _width = WIDTH; 00078 _height = HEIGHT; 00079 rotation = 0; 00080 cursor_y = cursor_x = 0; 00081 textsize = 1; 00082 textcolor = textbgcolor = 0xFFFF; 00083 wrap = true; 00084 } 00085 00086 // Draw a circle outline 00087 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, 00088 uint16_t color) { 00089 int16_t f = 1 - r; 00090 int16_t ddF_x = 1; 00091 int16_t ddF_y = -2 * r; 00092 int16_t x = 0; 00093 int16_t y = r; 00094 00095 drawPixel(x0 , y0+r, color); 00096 drawPixel(x0 , y0-r, color); 00097 drawPixel(x0+r, y0 , color); 00098 drawPixel(x0-r, y0 , color); 00099 00100 while (x<y) { 00101 if (f >= 0) { 00102 y--; 00103 ddF_y += 2; 00104 f += ddF_y; 00105 } 00106 x++; 00107 ddF_x += 2; 00108 f += ddF_x; 00109 00110 drawPixel(x0 + x, y0 + y, color); 00111 drawPixel(x0 - x, y0 + y, color); 00112 drawPixel(x0 + x, y0 - y, color); 00113 drawPixel(x0 - x, y0 - y, color); 00114 drawPixel(x0 + y, y0 + x, color); 00115 drawPixel(x0 - y, y0 + x, color); 00116 drawPixel(x0 + y, y0 - x, color); 00117 drawPixel(x0 - y, y0 - x, color); 00118 } 00119 } 00120 00121 void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, 00122 int16_t r, uint8_t cornername, uint16_t color) { 00123 int16_t f = 1 - r; 00124 int16_t ddF_x = 1; 00125 int16_t ddF_y = -2 * r; 00126 int16_t x = 0; 00127 int16_t y = r; 00128 00129 while (x<y) { 00130 if (f >= 0) { 00131 y--; 00132 ddF_y += 2; 00133 f += ddF_y; 00134 } 00135 x++; 00136 ddF_x += 2; 00137 f += ddF_x; 00138 if (cornername & 0x4) { 00139 drawPixel(x0 + x, y0 + y, color); 00140 drawPixel(x0 + y, y0 + x, color); 00141 } 00142 if (cornername & 0x2) { 00143 drawPixel(x0 + x, y0 - y, color); 00144 drawPixel(x0 + y, y0 - x, color); 00145 } 00146 if (cornername & 0x8) { 00147 drawPixel(x0 - y, y0 + x, color); 00148 drawPixel(x0 - x, y0 + y, color); 00149 } 00150 if (cornername & 0x1) { 00151 drawPixel(x0 - y, y0 - x, color); 00152 drawPixel(x0 - x, y0 - y, color); 00153 } 00154 } 00155 } 00156 00157 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, 00158 uint16_t color) { 00159 drawFastVLine(x0, y0-r, 2*r+1, color); 00160 fillCircleHelper(x0, y0, r, 3, 0, color); 00161 } 00162 00163 // Used to do circles and roundrects 00164 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, 00165 uint8_t cornername, int16_t delta, uint16_t color) { 00166 00167 int16_t f = 1 - r; 00168 int16_t ddF_x = 1; 00169 int16_t ddF_y = -2 * r; 00170 int16_t x = 0; 00171 int16_t y = r; 00172 00173 while (x<y) { 00174 if (f >= 0) { 00175 y--; 00176 ddF_y += 2; 00177 f += ddF_y; 00178 } 00179 x++; 00180 ddF_x += 2; 00181 f += ddF_x; 00182 00183 if (cornername & 0x1) { 00184 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 00185 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 00186 } 00187 if (cornername & 0x2) { 00188 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); 00189 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); 00190 } 00191 } 00192 } 00193 00194 // Bresenham's algorithm - thx wikpedia 00195 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, 00196 int16_t x1, int16_t y1, 00197 uint16_t color) { 00198 int16_t steep = abs(y1 - y0) > abs(x1 - x0); 00199 if (steep) { 00200 swap(x0, y0); 00201 swap(x1, y1); 00202 } 00203 00204 if (x0 > x1) { 00205 swap(x0, x1); 00206 swap(y0, y1); 00207 } 00208 00209 int16_t dx, dy; 00210 dx = x1 - x0; 00211 dy = abs(y1 - y0); 00212 00213 int16_t err = dx / 2; 00214 int16_t ystep; 00215 00216 if (y0 < y1) { 00217 ystep = 1; 00218 } else { 00219 ystep = -1; 00220 } 00221 00222 for (; x0<=x1; x0++) { 00223 if (steep) { 00224 drawPixel(y0, x0, color); 00225 } else { 00226 drawPixel(x0, y0, color); 00227 } 00228 err -= dy; 00229 if (err < 0) { 00230 y0 += ystep; 00231 err += dx; 00232 } 00233 } 00234 } 00235 00236 // Draw a rectangle 00237 void Adafruit_GFX::drawRect(int16_t x, int16_t y, 00238 int16_t w, int16_t h, 00239 uint16_t color) { 00240 drawFastHLine(x, y, w, color); 00241 drawFastHLine(x, y+h-1, w, color); 00242 drawFastVLine(x, y, h, color); 00243 drawFastVLine(x+w-1, y, h, color); 00244 } 00245 00246 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, 00247 int16_t h, uint16_t color) { 00248 // Update in subclasses if desired! 00249 drawLine(x, y, x, y+h-1, color); 00250 } 00251 00252 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, 00253 int16_t w, uint16_t color) { 00254 // Update in subclasses if desired! 00255 drawLine(x, y, x+w-1, y, color); 00256 } 00257 00258 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 00259 uint16_t color) { 00260 // Update in subclasses if desired! 00261 for (int16_t i=x; i<x+w; i++) { 00262 drawFastVLine(i, y, h, color); 00263 } 00264 } 00265 00266 void Adafruit_GFX::fillScreen(uint16_t color) { 00267 fillRect(0, 0, _width, _height, color); 00268 } 00269 00270 // Draw a rounded rectangle 00271 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, 00272 int16_t h, int16_t r, uint16_t color) { 00273 // smarter version 00274 drawFastHLine(x+r , y , w-2*r, color); // Top 00275 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom 00276 drawFastVLine(x , y+r , h-2*r, color); // Left 00277 drawFastVLine(x+w-1, y+r , h-2*r, color); // Right 00278 // draw four corners 00279 drawCircleHelper(x+r , y+r , r, 1, color); 00280 drawCircleHelper(x+w-r-1, y+r , r, 2, color); 00281 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); 00282 drawCircleHelper(x+r , y+h-r-1, r, 8, color); 00283 } 00284 00285 // Fill a rounded rectangle 00286 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, 00287 int16_t h, int16_t r, uint16_t color) { 00288 // smarter version 00289 fillRect(x+r, y, w-2*r, h, color); 00290 00291 // draw four corners 00292 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); 00293 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); 00294 } 00295 00296 // Draw a triangle 00297 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0, 00298 int16_t x1, int16_t y1, 00299 int16_t x2, int16_t y2, uint16_t color) { 00300 drawLine(x0, y0, x1, y1, color); 00301 drawLine(x1, y1, x2, y2, color); 00302 drawLine(x2, y2, x0, y0, color); 00303 } 00304 00305 // Fill a triangle 00306 void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0, 00307 int16_t x1, int16_t y1, 00308 int16_t x2, int16_t y2, uint16_t color) { 00309 00310 int16_t a, b, y, last; 00311 00312 // Sort coordinates by Y order (y2 >= y1 >= y0) 00313 if (y0 > y1) { 00314 swap(y0, y1); swap(x0, x1); 00315 } 00316 if (y1 > y2) { 00317 swap(y2, y1); swap(x2, x1); 00318 } 00319 if (y0 > y1) { 00320 swap(y0, y1); swap(x0, x1); 00321 } 00322 00323 if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing 00324 a = b = x0; 00325 if(x1 < a) a = x1; 00326 else if(x1 > b) b = x1; 00327 if(x2 < a) a = x2; 00328 else if(x2 > b) b = x2; 00329 drawFastHLine(a, y0, b-a+1, color); 00330 return; 00331 } 00332 00333 int16_t 00334 dx01 = x1 - x0, 00335 dy01 = y1 - y0, 00336 dx02 = x2 - x0, 00337 dy02 = y2 - y0, 00338 dx12 = x2 - x1, 00339 dy12 = y2 - y1; 00340 int32_t 00341 sa = 0, 00342 sb = 0; 00343 00344 // For upper part of triangle, find scanline crossings for segments 00345 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 00346 // is included here (and second loop will be skipped, avoiding a /0 00347 // error there), otherwise scanline y1 is skipped here and handled 00348 // in the second loop...which also avoids a /0 error here if y0=y1 00349 // (flat-topped triangle). 00350 if(y1 == y2) last = y1; // Include y1 scanline 00351 else last = y1-1; // Skip it 00352 00353 for(y=y0; y<=last; y++) { 00354 a = x0 + sa / dy01; 00355 b = x0 + sb / dy02; 00356 sa += dx01; 00357 sb += dx02; 00358 /* longhand: 00359 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); 00360 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00361 */ 00362 if(a > b) swap(a,b); 00363 drawFastHLine(a, y, b-a+1, color); 00364 } 00365 00366 // For lower part of triangle, find scanline crossings for segments 00367 // 0-2 and 1-2. This loop is skipped if y1=y2. 00368 sa = dx12 * (y - y1); 00369 sb = dx02 * (y - y0); 00370 for(; y<=y2; y++) { 00371 a = x1 + sa / dy12; 00372 b = x0 + sb / dy02; 00373 sa += dx12; 00374 sb += dx02; 00375 /* longhand: 00376 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); 00377 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00378 */ 00379 if(a > b) swap(a,b); 00380 drawFastHLine(a, y, b-a+1, color); 00381 } 00382 } 00383 00384 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, 00385 const uint8_t *bitmap, int16_t w, int16_t h, 00386 uint16_t color) { 00387 00388 int16_t i, j, byteWidth = (w + 7) / 8; 00389 00390 for(j=0; j<h; j++) { 00391 for(i=0; i<w; i++ ) { 00392 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { 00393 drawPixel(x+i, y+j, color); 00394 } 00395 } 00396 } 00397 } 00398 00399 // Draw a 1-bit color bitmap at the specified x, y position from the 00400 // provided bitmap buffer (must be PROGMEM memory) using color as the 00401 // foreground color and bg as the background color. 00402 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, 00403 const uint8_t *bitmap, int16_t w, int16_t h, 00404 uint16_t color, uint16_t bg) { 00405 00406 int16_t i, j, byteWidth = (w + 7) / 8; 00407 00408 for(j=0; j<h; j++) { 00409 for(i=0; i<w; i++ ) { 00410 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { 00411 drawPixel(x+i, y+j, color); 00412 } 00413 else { 00414 drawPixel(x+i, y+j, bg); 00415 } 00416 } 00417 } 00418 } 00419 00420 //Draw XBitMap Files (*.xbm), exported from GIMP, 00421 //Usage: Export from GIMP to *.xbm, rename *.xbm to *.c and open in editor. 00422 //C Array can be directly used with this function 00423 void Adafruit_GFX::drawXBitmap(int16_t x, int16_t y, 00424 const uint8_t *bitmap, int16_t w, int16_t h, 00425 uint16_t color) { 00426 00427 int16_t i, j, byteWidth = (w + 7) / 8; 00428 00429 for(j=0; j<h; j++) { 00430 for(i=0; i<w; i++ ) { 00431 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (1 << (i % 8))) { 00432 drawPixel(x+i, y+j, color); 00433 } 00434 } 00435 } 00436 } 00437 00438 #if ARDUINO >= 100 00439 size_t Adafruit_GFX::write(uint8_t c) { 00440 #else 00441 void Adafruit_GFX::write(uint8_t c) { 00442 #endif 00443 if (c == '\n') { 00444 cursor_y += textsize*8; 00445 cursor_x = 0; 00446 } else if (c == '\r') { 00447 // skip em 00448 } else { 00449 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); 00450 cursor_x += textsize*6; 00451 if (wrap && (cursor_x > (_width - textsize*6))) { 00452 cursor_y += textsize*8; 00453 cursor_x = 0; 00454 } 00455 } 00456 #if ARDUINO >= 100 00457 return 1; 00458 #endif 00459 } 00460 00461 // Draw a character 00462 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, 00463 uint16_t color, uint16_t bg, uint8_t size) { 00464 00465 if((x >= _width) || // Clip right 00466 (y >= _height) || // Clip bottom 00467 ((x + 6 * size - 1) < 0) || // Clip left 00468 ((y + 8 * size - 1) < 0)) // Clip top 00469 return; 00470 00471 for (int8_t i=0; i<6; i++ ) { 00472 uint8_t line; 00473 if (i == 5) 00474 line = 0x0; 00475 else 00476 line = pgm_read_byte(font+(c*5)+i); 00477 for (int8_t j = 0; j<8; j++) { 00478 if (line & 0x1) { 00479 if (size == 1) // default size 00480 drawPixel(x+i, y+j, color); 00481 else { // big size 00482 fillRect(x+(i*size), y+(j*size), size, size, color); 00483 } 00484 } else if (bg != color) { 00485 if (size == 1) // default size 00486 drawPixel(x+i, y+j, bg); 00487 else { // big size 00488 fillRect(x+i*size, y+j*size, size, size, bg); 00489 } 00490 } 00491 line >>= 1; 00492 } 00493 } 00494 } 00495 00496 void Adafruit_GFX::setCursor(int16_t x, int16_t y) { 00497 cursor_x = x; 00498 cursor_y = y; 00499 } 00500 00501 void Adafruit_GFX::setTextSize(uint8_t s) { 00502 textsize = (s > 0) ? s : 1; 00503 } 00504 00505 void Adafruit_GFX::setTextColor(uint16_t c) { 00506 // For 'transparent' background, we'll set the bg 00507 // to the same as fg instead of using a flag 00508 textcolor = textbgcolor = c; 00509 } 00510 00511 void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) { 00512 textcolor = c; 00513 textbgcolor = b; 00514 } 00515 00516 void Adafruit_GFX::setTextWrap(char w) { 00517 wrap = w; 00518 } 00519 00520 uint8_t Adafruit_GFX::getRotation(void) const { 00521 return rotation; 00522 } 00523 00524 void Adafruit_GFX::setRotation(uint8_t x) { 00525 rotation = (x & 3); 00526 switch(rotation) { 00527 case 0: 00528 case 2: 00529 _width = WIDTH; 00530 _height = HEIGHT; 00531 break; 00532 case 1: 00533 case 3: 00534 _width = HEIGHT; 00535 _height = WIDTH; 00536 break; 00537 } 00538 } 00539 00540 // Return the size of the display (per current rotation) 00541 int16_t Adafruit_GFX::width(void) const { 00542 return _width; 00543 } 00544 00545 int16_t Adafruit_GFX::height(void) const { 00546 return _height; 00547 } 00548 00549 void Adafruit_GFX::invertDisplay(char i) { 00550 // Do nothing, must be subclassed if supported 00551 } 00552 00553
Generated on Thu Jul 14 2022 16:40:07 by 1.7.2