David Prentice
/
Nucleo_dir_L152
Please run it on your NUCLEO-L152
Embed:
(wiki syntax)
Show/hide line numbers
ADA_GFX_kbv.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 #include "ADA_GFX_kbv.h" 00035 #ifdef __AVR__ 00036 #include <avr/pgmspace.h> 00037 #else 00038 #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) 00039 #define PROGMEM 00040 #endif 00041 #include "glcdfont.inc" 00042 00043 Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): 00044 WIDTH(w), HEIGHT(h) 00045 { 00046 _width = WIDTH; 00047 _height = HEIGHT; 00048 rotation = 0; 00049 cursor_y = cursor_x = 0; 00050 textsize = 1; 00051 textcolor = textbgcolor = 0xFFFF; 00052 wrap = true; 00053 } 00054 00055 // Draw a circle outline 00056 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, 00057 uint16_t color) { 00058 int16_t f = 1 - r; 00059 int16_t ddF_x = 1; 00060 int16_t ddF_y = -2 * r; 00061 int16_t x = 0; 00062 int16_t y = r; 00063 00064 drawPixel(x0 , y0+r, color); 00065 drawPixel(x0 , y0-r, color); 00066 drawPixel(x0+r, y0 , color); 00067 drawPixel(x0-r, y0 , color); 00068 00069 while (x<y) { 00070 if (f >= 0) { 00071 y--; 00072 ddF_y += 2; 00073 f += ddF_y; 00074 } 00075 x++; 00076 ddF_x += 2; 00077 f += ddF_x; 00078 00079 drawPixel(x0 + x, y0 + y, color); 00080 drawPixel(x0 - x, y0 + y, color); 00081 drawPixel(x0 + x, y0 - y, color); 00082 drawPixel(x0 - x, y0 - y, color); 00083 drawPixel(x0 + y, y0 + x, color); 00084 drawPixel(x0 - y, y0 + x, color); 00085 drawPixel(x0 + y, y0 - x, color); 00086 drawPixel(x0 - y, y0 - x, color); 00087 } 00088 } 00089 00090 void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, 00091 int16_t r, uint8_t cornername, uint16_t color) { 00092 int16_t f = 1 - r; 00093 int16_t ddF_x = 1; 00094 int16_t ddF_y = -2 * r; 00095 int16_t x = 0; 00096 int16_t y = r; 00097 00098 while (x<y) { 00099 if (f >= 0) { 00100 y--; 00101 ddF_y += 2; 00102 f += ddF_y; 00103 } 00104 x++; 00105 ddF_x += 2; 00106 f += ddF_x; 00107 if (cornername & 0x4) { 00108 drawPixel(x0 + x, y0 + y, color); 00109 drawPixel(x0 + y, y0 + x, color); 00110 } 00111 if (cornername & 0x2) { 00112 drawPixel(x0 + x, y0 - y, color); 00113 drawPixel(x0 + y, y0 - x, color); 00114 } 00115 if (cornername & 0x8) { 00116 drawPixel(x0 - y, y0 + x, color); 00117 drawPixel(x0 - x, y0 + y, color); 00118 } 00119 if (cornername & 0x1) { 00120 drawPixel(x0 - y, y0 - x, color); 00121 drawPixel(x0 - x, y0 - y, color); 00122 } 00123 } 00124 } 00125 00126 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, 00127 uint16_t color) { 00128 drawFastVLine(x0, y0-r, 2*r+1, color); 00129 fillCircleHelper(x0, y0, r, 3, 0, color); 00130 } 00131 00132 // Used to do circles and roundrects 00133 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, 00134 uint8_t cornername, int16_t delta, uint16_t color) { 00135 00136 int16_t f = 1 - r; 00137 int16_t ddF_x = 1; 00138 int16_t ddF_y = -2 * r; 00139 int16_t x = 0; 00140 int16_t y = r; 00141 00142 while (x<y) { 00143 if (f >= 0) { 00144 y--; 00145 ddF_y += 2; 00146 f += ddF_y; 00147 } 00148 x++; 00149 ddF_x += 2; 00150 f += ddF_x; 00151 00152 if (cornername & 0x1) { 00153 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 00154 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 00155 } 00156 if (cornername & 0x2) { 00157 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); 00158 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); 00159 } 00160 } 00161 } 00162 00163 // Bresenham's algorithm - thx wikpedia 00164 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, 00165 int16_t x1, int16_t y1, 00166 uint16_t color) { 00167 int16_t steep = abs(y1 - y0) > abs(x1 - x0); 00168 if (steep) { 00169 swap(x0, y0); 00170 swap(x1, y1); 00171 } 00172 00173 if (x0 > x1) { 00174 swap(x0, x1); 00175 swap(y0, y1); 00176 } 00177 00178 int16_t dx, dy; 00179 dx = x1 - x0; 00180 dy = abs(y1 - y0); 00181 00182 int16_t err = dx / 2; 00183 int16_t ystep; 00184 00185 if (y0 < y1) { 00186 ystep = 1; 00187 } else { 00188 ystep = -1; 00189 } 00190 00191 for (; x0<=x1; x0++) { 00192 if (steep) { 00193 drawPixel(y0, x0, color); 00194 } else { 00195 drawPixel(x0, y0, color); 00196 } 00197 err -= dy; 00198 if (err < 0) { 00199 y0 += ystep; 00200 err += dx; 00201 } 00202 } 00203 } 00204 00205 // Draw a rectangle 00206 void Adafruit_GFX::drawRect(int16_t x, int16_t y, 00207 int16_t w, int16_t h, 00208 uint16_t color) { 00209 drawFastHLine(x, y, w, color); 00210 drawFastHLine(x, y+h-1, w, color); 00211 drawFastVLine(x, y, h, color); 00212 drawFastVLine(x+w-1, y, h, color); 00213 } 00214 00215 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, 00216 int16_t h, uint16_t color) { 00217 // Update in subclasses if desired! 00218 drawLine(x, y, x, y+h-1, color); 00219 } 00220 00221 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, 00222 int16_t w, uint16_t color) { 00223 // Update in subclasses if desired! 00224 drawLine(x, y, x+w-1, y, color); 00225 } 00226 00227 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 00228 uint16_t color) { 00229 // Update in subclasses if desired! 00230 for (int16_t i=x; i<x+w; i++) { 00231 drawFastVLine(i, y, h, color); 00232 } 00233 } 00234 00235 void Adafruit_GFX::fillScreen(uint16_t color) { 00236 fillRect(0, 0, _width, _height, color); 00237 } 00238 00239 // Draw a rounded rectangle 00240 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, 00241 int16_t h, int16_t r, uint16_t color) { 00242 // smarter version 00243 drawFastHLine(x+r , y , w-2*r, color); // Top 00244 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom 00245 drawFastVLine(x , y+r , h-2*r, color); // Left 00246 drawFastVLine(x+w-1, y+r , h-2*r, color); // Right 00247 // draw four corners 00248 drawCircleHelper(x+r , y+r , r, 1, color); 00249 drawCircleHelper(x+w-r-1, y+r , r, 2, color); 00250 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); 00251 drawCircleHelper(x+r , y+h-r-1, r, 8, color); 00252 } 00253 00254 // Fill a rounded rectangle 00255 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, 00256 int16_t h, int16_t r, uint16_t color) { 00257 // smarter version 00258 fillRect(x+r, y, w-2*r, h, color); 00259 00260 // draw four corners 00261 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); 00262 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); 00263 } 00264 00265 // Draw a triangle 00266 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0, 00267 int16_t x1, int16_t y1, 00268 int16_t x2, int16_t y2, uint16_t color) { 00269 drawLine(x0, y0, x1, y1, color); 00270 drawLine(x1, y1, x2, y2, color); 00271 drawLine(x2, y2, x0, y0, color); 00272 } 00273 00274 // Fill a triangle 00275 void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0, 00276 int16_t x1, int16_t y1, 00277 int16_t x2, int16_t y2, uint16_t color) { 00278 00279 int16_t a, b, y, last; 00280 00281 // Sort coordinates by Y order (y2 >= y1 >= y0) 00282 if (y0 > y1) { 00283 swap(y0, y1); swap(x0, x1); 00284 } 00285 if (y1 > y2) { 00286 swap(y2, y1); swap(x2, x1); 00287 } 00288 if (y0 > y1) { 00289 swap(y0, y1); swap(x0, x1); 00290 } 00291 00292 if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing 00293 a = b = x0; 00294 if(x1 < a) a = x1; 00295 else if(x1 > b) b = x1; 00296 if(x2 < a) a = x2; 00297 else if(x2 > b) b = x2; 00298 drawFastHLine(a, y0, b-a+1, color); 00299 return; 00300 } 00301 00302 int16_t 00303 dx01 = x1 - x0, 00304 dy01 = y1 - y0, 00305 dx02 = x2 - x0, 00306 dy02 = y2 - y0, 00307 dx12 = x2 - x1, 00308 dy12 = y2 - y1; 00309 int32_t //.kbv larger triangles overflow with int16_t 00310 sa = 0, 00311 sb = 0; 00312 00313 // For upper part of triangle, find scanline crossings for segments 00314 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 00315 // is included here (and second loop will be skipped, avoiding a /0 00316 // error there), otherwise scanline y1 is skipped here and handled 00317 // in the second loop...which also avoids a /0 error here if y0=y1 00318 // (flat-topped triangle). 00319 if(y1 == y2) last = y1; // Include y1 scanline 00320 else last = y1-1; // Skip it 00321 00322 for(y=y0; y<=last; y++) { 00323 a = x0 + sa / dy01; 00324 b = x0 + sb / dy02; 00325 sa += dx01; 00326 sb += dx02; 00327 /* longhand: 00328 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); 00329 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00330 */ 00331 if(a > b) swap(a,b); 00332 drawFastHLine(a, y, b-a+1, color); 00333 } 00334 00335 // For lower part of triangle, find scanline crossings for segments 00336 // 0-2 and 1-2. This loop is skipped if y1=y2. 00337 sa = dx12 * (y - y1); 00338 sb = dx02 * (y - y0); 00339 for(; y<=y2; y++) { 00340 a = x1 + sa / dy12; 00341 b = x0 + sb / dy02; 00342 sa += dx12; 00343 sb += dx02; 00344 /* longhand: 00345 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); 00346 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00347 */ 00348 if(a > b) 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, 00354 const uint8_t *bitmap, int16_t w, int16_t h, 00355 uint16_t color) { 00356 00357 int16_t i, j, byteWidth = (w + 7) / 8; 00358 00359 for(j=0; j<h; j++) { 00360 for(i=0; i<w; i++ ) { 00361 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { 00362 drawPixel(x+i, y+j, color); 00363 } 00364 } 00365 } 00366 } 00367 00368 #if defined(ARDUINO) && ARDUINO < 100 00369 virtual void Adafruit_GFX::write(uint8_t c) { 00370 #else 00371 size_t Adafruit_GFX::write(uint8_t c) { 00372 #endif 00373 if (c == '\n') { 00374 cursor_y += textsize*8; 00375 cursor_x = 0; 00376 } else if (c == '\r') { 00377 // skip em 00378 } else { 00379 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); 00380 cursor_x += textsize*6; 00381 if (wrap && (cursor_x > (_width - textsize*6))) { 00382 cursor_y += textsize*8; 00383 cursor_x = 0; 00384 } 00385 } 00386 #if !(defined(ARDUINO) && ARDUINO < 100) 00387 return 1; 00388 #endif 00389 } 00390 00391 // Draw a character 00392 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, 00393 uint16_t color, uint16_t bg, uint8_t size) { 00394 00395 if((x >= _width) || // Clip right 00396 (y >= _height) || // Clip bottom 00397 ((x + 6 * size - 1) < 0) || // Clip left 00398 ((y + 8 * size - 1) < 0)) // Clip top 00399 return; 00400 00401 for (int8_t i=0; i<6; i++ ) { 00402 uint8_t line; 00403 if (i == 5) 00404 line = 0x0; 00405 else 00406 line = pgm_read_byte(font+(c*5)+i); 00407 for (int8_t j = 0; j<8; j++) { 00408 if (line & 0x1) { 00409 if (size == 1) // default size 00410 drawPixel(x+i, y+j, color); 00411 else { // big size 00412 fillRect(x+(i*size), y+(j*size), size, size, color); 00413 } 00414 } else if (bg != color) { 00415 if (size == 1) // default size 00416 drawPixel(x+i, y+j, bg); 00417 else { // big size 00418 fillRect(x+i*size, y+j*size, size, size, bg); 00419 } 00420 } 00421 line >>= 1; 00422 } 00423 } 00424 } 00425 00426 void Adafruit_GFX::setCursor(int16_t x, int16_t y) { 00427 cursor_x = x; 00428 cursor_y = y; 00429 } 00430 00431 void Adafruit_GFX::setTextSize(uint8_t s) { 00432 textsize = (s > 0) ? s : 1; 00433 } 00434 00435 void Adafruit_GFX::setTextColor(uint16_t c) { 00436 // For 'transparent' background, we'll set the bg 00437 // to the same as fg instead of using a flag 00438 textcolor = textbgcolor = c; 00439 } 00440 00441 void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) { 00442 textcolor = c; 00443 textbgcolor = b; 00444 } 00445 00446 void Adafruit_GFX::setTextWrap(boolean w) { 00447 wrap = w; 00448 } 00449 00450 uint8_t Adafruit_GFX::getRotation(void) { 00451 return rotation; 00452 } 00453 00454 void Adafruit_GFX::setRotation(uint8_t x) { 00455 rotation = (x & 3); 00456 switch(rotation) { 00457 case 0: 00458 case 2: 00459 _width = WIDTH; 00460 _height = HEIGHT; 00461 break; 00462 case 1: 00463 case 3: 00464 _width = HEIGHT; 00465 _height = WIDTH; 00466 break; 00467 } 00468 } 00469 00470 // Return the size of the display (per current rotation) 00471 int16_t Adafruit_GFX::width(void) { 00472 return _width; 00473 } 00474 00475 int16_t Adafruit_GFX::height(void) { 00476 return _height; 00477 } 00478 00479 void Adafruit_GFX::invertDisplay(boolean i) { 00480 // Do nothing, must be subclassed if supported 00481 } 00482 00483 // this looks the most convenient method of all. i.e. forget about print() and println() 00484 // and could be part of ADA_GFX_kbv.cpp. possibly overwritten by later classes. 00485 // possibly use global buffer rather than stack. 00486 #include <stdarg.h> 00487 int Adafruit_GFX::printf(const char* format, ...) 00488 { 00489 char buffer[80]; 00490 va_list args; 00491 va_start (args, format); 00492 vsnprintf (buffer, 80, format, args); 00493 for (char *p = buffer; *p; p++) write(*p); 00494 va_end (args); 00495 return strlen(buffer); 00496 }
Generated on Sat Jul 23 2022 01:16:42 by 1.7.2