dd

Dependencies:   Final HCSR04 TB6612FNG

Committer:
eunmango
Date:
Sun Jun 16 04:44:35 2019 +0000
Revision:
97:b483e656bd14
t

Who changed what in which revision?

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