Hacked version of AdaFruit graphics library for SSD1306 usage on I2C

Dependencies:   mbed

Committer:
eggsylah
Date:
Thu Jun 15 15:01:14 2017 +0000
Revision:
0:b0151666c710
First working i2c version

Who changed what in which revision?

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