Final

Dependencies:   IRremote HCSR04 TB6612FNG

Committer:
eunmango
Date:
Sun Jun 16 04:51:51 2019 +0000
Revision:
97:59d348745d96
s

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eunmango 97:59d348745d96 1 /*
eunmango 97:59d348745d96 2 This is the core graphics library for all our displays, providing a common
eunmango 97:59d348745d96 3 set of graphics primitives (points, lines, circles, etc.). It needs to be
eunmango 97:59d348745d96 4 paired with a hardware-specific library for each display device we carry
eunmango 97:59d348745d96 5 (to handle the lower-level functions).
eunmango 97:59d348745d96 6
eunmango 97:59d348745d96 7 Adafruit invests time and resources providing this open source code, please
eunmango 97:59d348745d96 8 support Adafruit & open-source hardware by purchasing products from Adafruit!
eunmango 97:59d348745d96 9
eunmango 97:59d348745d96 10 Copyright (c) 2013 Adafruit Industries. All rights reserved.
eunmango 97:59d348745d96 11
eunmango 97:59d348745d96 12 Redistribution and use in source and binary forms, with or without
eunmango 97:59d348745d96 13 modification, are permitted provided that the following conditions are met:
eunmango 97:59d348745d96 14
eunmango 97:59d348745d96 15 - Redistributions of source code must retain the above copyright notice,
eunmango 97:59d348745d96 16 this list of conditions and the following disclaimer.
eunmango 97:59d348745d96 17 - Redistributions in binary form must reproduce the above copyright notice,
eunmango 97:59d348745d96 18 this list of conditions and the following disclaimer in the documentation
eunmango 97:59d348745d96 19 and/or other materials provided with the distribution.
eunmango 97:59d348745d96 20
eunmango 97:59d348745d96 21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
eunmango 97:59d348745d96 22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
eunmango 97:59d348745d96 23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
eunmango 97:59d348745d96 24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
eunmango 97:59d348745d96 25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
eunmango 97:59d348745d96 26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
eunmango 97:59d348745d96 27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
eunmango 97:59d348745d96 28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
eunmango 97:59d348745d96 29 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
eunmango 97:59d348745d96 30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
eunmango 97:59d348745d96 31 POSSIBILITY OF SUCH DAMAGE.
eunmango 97:59d348745d96 32 */
eunmango 97:59d348745d96 33
eunmango 97:59d348745d96 34 #include "Adafruit_GFX.h"
eunmango 97:59d348745d96 35 #include "glcdfont.c"
eunmango 97:59d348745d96 36
eunmango 97:59d348745d96 37 // Many (but maybe not all) non-AVR board installs define macros
eunmango 97:59d348745d96 38 // for compatibility with existing PROGMEM-reading AVR code.
eunmango 97:59d348745d96 39 // Do our own checks and defines here for good measure...
eunmango 97:59d348745d96 40
eunmango 97:59d348745d96 41 #ifndef pgm_read_byte
eunmango 97:59d348745d96 42 #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
eunmango 97:59d348745d96 43 #endif
eunmango 97:59d348745d96 44 #ifndef pgm_read_word
eunmango 97:59d348745d96 45 #define pgm_read_word(addr) (*(const unsigned short *)(addr))
eunmango 97:59d348745d96 46 #endif
eunmango 97:59d348745d96 47 #ifndef pgm_read_dword
eunmango 97:59d348745d96 48 #define pgm_read_dword(addr) (*(const unsigned long *)(addr))
eunmango 97:59d348745d96 49 #endif
eunmango 97:59d348745d96 50
eunmango 97:59d348745d96 51 // Pointers are a peculiar case...typically 16-bit on AVR boards,
eunmango 97:59d348745d96 52 // 32 bits elsewhere. Try to accommodate both...
eunmango 97:59d348745d96 53
eunmango 97:59d348745d96 54 #if !defined(__INT_MAX__) || (__INT_MAX__ > 0xFFFF)
eunmango 97:59d348745d96 55 #define pgm_read_pointer(addr) ((void *)pgm_read_dword(addr))
eunmango 97:59d348745d96 56 #else
eunmango 97:59d348745d96 57 #define pgm_read_pointer(addr) ((void *)pgm_read_word(addr))
eunmango 97:59d348745d96 58 #endif
eunmango 97:59d348745d96 59
eunmango 97:59d348745d96 60 #ifndef min
eunmango 97:59d348745d96 61 #define min(a,b) (((a) < (b)) ? (a) : (b))
eunmango 97:59d348745d96 62 #endif
eunmango 97:59d348745d96 63
eunmango 97:59d348745d96 64 #ifndef _swap_int16_t
eunmango 97:59d348745d96 65 #define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }
eunmango 97:59d348745d96 66 #endif
eunmango 97:59d348745d96 67
eunmango 97:59d348745d96 68 Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h):
eunmango 97:59d348745d96 69 WIDTH(w), HEIGHT(h)
eunmango 97:59d348745d96 70 {
eunmango 97:59d348745d96 71 _width = WIDTH;
eunmango 97:59d348745d96 72 _height = HEIGHT;
eunmango 97:59d348745d96 73 rotation = 0;
eunmango 97:59d348745d96 74 cursor_y = cursor_x = 0;
eunmango 97:59d348745d96 75 textsize = 1;
eunmango 97:59d348745d96 76 textcolor = textbgcolor = 0xFFFF;
eunmango 97:59d348745d96 77 wrap = true;
eunmango 97:59d348745d96 78 gfxFont = NULL;
eunmango 97:59d348745d96 79 }
eunmango 97:59d348745d96 80
eunmango 97:59d348745d96 81 // Draw a circle outline
eunmango 97:59d348745d96 82 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
eunmango 97:59d348745d96 83 uint16_t color) {
eunmango 97:59d348745d96 84 int16_t f = 1 - r;
eunmango 97:59d348745d96 85 int16_t ddF_x = 1;
eunmango 97:59d348745d96 86 int16_t ddF_y = -2 * r;
eunmango 97:59d348745d96 87 int16_t x = 0;
eunmango 97:59d348745d96 88 int16_t y = r;
eunmango 97:59d348745d96 89
eunmango 97:59d348745d96 90 drawPixel(x0 , y0+r, color);
eunmango 97:59d348745d96 91 drawPixel(x0 , y0-r, color);
eunmango 97:59d348745d96 92 drawPixel(x0+r, y0 , color);
eunmango 97:59d348745d96 93 drawPixel(x0-r, y0 , color);
eunmango 97:59d348745d96 94
eunmango 97:59d348745d96 95 while (x<y) {
eunmango 97:59d348745d96 96 if (f >= 0) {
eunmango 97:59d348745d96 97 y--;
eunmango 97:59d348745d96 98 ddF_y += 2;
eunmango 97:59d348745d96 99 f += ddF_y;
eunmango 97:59d348745d96 100 }
eunmango 97:59d348745d96 101 x++;
eunmango 97:59d348745d96 102 ddF_x += 2;
eunmango 97:59d348745d96 103 f += ddF_x;
eunmango 97:59d348745d96 104
eunmango 97:59d348745d96 105 drawPixel(x0 + x, y0 + y, color);
eunmango 97:59d348745d96 106 drawPixel(x0 - x, y0 + y, color);
eunmango 97:59d348745d96 107 drawPixel(x0 + x, y0 - y, color);
eunmango 97:59d348745d96 108 drawPixel(x0 - x, y0 - y, color);
eunmango 97:59d348745d96 109 drawPixel(x0 + y, y0 + x, color);
eunmango 97:59d348745d96 110 drawPixel(x0 - y, y0 + x, color);
eunmango 97:59d348745d96 111 drawPixel(x0 + y, y0 - x, color);
eunmango 97:59d348745d96 112 drawPixel(x0 - y, y0 - x, color);
eunmango 97:59d348745d96 113 }
eunmango 97:59d348745d96 114 }
eunmango 97:59d348745d96 115
eunmango 97:59d348745d96 116 void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0,
eunmango 97:59d348745d96 117 int16_t r, uint8_t cornername, uint16_t color) {
eunmango 97:59d348745d96 118 int16_t f = 1 - r;
eunmango 97:59d348745d96 119 int16_t ddF_x = 1;
eunmango 97:59d348745d96 120 int16_t ddF_y = -2 * r;
eunmango 97:59d348745d96 121 int16_t x = 0;
eunmango 97:59d348745d96 122 int16_t y = r;
eunmango 97:59d348745d96 123
eunmango 97:59d348745d96 124 while (x<y) {
eunmango 97:59d348745d96 125 if (f >= 0) {
eunmango 97:59d348745d96 126 y--;
eunmango 97:59d348745d96 127 ddF_y += 2;
eunmango 97:59d348745d96 128 f += ddF_y;
eunmango 97:59d348745d96 129 }
eunmango 97:59d348745d96 130 x++;
eunmango 97:59d348745d96 131 ddF_x += 2;
eunmango 97:59d348745d96 132 f += ddF_x;
eunmango 97:59d348745d96 133 if (cornername & 0x4) {
eunmango 97:59d348745d96 134 drawPixel(x0 + x, y0 + y, color);
eunmango 97:59d348745d96 135 drawPixel(x0 + y, y0 + x, color);
eunmango 97:59d348745d96 136 }
eunmango 97:59d348745d96 137 if (cornername & 0x2) {
eunmango 97:59d348745d96 138 drawPixel(x0 + x, y0 - y, color);
eunmango 97:59d348745d96 139 drawPixel(x0 + y, y0 - x, color);
eunmango 97:59d348745d96 140 }
eunmango 97:59d348745d96 141 if (cornername & 0x8) {
eunmango 97:59d348745d96 142 drawPixel(x0 - y, y0 + x, color);
eunmango 97:59d348745d96 143 drawPixel(x0 - x, y0 + y, color);
eunmango 97:59d348745d96 144 }
eunmango 97:59d348745d96 145 if (cornername & 0x1) {
eunmango 97:59d348745d96 146 drawPixel(x0 - y, y0 - x, color);
eunmango 97:59d348745d96 147 drawPixel(x0 - x, y0 - y, color);
eunmango 97:59d348745d96 148 }
eunmango 97:59d348745d96 149 }
eunmango 97:59d348745d96 150 }
eunmango 97:59d348745d96 151
eunmango 97:59d348745d96 152 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) {
eunmango 97:59d348745d96 153 drawFastVLine(x0, y0-r, 2*r+1, color);
eunmango 97:59d348745d96 154 fillCircleHelper(x0, y0, r, 3, 0, color);
eunmango 97:59d348745d96 155 }
eunmango 97:59d348745d96 156
eunmango 97:59d348745d96 157 // Used to do circles and roundrects
eunmango 97:59d348745d96 158 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
eunmango 97:59d348745d96 159 uint8_t cornername, int16_t delta, uint16_t color) {
eunmango 97:59d348745d96 160
eunmango 97:59d348745d96 161 int16_t f = 1 - r;
eunmango 97:59d348745d96 162 int16_t ddF_x = 1;
eunmango 97:59d348745d96 163 int16_t ddF_y = -2 * r;
eunmango 97:59d348745d96 164 int16_t x = 0;
eunmango 97:59d348745d96 165 int16_t y = r;
eunmango 97:59d348745d96 166
eunmango 97:59d348745d96 167 while (x<y) {
eunmango 97:59d348745d96 168 if (f >= 0) {
eunmango 97:59d348745d96 169 y--;
eunmango 97:59d348745d96 170 ddF_y += 2;
eunmango 97:59d348745d96 171 f += ddF_y;
eunmango 97:59d348745d96 172 }
eunmango 97:59d348745d96 173 x++;
eunmango 97:59d348745d96 174 ddF_x += 2;
eunmango 97:59d348745d96 175 f += ddF_x;
eunmango 97:59d348745d96 176
eunmango 97:59d348745d96 177 if (cornername & 0x1) {
eunmango 97:59d348745d96 178 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
eunmango 97:59d348745d96 179 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
eunmango 97:59d348745d96 180 }
eunmango 97:59d348745d96 181 if (cornername & 0x2) {
eunmango 97:59d348745d96 182 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
eunmango 97:59d348745d96 183 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
eunmango 97:59d348745d96 184 }
eunmango 97:59d348745d96 185 }
eunmango 97:59d348745d96 186 }
eunmango 97:59d348745d96 187
eunmango 97:59d348745d96 188 // Bresenham's algorithm - thx wikpedia
eunmango 97:59d348745d96 189 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
eunmango 97:59d348745d96 190 uint16_t color) {
eunmango 97:59d348745d96 191 int16_t steep = abs(y1 - y0) > abs(x1 - x0);
eunmango 97:59d348745d96 192 if (steep) {
eunmango 97:59d348745d96 193 _swap_int16_t(x0, y0);
eunmango 97:59d348745d96 194 _swap_int16_t(x1, y1);
eunmango 97:59d348745d96 195 }
eunmango 97:59d348745d96 196
eunmango 97:59d348745d96 197 if (x0 > x1) {
eunmango 97:59d348745d96 198 _swap_int16_t(x0, x1);
eunmango 97:59d348745d96 199 _swap_int16_t(y0, y1);
eunmango 97:59d348745d96 200 }
eunmango 97:59d348745d96 201
eunmango 97:59d348745d96 202 int16_t dx, dy;
eunmango 97:59d348745d96 203 dx = x1 - x0;
eunmango 97:59d348745d96 204 dy = abs(y1 - y0);
eunmango 97:59d348745d96 205
eunmango 97:59d348745d96 206 int16_t err = dx / 2;
eunmango 97:59d348745d96 207 int16_t ystep;
eunmango 97:59d348745d96 208
eunmango 97:59d348745d96 209 if (y0 < y1) {
eunmango 97:59d348745d96 210 ystep = 1;
eunmango 97:59d348745d96 211 } else {
eunmango 97:59d348745d96 212 ystep = -1;
eunmango 97:59d348745d96 213 }
eunmango 97:59d348745d96 214
eunmango 97:59d348745d96 215 for (; x0<=x1; x0++) {
eunmango 97:59d348745d96 216 if (steep) {
eunmango 97:59d348745d96 217 drawPixel(y0, x0, color);
eunmango 97:59d348745d96 218 } else {
eunmango 97:59d348745d96 219 drawPixel(x0, y0, color);
eunmango 97:59d348745d96 220 }
eunmango 97:59d348745d96 221 err -= dy;
eunmango 97:59d348745d96 222 if (err < 0) {
eunmango 97:59d348745d96 223 y0 += ystep;
eunmango 97:59d348745d96 224 err += dx;
eunmango 97:59d348745d96 225 }
eunmango 97:59d348745d96 226 }
eunmango 97:59d348745d96 227 }
eunmango 97:59d348745d96 228
eunmango 97:59d348745d96 229 // Draw a rectangle
eunmango 97:59d348745d96 230 void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h,
eunmango 97:59d348745d96 231 uint16_t color) {
eunmango 97:59d348745d96 232 drawFastHLine(x, y, w, color);
eunmango 97:59d348745d96 233 drawFastHLine(x, y+h-1, w, color);
eunmango 97:59d348745d96 234 drawFastVLine(x, y, h, color);
eunmango 97:59d348745d96 235 drawFastVLine(x+w-1, y, h, color);
eunmango 97:59d348745d96 236 }
eunmango 97:59d348745d96 237
eunmango 97:59d348745d96 238 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y,
eunmango 97:59d348745d96 239 int16_t h, uint16_t color) {
eunmango 97:59d348745d96 240 // Update in subclasses if desired!
eunmango 97:59d348745d96 241 drawLine(x, y, x, y+h-1, color);
eunmango 97:59d348745d96 242 }
eunmango 97:59d348745d96 243
eunmango 97:59d348745d96 244 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y,
eunmango 97:59d348745d96 245 int16_t w, uint16_t color) {
eunmango 97:59d348745d96 246 // Update in subclasses if desired!
eunmango 97:59d348745d96 247 drawLine(x, y, x+w-1, y, color);
eunmango 97:59d348745d96 248 }
eunmango 97:59d348745d96 249
eunmango 97:59d348745d96 250 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
eunmango 97:59d348745d96 251 uint16_t color) {
eunmango 97:59d348745d96 252 // Update in subclasses if desired!
eunmango 97:59d348745d96 253 for (int16_t i=x; i<x+w; i++) {
eunmango 97:59d348745d96 254 drawFastVLine(i, y, h, color);
eunmango 97:59d348745d96 255 }
eunmango 97:59d348745d96 256 }
eunmango 97:59d348745d96 257
eunmango 97:59d348745d96 258 void Adafruit_GFX::fillScreen(uint16_t color) {
eunmango 97:59d348745d96 259 fillRect(0, 0, _width, _height, color);
eunmango 97:59d348745d96 260 }
eunmango 97:59d348745d96 261
eunmango 97:59d348745d96 262 // Draw a rounded rectangle
eunmango 97:59d348745d96 263 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w,
eunmango 97:59d348745d96 264 int16_t h, int16_t r, uint16_t color) {
eunmango 97:59d348745d96 265 // smarter version
eunmango 97:59d348745d96 266 drawFastHLine(x+r , y , w-2*r, color); // Top
eunmango 97:59d348745d96 267 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom
eunmango 97:59d348745d96 268 drawFastVLine(x , y+r , h-2*r, color); // Left
eunmango 97:59d348745d96 269 drawFastVLine(x+w-1, y+r , h-2*r, color); // Right
eunmango 97:59d348745d96 270 // draw four corners
eunmango 97:59d348745d96 271 drawCircleHelper(x+r , y+r , r, 1, color);
eunmango 97:59d348745d96 272 drawCircleHelper(x+w-r-1, y+r , r, 2, color);
eunmango 97:59d348745d96 273 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
eunmango 97:59d348745d96 274 drawCircleHelper(x+r , y+h-r-1, r, 8, color);
eunmango 97:59d348745d96 275 }
eunmango 97:59d348745d96 276
eunmango 97:59d348745d96 277 // Fill a rounded rectangle
eunmango 97:59d348745d96 278 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w,
eunmango 97:59d348745d96 279 int16_t h, int16_t r, uint16_t color) {
eunmango 97:59d348745d96 280 // smarter version
eunmango 97:59d348745d96 281 fillRect(x+r, y, w-2*r, h, color);
eunmango 97:59d348745d96 282
eunmango 97:59d348745d96 283 // draw four corners
eunmango 97:59d348745d96 284 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
eunmango 97:59d348745d96 285 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color);
eunmango 97:59d348745d96 286 }
eunmango 97:59d348745d96 287
eunmango 97:59d348745d96 288 // Draw a triangle
eunmango 97:59d348745d96 289 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0,
eunmango 97:59d348745d96 290 int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) {
eunmango 97:59d348745d96 291 drawLine(x0, y0, x1, y1, color);
eunmango 97:59d348745d96 292 drawLine(x1, y1, x2, y2, color);
eunmango 97:59d348745d96 293 drawLine(x2, y2, x0, y0, color);
eunmango 97:59d348745d96 294 }
eunmango 97:59d348745d96 295
eunmango 97:59d348745d96 296 // Fill a triangle
eunmango 97:59d348745d96 297 void Adafruit_GFX::fillTriangle(int16_t x0, int16_t y0,
eunmango 97:59d348745d96 298 int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) {
eunmango 97:59d348745d96 299
eunmango 97:59d348745d96 300 int16_t a, b, y, last;
eunmango 97:59d348745d96 301
eunmango 97:59d348745d96 302 // Sort coordinates by Y order (y2 >= y1 >= y0)
eunmango 97:59d348745d96 303 if (y0 > y1) {
eunmango 97:59d348745d96 304 _swap_int16_t(y0, y1); _swap_int16_t(x0, x1);
eunmango 97:59d348745d96 305 }
eunmango 97:59d348745d96 306 if (y1 > y2) {
eunmango 97:59d348745d96 307 _swap_int16_t(y2, y1); _swap_int16_t(x2, x1);
eunmango 97:59d348745d96 308 }
eunmango 97:59d348745d96 309 if (y0 > y1) {
eunmango 97:59d348745d96 310 _swap_int16_t(y0, y1); _swap_int16_t(x0, x1);
eunmango 97:59d348745d96 311 }
eunmango 97:59d348745d96 312
eunmango 97:59d348745d96 313 if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
eunmango 97:59d348745d96 314 a = b = x0;
eunmango 97:59d348745d96 315 if(x1 < a) a = x1;
eunmango 97:59d348745d96 316 else if(x1 > b) b = x1;
eunmango 97:59d348745d96 317 if(x2 < a) a = x2;
eunmango 97:59d348745d96 318 else if(x2 > b) b = x2;
eunmango 97:59d348745d96 319 drawFastHLine(a, y0, b-a+1, color);
eunmango 97:59d348745d96 320 return;
eunmango 97:59d348745d96 321 }
eunmango 97:59d348745d96 322
eunmango 97:59d348745d96 323 int16_t
eunmango 97:59d348745d96 324 dx01 = x1 - x0,
eunmango 97:59d348745d96 325 dy01 = y1 - y0,
eunmango 97:59d348745d96 326 dx02 = x2 - x0,
eunmango 97:59d348745d96 327 dy02 = y2 - y0,
eunmango 97:59d348745d96 328 dx12 = x2 - x1,
eunmango 97:59d348745d96 329 dy12 = y2 - y1;
eunmango 97:59d348745d96 330 int32_t
eunmango 97:59d348745d96 331 sa = 0,
eunmango 97:59d348745d96 332 sb = 0;
eunmango 97:59d348745d96 333
eunmango 97:59d348745d96 334 // For upper part of triangle, find scanline crossings for segments
eunmango 97:59d348745d96 335 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
eunmango 97:59d348745d96 336 // is included here (and second loop will be skipped, avoiding a /0
eunmango 97:59d348745d96 337 // error there), otherwise scanline y1 is skipped here and handled
eunmango 97:59d348745d96 338 // in the second loop...which also avoids a /0 error here if y0=y1
eunmango 97:59d348745d96 339 // (flat-topped triangle).
eunmango 97:59d348745d96 340 if(y1 == y2) last = y1; // Include y1 scanline
eunmango 97:59d348745d96 341 else last = y1-1; // Skip it
eunmango 97:59d348745d96 342
eunmango 97:59d348745d96 343 for(y=y0; y<=last; y++) {
eunmango 97:59d348745d96 344 a = x0 + sa / dy01;
eunmango 97:59d348745d96 345 b = x0 + sb / dy02;
eunmango 97:59d348745d96 346 sa += dx01;
eunmango 97:59d348745d96 347 sb += dx02;
eunmango 97:59d348745d96 348 /* longhand:
eunmango 97:59d348745d96 349 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
eunmango 97:59d348745d96 350 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
eunmango 97:59d348745d96 351 */
eunmango 97:59d348745d96 352 if(a > b) _swap_int16_t(a,b);
eunmango 97:59d348745d96 353 drawFastHLine(a, y, b-a+1, color);
eunmango 97:59d348745d96 354 }
eunmango 97:59d348745d96 355
eunmango 97:59d348745d96 356 // For lower part of triangle, find scanline crossings for segments
eunmango 97:59d348745d96 357 // 0-2 and 1-2. This loop is skipped if y1=y2.
eunmango 97:59d348745d96 358 sa = dx12 * (y - y1);
eunmango 97:59d348745d96 359 sb = dx02 * (y - y0);
eunmango 97:59d348745d96 360 for(; y<=y2; y++) {
eunmango 97:59d348745d96 361 a = x1 + sa / dy12;
eunmango 97:59d348745d96 362 b = x0 + sb / dy02;
eunmango 97:59d348745d96 363 sa += dx12;
eunmango 97:59d348745d96 364 sb += dx02;
eunmango 97:59d348745d96 365 /* longhand:
eunmango 97:59d348745d96 366 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
eunmango 97:59d348745d96 367 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
eunmango 97:59d348745d96 368 */
eunmango 97:59d348745d96 369 if(a > b) _swap_int16_t(a,b);
eunmango 97:59d348745d96 370 drawFastHLine(a, y, b-a+1, color);
eunmango 97:59d348745d96 371 }
eunmango 97:59d348745d96 372 }
eunmango 97:59d348745d96 373
eunmango 97:59d348745d96 374
eunmango 97:59d348745d96 375 // Draw a 1-bit image (bitmap) at the specified (x,y) position from the
eunmango 97:59d348745d96 376 // provided bitmap buffer using the specified
eunmango 97:59d348745d96 377 // foreground color (unset bits are transparent).
eunmango 97:59d348745d96 378 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
eunmango 97:59d348745d96 379 const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) {
eunmango 97:59d348745d96 380
eunmango 97:59d348745d96 381 int16_t i, j, byteWidth = (w + 7) / 8;
eunmango 97:59d348745d96 382 uint8_t byte;
eunmango 97:59d348745d96 383
eunmango 97:59d348745d96 384 for(j=0; j<h; j++) {
eunmango 97:59d348745d96 385 for(i=0; i<w; i++ ) {
eunmango 97:59d348745d96 386 if(i & 7) byte <<= 1;
eunmango 97:59d348745d96 387 else byte = bitmap[j * byteWidth + i / 8];
eunmango 97:59d348745d96 388 if(byte & 0x80) drawPixel(x+i, y+j, color);
eunmango 97:59d348745d96 389 }
eunmango 97:59d348745d96 390 }
eunmango 97:59d348745d96 391 }
eunmango 97:59d348745d96 392
eunmango 97:59d348745d96 393 // Draw a 1-bit image (bitmap) at the specified (x,y) position from the
eunmango 97:59d348745d96 394 // provided bitmap buffer using the specified
eunmango 97:59d348745d96 395 // foreground (for set bits) and background (for clear bits) colors.
eunmango 97:59d348745d96 396 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
eunmango 97:59d348745d96 397 const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg) {
eunmango 97:59d348745d96 398
eunmango 97:59d348745d96 399 int16_t i, j, byteWidth = (w + 7) / 8;
eunmango 97:59d348745d96 400 uint8_t byte;
eunmango 97:59d348745d96 401
eunmango 97:59d348745d96 402 for(j=0; j<h; j++) {
eunmango 97:59d348745d96 403 for(i=0; i<w; i++ ) {
eunmango 97:59d348745d96 404 if(i & 7) byte <<= 1;
eunmango 97:59d348745d96 405 else byte = bitmap[j * byteWidth + i / 8];
eunmango 97:59d348745d96 406 if(byte & 0x80) drawPixel(x+i, y+j, color);
eunmango 97:59d348745d96 407 else drawPixel(x+i, y+j, bg);
eunmango 97:59d348745d96 408 }
eunmango 97:59d348745d96 409 }
eunmango 97:59d348745d96 410 }
eunmango 97:59d348745d96 411
eunmango 97:59d348745d96 412 //Draw XBitMap Files (*.xbm), exported from GIMP,
eunmango 97:59d348745d96 413 //Usage: Export from GIMP to *.xbm, rename *.xbm to *.c and open in editor.
eunmango 97:59d348745d96 414 //C Array can be directly used with this function
eunmango 97:59d348745d96 415 void Adafruit_GFX::drawXBitmap(int16_t x, int16_t y,
eunmango 97:59d348745d96 416 const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) {
eunmango 97:59d348745d96 417
eunmango 97:59d348745d96 418 int16_t i, j, byteWidth = (w + 7) / 8;
eunmango 97:59d348745d96 419 uint8_t byte;
eunmango 97:59d348745d96 420
eunmango 97:59d348745d96 421 for(j=0; j<h; j++) {
eunmango 97:59d348745d96 422 for(i=0; i<w; i++ ) {
eunmango 97:59d348745d96 423 if(i & 7) byte >>= 1;
eunmango 97:59d348745d96 424 else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8);
eunmango 97:59d348745d96 425 if(byte & 0x01) drawPixel(x+i, y+j, color);
eunmango 97:59d348745d96 426 }
eunmango 97:59d348745d96 427 }
eunmango 97:59d348745d96 428 }
eunmango 97:59d348745d96 429
eunmango 97:59d348745d96 430 size_t Adafruit_GFX::write(uint8_t c) {
eunmango 97:59d348745d96 431 if(!gfxFont) { // 'Classic' built-in font
eunmango 97:59d348745d96 432
eunmango 97:59d348745d96 433 if(c == '\n') {
eunmango 97:59d348745d96 434 cursor_y += textsize*8;
eunmango 97:59d348745d96 435 cursor_x = 0;
eunmango 97:59d348745d96 436 } else if(c == '\r') {
eunmango 97:59d348745d96 437 // skip em
eunmango 97:59d348745d96 438 } else {
eunmango 97:59d348745d96 439 if(wrap && ((cursor_x + textsize * 6) >= _width)) { // Heading off edge?
eunmango 97:59d348745d96 440 cursor_x = 0; // Reset x to zero
eunmango 97:59d348745d96 441 cursor_y += textsize * 8; // Advance y one line
eunmango 97:59d348745d96 442 }
eunmango 97:59d348745d96 443 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
eunmango 97:59d348745d96 444 cursor_x += textsize * 6;
eunmango 97:59d348745d96 445 }
eunmango 97:59d348745d96 446
eunmango 97:59d348745d96 447 } else { // Custom font
eunmango 97:59d348745d96 448
eunmango 97:59d348745d96 449 if(c == '\n') {
eunmango 97:59d348745d96 450 cursor_x = 0;
eunmango 97:59d348745d96 451 cursor_y += (int16_t)textsize *
eunmango 97:59d348745d96 452 (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
eunmango 97:59d348745d96 453 } else if(c != '\r') {
eunmango 97:59d348745d96 454 uint8_t first = pgm_read_byte(&gfxFont->first);
eunmango 97:59d348745d96 455 if((c >= first) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last))) {
eunmango 97:59d348745d96 456 uint8_t c2 = c - pgm_read_byte(&gfxFont->first);
eunmango 97:59d348745d96 457 GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c2]);
eunmango 97:59d348745d96 458 uint8_t w = pgm_read_byte(&glyph->width),
eunmango 97:59d348745d96 459 h = pgm_read_byte(&glyph->height);
eunmango 97:59d348745d96 460 if((w > 0) && (h > 0)) { // Is there an associated bitmap?
eunmango 97:59d348745d96 461 int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic
eunmango 97:59d348745d96 462 if(wrap && ((cursor_x + textsize * (xo + w)) >= _width)) {
eunmango 97:59d348745d96 463 // Drawing character would go off right edge; wrap to new line
eunmango 97:59d348745d96 464 cursor_x = 0;
eunmango 97:59d348745d96 465 cursor_y += (int16_t)textsize *
eunmango 97:59d348745d96 466 (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
eunmango 97:59d348745d96 467 }
eunmango 97:59d348745d96 468 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
eunmango 97:59d348745d96 469 }
eunmango 97:59d348745d96 470 cursor_x += pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize;
eunmango 97:59d348745d96 471 }
eunmango 97:59d348745d96 472 }
eunmango 97:59d348745d96 473
eunmango 97:59d348745d96 474 }
eunmango 97:59d348745d96 475 return 1;
eunmango 97:59d348745d96 476 }
eunmango 97:59d348745d96 477
eunmango 97:59d348745d96 478 // Draw a character
eunmango 97:59d348745d96 479 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
eunmango 97:59d348745d96 480 uint16_t color, uint16_t bg, uint8_t size) {
eunmango 97:59d348745d96 481
eunmango 97:59d348745d96 482 if(!gfxFont) { // 'Classic' built-in font
eunmango 97:59d348745d96 483
eunmango 97:59d348745d96 484 if((x >= _width) || // Clip right
eunmango 97:59d348745d96 485 (y >= _height) || // Clip bottom
eunmango 97:59d348745d96 486 ((x + 6 * size - 1) < 0) || // Clip left
eunmango 97:59d348745d96 487 ((y + 8 * size - 1) < 0)) // Clip top
eunmango 97:59d348745d96 488 return;
eunmango 97:59d348745d96 489
eunmango 97:59d348745d96 490 for(int8_t i=0; i<6; i++ ) {
eunmango 97:59d348745d96 491 uint8_t line;
eunmango 97:59d348745d96 492 if(i < 5) line = pgm_read_byte(font+(c*5)+i);
eunmango 97:59d348745d96 493 else line = 0x0;
eunmango 97:59d348745d96 494 for(int8_t j=0; j<8; j++, line >>= 1) {
eunmango 97:59d348745d96 495 if(line & 0x1) {
eunmango 97:59d348745d96 496 if(size == 1) drawPixel(x+i, y+j, color);
eunmango 97:59d348745d96 497 else fillRect(x+(i*size), y+(j*size), size, size, color);
eunmango 97:59d348745d96 498 } else if(bg != color) {
eunmango 97:59d348745d96 499 if(size == 1) drawPixel(x+i, y+j, bg);
eunmango 97:59d348745d96 500 else fillRect(x+i*size, y+j*size, size, size, bg);
eunmango 97:59d348745d96 501 }
eunmango 97:59d348745d96 502 }
eunmango 97:59d348745d96 503 }
eunmango 97:59d348745d96 504
eunmango 97:59d348745d96 505 } else { // Custom font
eunmango 97:59d348745d96 506
eunmango 97:59d348745d96 507 // Character is assumed previously filtered by write() to eliminate
eunmango 97:59d348745d96 508 // newlines, returns, non-printable characters, etc. Calling drawChar()
eunmango 97:59d348745d96 509 // directly with 'bad' characters of font may cause mayhem!
eunmango 97:59d348745d96 510
eunmango 97:59d348745d96 511 c -= pgm_read_byte(&gfxFont->first);
eunmango 97:59d348745d96 512 GFXglyph *glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]);
eunmango 97:59d348745d96 513 uint8_t *bitmap = (uint8_t *)pgm_read_pointer(&gfxFont->bitmap);
eunmango 97:59d348745d96 514
eunmango 97:59d348745d96 515 uint16_t bo = pgm_read_word(&glyph->bitmapOffset);
eunmango 97:59d348745d96 516 uint8_t w = pgm_read_byte(&glyph->width),
eunmango 97:59d348745d96 517 h = pgm_read_byte(&glyph->height),
eunmango 97:59d348745d96 518 xa = pgm_read_byte(&glyph->xAdvance);
eunmango 97:59d348745d96 519 int8_t xo = pgm_read_byte(&glyph->xOffset);
eunmango 97:59d348745d96 520 int8_t yo = pgm_read_byte(&glyph->yOffset);
eunmango 97:59d348745d96 521 uint8_t xx, yy, bits, bit = 0;
eunmango 97:59d348745d96 522 int16_t xo16, yo16;
eunmango 97:59d348745d96 523
eunmango 97:59d348745d96 524 if(size > 1) {
eunmango 97:59d348745d96 525 xo16 = xo;
eunmango 97:59d348745d96 526 yo16 = yo;
eunmango 97:59d348745d96 527 }
eunmango 97:59d348745d96 528
eunmango 97:59d348745d96 529 // Todo: Add character clipping here
eunmango 97:59d348745d96 530
eunmango 97:59d348745d96 531 // NOTE: THERE IS NO 'BACKGROUND' COLOR OPTION ON CUSTOM FONTS.
eunmango 97:59d348745d96 532 // THIS IS ON PURPOSE AND BY DESIGN. The background color feature
eunmango 97:59d348745d96 533 // has typically been used with the 'classic' font to overwrite old
eunmango 97:59d348745d96 534 // screen contents with new data. This ONLY works because the
eunmango 97:59d348745d96 535 // characters are a uniform size; it's not a sensible thing to do with
eunmango 97:59d348745d96 536 // proportionally-spaced fonts with glyphs of varying sizes (and that
eunmango 97:59d348745d96 537 // may overlap). To replace previously-drawn text when using a custom
eunmango 97:59d348745d96 538 // font, use the getTextBounds() function to determine the smallest
eunmango 97:59d348745d96 539 // rectangle encompassing a string, erase the area with fillRect(),
eunmango 97:59d348745d96 540 // then draw new text. This WILL infortunately 'blink' the text, but
eunmango 97:59d348745d96 541 // is unavoidable. Drawing 'background' pixels will NOT fix this,
eunmango 97:59d348745d96 542 // only creates a new set of problems. Have an idea to work around
eunmango 97:59d348745d96 543 // this (a canvas object type for MCUs that can afford the RAM and
eunmango 97:59d348745d96 544 // displays supporting setAddrWindow() and pushColors()), but haven't
eunmango 97:59d348745d96 545 // implemented this yet.
eunmango 97:59d348745d96 546
eunmango 97:59d348745d96 547 for(yy=0; yy<h; yy++) {
eunmango 97:59d348745d96 548 for(xx=0; xx<w; xx++) {
eunmango 97:59d348745d96 549 if(!(bit++ & 7)) {
eunmango 97:59d348745d96 550 bits = pgm_read_byte(&bitmap[bo++]);
eunmango 97:59d348745d96 551 }
eunmango 97:59d348745d96 552 if(bits & 0x80) {
eunmango 97:59d348745d96 553 if(size == 1) {
eunmango 97:59d348745d96 554 drawPixel(x+xo+xx, y+yo+yy, color);
eunmango 97:59d348745d96 555 } else {
eunmango 97:59d348745d96 556 fillRect(x+(xo16+xx)*size, y+(yo16+yy)*size, size, size, color);
eunmango 97:59d348745d96 557 }
eunmango 97:59d348745d96 558 }
eunmango 97:59d348745d96 559 bits <<= 1;
eunmango 97:59d348745d96 560 }
eunmango 97:59d348745d96 561 }
eunmango 97:59d348745d96 562
eunmango 97:59d348745d96 563 } // End classic vs custom font
eunmango 97:59d348745d96 564 }
eunmango 97:59d348745d96 565
eunmango 97:59d348745d96 566 void Adafruit_GFX::setCursor(int16_t x, int16_t y) {
eunmango 97:59d348745d96 567 cursor_x = x;
eunmango 97:59d348745d96 568 cursor_y = y;
eunmango 97:59d348745d96 569 }
eunmango 97:59d348745d96 570
eunmango 97:59d348745d96 571 int16_t Adafruit_GFX::getCursorX(void) const {
eunmango 97:59d348745d96 572 return cursor_x;
eunmango 97:59d348745d96 573 }
eunmango 97:59d348745d96 574
eunmango 97:59d348745d96 575 int16_t Adafruit_GFX::getCursorY(void) const {
eunmango 97:59d348745d96 576 return cursor_y;
eunmango 97:59d348745d96 577 }
eunmango 97:59d348745d96 578
eunmango 97:59d348745d96 579 void Adafruit_GFX::setTextSize(uint8_t s) {
eunmango 97:59d348745d96 580 textsize = (s > 0) ? s : 1;
eunmango 97:59d348745d96 581 }
eunmango 97:59d348745d96 582
eunmango 97:59d348745d96 583 void Adafruit_GFX::setTextColor(uint16_t c) {
eunmango 97:59d348745d96 584 // For 'transparent' background, we'll set the bg
eunmango 97:59d348745d96 585 // to the same as fg instead of using a flag
eunmango 97:59d348745d96 586 textcolor = textbgcolor = c;
eunmango 97:59d348745d96 587 }
eunmango 97:59d348745d96 588
eunmango 97:59d348745d96 589 void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
eunmango 97:59d348745d96 590 textcolor = c;
eunmango 97:59d348745d96 591 textbgcolor = b;
eunmango 97:59d348745d96 592 }
eunmango 97:59d348745d96 593
eunmango 97:59d348745d96 594 void Adafruit_GFX::setTextWrap(bool w) {
eunmango 97:59d348745d96 595 wrap = w;
eunmango 97:59d348745d96 596 }
eunmango 97:59d348745d96 597
eunmango 97:59d348745d96 598 uint8_t Adafruit_GFX::getRotation(void) const {
eunmango 97:59d348745d96 599 return rotation;
eunmango 97:59d348745d96 600 }
eunmango 97:59d348745d96 601
eunmango 97:59d348745d96 602 void Adafruit_GFX::setRotation(uint8_t x) {
eunmango 97:59d348745d96 603 rotation = (x & 3);
eunmango 97:59d348745d96 604 switch(rotation) {
eunmango 97:59d348745d96 605 case 0:
eunmango 97:59d348745d96 606 case 2:
eunmango 97:59d348745d96 607 _width = WIDTH;
eunmango 97:59d348745d96 608 _height = HEIGHT;
eunmango 97:59d348745d96 609 break;
eunmango 97:59d348745d96 610 case 1:
eunmango 97:59d348745d96 611 case 3:
eunmango 97:59d348745d96 612 _width = HEIGHT;
eunmango 97:59d348745d96 613 _height = WIDTH;
eunmango 97:59d348745d96 614 break;
eunmango 97:59d348745d96 615 }
eunmango 97:59d348745d96 616 }
eunmango 97:59d348745d96 617
eunmango 97:59d348745d96 618
eunmango 97:59d348745d96 619 void Adafruit_GFX::setFont(const GFXfont *f) {
eunmango 97:59d348745d96 620 if(f) { // Font struct pointer passed in?
eunmango 97:59d348745d96 621 if(!gfxFont) { // And no current font struct?
eunmango 97:59d348745d96 622 // Switching from classic to new font behavior.
eunmango 97:59d348745d96 623 // Move cursor pos down 6 pixels so it's on baseline.
eunmango 97:59d348745d96 624 cursor_y += 6;
eunmango 97:59d348745d96 625 }
eunmango 97:59d348745d96 626 } else if(gfxFont) { // NULL passed. Current font struct defined?
eunmango 97:59d348745d96 627 // Switching from new to classic font behavior.
eunmango 97:59d348745d96 628 // Move cursor pos up 6 pixels so it's at top-left of char.
eunmango 97:59d348745d96 629 cursor_y -= 6;
eunmango 97:59d348745d96 630 }
eunmango 97:59d348745d96 631 gfxFont = (GFXfont *)f;
eunmango 97:59d348745d96 632 }
eunmango 97:59d348745d96 633
eunmango 97:59d348745d96 634 // Pass string and a cursor position, returns UL corner and W,H.
eunmango 97:59d348745d96 635 void Adafruit_GFX::getTextBounds(char *str, int16_t x, int16_t y,
eunmango 97:59d348745d96 636 int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h) {
eunmango 97:59d348745d96 637 uint8_t c; // Current character
eunmango 97:59d348745d96 638
eunmango 97:59d348745d96 639 *x1 = x;
eunmango 97:59d348745d96 640 *y1 = y;
eunmango 97:59d348745d96 641 *w = *h = 0;
eunmango 97:59d348745d96 642
eunmango 97:59d348745d96 643 if(gfxFont) {
eunmango 97:59d348745d96 644
eunmango 97:59d348745d96 645 GFXglyph *glyph;
eunmango 97:59d348745d96 646 uint8_t first = pgm_read_byte(&gfxFont->first),
eunmango 97:59d348745d96 647 last = pgm_read_byte(&gfxFont->last),
eunmango 97:59d348745d96 648 gw, gh, xa;
eunmango 97:59d348745d96 649 int8_t xo, yo;
eunmango 97:59d348745d96 650 int16_t minx = _width, miny = _height, maxx = -1, maxy = -1,
eunmango 97:59d348745d96 651 gx1, gy1, gx2, gy2, ts = (int16_t)textsize,
eunmango 97:59d348745d96 652 ya = ts * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
eunmango 97:59d348745d96 653
eunmango 97:59d348745d96 654 while((c = *str++)) {
eunmango 97:59d348745d96 655 if(c != '\n') { // Not a newline
eunmango 97:59d348745d96 656 if(c != '\r') { // Not a carriage return, is normal char
eunmango 97:59d348745d96 657 if((c >= first) && (c <= last)) { // Char present in current font
eunmango 97:59d348745d96 658 c -= first;
eunmango 97:59d348745d96 659 glyph = &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]);
eunmango 97:59d348745d96 660 gw = pgm_read_byte(&glyph->width);
eunmango 97:59d348745d96 661 gh = pgm_read_byte(&glyph->height);
eunmango 97:59d348745d96 662 xa = pgm_read_byte(&glyph->xAdvance);
eunmango 97:59d348745d96 663 xo = pgm_read_byte(&glyph->xOffset);
eunmango 97:59d348745d96 664 yo = pgm_read_byte(&glyph->yOffset);
eunmango 97:59d348745d96 665 if(wrap && ((x + (((int16_t)xo + gw) * ts)) >= _width)) {
eunmango 97:59d348745d96 666 // Line wrap
eunmango 97:59d348745d96 667 x = 0; // Reset x to 0
eunmango 97:59d348745d96 668 y += ya; // Advance y by 1 line
eunmango 97:59d348745d96 669 }
eunmango 97:59d348745d96 670 gx1 = x + xo * ts;
eunmango 97:59d348745d96 671 gy1 = y + yo * ts;
eunmango 97:59d348745d96 672 gx2 = gx1 + gw * ts - 1;
eunmango 97:59d348745d96 673 gy2 = gy1 + gh * ts - 1;
eunmango 97:59d348745d96 674 if(gx1 < minx) minx = gx1;
eunmango 97:59d348745d96 675 if(gy1 < miny) miny = gy1;
eunmango 97:59d348745d96 676 if(gx2 > maxx) maxx = gx2;
eunmango 97:59d348745d96 677 if(gy2 > maxy) maxy = gy2;
eunmango 97:59d348745d96 678 x += xa * ts;
eunmango 97:59d348745d96 679 }
eunmango 97:59d348745d96 680 } // Carriage return = do nothing
eunmango 97:59d348745d96 681 } else { // Newline
eunmango 97:59d348745d96 682 x = 0; // Reset x
eunmango 97:59d348745d96 683 y += ya; // Advance y by 1 line
eunmango 97:59d348745d96 684 }
eunmango 97:59d348745d96 685 }
eunmango 97:59d348745d96 686 // End of string
eunmango 97:59d348745d96 687 *x1 = minx;
eunmango 97:59d348745d96 688 *y1 = miny;
eunmango 97:59d348745d96 689 if(maxx >= minx) *w = maxx - minx + 1;
eunmango 97:59d348745d96 690 if(maxy >= miny) *h = maxy - miny + 1;
eunmango 97:59d348745d96 691
eunmango 97:59d348745d96 692 } else { // Default font
eunmango 97:59d348745d96 693
eunmango 97:59d348745d96 694 uint16_t lineWidth = 0, maxWidth = 0; // Width of current, all lines
eunmango 97:59d348745d96 695
eunmango 97:59d348745d96 696 while((c = *str++)) {
eunmango 97:59d348745d96 697 if(c != '\n') { // Not a newline
eunmango 97:59d348745d96 698 if(c != '\r') { // Not a carriage return, is normal char
eunmango 97:59d348745d96 699 if(wrap && ((x + textsize * 6) >= _width)) {
eunmango 97:59d348745d96 700 x = 0; // Reset x to 0
eunmango 97:59d348745d96 701 y += textsize * 8; // Advance y by 1 line
eunmango 97:59d348745d96 702 if(lineWidth > maxWidth) maxWidth = lineWidth; // Save widest line
eunmango 97:59d348745d96 703 lineWidth = textsize * 6; // First char on new line
eunmango 97:59d348745d96 704 } else { // No line wrap, just keep incrementing X
eunmango 97:59d348745d96 705 lineWidth += textsize * 6; // Includes interchar x gap
eunmango 97:59d348745d96 706 }
eunmango 97:59d348745d96 707 } // Carriage return = do nothing
eunmango 97:59d348745d96 708 } else { // Newline
eunmango 97:59d348745d96 709 x = 0; // Reset x to 0
eunmango 97:59d348745d96 710 y += textsize * 8; // Advance y by 1 line
eunmango 97:59d348745d96 711 if(lineWidth > maxWidth) maxWidth = lineWidth; // Save widest line
eunmango 97:59d348745d96 712 lineWidth = 0; // Reset lineWidth for new line
eunmango 97:59d348745d96 713 }
eunmango 97:59d348745d96 714 }
eunmango 97:59d348745d96 715 // End of string
eunmango 97:59d348745d96 716 if(lineWidth) y += textsize * 8; // Add height of last (or only) line
eunmango 97:59d348745d96 717 if(lineWidth > maxWidth) maxWidth = lineWidth; // Is the last or only line the widest?
eunmango 97:59d348745d96 718 *w = maxWidth - 1; // Don't include last interchar x gap
eunmango 97:59d348745d96 719 *h = y - *y1;
eunmango 97:59d348745d96 720
eunmango 97:59d348745d96 721 } // End classic vs custom font
eunmango 97:59d348745d96 722 }
eunmango 97:59d348745d96 723
eunmango 97:59d348745d96 724
eunmango 97:59d348745d96 725
eunmango 97:59d348745d96 726 void Adafruit_GFX::print(const char* str) {
eunmango 97:59d348745d96 727 const char* p = str;
eunmango 97:59d348745d96 728 while (*p!=0)
eunmango 97:59d348745d96 729 write(*p++);
eunmango 97:59d348745d96 730 }
eunmango 97:59d348745d96 731
eunmango 97:59d348745d96 732 void Adafruit_GFX::println(const char* str) {
eunmango 97:59d348745d96 733 print(str);
eunmango 97:59d348745d96 734 write('\n');
eunmango 97:59d348745d96 735 }
eunmango 97:59d348745d96 736
eunmango 97:59d348745d96 737 // Return the size of the display (per current rotation)
eunmango 97:59d348745d96 738 int16_t Adafruit_GFX::width(void) const {
eunmango 97:59d348745d96 739 return _width;
eunmango 97:59d348745d96 740 }
eunmango 97:59d348745d96 741
eunmango 97:59d348745d96 742 int16_t Adafruit_GFX::height(void) const {
eunmango 97:59d348745d96 743 return _height;
eunmango 97:59d348745d96 744 }
eunmango 97:59d348745d96 745
eunmango 97:59d348745d96 746 void Adafruit_GFX::invertDisplay(bool i) {
eunmango 97:59d348745d96 747 // Do nothing, must be subclassed if supported by hardware
eunmango 97:59d348745d96 748 }
eunmango 97:59d348745d96 749
eunmango 97:59d348745d96 750
eunmango 97:59d348745d96 751 /***************************************************************************/
eunmango 97:59d348745d96 752