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