Basic Adafruit_GFX v1.10.7 library files with ADA_GFX_kbv.h and renamed glcdfont.inc MCUFRIEND_kbv library inherits from Adafruit_GFX

Dependents:   TFT_Touch_botao_v1 TFT_Touch_exemplo5_git_touch TESTE_1 TFT_Touch_exemplo6_git_touch_button_3_ ... more

Committer:
davidprentice
Date:
Mon Apr 26 14:39:27 2021 +0000
Revision:
0:8ee30e15ac7b
Basic Adafruit_GFX v1.10.7 Arduino library files; with ADA_GFX_kbv.h and renamed glcdfont.inc

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davidprentice 0:8ee30e15ac7b 1 /*
davidprentice 0:8ee30e15ac7b 2 This is the core graphics library for all our displays, providing a common
davidprentice 0:8ee30e15ac7b 3 set of graphics primitives (points, lines, circles, etc.). It needs to be
davidprentice 0:8ee30e15ac7b 4 paired with a hardware-specific library for each display device we carry
davidprentice 0:8ee30e15ac7b 5 (to handle the lower-level functions).
davidprentice 0:8ee30e15ac7b 6
davidprentice 0:8ee30e15ac7b 7 Adafruit invests time and resources providing this open source code, please
davidprentice 0:8ee30e15ac7b 8 support Adafruit & open-source hardware by purchasing products from Adafruit!
davidprentice 0:8ee30e15ac7b 9
davidprentice 0:8ee30e15ac7b 10 Copyright (c) 2013 Adafruit Industries. All rights reserved.
davidprentice 0:8ee30e15ac7b 11
davidprentice 0:8ee30e15ac7b 12 Redistribution and use in source and binary forms, with or without
davidprentice 0:8ee30e15ac7b 13 modification, are permitted provided that the following conditions are met:
davidprentice 0:8ee30e15ac7b 14
davidprentice 0:8ee30e15ac7b 15 - Redistributions of source code must retain the above copyright notice,
davidprentice 0:8ee30e15ac7b 16 this list of conditions and the following disclaimer.
davidprentice 0:8ee30e15ac7b 17 - Redistributions in binary form must reproduce the above copyright notice,
davidprentice 0:8ee30e15ac7b 18 this list of conditions and the following disclaimer in the documentation
davidprentice 0:8ee30e15ac7b 19 and/or other materials provided with the distribution.
davidprentice 0:8ee30e15ac7b 20
davidprentice 0:8ee30e15ac7b 21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
davidprentice 0:8ee30e15ac7b 22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
davidprentice 0:8ee30e15ac7b 23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
davidprentice 0:8ee30e15ac7b 24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
davidprentice 0:8ee30e15ac7b 25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
davidprentice 0:8ee30e15ac7b 26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
davidprentice 0:8ee30e15ac7b 27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
davidprentice 0:8ee30e15ac7b 28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
davidprentice 0:8ee30e15ac7b 29 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
davidprentice 0:8ee30e15ac7b 30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
davidprentice 0:8ee30e15ac7b 31 POSSIBILITY OF SUCH DAMAGE.
davidprentice 0:8ee30e15ac7b 32 */
davidprentice 0:8ee30e15ac7b 33
davidprentice 0:8ee30e15ac7b 34 #include "Adafruit_GFX.h"
davidprentice 0:8ee30e15ac7b 35 #include "glcdfont.inc" //.kbv
davidprentice 0:8ee30e15ac7b 36 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 37 #include <avr/pgmspace.h>
davidprentice 0:8ee30e15ac7b 38 #elif defined(ESP8266) || defined(ESP32)
davidprentice 0:8ee30e15ac7b 39 #include <pgmspace.h>
davidprentice 0:8ee30e15ac7b 40 #endif
davidprentice 0:8ee30e15ac7b 41
davidprentice 0:8ee30e15ac7b 42 // Many (but maybe not all) non-AVR board installs define macros
davidprentice 0:8ee30e15ac7b 43 // for compatibility with existing PROGMEM-reading AVR code.
davidprentice 0:8ee30e15ac7b 44 // Do our own checks and defines here for good measure...
davidprentice 0:8ee30e15ac7b 45
davidprentice 0:8ee30e15ac7b 46 #ifndef pgm_read_byte
davidprentice 0:8ee30e15ac7b 47 #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
davidprentice 0:8ee30e15ac7b 48 #endif
davidprentice 0:8ee30e15ac7b 49 #ifndef pgm_read_word
davidprentice 0:8ee30e15ac7b 50 #define pgm_read_word(addr) (*(const unsigned short *)(addr))
davidprentice 0:8ee30e15ac7b 51 #endif
davidprentice 0:8ee30e15ac7b 52 #ifndef pgm_read_dword
davidprentice 0:8ee30e15ac7b 53 #define pgm_read_dword(addr) (*(const unsigned long *)(addr))
davidprentice 0:8ee30e15ac7b 54 #endif
davidprentice 0:8ee30e15ac7b 55
davidprentice 0:8ee30e15ac7b 56 // Pointers are a peculiar case...typically 16-bit on AVR boards,
davidprentice 0:8ee30e15ac7b 57 // 32 bits elsewhere. Try to accommodate both...
davidprentice 0:8ee30e15ac7b 58
davidprentice 0:8ee30e15ac7b 59 #if !defined(__INT_MAX__) || (__INT_MAX__ > 0xFFFF)
davidprentice 0:8ee30e15ac7b 60 #define pgm_read_pointer(addr) ((void *)pgm_read_dword(addr))
davidprentice 0:8ee30e15ac7b 61 #else
davidprentice 0:8ee30e15ac7b 62 #define pgm_read_pointer(addr) ((void *)pgm_read_word(addr))
davidprentice 0:8ee30e15ac7b 63 #endif
davidprentice 0:8ee30e15ac7b 64
davidprentice 0:8ee30e15ac7b 65 inline GFXglyph *pgm_read_glyph_ptr(const GFXfont *gfxFont, uint8_t c) {
davidprentice 0:8ee30e15ac7b 66 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 67 return &(((GFXglyph *)pgm_read_pointer(&gfxFont->glyph))[c]);
davidprentice 0:8ee30e15ac7b 68 #else
davidprentice 0:8ee30e15ac7b 69 // expression in __AVR__ section may generate "dereferencing type-punned
davidprentice 0:8ee30e15ac7b 70 // pointer will break strict-aliasing rules" warning In fact, on other
davidprentice 0:8ee30e15ac7b 71 // platforms (such as STM32) there is no need to do this pointer magic as
davidprentice 0:8ee30e15ac7b 72 // program memory may be read in a usual way So expression may be simplified
davidprentice 0:8ee30e15ac7b 73 return gfxFont->glyph + c;
davidprentice 0:8ee30e15ac7b 74 #endif //__AVR__
davidprentice 0:8ee30e15ac7b 75 }
davidprentice 0:8ee30e15ac7b 76
davidprentice 0:8ee30e15ac7b 77 inline uint8_t *pgm_read_bitmap_ptr(const GFXfont *gfxFont) {
davidprentice 0:8ee30e15ac7b 78 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 79 return (uint8_t *)pgm_read_pointer(&gfxFont->bitmap);
davidprentice 0:8ee30e15ac7b 80 #else
davidprentice 0:8ee30e15ac7b 81 // expression in __AVR__ section generates "dereferencing type-punned pointer
davidprentice 0:8ee30e15ac7b 82 // will break strict-aliasing rules" warning In fact, on other platforms (such
davidprentice 0:8ee30e15ac7b 83 // as STM32) there is no need to do this pointer magic as program memory may
davidprentice 0:8ee30e15ac7b 84 // be read in a usual way So expression may be simplified
davidprentice 0:8ee30e15ac7b 85 return gfxFont->bitmap;
davidprentice 0:8ee30e15ac7b 86 #endif //__AVR__
davidprentice 0:8ee30e15ac7b 87 }
davidprentice 0:8ee30e15ac7b 88
davidprentice 0:8ee30e15ac7b 89 #ifndef min
davidprentice 0:8ee30e15ac7b 90 #define min(a, b) (((a) < (b)) ? (a) : (b))
davidprentice 0:8ee30e15ac7b 91 #endif
davidprentice 0:8ee30e15ac7b 92
davidprentice 0:8ee30e15ac7b 93 #ifndef _swap_int16_t
davidprentice 0:8ee30e15ac7b 94 #define _swap_int16_t(a, b) \
davidprentice 0:8ee30e15ac7b 95 { \
davidprentice 0:8ee30e15ac7b 96 int16_t t = a; \
davidprentice 0:8ee30e15ac7b 97 a = b; \
davidprentice 0:8ee30e15ac7b 98 b = t; \
davidprentice 0:8ee30e15ac7b 99 }
davidprentice 0:8ee30e15ac7b 100 #endif
davidprentice 0:8ee30e15ac7b 101
davidprentice 0:8ee30e15ac7b 102 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 103 /*!
davidprentice 0:8ee30e15ac7b 104 @brief Instatiate a GFX context for graphics! Can only be done by a
davidprentice 0:8ee30e15ac7b 105 superclass
davidprentice 0:8ee30e15ac7b 106 @param w Display width, in pixels
davidprentice 0:8ee30e15ac7b 107 @param h Display height, in pixels
davidprentice 0:8ee30e15ac7b 108 */
davidprentice 0:8ee30e15ac7b 109 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 110 Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h) : WIDTH(w), HEIGHT(h) {
davidprentice 0:8ee30e15ac7b 111 _width = WIDTH;
davidprentice 0:8ee30e15ac7b 112 _height = HEIGHT;
davidprentice 0:8ee30e15ac7b 113 rotation = 0;
davidprentice 0:8ee30e15ac7b 114 cursor_y = cursor_x = 0;
davidprentice 0:8ee30e15ac7b 115 textsize_x = textsize_y = 1;
davidprentice 0:8ee30e15ac7b 116 textcolor = textbgcolor = 0xFFFF;
davidprentice 0:8ee30e15ac7b 117 wrap = true;
davidprentice 0:8ee30e15ac7b 118 _cp437 = false;
davidprentice 0:8ee30e15ac7b 119 gfxFont = NULL;
davidprentice 0:8ee30e15ac7b 120 }
davidprentice 0:8ee30e15ac7b 121
davidprentice 0:8ee30e15ac7b 122 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 123 /*!
davidprentice 0:8ee30e15ac7b 124 @brief Write a line. Bresenham's algorithm - thx wikpedia
davidprentice 0:8ee30e15ac7b 125 @param x0 Start point x coordinate
davidprentice 0:8ee30e15ac7b 126 @param y0 Start point y coordinate
davidprentice 0:8ee30e15ac7b 127 @param x1 End point x coordinate
davidprentice 0:8ee30e15ac7b 128 @param y1 End point y coordinate
davidprentice 0:8ee30e15ac7b 129 @param color 16-bit 5-6-5 Color to draw with
davidprentice 0:8ee30e15ac7b 130 */
davidprentice 0:8ee30e15ac7b 131 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 132 void Adafruit_GFX::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
davidprentice 0:8ee30e15ac7b 133 uint16_t color) {
davidprentice 0:8ee30e15ac7b 134 #if defined(ESP8266)
davidprentice 0:8ee30e15ac7b 135 yield();
davidprentice 0:8ee30e15ac7b 136 #endif
davidprentice 0:8ee30e15ac7b 137 int16_t steep = abs(y1 - y0) > abs(x1 - x0);
davidprentice 0:8ee30e15ac7b 138 if (steep) {
davidprentice 0:8ee30e15ac7b 139 _swap_int16_t(x0, y0);
davidprentice 0:8ee30e15ac7b 140 _swap_int16_t(x1, y1);
davidprentice 0:8ee30e15ac7b 141 }
davidprentice 0:8ee30e15ac7b 142
davidprentice 0:8ee30e15ac7b 143 if (x0 > x1) {
davidprentice 0:8ee30e15ac7b 144 _swap_int16_t(x0, x1);
davidprentice 0:8ee30e15ac7b 145 _swap_int16_t(y0, y1);
davidprentice 0:8ee30e15ac7b 146 }
davidprentice 0:8ee30e15ac7b 147
davidprentice 0:8ee30e15ac7b 148 int16_t dx, dy;
davidprentice 0:8ee30e15ac7b 149 dx = x1 - x0;
davidprentice 0:8ee30e15ac7b 150 dy = abs(y1 - y0);
davidprentice 0:8ee30e15ac7b 151
davidprentice 0:8ee30e15ac7b 152 int16_t err = dx / 2;
davidprentice 0:8ee30e15ac7b 153 int16_t ystep;
davidprentice 0:8ee30e15ac7b 154
davidprentice 0:8ee30e15ac7b 155 if (y0 < y1) {
davidprentice 0:8ee30e15ac7b 156 ystep = 1;
davidprentice 0:8ee30e15ac7b 157 } else {
davidprentice 0:8ee30e15ac7b 158 ystep = -1;
davidprentice 0:8ee30e15ac7b 159 }
davidprentice 0:8ee30e15ac7b 160
davidprentice 0:8ee30e15ac7b 161 for (; x0 <= x1; x0++) {
davidprentice 0:8ee30e15ac7b 162 if (steep) {
davidprentice 0:8ee30e15ac7b 163 writePixel(y0, x0, color);
davidprentice 0:8ee30e15ac7b 164 } else {
davidprentice 0:8ee30e15ac7b 165 writePixel(x0, y0, color);
davidprentice 0:8ee30e15ac7b 166 }
davidprentice 0:8ee30e15ac7b 167 err -= dy;
davidprentice 0:8ee30e15ac7b 168 if (err < 0) {
davidprentice 0:8ee30e15ac7b 169 y0 += ystep;
davidprentice 0:8ee30e15ac7b 170 err += dx;
davidprentice 0:8ee30e15ac7b 171 }
davidprentice 0:8ee30e15ac7b 172 }
davidprentice 0:8ee30e15ac7b 173 }
davidprentice 0:8ee30e15ac7b 174
davidprentice 0:8ee30e15ac7b 175 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 176 /*!
davidprentice 0:8ee30e15ac7b 177 @brief Start a display-writing routine, overwrite in subclasses.
davidprentice 0:8ee30e15ac7b 178 */
davidprentice 0:8ee30e15ac7b 179 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 180 void Adafruit_GFX::startWrite() {}
davidprentice 0:8ee30e15ac7b 181
davidprentice 0:8ee30e15ac7b 182 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 183 /*!
davidprentice 0:8ee30e15ac7b 184 @brief Write a pixel, overwrite in subclasses if startWrite is defined!
davidprentice 0:8ee30e15ac7b 185 @param x x coordinate
davidprentice 0:8ee30e15ac7b 186 @param y y coordinate
davidprentice 0:8ee30e15ac7b 187 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 188 */
davidprentice 0:8ee30e15ac7b 189 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 190 void Adafruit_GFX::writePixel(int16_t x, int16_t y, uint16_t color) {
davidprentice 0:8ee30e15ac7b 191 drawPixel(x, y, color);
davidprentice 0:8ee30e15ac7b 192 }
davidprentice 0:8ee30e15ac7b 193
davidprentice 0:8ee30e15ac7b 194 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 195 /*!
davidprentice 0:8ee30e15ac7b 196 @brief Write a perfectly vertical line, overwrite in subclasses if
davidprentice 0:8ee30e15ac7b 197 startWrite is defined!
davidprentice 0:8ee30e15ac7b 198 @param x Top-most x coordinate
davidprentice 0:8ee30e15ac7b 199 @param y Top-most y coordinate
davidprentice 0:8ee30e15ac7b 200 @param h Height in pixels
davidprentice 0:8ee30e15ac7b 201 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 202 */
davidprentice 0:8ee30e15ac7b 203 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 204 void Adafruit_GFX::writeFastVLine(int16_t x, int16_t y, int16_t h,
davidprentice 0:8ee30e15ac7b 205 uint16_t color) {
davidprentice 0:8ee30e15ac7b 206 // Overwrite in subclasses if startWrite is defined!
davidprentice 0:8ee30e15ac7b 207 // Can be just writeLine(x, y, x, y+h-1, color);
davidprentice 0:8ee30e15ac7b 208 // or writeFillRect(x, y, 1, h, color);
davidprentice 0:8ee30e15ac7b 209 drawFastVLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 210 }
davidprentice 0:8ee30e15ac7b 211
davidprentice 0:8ee30e15ac7b 212 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 213 /*!
davidprentice 0:8ee30e15ac7b 214 @brief Write a perfectly horizontal line, overwrite in subclasses if
davidprentice 0:8ee30e15ac7b 215 startWrite is defined!
davidprentice 0:8ee30e15ac7b 216 @param x Left-most x coordinate
davidprentice 0:8ee30e15ac7b 217 @param y Left-most y coordinate
davidprentice 0:8ee30e15ac7b 218 @param w Width in pixels
davidprentice 0:8ee30e15ac7b 219 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 220 */
davidprentice 0:8ee30e15ac7b 221 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 222 void Adafruit_GFX::writeFastHLine(int16_t x, int16_t y, int16_t w,
davidprentice 0:8ee30e15ac7b 223 uint16_t color) {
davidprentice 0:8ee30e15ac7b 224 // Overwrite in subclasses if startWrite is defined!
davidprentice 0:8ee30e15ac7b 225 // Example: writeLine(x, y, x+w-1, y, color);
davidprentice 0:8ee30e15ac7b 226 // or writeFillRect(x, y, w, 1, color);
davidprentice 0:8ee30e15ac7b 227 drawFastHLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 228 }
davidprentice 0:8ee30e15ac7b 229
davidprentice 0:8ee30e15ac7b 230 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 231 /*!
davidprentice 0:8ee30e15ac7b 232 @brief Write a rectangle completely with one color, overwrite in
davidprentice 0:8ee30e15ac7b 233 subclasses if startWrite is defined!
davidprentice 0:8ee30e15ac7b 234 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 235 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 236 @param w Width in pixels
davidprentice 0:8ee30e15ac7b 237 @param h Height in pixels
davidprentice 0:8ee30e15ac7b 238 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 239 */
davidprentice 0:8ee30e15ac7b 240 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 241 void Adafruit_GFX::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h,
davidprentice 0:8ee30e15ac7b 242 uint16_t color) {
davidprentice 0:8ee30e15ac7b 243 // Overwrite in subclasses if desired!
davidprentice 0:8ee30e15ac7b 244 fillRect(x, y, w, h, color);
davidprentice 0:8ee30e15ac7b 245 }
davidprentice 0:8ee30e15ac7b 246
davidprentice 0:8ee30e15ac7b 247 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 248 /*!
davidprentice 0:8ee30e15ac7b 249 @brief End a display-writing routine, overwrite in subclasses if
davidprentice 0:8ee30e15ac7b 250 startWrite is defined!
davidprentice 0:8ee30e15ac7b 251 */
davidprentice 0:8ee30e15ac7b 252 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 253 void Adafruit_GFX::endWrite() {}
davidprentice 0:8ee30e15ac7b 254
davidprentice 0:8ee30e15ac7b 255 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 256 /*!
davidprentice 0:8ee30e15ac7b 257 @brief Draw a perfectly vertical line (this is often optimized in a
davidprentice 0:8ee30e15ac7b 258 subclass!)
davidprentice 0:8ee30e15ac7b 259 @param x Top-most x coordinate
davidprentice 0:8ee30e15ac7b 260 @param y Top-most y coordinate
davidprentice 0:8ee30e15ac7b 261 @param h Height in pixels
davidprentice 0:8ee30e15ac7b 262 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 263 */
davidprentice 0:8ee30e15ac7b 264 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 265 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, int16_t h,
davidprentice 0:8ee30e15ac7b 266 uint16_t color) {
davidprentice 0:8ee30e15ac7b 267 startWrite();
davidprentice 0:8ee30e15ac7b 268 writeLine(x, y, x, y + h - 1, color);
davidprentice 0:8ee30e15ac7b 269 endWrite();
davidprentice 0:8ee30e15ac7b 270 }
davidprentice 0:8ee30e15ac7b 271
davidprentice 0:8ee30e15ac7b 272 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 273 /*!
davidprentice 0:8ee30e15ac7b 274 @brief Draw a perfectly horizontal line (this is often optimized in a
davidprentice 0:8ee30e15ac7b 275 subclass!)
davidprentice 0:8ee30e15ac7b 276 @param x Left-most x coordinate
davidprentice 0:8ee30e15ac7b 277 @param y Left-most y coordinate
davidprentice 0:8ee30e15ac7b 278 @param w Width in pixels
davidprentice 0:8ee30e15ac7b 279 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 280 */
davidprentice 0:8ee30e15ac7b 281 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 282 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, int16_t w,
davidprentice 0:8ee30e15ac7b 283 uint16_t color) {
davidprentice 0:8ee30e15ac7b 284 startWrite();
davidprentice 0:8ee30e15ac7b 285 writeLine(x, y, x + w - 1, y, color);
davidprentice 0:8ee30e15ac7b 286 endWrite();
davidprentice 0:8ee30e15ac7b 287 }
davidprentice 0:8ee30e15ac7b 288
davidprentice 0:8ee30e15ac7b 289 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 290 /*!
davidprentice 0:8ee30e15ac7b 291 @brief Fill a rectangle completely with one color. Update in subclasses if
davidprentice 0:8ee30e15ac7b 292 desired!
davidprentice 0:8ee30e15ac7b 293 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 294 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 295 @param w Width in pixels
davidprentice 0:8ee30e15ac7b 296 @param h Height in pixels
davidprentice 0:8ee30e15ac7b 297 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 298 */
davidprentice 0:8ee30e15ac7b 299 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 300 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
davidprentice 0:8ee30e15ac7b 301 uint16_t color) {
davidprentice 0:8ee30e15ac7b 302 startWrite();
davidprentice 0:8ee30e15ac7b 303 for (int16_t i = x; i < x + w; i++) {
davidprentice 0:8ee30e15ac7b 304 writeFastVLine(i, y, h, color);
davidprentice 0:8ee30e15ac7b 305 }
davidprentice 0:8ee30e15ac7b 306 endWrite();
davidprentice 0:8ee30e15ac7b 307 }
davidprentice 0:8ee30e15ac7b 308
davidprentice 0:8ee30e15ac7b 309 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 310 /*!
davidprentice 0:8ee30e15ac7b 311 @brief Fill the screen completely with one color. Update in subclasses if
davidprentice 0:8ee30e15ac7b 312 desired!
davidprentice 0:8ee30e15ac7b 313 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 314 */
davidprentice 0:8ee30e15ac7b 315 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 316 void Adafruit_GFX::fillScreen(uint16_t color) {
davidprentice 0:8ee30e15ac7b 317 fillRect(0, 0, _width, _height, color);
davidprentice 0:8ee30e15ac7b 318 }
davidprentice 0:8ee30e15ac7b 319
davidprentice 0:8ee30e15ac7b 320 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 321 /*!
davidprentice 0:8ee30e15ac7b 322 @brief Draw a line
davidprentice 0:8ee30e15ac7b 323 @param x0 Start point x coordinate
davidprentice 0:8ee30e15ac7b 324 @param y0 Start point y coordinate
davidprentice 0:8ee30e15ac7b 325 @param x1 End point x coordinate
davidprentice 0:8ee30e15ac7b 326 @param y1 End point y coordinate
davidprentice 0:8ee30e15ac7b 327 @param color 16-bit 5-6-5 Color to draw with
davidprentice 0:8ee30e15ac7b 328 */
davidprentice 0:8ee30e15ac7b 329 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 330 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
davidprentice 0:8ee30e15ac7b 331 uint16_t color) {
davidprentice 0:8ee30e15ac7b 332 // Update in subclasses if desired!
davidprentice 0:8ee30e15ac7b 333 if (x0 == x1) {
davidprentice 0:8ee30e15ac7b 334 if (y0 > y1)
davidprentice 0:8ee30e15ac7b 335 _swap_int16_t(y0, y1);
davidprentice 0:8ee30e15ac7b 336 drawFastVLine(x0, y0, y1 - y0 + 1, color);
davidprentice 0:8ee30e15ac7b 337 } else if (y0 == y1) {
davidprentice 0:8ee30e15ac7b 338 if (x0 > x1)
davidprentice 0:8ee30e15ac7b 339 _swap_int16_t(x0, x1);
davidprentice 0:8ee30e15ac7b 340 drawFastHLine(x0, y0, x1 - x0 + 1, color);
davidprentice 0:8ee30e15ac7b 341 } else {
davidprentice 0:8ee30e15ac7b 342 startWrite();
davidprentice 0:8ee30e15ac7b 343 writeLine(x0, y0, x1, y1, color);
davidprentice 0:8ee30e15ac7b 344 endWrite();
davidprentice 0:8ee30e15ac7b 345 }
davidprentice 0:8ee30e15ac7b 346 }
davidprentice 0:8ee30e15ac7b 347
davidprentice 0:8ee30e15ac7b 348 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 349 /*!
davidprentice 0:8ee30e15ac7b 350 @brief Draw a circle outline
davidprentice 0:8ee30e15ac7b 351 @param x0 Center-point x coordinate
davidprentice 0:8ee30e15ac7b 352 @param y0 Center-point y coordinate
davidprentice 0:8ee30e15ac7b 353 @param r Radius of circle
davidprentice 0:8ee30e15ac7b 354 @param color 16-bit 5-6-5 Color to draw with
davidprentice 0:8ee30e15ac7b 355 */
davidprentice 0:8ee30e15ac7b 356 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 357 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
davidprentice 0:8ee30e15ac7b 358 uint16_t color) {
davidprentice 0:8ee30e15ac7b 359 #if defined(ESP8266)
davidprentice 0:8ee30e15ac7b 360 yield();
davidprentice 0:8ee30e15ac7b 361 #endif
davidprentice 0:8ee30e15ac7b 362 int16_t f = 1 - r;
davidprentice 0:8ee30e15ac7b 363 int16_t ddF_x = 1;
davidprentice 0:8ee30e15ac7b 364 int16_t ddF_y = -2 * r;
davidprentice 0:8ee30e15ac7b 365 int16_t x = 0;
davidprentice 0:8ee30e15ac7b 366 int16_t y = r;
davidprentice 0:8ee30e15ac7b 367
davidprentice 0:8ee30e15ac7b 368 startWrite();
davidprentice 0:8ee30e15ac7b 369 writePixel(x0, y0 + r, color);
davidprentice 0:8ee30e15ac7b 370 writePixel(x0, y0 - r, color);
davidprentice 0:8ee30e15ac7b 371 writePixel(x0 + r, y0, color);
davidprentice 0:8ee30e15ac7b 372 writePixel(x0 - r, y0, color);
davidprentice 0:8ee30e15ac7b 373
davidprentice 0:8ee30e15ac7b 374 while (x < y) {
davidprentice 0:8ee30e15ac7b 375 if (f >= 0) {
davidprentice 0:8ee30e15ac7b 376 y--;
davidprentice 0:8ee30e15ac7b 377 ddF_y += 2;
davidprentice 0:8ee30e15ac7b 378 f += ddF_y;
davidprentice 0:8ee30e15ac7b 379 }
davidprentice 0:8ee30e15ac7b 380 x++;
davidprentice 0:8ee30e15ac7b 381 ddF_x += 2;
davidprentice 0:8ee30e15ac7b 382 f += ddF_x;
davidprentice 0:8ee30e15ac7b 383
davidprentice 0:8ee30e15ac7b 384 writePixel(x0 + x, y0 + y, color);
davidprentice 0:8ee30e15ac7b 385 writePixel(x0 - x, y0 + y, color);
davidprentice 0:8ee30e15ac7b 386 writePixel(x0 + x, y0 - y, color);
davidprentice 0:8ee30e15ac7b 387 writePixel(x0 - x, y0 - y, color);
davidprentice 0:8ee30e15ac7b 388 writePixel(x0 + y, y0 + x, color);
davidprentice 0:8ee30e15ac7b 389 writePixel(x0 - y, y0 + x, color);
davidprentice 0:8ee30e15ac7b 390 writePixel(x0 + y, y0 - x, color);
davidprentice 0:8ee30e15ac7b 391 writePixel(x0 - y, y0 - x, color);
davidprentice 0:8ee30e15ac7b 392 }
davidprentice 0:8ee30e15ac7b 393 endWrite();
davidprentice 0:8ee30e15ac7b 394 }
davidprentice 0:8ee30e15ac7b 395
davidprentice 0:8ee30e15ac7b 396 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 397 /*!
davidprentice 0:8ee30e15ac7b 398 @brief Quarter-circle drawer, used to do circles and roundrects
davidprentice 0:8ee30e15ac7b 399 @param x0 Center-point x coordinate
davidprentice 0:8ee30e15ac7b 400 @param y0 Center-point y coordinate
davidprentice 0:8ee30e15ac7b 401 @param r Radius of circle
davidprentice 0:8ee30e15ac7b 402 @param cornername Mask bit #1 or bit #2 to indicate which quarters of
davidprentice 0:8ee30e15ac7b 403 the circle we're doing
davidprentice 0:8ee30e15ac7b 404 @param color 16-bit 5-6-5 Color to draw with
davidprentice 0:8ee30e15ac7b 405 */
davidprentice 0:8ee30e15ac7b 406 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 407 void Adafruit_GFX::drawCircleHelper(int16_t x0, int16_t y0, int16_t r,
davidprentice 0:8ee30e15ac7b 408 uint8_t cornername, uint16_t color) {
davidprentice 0:8ee30e15ac7b 409 int16_t f = 1 - r;
davidprentice 0:8ee30e15ac7b 410 int16_t ddF_x = 1;
davidprentice 0:8ee30e15ac7b 411 int16_t ddF_y = -2 * r;
davidprentice 0:8ee30e15ac7b 412 int16_t x = 0;
davidprentice 0:8ee30e15ac7b 413 int16_t y = r;
davidprentice 0:8ee30e15ac7b 414
davidprentice 0:8ee30e15ac7b 415 while (x < y) {
davidprentice 0:8ee30e15ac7b 416 if (f >= 0) {
davidprentice 0:8ee30e15ac7b 417 y--;
davidprentice 0:8ee30e15ac7b 418 ddF_y += 2;
davidprentice 0:8ee30e15ac7b 419 f += ddF_y;
davidprentice 0:8ee30e15ac7b 420 }
davidprentice 0:8ee30e15ac7b 421 x++;
davidprentice 0:8ee30e15ac7b 422 ddF_x += 2;
davidprentice 0:8ee30e15ac7b 423 f += ddF_x;
davidprentice 0:8ee30e15ac7b 424 if (cornername & 0x4) {
davidprentice 0:8ee30e15ac7b 425 writePixel(x0 + x, y0 + y, color);
davidprentice 0:8ee30e15ac7b 426 writePixel(x0 + y, y0 + x, color);
davidprentice 0:8ee30e15ac7b 427 }
davidprentice 0:8ee30e15ac7b 428 if (cornername & 0x2) {
davidprentice 0:8ee30e15ac7b 429 writePixel(x0 + x, y0 - y, color);
davidprentice 0:8ee30e15ac7b 430 writePixel(x0 + y, y0 - x, color);
davidprentice 0:8ee30e15ac7b 431 }
davidprentice 0:8ee30e15ac7b 432 if (cornername & 0x8) {
davidprentice 0:8ee30e15ac7b 433 writePixel(x0 - y, y0 + x, color);
davidprentice 0:8ee30e15ac7b 434 writePixel(x0 - x, y0 + y, color);
davidprentice 0:8ee30e15ac7b 435 }
davidprentice 0:8ee30e15ac7b 436 if (cornername & 0x1) {
davidprentice 0:8ee30e15ac7b 437 writePixel(x0 - y, y0 - x, color);
davidprentice 0:8ee30e15ac7b 438 writePixel(x0 - x, y0 - y, color);
davidprentice 0:8ee30e15ac7b 439 }
davidprentice 0:8ee30e15ac7b 440 }
davidprentice 0:8ee30e15ac7b 441 }
davidprentice 0:8ee30e15ac7b 442
davidprentice 0:8ee30e15ac7b 443 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 444 /*!
davidprentice 0:8ee30e15ac7b 445 @brief Draw a circle with filled color
davidprentice 0:8ee30e15ac7b 446 @param x0 Center-point x coordinate
davidprentice 0:8ee30e15ac7b 447 @param y0 Center-point y coordinate
davidprentice 0:8ee30e15ac7b 448 @param r Radius of circle
davidprentice 0:8ee30e15ac7b 449 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 450 */
davidprentice 0:8ee30e15ac7b 451 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 452 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r,
davidprentice 0:8ee30e15ac7b 453 uint16_t color) {
davidprentice 0:8ee30e15ac7b 454 startWrite();
davidprentice 0:8ee30e15ac7b 455 writeFastVLine(x0, y0 - r, 2 * r + 1, color);
davidprentice 0:8ee30e15ac7b 456 fillCircleHelper(x0, y0, r, 3, 0, color);
davidprentice 0:8ee30e15ac7b 457 endWrite();
davidprentice 0:8ee30e15ac7b 458 }
davidprentice 0:8ee30e15ac7b 459
davidprentice 0:8ee30e15ac7b 460 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 461 /*!
davidprentice 0:8ee30e15ac7b 462 @brief Quarter-circle drawer with fill, used for circles and roundrects
davidprentice 0:8ee30e15ac7b 463 @param x0 Center-point x coordinate
davidprentice 0:8ee30e15ac7b 464 @param y0 Center-point y coordinate
davidprentice 0:8ee30e15ac7b 465 @param r Radius of circle
davidprentice 0:8ee30e15ac7b 466 @param corners Mask bits indicating which quarters we're doing
davidprentice 0:8ee30e15ac7b 467 @param delta Offset from center-point, used for round-rects
davidprentice 0:8ee30e15ac7b 468 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 469 */
davidprentice 0:8ee30e15ac7b 470 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 471 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
davidprentice 0:8ee30e15ac7b 472 uint8_t corners, int16_t delta,
davidprentice 0:8ee30e15ac7b 473 uint16_t color) {
davidprentice 0:8ee30e15ac7b 474
davidprentice 0:8ee30e15ac7b 475 int16_t f = 1 - r;
davidprentice 0:8ee30e15ac7b 476 int16_t ddF_x = 1;
davidprentice 0:8ee30e15ac7b 477 int16_t ddF_y = -2 * r;
davidprentice 0:8ee30e15ac7b 478 int16_t x = 0;
davidprentice 0:8ee30e15ac7b 479 int16_t y = r;
davidprentice 0:8ee30e15ac7b 480 int16_t px = x;
davidprentice 0:8ee30e15ac7b 481 int16_t py = y;
davidprentice 0:8ee30e15ac7b 482
davidprentice 0:8ee30e15ac7b 483 delta++; // Avoid some +1's in the loop
davidprentice 0:8ee30e15ac7b 484
davidprentice 0:8ee30e15ac7b 485 while (x < y) {
davidprentice 0:8ee30e15ac7b 486 if (f >= 0) {
davidprentice 0:8ee30e15ac7b 487 y--;
davidprentice 0:8ee30e15ac7b 488 ddF_y += 2;
davidprentice 0:8ee30e15ac7b 489 f += ddF_y;
davidprentice 0:8ee30e15ac7b 490 }
davidprentice 0:8ee30e15ac7b 491 x++;
davidprentice 0:8ee30e15ac7b 492 ddF_x += 2;
davidprentice 0:8ee30e15ac7b 493 f += ddF_x;
davidprentice 0:8ee30e15ac7b 494 // These checks avoid double-drawing certain lines, important
davidprentice 0:8ee30e15ac7b 495 // for the SSD1306 library which has an INVERT drawing mode.
davidprentice 0:8ee30e15ac7b 496 if (x < (y + 1)) {
davidprentice 0:8ee30e15ac7b 497 if (corners & 1)
davidprentice 0:8ee30e15ac7b 498 writeFastVLine(x0 + x, y0 - y, 2 * y + delta, color);
davidprentice 0:8ee30e15ac7b 499 if (corners & 2)
davidprentice 0:8ee30e15ac7b 500 writeFastVLine(x0 - x, y0 - y, 2 * y + delta, color);
davidprentice 0:8ee30e15ac7b 501 }
davidprentice 0:8ee30e15ac7b 502 if (y != py) {
davidprentice 0:8ee30e15ac7b 503 if (corners & 1)
davidprentice 0:8ee30e15ac7b 504 writeFastVLine(x0 + py, y0 - px, 2 * px + delta, color);
davidprentice 0:8ee30e15ac7b 505 if (corners & 2)
davidprentice 0:8ee30e15ac7b 506 writeFastVLine(x0 - py, y0 - px, 2 * px + delta, color);
davidprentice 0:8ee30e15ac7b 507 py = y;
davidprentice 0:8ee30e15ac7b 508 }
davidprentice 0:8ee30e15ac7b 509 px = x;
davidprentice 0:8ee30e15ac7b 510 }
davidprentice 0:8ee30e15ac7b 511 }
davidprentice 0:8ee30e15ac7b 512
davidprentice 0:8ee30e15ac7b 513 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 514 /*!
davidprentice 0:8ee30e15ac7b 515 @brief Draw a rectangle with no fill color
davidprentice 0:8ee30e15ac7b 516 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 517 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 518 @param w Width in pixels
davidprentice 0:8ee30e15ac7b 519 @param h Height in pixels
davidprentice 0:8ee30e15ac7b 520 @param color 16-bit 5-6-5 Color to draw with
davidprentice 0:8ee30e15ac7b 521 */
davidprentice 0:8ee30e15ac7b 522 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 523 void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h,
davidprentice 0:8ee30e15ac7b 524 uint16_t color) {
davidprentice 0:8ee30e15ac7b 525 startWrite();
davidprentice 0:8ee30e15ac7b 526 writeFastHLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 527 writeFastHLine(x, y + h - 1, w, color);
davidprentice 0:8ee30e15ac7b 528 writeFastVLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 529 writeFastVLine(x + w - 1, y, h, color);
davidprentice 0:8ee30e15ac7b 530 endWrite();
davidprentice 0:8ee30e15ac7b 531 }
davidprentice 0:8ee30e15ac7b 532
davidprentice 0:8ee30e15ac7b 533 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 534 /*!
davidprentice 0:8ee30e15ac7b 535 @brief Draw a rounded rectangle with no fill color
davidprentice 0:8ee30e15ac7b 536 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 537 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 538 @param w Width in pixels
davidprentice 0:8ee30e15ac7b 539 @param h Height in pixels
davidprentice 0:8ee30e15ac7b 540 @param r Radius of corner rounding
davidprentice 0:8ee30e15ac7b 541 @param color 16-bit 5-6-5 Color to draw with
davidprentice 0:8ee30e15ac7b 542 */
davidprentice 0:8ee30e15ac7b 543 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 544 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h,
davidprentice 0:8ee30e15ac7b 545 int16_t r, uint16_t color) {
davidprentice 0:8ee30e15ac7b 546 int16_t max_radius = ((w < h) ? w : h) / 2; // 1/2 minor axis
davidprentice 0:8ee30e15ac7b 547 if (r > max_radius)
davidprentice 0:8ee30e15ac7b 548 r = max_radius;
davidprentice 0:8ee30e15ac7b 549 // smarter version
davidprentice 0:8ee30e15ac7b 550 startWrite();
davidprentice 0:8ee30e15ac7b 551 writeFastHLine(x + r, y, w - 2 * r, color); // Top
davidprentice 0:8ee30e15ac7b 552 writeFastHLine(x + r, y + h - 1, w - 2 * r, color); // Bottom
davidprentice 0:8ee30e15ac7b 553 writeFastVLine(x, y + r, h - 2 * r, color); // Left
davidprentice 0:8ee30e15ac7b 554 writeFastVLine(x + w - 1, y + r, h - 2 * r, color); // Right
davidprentice 0:8ee30e15ac7b 555 // draw four corners
davidprentice 0:8ee30e15ac7b 556 drawCircleHelper(x + r, y + r, r, 1, color);
davidprentice 0:8ee30e15ac7b 557 drawCircleHelper(x + w - r - 1, y + r, r, 2, color);
davidprentice 0:8ee30e15ac7b 558 drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4, color);
davidprentice 0:8ee30e15ac7b 559 drawCircleHelper(x + r, y + h - r - 1, r, 8, color);
davidprentice 0:8ee30e15ac7b 560 endWrite();
davidprentice 0:8ee30e15ac7b 561 }
davidprentice 0:8ee30e15ac7b 562
davidprentice 0:8ee30e15ac7b 563 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 564 /*!
davidprentice 0:8ee30e15ac7b 565 @brief Draw a rounded rectangle with fill color
davidprentice 0:8ee30e15ac7b 566 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 567 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 568 @param w Width in pixels
davidprentice 0:8ee30e15ac7b 569 @param h Height in pixels
davidprentice 0:8ee30e15ac7b 570 @param r Radius of corner rounding
davidprentice 0:8ee30e15ac7b 571 @param color 16-bit 5-6-5 Color to draw/fill with
davidprentice 0:8ee30e15ac7b 572 */
davidprentice 0:8ee30e15ac7b 573 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 574 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h,
davidprentice 0:8ee30e15ac7b 575 int16_t r, uint16_t color) {
davidprentice 0:8ee30e15ac7b 576 int16_t max_radius = ((w < h) ? w : h) / 2; // 1/2 minor axis
davidprentice 0:8ee30e15ac7b 577 if (r > max_radius)
davidprentice 0:8ee30e15ac7b 578 r = max_radius;
davidprentice 0:8ee30e15ac7b 579 // smarter version
davidprentice 0:8ee30e15ac7b 580 startWrite();
davidprentice 0:8ee30e15ac7b 581 writeFillRect(x + r, y, w - 2 * r, h, color);
davidprentice 0:8ee30e15ac7b 582 // draw four corners
davidprentice 0:8ee30e15ac7b 583 fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);
davidprentice 0:8ee30e15ac7b 584 fillCircleHelper(x + r, y + r, r, 2, h - 2 * r - 1, color);
davidprentice 0:8ee30e15ac7b 585 endWrite();
davidprentice 0:8ee30e15ac7b 586 }
davidprentice 0:8ee30e15ac7b 587
davidprentice 0:8ee30e15ac7b 588 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 589 /*!
davidprentice 0:8ee30e15ac7b 590 @brief Draw a triangle with no fill color
davidprentice 0:8ee30e15ac7b 591 @param x0 Vertex #0 x coordinate
davidprentice 0:8ee30e15ac7b 592 @param y0 Vertex #0 y coordinate
davidprentice 0:8ee30e15ac7b 593 @param x1 Vertex #1 x coordinate
davidprentice 0:8ee30e15ac7b 594 @param y1 Vertex #1 y coordinate
davidprentice 0:8ee30e15ac7b 595 @param x2 Vertex #2 x coordinate
davidprentice 0:8ee30e15ac7b 596 @param y2 Vertex #2 y coordinate
davidprentice 0:8ee30e15ac7b 597 @param color 16-bit 5-6-5 Color to draw with
davidprentice 0:8ee30e15ac7b 598 */
davidprentice 0:8ee30e15ac7b 599 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 600 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
davidprentice 0:8ee30e15ac7b 601 int16_t x2, int16_t y2, uint16_t color) {
davidprentice 0:8ee30e15ac7b 602 drawLine(x0, y0, x1, y1, color);
davidprentice 0:8ee30e15ac7b 603 drawLine(x1, y1, x2, y2, color);
davidprentice 0:8ee30e15ac7b 604 drawLine(x2, y2, x0, y0, color);
davidprentice 0:8ee30e15ac7b 605 }
davidprentice 0:8ee30e15ac7b 606
davidprentice 0:8ee30e15ac7b 607 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 608 /*!
davidprentice 0:8ee30e15ac7b 609 @brief Draw a triangle with color-fill
davidprentice 0:8ee30e15ac7b 610 @param x0 Vertex #0 x coordinate
davidprentice 0:8ee30e15ac7b 611 @param y0 Vertex #0 y coordinate
davidprentice 0:8ee30e15ac7b 612 @param x1 Vertex #1 x coordinate
davidprentice 0:8ee30e15ac7b 613 @param y1 Vertex #1 y coordinate
davidprentice 0:8ee30e15ac7b 614 @param x2 Vertex #2 x coordinate
davidprentice 0:8ee30e15ac7b 615 @param y2 Vertex #2 y coordinate
davidprentice 0:8ee30e15ac7b 616 @param color 16-bit 5-6-5 Color to fill/draw with
davidprentice 0:8ee30e15ac7b 617 */
davidprentice 0:8ee30e15ac7b 618 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 619 void Adafruit_GFX::fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
davidprentice 0:8ee30e15ac7b 620 int16_t x2, int16_t y2, uint16_t color) {
davidprentice 0:8ee30e15ac7b 621
davidprentice 0:8ee30e15ac7b 622 int16_t a, b, y, last;
davidprentice 0:8ee30e15ac7b 623
davidprentice 0:8ee30e15ac7b 624 // Sort coordinates by Y order (y2 >= y1 >= y0)
davidprentice 0:8ee30e15ac7b 625 if (y0 > y1) {
davidprentice 0:8ee30e15ac7b 626 _swap_int16_t(y0, y1);
davidprentice 0:8ee30e15ac7b 627 _swap_int16_t(x0, x1);
davidprentice 0:8ee30e15ac7b 628 }
davidprentice 0:8ee30e15ac7b 629 if (y1 > y2) {
davidprentice 0:8ee30e15ac7b 630 _swap_int16_t(y2, y1);
davidprentice 0:8ee30e15ac7b 631 _swap_int16_t(x2, x1);
davidprentice 0:8ee30e15ac7b 632 }
davidprentice 0:8ee30e15ac7b 633 if (y0 > y1) {
davidprentice 0:8ee30e15ac7b 634 _swap_int16_t(y0, y1);
davidprentice 0:8ee30e15ac7b 635 _swap_int16_t(x0, x1);
davidprentice 0:8ee30e15ac7b 636 }
davidprentice 0:8ee30e15ac7b 637
davidprentice 0:8ee30e15ac7b 638 startWrite();
davidprentice 0:8ee30e15ac7b 639 if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
davidprentice 0:8ee30e15ac7b 640 a = b = x0;
davidprentice 0:8ee30e15ac7b 641 if (x1 < a)
davidprentice 0:8ee30e15ac7b 642 a = x1;
davidprentice 0:8ee30e15ac7b 643 else if (x1 > b)
davidprentice 0:8ee30e15ac7b 644 b = x1;
davidprentice 0:8ee30e15ac7b 645 if (x2 < a)
davidprentice 0:8ee30e15ac7b 646 a = x2;
davidprentice 0:8ee30e15ac7b 647 else if (x2 > b)
davidprentice 0:8ee30e15ac7b 648 b = x2;
davidprentice 0:8ee30e15ac7b 649 writeFastHLine(a, y0, b - a + 1, color);
davidprentice 0:8ee30e15ac7b 650 endWrite();
davidprentice 0:8ee30e15ac7b 651 return;
davidprentice 0:8ee30e15ac7b 652 }
davidprentice 0:8ee30e15ac7b 653
davidprentice 0:8ee30e15ac7b 654 int16_t dx01 = x1 - x0, dy01 = y1 - y0, dx02 = x2 - x0, dy02 = y2 - y0,
davidprentice 0:8ee30e15ac7b 655 dx12 = x2 - x1, dy12 = y2 - y1;
davidprentice 0:8ee30e15ac7b 656 int32_t sa = 0, sb = 0;
davidprentice 0:8ee30e15ac7b 657
davidprentice 0:8ee30e15ac7b 658 // For upper part of triangle, find scanline crossings for segments
davidprentice 0:8ee30e15ac7b 659 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
davidprentice 0:8ee30e15ac7b 660 // is included here (and second loop will be skipped, avoiding a /0
davidprentice 0:8ee30e15ac7b 661 // error there), otherwise scanline y1 is skipped here and handled
davidprentice 0:8ee30e15ac7b 662 // in the second loop...which also avoids a /0 error here if y0=y1
davidprentice 0:8ee30e15ac7b 663 // (flat-topped triangle).
davidprentice 0:8ee30e15ac7b 664 if (y1 == y2)
davidprentice 0:8ee30e15ac7b 665 last = y1; // Include y1 scanline
davidprentice 0:8ee30e15ac7b 666 else
davidprentice 0:8ee30e15ac7b 667 last = y1 - 1; // Skip it
davidprentice 0:8ee30e15ac7b 668
davidprentice 0:8ee30e15ac7b 669 for (y = y0; y <= last; y++) {
davidprentice 0:8ee30e15ac7b 670 a = x0 + sa / dy01;
davidprentice 0:8ee30e15ac7b 671 b = x0 + sb / dy02;
davidprentice 0:8ee30e15ac7b 672 sa += dx01;
davidprentice 0:8ee30e15ac7b 673 sb += dx02;
davidprentice 0:8ee30e15ac7b 674 /* longhand:
davidprentice 0:8ee30e15ac7b 675 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
davidprentice 0:8ee30e15ac7b 676 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
davidprentice 0:8ee30e15ac7b 677 */
davidprentice 0:8ee30e15ac7b 678 if (a > b)
davidprentice 0:8ee30e15ac7b 679 _swap_int16_t(a, b);
davidprentice 0:8ee30e15ac7b 680 writeFastHLine(a, y, b - a + 1, color);
davidprentice 0:8ee30e15ac7b 681 }
davidprentice 0:8ee30e15ac7b 682
davidprentice 0:8ee30e15ac7b 683 // For lower part of triangle, find scanline crossings for segments
davidprentice 0:8ee30e15ac7b 684 // 0-2 and 1-2. This loop is skipped if y1=y2.
davidprentice 0:8ee30e15ac7b 685 sa = (int32_t)dx12 * (y - y1);
davidprentice 0:8ee30e15ac7b 686 sb = (int32_t)dx02 * (y - y0);
davidprentice 0:8ee30e15ac7b 687 for (; y <= y2; y++) {
davidprentice 0:8ee30e15ac7b 688 a = x1 + sa / dy12;
davidprentice 0:8ee30e15ac7b 689 b = x0 + sb / dy02;
davidprentice 0:8ee30e15ac7b 690 sa += dx12;
davidprentice 0:8ee30e15ac7b 691 sb += dx02;
davidprentice 0:8ee30e15ac7b 692 /* longhand:
davidprentice 0:8ee30e15ac7b 693 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
davidprentice 0:8ee30e15ac7b 694 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
davidprentice 0:8ee30e15ac7b 695 */
davidprentice 0:8ee30e15ac7b 696 if (a > b)
davidprentice 0:8ee30e15ac7b 697 _swap_int16_t(a, b);
davidprentice 0:8ee30e15ac7b 698 writeFastHLine(a, y, b - a + 1, color);
davidprentice 0:8ee30e15ac7b 699 }
davidprentice 0:8ee30e15ac7b 700 endWrite();
davidprentice 0:8ee30e15ac7b 701 }
davidprentice 0:8ee30e15ac7b 702
davidprentice 0:8ee30e15ac7b 703 // BITMAP / XBITMAP / GRAYSCALE / RGB BITMAP FUNCTIONS ---------------------
davidprentice 0:8ee30e15ac7b 704
davidprentice 0:8ee30e15ac7b 705 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 706 /*!
davidprentice 0:8ee30e15ac7b 707 @brief Draw a PROGMEM-resident 1-bit image at the specified (x,y)
davidprentice 0:8ee30e15ac7b 708 position, using the specified foreground color (unset bits are transparent).
davidprentice 0:8ee30e15ac7b 709 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 710 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 711 @param bitmap byte array with monochrome bitmap
davidprentice 0:8ee30e15ac7b 712 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 713 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 714 @param color 16-bit 5-6-5 Color to draw with
davidprentice 0:8ee30e15ac7b 715 */
davidprentice 0:8ee30e15ac7b 716 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 717 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[],
davidprentice 0:8ee30e15ac7b 718 int16_t w, int16_t h, uint16_t color) {
davidprentice 0:8ee30e15ac7b 719
davidprentice 0:8ee30e15ac7b 720 int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
davidprentice 0:8ee30e15ac7b 721 uint8_t byte = 0;
davidprentice 0:8ee30e15ac7b 722
davidprentice 0:8ee30e15ac7b 723 startWrite();
davidprentice 0:8ee30e15ac7b 724 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 725 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 726 if (i & 7)
davidprentice 0:8ee30e15ac7b 727 byte <<= 1;
davidprentice 0:8ee30e15ac7b 728 else
davidprentice 0:8ee30e15ac7b 729 byte = pgm_read_byte(&bitmap[j * byteWidth + i / 8]);
davidprentice 0:8ee30e15ac7b 730 if (byte & 0x80)
davidprentice 0:8ee30e15ac7b 731 writePixel(x + i, y, color);
davidprentice 0:8ee30e15ac7b 732 }
davidprentice 0:8ee30e15ac7b 733 }
davidprentice 0:8ee30e15ac7b 734 endWrite();
davidprentice 0:8ee30e15ac7b 735 }
davidprentice 0:8ee30e15ac7b 736
davidprentice 0:8ee30e15ac7b 737 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 738 /*!
davidprentice 0:8ee30e15ac7b 739 @brief Draw a PROGMEM-resident 1-bit image at the specified (x,y)
davidprentice 0:8ee30e15ac7b 740 position, using the specified foreground (for set bits) and background (unset
davidprentice 0:8ee30e15ac7b 741 bits) colors.
davidprentice 0:8ee30e15ac7b 742 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 743 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 744 @param bitmap byte array with monochrome bitmap
davidprentice 0:8ee30e15ac7b 745 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 746 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 747 @param color 16-bit 5-6-5 Color to draw pixels with
davidprentice 0:8ee30e15ac7b 748 @param bg 16-bit 5-6-5 Color to draw background with
davidprentice 0:8ee30e15ac7b 749 */
davidprentice 0:8ee30e15ac7b 750 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 751 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[],
davidprentice 0:8ee30e15ac7b 752 int16_t w, int16_t h, uint16_t color,
davidprentice 0:8ee30e15ac7b 753 uint16_t bg) {
davidprentice 0:8ee30e15ac7b 754
davidprentice 0:8ee30e15ac7b 755 int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
davidprentice 0:8ee30e15ac7b 756 uint8_t byte = 0;
davidprentice 0:8ee30e15ac7b 757
davidprentice 0:8ee30e15ac7b 758 startWrite();
davidprentice 0:8ee30e15ac7b 759 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 760 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 761 if (i & 7)
davidprentice 0:8ee30e15ac7b 762 byte <<= 1;
davidprentice 0:8ee30e15ac7b 763 else
davidprentice 0:8ee30e15ac7b 764 byte = pgm_read_byte(&bitmap[j * byteWidth + i / 8]);
davidprentice 0:8ee30e15ac7b 765 writePixel(x + i, y, (byte & 0x80) ? color : bg);
davidprentice 0:8ee30e15ac7b 766 }
davidprentice 0:8ee30e15ac7b 767 }
davidprentice 0:8ee30e15ac7b 768 endWrite();
davidprentice 0:8ee30e15ac7b 769 }
davidprentice 0:8ee30e15ac7b 770
davidprentice 0:8ee30e15ac7b 771 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 772 /*!
davidprentice 0:8ee30e15ac7b 773 @brief Draw a RAM-resident 1-bit image at the specified (x,y) position,
davidprentice 0:8ee30e15ac7b 774 using the specified foreground color (unset bits are transparent).
davidprentice 0:8ee30e15ac7b 775 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 776 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 777 @param bitmap byte array with monochrome bitmap
davidprentice 0:8ee30e15ac7b 778 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 779 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 780 @param color 16-bit 5-6-5 Color to draw with
davidprentice 0:8ee30e15ac7b 781 */
davidprentice 0:8ee30e15ac7b 782 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 783 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w,
davidprentice 0:8ee30e15ac7b 784 int16_t h, uint16_t color) {
davidprentice 0:8ee30e15ac7b 785
davidprentice 0:8ee30e15ac7b 786 int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
davidprentice 0:8ee30e15ac7b 787 uint8_t byte = 0;
davidprentice 0:8ee30e15ac7b 788
davidprentice 0:8ee30e15ac7b 789 startWrite();
davidprentice 0:8ee30e15ac7b 790 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 791 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 792 if (i & 7)
davidprentice 0:8ee30e15ac7b 793 byte <<= 1;
davidprentice 0:8ee30e15ac7b 794 else
davidprentice 0:8ee30e15ac7b 795 byte = bitmap[j * byteWidth + i / 8];
davidprentice 0:8ee30e15ac7b 796 if (byte & 0x80)
davidprentice 0:8ee30e15ac7b 797 writePixel(x + i, y, color);
davidprentice 0:8ee30e15ac7b 798 }
davidprentice 0:8ee30e15ac7b 799 }
davidprentice 0:8ee30e15ac7b 800 endWrite();
davidprentice 0:8ee30e15ac7b 801 }
davidprentice 0:8ee30e15ac7b 802
davidprentice 0:8ee30e15ac7b 803 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 804 /*!
davidprentice 0:8ee30e15ac7b 805 @brief Draw a RAM-resident 1-bit image at the specified (x,y) position,
davidprentice 0:8ee30e15ac7b 806 using the specified foreground (for set bits) and background (unset bits)
davidprentice 0:8ee30e15ac7b 807 colors.
davidprentice 0:8ee30e15ac7b 808 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 809 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 810 @param bitmap byte array with monochrome bitmap
davidprentice 0:8ee30e15ac7b 811 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 812 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 813 @param color 16-bit 5-6-5 Color to draw pixels with
davidprentice 0:8ee30e15ac7b 814 @param bg 16-bit 5-6-5 Color to draw background with
davidprentice 0:8ee30e15ac7b 815 */
davidprentice 0:8ee30e15ac7b 816 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 817 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w,
davidprentice 0:8ee30e15ac7b 818 int16_t h, uint16_t color, uint16_t bg) {
davidprentice 0:8ee30e15ac7b 819
davidprentice 0:8ee30e15ac7b 820 int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
davidprentice 0:8ee30e15ac7b 821 uint8_t byte = 0;
davidprentice 0:8ee30e15ac7b 822
davidprentice 0:8ee30e15ac7b 823 startWrite();
davidprentice 0:8ee30e15ac7b 824 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 825 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 826 if (i & 7)
davidprentice 0:8ee30e15ac7b 827 byte <<= 1;
davidprentice 0:8ee30e15ac7b 828 else
davidprentice 0:8ee30e15ac7b 829 byte = bitmap[j * byteWidth + i / 8];
davidprentice 0:8ee30e15ac7b 830 writePixel(x + i, y, (byte & 0x80) ? color : bg);
davidprentice 0:8ee30e15ac7b 831 }
davidprentice 0:8ee30e15ac7b 832 }
davidprentice 0:8ee30e15ac7b 833 endWrite();
davidprentice 0:8ee30e15ac7b 834 }
davidprentice 0:8ee30e15ac7b 835
davidprentice 0:8ee30e15ac7b 836 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 837 /*!
davidprentice 0:8ee30e15ac7b 838 @brief Draw PROGMEM-resident XBitMap Files (*.xbm), exported from GIMP.
davidprentice 0:8ee30e15ac7b 839 Usage: Export from GIMP to *.xbm, rename *.xbm to *.c and open in editor.
davidprentice 0:8ee30e15ac7b 840 C Array can be directly used with this function.
davidprentice 0:8ee30e15ac7b 841 There is no RAM-resident version of this function; if generating bitmaps
davidprentice 0:8ee30e15ac7b 842 in RAM, use the format defined by drawBitmap() and call that instead.
davidprentice 0:8ee30e15ac7b 843 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 844 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 845 @param bitmap byte array with monochrome bitmap
davidprentice 0:8ee30e15ac7b 846 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 847 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 848 @param color 16-bit 5-6-5 Color to draw pixels with
davidprentice 0:8ee30e15ac7b 849 */
davidprentice 0:8ee30e15ac7b 850 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 851 void Adafruit_GFX::drawXBitmap(int16_t x, int16_t y, const uint8_t bitmap[],
davidprentice 0:8ee30e15ac7b 852 int16_t w, int16_t h, uint16_t color) {
davidprentice 0:8ee30e15ac7b 853
davidprentice 0:8ee30e15ac7b 854 int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
davidprentice 0:8ee30e15ac7b 855 uint8_t byte = 0;
davidprentice 0:8ee30e15ac7b 856
davidprentice 0:8ee30e15ac7b 857 startWrite();
davidprentice 0:8ee30e15ac7b 858 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 859 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 860 if (i & 7)
davidprentice 0:8ee30e15ac7b 861 byte >>= 1;
davidprentice 0:8ee30e15ac7b 862 else
davidprentice 0:8ee30e15ac7b 863 byte = pgm_read_byte(&bitmap[j * byteWidth + i / 8]);
davidprentice 0:8ee30e15ac7b 864 // Nearly identical to drawBitmap(), only the bit order
davidprentice 0:8ee30e15ac7b 865 // is reversed here (left-to-right = LSB to MSB):
davidprentice 0:8ee30e15ac7b 866 if (byte & 0x01)
davidprentice 0:8ee30e15ac7b 867 writePixel(x + i, y, color);
davidprentice 0:8ee30e15ac7b 868 }
davidprentice 0:8ee30e15ac7b 869 }
davidprentice 0:8ee30e15ac7b 870 endWrite();
davidprentice 0:8ee30e15ac7b 871 }
davidprentice 0:8ee30e15ac7b 872
davidprentice 0:8ee30e15ac7b 873 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 874 /*!
davidprentice 0:8ee30e15ac7b 875 @brief Draw a PROGMEM-resident 8-bit image (grayscale) at the specified
davidprentice 0:8ee30e15ac7b 876 (x,y) pos. Specifically for 8-bit display devices such as IS31FL3731; no
davidprentice 0:8ee30e15ac7b 877 color reduction/expansion is performed.
davidprentice 0:8ee30e15ac7b 878 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 879 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 880 @param bitmap byte array with grayscale bitmap
davidprentice 0:8ee30e15ac7b 881 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 882 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 883 */
davidprentice 0:8ee30e15ac7b 884 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 885 void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y,
davidprentice 0:8ee30e15ac7b 886 const uint8_t bitmap[], int16_t w,
davidprentice 0:8ee30e15ac7b 887 int16_t h) {
davidprentice 0:8ee30e15ac7b 888 startWrite();
davidprentice 0:8ee30e15ac7b 889 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 890 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 891 writePixel(x + i, y, (uint8_t)pgm_read_byte(&bitmap[j * w + i]));
davidprentice 0:8ee30e15ac7b 892 }
davidprentice 0:8ee30e15ac7b 893 }
davidprentice 0:8ee30e15ac7b 894 endWrite();
davidprentice 0:8ee30e15ac7b 895 }
davidprentice 0:8ee30e15ac7b 896
davidprentice 0:8ee30e15ac7b 897 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 898 /*!
davidprentice 0:8ee30e15ac7b 899 @brief Draw a RAM-resident 8-bit image (grayscale) at the specified (x,y)
davidprentice 0:8ee30e15ac7b 900 pos. Specifically for 8-bit display devices such as IS31FL3731; no color
davidprentice 0:8ee30e15ac7b 901 reduction/expansion is performed.
davidprentice 0:8ee30e15ac7b 902 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 903 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 904 @param bitmap byte array with grayscale bitmap
davidprentice 0:8ee30e15ac7b 905 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 906 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 907 */
davidprentice 0:8ee30e15ac7b 908 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 909 void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap,
davidprentice 0:8ee30e15ac7b 910 int16_t w, int16_t h) {
davidprentice 0:8ee30e15ac7b 911 startWrite();
davidprentice 0:8ee30e15ac7b 912 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 913 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 914 writePixel(x + i, y, bitmap[j * w + i]);
davidprentice 0:8ee30e15ac7b 915 }
davidprentice 0:8ee30e15ac7b 916 }
davidprentice 0:8ee30e15ac7b 917 endWrite();
davidprentice 0:8ee30e15ac7b 918 }
davidprentice 0:8ee30e15ac7b 919
davidprentice 0:8ee30e15ac7b 920 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 921 /*!
davidprentice 0:8ee30e15ac7b 922 @brief Draw a PROGMEM-resident 8-bit image (grayscale) with a 1-bit mask
davidprentice 0:8ee30e15ac7b 923 (set bits = opaque, unset bits = clear) at the specified (x,y) position.
davidprentice 0:8ee30e15ac7b 924 BOTH buffers (grayscale and mask) must be PROGMEM-resident.
davidprentice 0:8ee30e15ac7b 925 Specifically for 8-bit display devices such as IS31FL3731; no color
davidprentice 0:8ee30e15ac7b 926 reduction/expansion is performed.
davidprentice 0:8ee30e15ac7b 927 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 928 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 929 @param bitmap byte array with grayscale bitmap
davidprentice 0:8ee30e15ac7b 930 @param mask byte array with mask bitmap
davidprentice 0:8ee30e15ac7b 931 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 932 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 933 */
davidprentice 0:8ee30e15ac7b 934 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 935 void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y,
davidprentice 0:8ee30e15ac7b 936 const uint8_t bitmap[],
davidprentice 0:8ee30e15ac7b 937 const uint8_t mask[], int16_t w,
davidprentice 0:8ee30e15ac7b 938 int16_t h) {
davidprentice 0:8ee30e15ac7b 939 int16_t bw = (w + 7) / 8; // Bitmask scanline pad = whole byte
davidprentice 0:8ee30e15ac7b 940 uint8_t byte = 0;
davidprentice 0:8ee30e15ac7b 941 startWrite();
davidprentice 0:8ee30e15ac7b 942 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 943 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 944 if (i & 7)
davidprentice 0:8ee30e15ac7b 945 byte <<= 1;
davidprentice 0:8ee30e15ac7b 946 else
davidprentice 0:8ee30e15ac7b 947 byte = pgm_read_byte(&mask[j * bw + i / 8]);
davidprentice 0:8ee30e15ac7b 948 if (byte & 0x80) {
davidprentice 0:8ee30e15ac7b 949 writePixel(x + i, y, (uint8_t)pgm_read_byte(&bitmap[j * w + i]));
davidprentice 0:8ee30e15ac7b 950 }
davidprentice 0:8ee30e15ac7b 951 }
davidprentice 0:8ee30e15ac7b 952 }
davidprentice 0:8ee30e15ac7b 953 endWrite();
davidprentice 0:8ee30e15ac7b 954 }
davidprentice 0:8ee30e15ac7b 955
davidprentice 0:8ee30e15ac7b 956 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 957 /*!
davidprentice 0:8ee30e15ac7b 958 @brief Draw a RAM-resident 8-bit image (grayscale) with a 1-bit mask
davidprentice 0:8ee30e15ac7b 959 (set bits = opaque, unset bits = clear) at the specified (x,y) position.
davidprentice 0:8ee30e15ac7b 960 BOTH buffers (grayscale and mask) must be RAM-residentt, no mix-and-match
davidprentice 0:8ee30e15ac7b 961 Specifically for 8-bit display devices such as IS31FL3731; no color
davidprentice 0:8ee30e15ac7b 962 reduction/expansion is performed.
davidprentice 0:8ee30e15ac7b 963 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 964 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 965 @param bitmap byte array with grayscale bitmap
davidprentice 0:8ee30e15ac7b 966 @param mask byte array with mask bitmap
davidprentice 0:8ee30e15ac7b 967 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 968 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 969 */
davidprentice 0:8ee30e15ac7b 970 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 971 void Adafruit_GFX::drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap,
davidprentice 0:8ee30e15ac7b 972 uint8_t *mask, int16_t w, int16_t h) {
davidprentice 0:8ee30e15ac7b 973 int16_t bw = (w + 7) / 8; // Bitmask scanline pad = whole byte
davidprentice 0:8ee30e15ac7b 974 uint8_t byte = 0;
davidprentice 0:8ee30e15ac7b 975 startWrite();
davidprentice 0:8ee30e15ac7b 976 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 977 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 978 if (i & 7)
davidprentice 0:8ee30e15ac7b 979 byte <<= 1;
davidprentice 0:8ee30e15ac7b 980 else
davidprentice 0:8ee30e15ac7b 981 byte = mask[j * bw + i / 8];
davidprentice 0:8ee30e15ac7b 982 if (byte & 0x80) {
davidprentice 0:8ee30e15ac7b 983 writePixel(x + i, y, bitmap[j * w + i]);
davidprentice 0:8ee30e15ac7b 984 }
davidprentice 0:8ee30e15ac7b 985 }
davidprentice 0:8ee30e15ac7b 986 }
davidprentice 0:8ee30e15ac7b 987 endWrite();
davidprentice 0:8ee30e15ac7b 988 }
davidprentice 0:8ee30e15ac7b 989
davidprentice 0:8ee30e15ac7b 990 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 991 /*!
davidprentice 0:8ee30e15ac7b 992 @brief Draw a PROGMEM-resident 16-bit image (RGB 5/6/5) at the specified
davidprentice 0:8ee30e15ac7b 993 (x,y) position. For 16-bit display devices; no color reduction performed.
davidprentice 0:8ee30e15ac7b 994 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 995 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 996 @param bitmap byte array with 16-bit color bitmap
davidprentice 0:8ee30e15ac7b 997 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 998 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 999 */
davidprentice 0:8ee30e15ac7b 1000 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1001 void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[],
davidprentice 0:8ee30e15ac7b 1002 int16_t w, int16_t h) {
davidprentice 0:8ee30e15ac7b 1003 startWrite();
davidprentice 0:8ee30e15ac7b 1004 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 1005 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 1006 writePixel(x + i, y, pgm_read_word(&bitmap[j * w + i]));
davidprentice 0:8ee30e15ac7b 1007 }
davidprentice 0:8ee30e15ac7b 1008 }
davidprentice 0:8ee30e15ac7b 1009 endWrite();
davidprentice 0:8ee30e15ac7b 1010 }
davidprentice 0:8ee30e15ac7b 1011
davidprentice 0:8ee30e15ac7b 1012 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1013 /*!
davidprentice 0:8ee30e15ac7b 1014 @brief Draw a RAM-resident 16-bit image (RGB 5/6/5) at the specified (x,y)
davidprentice 0:8ee30e15ac7b 1015 position. For 16-bit display devices; no color reduction performed.
davidprentice 0:8ee30e15ac7b 1016 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 1017 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 1018 @param bitmap byte array with 16-bit color bitmap
davidprentice 0:8ee30e15ac7b 1019 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 1020 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 1021 */
davidprentice 0:8ee30e15ac7b 1022 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1023 void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap,
davidprentice 0:8ee30e15ac7b 1024 int16_t w, int16_t h) {
davidprentice 0:8ee30e15ac7b 1025 startWrite();
davidprentice 0:8ee30e15ac7b 1026 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 1027 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 1028 writePixel(x + i, y, bitmap[j * w + i]);
davidprentice 0:8ee30e15ac7b 1029 }
davidprentice 0:8ee30e15ac7b 1030 }
davidprentice 0:8ee30e15ac7b 1031 endWrite();
davidprentice 0:8ee30e15ac7b 1032 }
davidprentice 0:8ee30e15ac7b 1033
davidprentice 0:8ee30e15ac7b 1034 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1035 /*!
davidprentice 0:8ee30e15ac7b 1036 @brief Draw a PROGMEM-resident 16-bit image (RGB 5/6/5) with a 1-bit mask
davidprentice 0:8ee30e15ac7b 1037 (set bits = opaque, unset bits = clear) at the specified (x,y) position. BOTH
davidprentice 0:8ee30e15ac7b 1038 buffers (color and mask) must be PROGMEM-resident. For 16-bit display
davidprentice 0:8ee30e15ac7b 1039 devices; no color reduction performed.
davidprentice 0:8ee30e15ac7b 1040 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 1041 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 1042 @param bitmap byte array with 16-bit color bitmap
davidprentice 0:8ee30e15ac7b 1043 @param mask byte array with monochrome mask bitmap
davidprentice 0:8ee30e15ac7b 1044 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 1045 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 1046 */
davidprentice 0:8ee30e15ac7b 1047 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1048 void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[],
davidprentice 0:8ee30e15ac7b 1049 const uint8_t mask[], int16_t w, int16_t h) {
davidprentice 0:8ee30e15ac7b 1050 int16_t bw = (w + 7) / 8; // Bitmask scanline pad = whole byte
davidprentice 0:8ee30e15ac7b 1051 uint8_t byte = 0;
davidprentice 0:8ee30e15ac7b 1052 startWrite();
davidprentice 0:8ee30e15ac7b 1053 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 1054 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 1055 if (i & 7)
davidprentice 0:8ee30e15ac7b 1056 byte <<= 1;
davidprentice 0:8ee30e15ac7b 1057 else
davidprentice 0:8ee30e15ac7b 1058 byte = pgm_read_byte(&mask[j * bw + i / 8]);
davidprentice 0:8ee30e15ac7b 1059 if (byte & 0x80) {
davidprentice 0:8ee30e15ac7b 1060 writePixel(x + i, y, pgm_read_word(&bitmap[j * w + i]));
davidprentice 0:8ee30e15ac7b 1061 }
davidprentice 0:8ee30e15ac7b 1062 }
davidprentice 0:8ee30e15ac7b 1063 }
davidprentice 0:8ee30e15ac7b 1064 endWrite();
davidprentice 0:8ee30e15ac7b 1065 }
davidprentice 0:8ee30e15ac7b 1066
davidprentice 0:8ee30e15ac7b 1067 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1068 /*!
davidprentice 0:8ee30e15ac7b 1069 @brief Draw a RAM-resident 16-bit image (RGB 5/6/5) with a 1-bit mask (set
davidprentice 0:8ee30e15ac7b 1070 bits = opaque, unset bits = clear) at the specified (x,y) position. BOTH
davidprentice 0:8ee30e15ac7b 1071 buffers (color and mask) must be RAM-resident. For 16-bit display devices; no
davidprentice 0:8ee30e15ac7b 1072 color reduction performed.
davidprentice 0:8ee30e15ac7b 1073 @param x Top left corner x coordinate
davidprentice 0:8ee30e15ac7b 1074 @param y Top left corner y coordinate
davidprentice 0:8ee30e15ac7b 1075 @param bitmap byte array with 16-bit color bitmap
davidprentice 0:8ee30e15ac7b 1076 @param mask byte array with monochrome mask bitmap
davidprentice 0:8ee30e15ac7b 1077 @param w Width of bitmap in pixels
davidprentice 0:8ee30e15ac7b 1078 @param h Height of bitmap in pixels
davidprentice 0:8ee30e15ac7b 1079 */
davidprentice 0:8ee30e15ac7b 1080 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1081 void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap,
davidprentice 0:8ee30e15ac7b 1082 uint8_t *mask, int16_t w, int16_t h) {
davidprentice 0:8ee30e15ac7b 1083 int16_t bw = (w + 7) / 8; // Bitmask scanline pad = whole byte
davidprentice 0:8ee30e15ac7b 1084 uint8_t byte = 0;
davidprentice 0:8ee30e15ac7b 1085 startWrite();
davidprentice 0:8ee30e15ac7b 1086 for (int16_t j = 0; j < h; j++, y++) {
davidprentice 0:8ee30e15ac7b 1087 for (int16_t i = 0; i < w; i++) {
davidprentice 0:8ee30e15ac7b 1088 if (i & 7)
davidprentice 0:8ee30e15ac7b 1089 byte <<= 1;
davidprentice 0:8ee30e15ac7b 1090 else
davidprentice 0:8ee30e15ac7b 1091 byte = mask[j * bw + i / 8];
davidprentice 0:8ee30e15ac7b 1092 if (byte & 0x80) {
davidprentice 0:8ee30e15ac7b 1093 writePixel(x + i, y, bitmap[j * w + i]);
davidprentice 0:8ee30e15ac7b 1094 }
davidprentice 0:8ee30e15ac7b 1095 }
davidprentice 0:8ee30e15ac7b 1096 }
davidprentice 0:8ee30e15ac7b 1097 endWrite();
davidprentice 0:8ee30e15ac7b 1098 }
davidprentice 0:8ee30e15ac7b 1099
davidprentice 0:8ee30e15ac7b 1100 // TEXT- AND CHARACTER-HANDLING FUNCTIONS ----------------------------------
davidprentice 0:8ee30e15ac7b 1101
davidprentice 0:8ee30e15ac7b 1102 // Draw a character
davidprentice 0:8ee30e15ac7b 1103 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1104 /*!
davidprentice 0:8ee30e15ac7b 1105 @brief Draw a single character
davidprentice 0:8ee30e15ac7b 1106 @param x Bottom left corner x coordinate
davidprentice 0:8ee30e15ac7b 1107 @param y Bottom left corner y coordinate
davidprentice 0:8ee30e15ac7b 1108 @param c The 8-bit font-indexed character (likely ascii)
davidprentice 0:8ee30e15ac7b 1109 @param color 16-bit 5-6-5 Color to draw chraracter with
davidprentice 0:8ee30e15ac7b 1110 @param bg 16-bit 5-6-5 Color to fill background with (if same as color,
davidprentice 0:8ee30e15ac7b 1111 no background)
davidprentice 0:8ee30e15ac7b 1112 @param size Font magnification level, 1 is 'original' size
davidprentice 0:8ee30e15ac7b 1113 */
davidprentice 0:8ee30e15ac7b 1114 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1115 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
davidprentice 0:8ee30e15ac7b 1116 uint16_t color, uint16_t bg, uint8_t size) {
davidprentice 0:8ee30e15ac7b 1117 drawChar(x, y, c, color, bg, size, size);
davidprentice 0:8ee30e15ac7b 1118 }
davidprentice 0:8ee30e15ac7b 1119
davidprentice 0:8ee30e15ac7b 1120 // Draw a character
davidprentice 0:8ee30e15ac7b 1121 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1122 /*!
davidprentice 0:8ee30e15ac7b 1123 @brief Draw a single character
davidprentice 0:8ee30e15ac7b 1124 @param x Bottom left corner x coordinate
davidprentice 0:8ee30e15ac7b 1125 @param y Bottom left corner y coordinate
davidprentice 0:8ee30e15ac7b 1126 @param c The 8-bit font-indexed character (likely ascii)
davidprentice 0:8ee30e15ac7b 1127 @param color 16-bit 5-6-5 Color to draw chraracter with
davidprentice 0:8ee30e15ac7b 1128 @param bg 16-bit 5-6-5 Color to fill background with (if same as color,
davidprentice 0:8ee30e15ac7b 1129 no background)
davidprentice 0:8ee30e15ac7b 1130 @param size_x Font magnification level in X-axis, 1 is 'original' size
davidprentice 0:8ee30e15ac7b 1131 @param size_y Font magnification level in Y-axis, 1 is 'original' size
davidprentice 0:8ee30e15ac7b 1132 */
davidprentice 0:8ee30e15ac7b 1133 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1134 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
davidprentice 0:8ee30e15ac7b 1135 uint16_t color, uint16_t bg, uint8_t size_x,
davidprentice 0:8ee30e15ac7b 1136 uint8_t size_y) {
davidprentice 0:8ee30e15ac7b 1137
davidprentice 0:8ee30e15ac7b 1138 if (!gfxFont) { // 'Classic' built-in font
davidprentice 0:8ee30e15ac7b 1139
davidprentice 0:8ee30e15ac7b 1140 if ((x >= _width) || // Clip right
davidprentice 0:8ee30e15ac7b 1141 (y >= _height) || // Clip bottom
davidprentice 0:8ee30e15ac7b 1142 ((x + 6 * size_x - 1) < 0) || // Clip left
davidprentice 0:8ee30e15ac7b 1143 ((y + 8 * size_y - 1) < 0)) // Clip top
davidprentice 0:8ee30e15ac7b 1144 return;
davidprentice 0:8ee30e15ac7b 1145
davidprentice 0:8ee30e15ac7b 1146 if (!_cp437 && (c >= 176))
davidprentice 0:8ee30e15ac7b 1147 c++; // Handle 'classic' charset behavior
davidprentice 0:8ee30e15ac7b 1148
davidprentice 0:8ee30e15ac7b 1149 startWrite();
davidprentice 0:8ee30e15ac7b 1150 for (int8_t i = 0; i < 5; i++) { // Char bitmap = 5 columns
davidprentice 0:8ee30e15ac7b 1151 uint8_t line = pgm_read_byte(&font[c * 5 + i]);
davidprentice 0:8ee30e15ac7b 1152 for (int8_t j = 0; j < 8; j++, line >>= 1) {
davidprentice 0:8ee30e15ac7b 1153 if (line & 1) {
davidprentice 0:8ee30e15ac7b 1154 if (size_x == 1 && size_y == 1)
davidprentice 0:8ee30e15ac7b 1155 writePixel(x + i, y + j, color);
davidprentice 0:8ee30e15ac7b 1156 else
davidprentice 0:8ee30e15ac7b 1157 writeFillRect(x + i * size_x, y + j * size_y, size_x, size_y,
davidprentice 0:8ee30e15ac7b 1158 color);
davidprentice 0:8ee30e15ac7b 1159 } else if (bg != color) {
davidprentice 0:8ee30e15ac7b 1160 if (size_x == 1 && size_y == 1)
davidprentice 0:8ee30e15ac7b 1161 writePixel(x + i, y + j, bg);
davidprentice 0:8ee30e15ac7b 1162 else
davidprentice 0:8ee30e15ac7b 1163 writeFillRect(x + i * size_x, y + j * size_y, size_x, size_y, bg);
davidprentice 0:8ee30e15ac7b 1164 }
davidprentice 0:8ee30e15ac7b 1165 }
davidprentice 0:8ee30e15ac7b 1166 }
davidprentice 0:8ee30e15ac7b 1167 if (bg != color) { // If opaque, draw vertical line for last column
davidprentice 0:8ee30e15ac7b 1168 if (size_x == 1 && size_y == 1)
davidprentice 0:8ee30e15ac7b 1169 writeFastVLine(x + 5, y, 8, bg);
davidprentice 0:8ee30e15ac7b 1170 else
davidprentice 0:8ee30e15ac7b 1171 writeFillRect(x + 5 * size_x, y, size_x, 8 * size_y, bg);
davidprentice 0:8ee30e15ac7b 1172 }
davidprentice 0:8ee30e15ac7b 1173 endWrite();
davidprentice 0:8ee30e15ac7b 1174
davidprentice 0:8ee30e15ac7b 1175 } else { // Custom font
davidprentice 0:8ee30e15ac7b 1176
davidprentice 0:8ee30e15ac7b 1177 // Character is assumed previously filtered by write() to eliminate
davidprentice 0:8ee30e15ac7b 1178 // newlines, returns, non-printable characters, etc. Calling
davidprentice 0:8ee30e15ac7b 1179 // drawChar() directly with 'bad' characters of font may cause mayhem!
davidprentice 0:8ee30e15ac7b 1180
davidprentice 0:8ee30e15ac7b 1181 c -= (uint8_t)pgm_read_byte(&gfxFont->first);
davidprentice 0:8ee30e15ac7b 1182 GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c);
davidprentice 0:8ee30e15ac7b 1183 uint8_t *bitmap = pgm_read_bitmap_ptr(gfxFont);
davidprentice 0:8ee30e15ac7b 1184
davidprentice 0:8ee30e15ac7b 1185 uint16_t bo = pgm_read_word(&glyph->bitmapOffset);
davidprentice 0:8ee30e15ac7b 1186 uint8_t w = pgm_read_byte(&glyph->width), h = pgm_read_byte(&glyph->height);
davidprentice 0:8ee30e15ac7b 1187 int8_t xo = pgm_read_byte(&glyph->xOffset),
davidprentice 0:8ee30e15ac7b 1188 yo = pgm_read_byte(&glyph->yOffset);
davidprentice 0:8ee30e15ac7b 1189 uint8_t xx, yy, bits = 0, bit = 0;
davidprentice 0:8ee30e15ac7b 1190 int16_t xo16 = 0, yo16 = 0;
davidprentice 0:8ee30e15ac7b 1191
davidprentice 0:8ee30e15ac7b 1192 if (size_x > 1 || size_y > 1) {
davidprentice 0:8ee30e15ac7b 1193 xo16 = xo;
davidprentice 0:8ee30e15ac7b 1194 yo16 = yo;
davidprentice 0:8ee30e15ac7b 1195 }
davidprentice 0:8ee30e15ac7b 1196
davidprentice 0:8ee30e15ac7b 1197 // Todo: Add character clipping here
davidprentice 0:8ee30e15ac7b 1198
davidprentice 0:8ee30e15ac7b 1199 // NOTE: THERE IS NO 'BACKGROUND' COLOR OPTION ON CUSTOM FONTS.
davidprentice 0:8ee30e15ac7b 1200 // THIS IS ON PURPOSE AND BY DESIGN. The background color feature
davidprentice 0:8ee30e15ac7b 1201 // has typically been used with the 'classic' font to overwrite old
davidprentice 0:8ee30e15ac7b 1202 // screen contents with new data. This ONLY works because the
davidprentice 0:8ee30e15ac7b 1203 // characters are a uniform size; it's not a sensible thing to do with
davidprentice 0:8ee30e15ac7b 1204 // proportionally-spaced fonts with glyphs of varying sizes (and that
davidprentice 0:8ee30e15ac7b 1205 // may overlap). To replace previously-drawn text when using a custom
davidprentice 0:8ee30e15ac7b 1206 // font, use the getTextBounds() function to determine the smallest
davidprentice 0:8ee30e15ac7b 1207 // rectangle encompassing a string, erase the area with fillRect(),
davidprentice 0:8ee30e15ac7b 1208 // then draw new text. This WILL infortunately 'blink' the text, but
davidprentice 0:8ee30e15ac7b 1209 // is unavoidable. Drawing 'background' pixels will NOT fix this,
davidprentice 0:8ee30e15ac7b 1210 // only creates a new set of problems. Have an idea to work around
davidprentice 0:8ee30e15ac7b 1211 // this (a canvas object type for MCUs that can afford the RAM and
davidprentice 0:8ee30e15ac7b 1212 // displays supporting setAddrWindow() and pushColors()), but haven't
davidprentice 0:8ee30e15ac7b 1213 // implemented this yet.
davidprentice 0:8ee30e15ac7b 1214
davidprentice 0:8ee30e15ac7b 1215 startWrite();
davidprentice 0:8ee30e15ac7b 1216 for (yy = 0; yy < h; yy++) {
davidprentice 0:8ee30e15ac7b 1217 for (xx = 0; xx < w; xx++) {
davidprentice 0:8ee30e15ac7b 1218 if (!(bit++ & 7)) {
davidprentice 0:8ee30e15ac7b 1219 bits = pgm_read_byte(&bitmap[bo++]);
davidprentice 0:8ee30e15ac7b 1220 }
davidprentice 0:8ee30e15ac7b 1221 if (bits & 0x80) {
davidprentice 0:8ee30e15ac7b 1222 if (size_x == 1 && size_y == 1) {
davidprentice 0:8ee30e15ac7b 1223 writePixel(x + xo + xx, y + yo + yy, color);
davidprentice 0:8ee30e15ac7b 1224 } else {
davidprentice 0:8ee30e15ac7b 1225 writeFillRect(x + (xo16 + xx) * size_x, y + (yo16 + yy) * size_y,
davidprentice 0:8ee30e15ac7b 1226 size_x, size_y, color);
davidprentice 0:8ee30e15ac7b 1227 }
davidprentice 0:8ee30e15ac7b 1228 }
davidprentice 0:8ee30e15ac7b 1229 bits <<= 1;
davidprentice 0:8ee30e15ac7b 1230 }
davidprentice 0:8ee30e15ac7b 1231 }
davidprentice 0:8ee30e15ac7b 1232 endWrite();
davidprentice 0:8ee30e15ac7b 1233
davidprentice 0:8ee30e15ac7b 1234 } // End classic vs custom font
davidprentice 0:8ee30e15ac7b 1235 }
davidprentice 0:8ee30e15ac7b 1236 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1237 /*!
davidprentice 0:8ee30e15ac7b 1238 @brief Print one byte/character of data, used to support print()
davidprentice 0:8ee30e15ac7b 1239 @param c The 8-bit ascii character to write
davidprentice 0:8ee30e15ac7b 1240 */
davidprentice 0:8ee30e15ac7b 1241 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1242 size_t Adafruit_GFX::write(uint8_t c) {
davidprentice 0:8ee30e15ac7b 1243 if (!gfxFont) { // 'Classic' built-in font
davidprentice 0:8ee30e15ac7b 1244
davidprentice 0:8ee30e15ac7b 1245 if (c == '\n') { // Newline?
davidprentice 0:8ee30e15ac7b 1246 cursor_x = 0; // Reset x to zero,
davidprentice 0:8ee30e15ac7b 1247 cursor_y += textsize_y * 8; // advance y one line
davidprentice 0:8ee30e15ac7b 1248 } else if (c != '\r') { // Ignore carriage returns
davidprentice 0:8ee30e15ac7b 1249 if (wrap && ((cursor_x + textsize_x * 6) > _width)) { // Off right?
davidprentice 0:8ee30e15ac7b 1250 cursor_x = 0; // Reset x to zero,
davidprentice 0:8ee30e15ac7b 1251 cursor_y += textsize_y * 8; // advance y one line
davidprentice 0:8ee30e15ac7b 1252 }
davidprentice 0:8ee30e15ac7b 1253 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize_x,
davidprentice 0:8ee30e15ac7b 1254 textsize_y);
davidprentice 0:8ee30e15ac7b 1255 cursor_x += textsize_x * 6; // Advance x one char
davidprentice 0:8ee30e15ac7b 1256 }
davidprentice 0:8ee30e15ac7b 1257
davidprentice 0:8ee30e15ac7b 1258 } else { // Custom font
davidprentice 0:8ee30e15ac7b 1259
davidprentice 0:8ee30e15ac7b 1260 if (c == '\n') {
davidprentice 0:8ee30e15ac7b 1261 cursor_x = 0;
davidprentice 0:8ee30e15ac7b 1262 cursor_y +=
davidprentice 0:8ee30e15ac7b 1263 (int16_t)textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
davidprentice 0:8ee30e15ac7b 1264 } else if (c != '\r') {
davidprentice 0:8ee30e15ac7b 1265 uint8_t first = pgm_read_byte(&gfxFont->first);
davidprentice 0:8ee30e15ac7b 1266 if ((c >= first) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last))) {
davidprentice 0:8ee30e15ac7b 1267 GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c - first);
davidprentice 0:8ee30e15ac7b 1268 uint8_t w = pgm_read_byte(&glyph->width),
davidprentice 0:8ee30e15ac7b 1269 h = pgm_read_byte(&glyph->height);
davidprentice 0:8ee30e15ac7b 1270 if ((w > 0) && (h > 0)) { // Is there an associated bitmap?
davidprentice 0:8ee30e15ac7b 1271 int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic
davidprentice 0:8ee30e15ac7b 1272 if (wrap && ((cursor_x + textsize_x * (xo + w)) > _width)) {
davidprentice 0:8ee30e15ac7b 1273 cursor_x = 0;
davidprentice 0:8ee30e15ac7b 1274 cursor_y += (int16_t)textsize_y *
davidprentice 0:8ee30e15ac7b 1275 (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
davidprentice 0:8ee30e15ac7b 1276 }
davidprentice 0:8ee30e15ac7b 1277 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize_x,
davidprentice 0:8ee30e15ac7b 1278 textsize_y);
davidprentice 0:8ee30e15ac7b 1279 }
davidprentice 0:8ee30e15ac7b 1280 cursor_x +=
davidprentice 0:8ee30e15ac7b 1281 (uint8_t)pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize_x;
davidprentice 0:8ee30e15ac7b 1282 }
davidprentice 0:8ee30e15ac7b 1283 }
davidprentice 0:8ee30e15ac7b 1284 }
davidprentice 0:8ee30e15ac7b 1285 return 1;
davidprentice 0:8ee30e15ac7b 1286 }
davidprentice 0:8ee30e15ac7b 1287
davidprentice 0:8ee30e15ac7b 1288 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1289 /*!
davidprentice 0:8ee30e15ac7b 1290 @brief Set text 'magnification' size. Each increase in s makes 1 pixel
davidprentice 0:8ee30e15ac7b 1291 that much bigger.
davidprentice 0:8ee30e15ac7b 1292 @param s Desired text size. 1 is default 6x8, 2 is 12x16, 3 is 18x24, etc
davidprentice 0:8ee30e15ac7b 1293 */
davidprentice 0:8ee30e15ac7b 1294 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1295 void Adafruit_GFX::setTextSize(uint8_t s) { setTextSize(s, s); }
davidprentice 0:8ee30e15ac7b 1296
davidprentice 0:8ee30e15ac7b 1297 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1298 /*!
davidprentice 0:8ee30e15ac7b 1299 @brief Set text 'magnification' size. Each increase in s makes 1 pixel
davidprentice 0:8ee30e15ac7b 1300 that much bigger.
davidprentice 0:8ee30e15ac7b 1301 @param s_x Desired text width magnification level in X-axis. 1 is default
davidprentice 0:8ee30e15ac7b 1302 @param s_y Desired text width magnification level in Y-axis. 1 is default
davidprentice 0:8ee30e15ac7b 1303 */
davidprentice 0:8ee30e15ac7b 1304 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1305 void Adafruit_GFX::setTextSize(uint8_t s_x, uint8_t s_y) {
davidprentice 0:8ee30e15ac7b 1306 textsize_x = (s_x > 0) ? s_x : 1;
davidprentice 0:8ee30e15ac7b 1307 textsize_y = (s_y > 0) ? s_y : 1;
davidprentice 0:8ee30e15ac7b 1308 }
davidprentice 0:8ee30e15ac7b 1309
davidprentice 0:8ee30e15ac7b 1310 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1311 /*!
davidprentice 0:8ee30e15ac7b 1312 @brief Set rotation setting for display
davidprentice 0:8ee30e15ac7b 1313 @param x 0 thru 3 corresponding to 4 cardinal rotations
davidprentice 0:8ee30e15ac7b 1314 */
davidprentice 0:8ee30e15ac7b 1315 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1316 void Adafruit_GFX::setRotation(uint8_t x) {
davidprentice 0:8ee30e15ac7b 1317 rotation = (x & 3);
davidprentice 0:8ee30e15ac7b 1318 switch (rotation) {
davidprentice 0:8ee30e15ac7b 1319 case 0:
davidprentice 0:8ee30e15ac7b 1320 case 2:
davidprentice 0:8ee30e15ac7b 1321 _width = WIDTH;
davidprentice 0:8ee30e15ac7b 1322 _height = HEIGHT;
davidprentice 0:8ee30e15ac7b 1323 break;
davidprentice 0:8ee30e15ac7b 1324 case 1:
davidprentice 0:8ee30e15ac7b 1325 case 3:
davidprentice 0:8ee30e15ac7b 1326 _width = HEIGHT;
davidprentice 0:8ee30e15ac7b 1327 _height = WIDTH;
davidprentice 0:8ee30e15ac7b 1328 break;
davidprentice 0:8ee30e15ac7b 1329 }
davidprentice 0:8ee30e15ac7b 1330 }
davidprentice 0:8ee30e15ac7b 1331
davidprentice 0:8ee30e15ac7b 1332 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1333 /*!
davidprentice 0:8ee30e15ac7b 1334 @brief Set the font to display when print()ing, either custom or default
davidprentice 0:8ee30e15ac7b 1335 @param f The GFXfont object, if NULL use built in 6x8 font
davidprentice 0:8ee30e15ac7b 1336 */
davidprentice 0:8ee30e15ac7b 1337 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1338 void Adafruit_GFX::setFont(const GFXfont *f) {
davidprentice 0:8ee30e15ac7b 1339 if (f) { // Font struct pointer passed in?
davidprentice 0:8ee30e15ac7b 1340 if (!gfxFont) { // And no current font struct?
davidprentice 0:8ee30e15ac7b 1341 // Switching from classic to new font behavior.
davidprentice 0:8ee30e15ac7b 1342 // Move cursor pos down 6 pixels so it's on baseline.
davidprentice 0:8ee30e15ac7b 1343 cursor_y += 6;
davidprentice 0:8ee30e15ac7b 1344 }
davidprentice 0:8ee30e15ac7b 1345 } else if (gfxFont) { // NULL passed. Current font struct defined?
davidprentice 0:8ee30e15ac7b 1346 // Switching from new to classic font behavior.
davidprentice 0:8ee30e15ac7b 1347 // Move cursor pos up 6 pixels so it's at top-left of char.
davidprentice 0:8ee30e15ac7b 1348 cursor_y -= 6;
davidprentice 0:8ee30e15ac7b 1349 }
davidprentice 0:8ee30e15ac7b 1350 gfxFont = (GFXfont *)f;
davidprentice 0:8ee30e15ac7b 1351 }
davidprentice 0:8ee30e15ac7b 1352
davidprentice 0:8ee30e15ac7b 1353 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1354 /*!
davidprentice 0:8ee30e15ac7b 1355 @brief Helper to determine size of a character with current font/size.
davidprentice 0:8ee30e15ac7b 1356 Broke this out as it's used by both the PROGMEM- and RAM-resident
davidprentice 0:8ee30e15ac7b 1357 getTextBounds() functions.
davidprentice 0:8ee30e15ac7b 1358 @param c The ASCII character in question
davidprentice 0:8ee30e15ac7b 1359 @param x Pointer to x location of character. Value is modified by
davidprentice 0:8ee30e15ac7b 1360 this function to advance to next character.
davidprentice 0:8ee30e15ac7b 1361 @param y Pointer to y location of character. Value is modified by
davidprentice 0:8ee30e15ac7b 1362 this function to advance to next character.
davidprentice 0:8ee30e15ac7b 1363 @param minx Pointer to minimum X coordinate, passed in to AND returned
davidprentice 0:8ee30e15ac7b 1364 by this function -- this is used to incrementally build a
davidprentice 0:8ee30e15ac7b 1365 bounding rectangle for a string.
davidprentice 0:8ee30e15ac7b 1366 @param miny Pointer to minimum Y coord, passed in AND returned.
davidprentice 0:8ee30e15ac7b 1367 @param maxx Pointer to maximum X coord, passed in AND returned.
davidprentice 0:8ee30e15ac7b 1368 @param maxy Pointer to maximum Y coord, passed in AND returned.
davidprentice 0:8ee30e15ac7b 1369 */
davidprentice 0:8ee30e15ac7b 1370 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1371 void Adafruit_GFX::charBounds(unsigned char c, int16_t *x, int16_t *y,
davidprentice 0:8ee30e15ac7b 1372 int16_t *minx, int16_t *miny, int16_t *maxx,
davidprentice 0:8ee30e15ac7b 1373 int16_t *maxy) {
davidprentice 0:8ee30e15ac7b 1374
davidprentice 0:8ee30e15ac7b 1375 if (gfxFont) {
davidprentice 0:8ee30e15ac7b 1376
davidprentice 0:8ee30e15ac7b 1377 if (c == '\n') { // Newline?
davidprentice 0:8ee30e15ac7b 1378 *x = 0; // Reset x to zero, advance y by one line
davidprentice 0:8ee30e15ac7b 1379 *y += textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
davidprentice 0:8ee30e15ac7b 1380 } else if (c != '\r') { // Not a carriage return; is normal char
davidprentice 0:8ee30e15ac7b 1381 uint8_t first = pgm_read_byte(&gfxFont->first),
davidprentice 0:8ee30e15ac7b 1382 last = pgm_read_byte(&gfxFont->last);
davidprentice 0:8ee30e15ac7b 1383 if ((c >= first) && (c <= last)) { // Char present in this font?
davidprentice 0:8ee30e15ac7b 1384 GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c - first);
davidprentice 0:8ee30e15ac7b 1385 uint8_t gw = pgm_read_byte(&glyph->width),
davidprentice 0:8ee30e15ac7b 1386 gh = pgm_read_byte(&glyph->height),
davidprentice 0:8ee30e15ac7b 1387 xa = pgm_read_byte(&glyph->xAdvance);
davidprentice 0:8ee30e15ac7b 1388 int8_t xo = pgm_read_byte(&glyph->xOffset),
davidprentice 0:8ee30e15ac7b 1389 yo = pgm_read_byte(&glyph->yOffset);
davidprentice 0:8ee30e15ac7b 1390 if (wrap && ((*x + (((int16_t)xo + gw) * textsize_x)) > _width)) {
davidprentice 0:8ee30e15ac7b 1391 *x = 0; // Reset x to zero, advance y by one line
davidprentice 0:8ee30e15ac7b 1392 *y += textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
davidprentice 0:8ee30e15ac7b 1393 }
davidprentice 0:8ee30e15ac7b 1394 int16_t tsx = (int16_t)textsize_x, tsy = (int16_t)textsize_y,
davidprentice 0:8ee30e15ac7b 1395 x1 = *x + xo * tsx, y1 = *y + yo * tsy, x2 = x1 + gw * tsx - 1,
davidprentice 0:8ee30e15ac7b 1396 y2 = y1 + gh * tsy - 1;
davidprentice 0:8ee30e15ac7b 1397 if (x1 < *minx)
davidprentice 0:8ee30e15ac7b 1398 *minx = x1;
davidprentice 0:8ee30e15ac7b 1399 if (y1 < *miny)
davidprentice 0:8ee30e15ac7b 1400 *miny = y1;
davidprentice 0:8ee30e15ac7b 1401 if (x2 > *maxx)
davidprentice 0:8ee30e15ac7b 1402 *maxx = x2;
davidprentice 0:8ee30e15ac7b 1403 if (y2 > *maxy)
davidprentice 0:8ee30e15ac7b 1404 *maxy = y2;
davidprentice 0:8ee30e15ac7b 1405 *x += xa * tsx;
davidprentice 0:8ee30e15ac7b 1406 }
davidprentice 0:8ee30e15ac7b 1407 }
davidprentice 0:8ee30e15ac7b 1408
davidprentice 0:8ee30e15ac7b 1409 } else { // Default font
davidprentice 0:8ee30e15ac7b 1410
davidprentice 0:8ee30e15ac7b 1411 if (c == '\n') { // Newline?
davidprentice 0:8ee30e15ac7b 1412 *x = 0; // Reset x to zero,
davidprentice 0:8ee30e15ac7b 1413 *y += textsize_y * 8; // advance y one line
davidprentice 0:8ee30e15ac7b 1414 // min/max x/y unchaged -- that waits for next 'normal' character
davidprentice 0:8ee30e15ac7b 1415 } else if (c != '\r') { // Normal char; ignore carriage returns
davidprentice 0:8ee30e15ac7b 1416 if (wrap && ((*x + textsize_x * 6) > _width)) { // Off right?
davidprentice 0:8ee30e15ac7b 1417 *x = 0; // Reset x to zero,
davidprentice 0:8ee30e15ac7b 1418 *y += textsize_y * 8; // advance y one line
davidprentice 0:8ee30e15ac7b 1419 }
davidprentice 0:8ee30e15ac7b 1420 int x2 = *x + textsize_x * 6 - 1, // Lower-right pixel of char
davidprentice 0:8ee30e15ac7b 1421 y2 = *y + textsize_y * 8 - 1;
davidprentice 0:8ee30e15ac7b 1422 if (x2 > *maxx)
davidprentice 0:8ee30e15ac7b 1423 *maxx = x2; // Track max x, y
davidprentice 0:8ee30e15ac7b 1424 if (y2 > *maxy)
davidprentice 0:8ee30e15ac7b 1425 *maxy = y2;
davidprentice 0:8ee30e15ac7b 1426 if (*x < *minx)
davidprentice 0:8ee30e15ac7b 1427 *minx = *x; // Track min x, y
davidprentice 0:8ee30e15ac7b 1428 if (*y < *miny)
davidprentice 0:8ee30e15ac7b 1429 *miny = *y;
davidprentice 0:8ee30e15ac7b 1430 *x += textsize_x * 6; // Advance x one char
davidprentice 0:8ee30e15ac7b 1431 }
davidprentice 0:8ee30e15ac7b 1432 }
davidprentice 0:8ee30e15ac7b 1433 }
davidprentice 0:8ee30e15ac7b 1434
davidprentice 0:8ee30e15ac7b 1435 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1436 /*!
davidprentice 0:8ee30e15ac7b 1437 @brief Helper to determine size of a string with current font/size.
davidprentice 0:8ee30e15ac7b 1438 Pass string and a cursor position, returns UL corner and W,H.
davidprentice 0:8ee30e15ac7b 1439 @param str The ASCII string to measure
davidprentice 0:8ee30e15ac7b 1440 @param x The current cursor X
davidprentice 0:8ee30e15ac7b 1441 @param y The current cursor Y
davidprentice 0:8ee30e15ac7b 1442 @param x1 The boundary X coordinate, returned by function
davidprentice 0:8ee30e15ac7b 1443 @param y1 The boundary Y coordinate, returned by function
davidprentice 0:8ee30e15ac7b 1444 @param w The boundary width, returned by function
davidprentice 0:8ee30e15ac7b 1445 @param h The boundary height, returned by function
davidprentice 0:8ee30e15ac7b 1446 */
davidprentice 0:8ee30e15ac7b 1447 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1448 void Adafruit_GFX::getTextBounds(const char *str, int16_t x, int16_t y,
davidprentice 0:8ee30e15ac7b 1449 int16_t *x1, int16_t *y1, uint16_t *w,
davidprentice 0:8ee30e15ac7b 1450 uint16_t *h) {
davidprentice 0:8ee30e15ac7b 1451
davidprentice 0:8ee30e15ac7b 1452 uint8_t c; // Current character
davidprentice 0:8ee30e15ac7b 1453 int16_t minx = 0x7FFF, miny = 0x7FFF, maxx = -1, maxy = -1; // Bound rect
davidprentice 0:8ee30e15ac7b 1454 // Bound rect is intentionally initialized inverted, so 1st char sets it
davidprentice 0:8ee30e15ac7b 1455
davidprentice 0:8ee30e15ac7b 1456 *x1 = x; // Initial position is value passed in
davidprentice 0:8ee30e15ac7b 1457 *y1 = y;
davidprentice 0:8ee30e15ac7b 1458 *w = *h = 0; // Initial size is zero
davidprentice 0:8ee30e15ac7b 1459
davidprentice 0:8ee30e15ac7b 1460 while ((c = *str++)) {
davidprentice 0:8ee30e15ac7b 1461 // charBounds() modifies x/y to advance for each character,
davidprentice 0:8ee30e15ac7b 1462 // and min/max x/y are updated to incrementally build bounding rect.
davidprentice 0:8ee30e15ac7b 1463 charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy);
davidprentice 0:8ee30e15ac7b 1464 }
davidprentice 0:8ee30e15ac7b 1465
davidprentice 0:8ee30e15ac7b 1466 if (maxx >= minx) { // If legit string bounds were found...
davidprentice 0:8ee30e15ac7b 1467 *x1 = minx; // Update x1 to least X coord,
davidprentice 0:8ee30e15ac7b 1468 *w = maxx - minx + 1; // And w to bound rect width
davidprentice 0:8ee30e15ac7b 1469 }
davidprentice 0:8ee30e15ac7b 1470 if (maxy >= miny) { // Same for height
davidprentice 0:8ee30e15ac7b 1471 *y1 = miny;
davidprentice 0:8ee30e15ac7b 1472 *h = maxy - miny + 1;
davidprentice 0:8ee30e15ac7b 1473 }
davidprentice 0:8ee30e15ac7b 1474 }
davidprentice 0:8ee30e15ac7b 1475
davidprentice 0:8ee30e15ac7b 1476 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1477 /*!
davidprentice 0:8ee30e15ac7b 1478 @brief Helper to determine size of a string with current font/size. Pass
davidprentice 0:8ee30e15ac7b 1479 string and a cursor position, returns UL corner and W,H.
davidprentice 0:8ee30e15ac7b 1480 @param str The ascii string to measure (as an arduino String() class)
davidprentice 0:8ee30e15ac7b 1481 @param x The current cursor X
davidprentice 0:8ee30e15ac7b 1482 @param y The current cursor Y
davidprentice 0:8ee30e15ac7b 1483 @param x1 The boundary X coordinate, set by function
davidprentice 0:8ee30e15ac7b 1484 @param y1 The boundary Y coordinate, set by function
davidprentice 0:8ee30e15ac7b 1485 @param w The boundary width, set by function
davidprentice 0:8ee30e15ac7b 1486 @param h The boundary height, set by function
davidprentice 0:8ee30e15ac7b 1487 */
davidprentice 0:8ee30e15ac7b 1488 #if defined(USE_STRING)
davidprentice 0:8ee30e15ac7b 1489 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1490 void Adafruit_GFX::getTextBounds(const String &str, int16_t x, int16_t y,
davidprentice 0:8ee30e15ac7b 1491 int16_t *x1, int16_t *y1, uint16_t *w,
davidprentice 0:8ee30e15ac7b 1492 uint16_t *h) {
davidprentice 0:8ee30e15ac7b 1493 if (str.length() != 0) {
davidprentice 0:8ee30e15ac7b 1494 getTextBounds(const_cast<char *>(str.c_str()), x, y, x1, y1, w, h);
davidprentice 0:8ee30e15ac7b 1495 }
davidprentice 0:8ee30e15ac7b 1496 }
davidprentice 0:8ee30e15ac7b 1497
davidprentice 0:8ee30e15ac7b 1498 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1499 /*!
davidprentice 0:8ee30e15ac7b 1500 @brief Helper to determine size of a PROGMEM string with current
davidprentice 0:8ee30e15ac7b 1501 font/size. Pass string and a cursor position, returns UL corner and W,H.
davidprentice 0:8ee30e15ac7b 1502 @param str The flash-memory ascii string to measure
davidprentice 0:8ee30e15ac7b 1503 @param x The current cursor X
davidprentice 0:8ee30e15ac7b 1504 @param y The current cursor Y
davidprentice 0:8ee30e15ac7b 1505 @param x1 The boundary X coordinate, set by function
davidprentice 0:8ee30e15ac7b 1506 @param y1 The boundary Y coordinate, set by function
davidprentice 0:8ee30e15ac7b 1507 @param w The boundary width, set by function
davidprentice 0:8ee30e15ac7b 1508 @param h The boundary height, set by function
davidprentice 0:8ee30e15ac7b 1509 */
davidprentice 0:8ee30e15ac7b 1510 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1511 void Adafruit_GFX::getTextBounds(const __FlashStringHelper *str, int16_t x,
davidprentice 0:8ee30e15ac7b 1512 int16_t y, int16_t *x1, int16_t *y1,
davidprentice 0:8ee30e15ac7b 1513 uint16_t *w, uint16_t *h) {
davidprentice 0:8ee30e15ac7b 1514 uint8_t *s = (uint8_t *)str, c;
davidprentice 0:8ee30e15ac7b 1515
davidprentice 0:8ee30e15ac7b 1516 *x1 = x;
davidprentice 0:8ee30e15ac7b 1517 *y1 = y;
davidprentice 0:8ee30e15ac7b 1518 *w = *h = 0;
davidprentice 0:8ee30e15ac7b 1519
davidprentice 0:8ee30e15ac7b 1520 int16_t minx = _width, miny = _height, maxx = -1, maxy = -1;
davidprentice 0:8ee30e15ac7b 1521
davidprentice 0:8ee30e15ac7b 1522 while ((c = pgm_read_byte(s++)))
davidprentice 0:8ee30e15ac7b 1523 charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy);
davidprentice 0:8ee30e15ac7b 1524
davidprentice 0:8ee30e15ac7b 1525 if (maxx >= minx) {
davidprentice 0:8ee30e15ac7b 1526 *x1 = minx;
davidprentice 0:8ee30e15ac7b 1527 *w = maxx - minx + 1;
davidprentice 0:8ee30e15ac7b 1528 }
davidprentice 0:8ee30e15ac7b 1529 if (maxy >= miny) {
davidprentice 0:8ee30e15ac7b 1530 *y1 = miny;
davidprentice 0:8ee30e15ac7b 1531 *h = maxy - miny + 1;
davidprentice 0:8ee30e15ac7b 1532 }
davidprentice 0:8ee30e15ac7b 1533 }
davidprentice 0:8ee30e15ac7b 1534 #endif
davidprentice 0:8ee30e15ac7b 1535
davidprentice 0:8ee30e15ac7b 1536 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1537 /*!
davidprentice 0:8ee30e15ac7b 1538 @brief Invert the display (ideally using built-in hardware command)
davidprentice 0:8ee30e15ac7b 1539 @param i True if you want to invert, false to make 'normal'
davidprentice 0:8ee30e15ac7b 1540 */
davidprentice 0:8ee30e15ac7b 1541 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1542 void Adafruit_GFX::invertDisplay(bool i) {
davidprentice 0:8ee30e15ac7b 1543 // Do nothing, must be subclassed if supported by hardware
davidprentice 0:8ee30e15ac7b 1544 (void)i; // disable -Wunused-parameter warning
davidprentice 0:8ee30e15ac7b 1545 }
davidprentice 0:8ee30e15ac7b 1546
davidprentice 0:8ee30e15ac7b 1547 /***************************************************************************/
davidprentice 0:8ee30e15ac7b 1548
davidprentice 0:8ee30e15ac7b 1549 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1550 /*!
davidprentice 0:8ee30e15ac7b 1551 @brief Create a simple drawn button UI element
davidprentice 0:8ee30e15ac7b 1552 */
davidprentice 0:8ee30e15ac7b 1553 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1554 Adafruit_GFX_Button::Adafruit_GFX_Button(void) { _gfx = 0; }
davidprentice 0:8ee30e15ac7b 1555
davidprentice 0:8ee30e15ac7b 1556 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1557 /*!
davidprentice 0:8ee30e15ac7b 1558 @brief Initialize button with our desired color/size/settings
davidprentice 0:8ee30e15ac7b 1559 @param gfx Pointer to our display so we can draw to it!
davidprentice 0:8ee30e15ac7b 1560 @param x The X coordinate of the center of the button
davidprentice 0:8ee30e15ac7b 1561 @param y The Y coordinate of the center of the button
davidprentice 0:8ee30e15ac7b 1562 @param w Width of the buttton
davidprentice 0:8ee30e15ac7b 1563 @param h Height of the buttton
davidprentice 0:8ee30e15ac7b 1564 @param outline Color of the outline (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1565 @param fill Color of the button fill (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1566 @param textcolor Color of the button label (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1567 @param label Ascii string of the text inside the button
davidprentice 0:8ee30e15ac7b 1568 @param textsize The font magnification of the label text
davidprentice 0:8ee30e15ac7b 1569 */
davidprentice 0:8ee30e15ac7b 1570 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1571 // Classic initButton() function: pass center & size
davidprentice 0:8ee30e15ac7b 1572 void Adafruit_GFX_Button::initButton(Adafruit_GFX *gfx, int16_t x, int16_t y,
davidprentice 0:8ee30e15ac7b 1573 uint16_t w, uint16_t h, uint16_t outline,
davidprentice 0:8ee30e15ac7b 1574 uint16_t fill, uint16_t textcolor,
davidprentice 0:8ee30e15ac7b 1575 char *label, uint8_t textsize) {
davidprentice 0:8ee30e15ac7b 1576 // Tweak arguments and pass to the newer initButtonUL() function...
davidprentice 0:8ee30e15ac7b 1577 initButtonUL(gfx, x - (w / 2), y - (h / 2), w, h, outline, fill, textcolor,
davidprentice 0:8ee30e15ac7b 1578 label, textsize);
davidprentice 0:8ee30e15ac7b 1579 }
davidprentice 0:8ee30e15ac7b 1580
davidprentice 0:8ee30e15ac7b 1581 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1582 /*!
davidprentice 0:8ee30e15ac7b 1583 @brief Initialize button with our desired color/size/settings
davidprentice 0:8ee30e15ac7b 1584 @param gfx Pointer to our display so we can draw to it!
davidprentice 0:8ee30e15ac7b 1585 @param x The X coordinate of the center of the button
davidprentice 0:8ee30e15ac7b 1586 @param y The Y coordinate of the center of the button
davidprentice 0:8ee30e15ac7b 1587 @param w Width of the buttton
davidprentice 0:8ee30e15ac7b 1588 @param h Height of the buttton
davidprentice 0:8ee30e15ac7b 1589 @param outline Color of the outline (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1590 @param fill Color of the button fill (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1591 @param textcolor Color of the button label (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1592 @param label Ascii string of the text inside the button
davidprentice 0:8ee30e15ac7b 1593 @param textsize_x The font magnification in X-axis of the label text
davidprentice 0:8ee30e15ac7b 1594 @param textsize_y The font magnification in Y-axis of the label text
davidprentice 0:8ee30e15ac7b 1595 */
davidprentice 0:8ee30e15ac7b 1596 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1597 // Classic initButton() function: pass center & size
davidprentice 0:8ee30e15ac7b 1598 void Adafruit_GFX_Button::initButton(Adafruit_GFX *gfx, int16_t x, int16_t y,
davidprentice 0:8ee30e15ac7b 1599 uint16_t w, uint16_t h, uint16_t outline,
davidprentice 0:8ee30e15ac7b 1600 uint16_t fill, uint16_t textcolor,
davidprentice 0:8ee30e15ac7b 1601 char *label, uint8_t textsize_x,
davidprentice 0:8ee30e15ac7b 1602 uint8_t textsize_y) {
davidprentice 0:8ee30e15ac7b 1603 // Tweak arguments and pass to the newer initButtonUL() function...
davidprentice 0:8ee30e15ac7b 1604 initButtonUL(gfx, x - (w / 2), y - (h / 2), w, h, outline, fill, textcolor,
davidprentice 0:8ee30e15ac7b 1605 label, textsize_x, textsize_y);
davidprentice 0:8ee30e15ac7b 1606 }
davidprentice 0:8ee30e15ac7b 1607
davidprentice 0:8ee30e15ac7b 1608 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1609 /*!
davidprentice 0:8ee30e15ac7b 1610 @brief Initialize button with our desired color/size/settings, with
davidprentice 0:8ee30e15ac7b 1611 upper-left coordinates
davidprentice 0:8ee30e15ac7b 1612 @param gfx Pointer to our display so we can draw to it!
davidprentice 0:8ee30e15ac7b 1613 @param x1 The X coordinate of the Upper-Left corner of the button
davidprentice 0:8ee30e15ac7b 1614 @param y1 The Y coordinate of the Upper-Left corner of the button
davidprentice 0:8ee30e15ac7b 1615 @param w Width of the buttton
davidprentice 0:8ee30e15ac7b 1616 @param h Height of the buttton
davidprentice 0:8ee30e15ac7b 1617 @param outline Color of the outline (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1618 @param fill Color of the button fill (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1619 @param textcolor Color of the button label (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1620 @param label Ascii string of the text inside the button
davidprentice 0:8ee30e15ac7b 1621 @param textsize The font magnification of the label text
davidprentice 0:8ee30e15ac7b 1622 */
davidprentice 0:8ee30e15ac7b 1623 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1624 void Adafruit_GFX_Button::initButtonUL(Adafruit_GFX *gfx, int16_t x1,
davidprentice 0:8ee30e15ac7b 1625 int16_t y1, uint16_t w, uint16_t h,
davidprentice 0:8ee30e15ac7b 1626 uint16_t outline, uint16_t fill,
davidprentice 0:8ee30e15ac7b 1627 uint16_t textcolor, char *label,
davidprentice 0:8ee30e15ac7b 1628 uint8_t textsize) {
davidprentice 0:8ee30e15ac7b 1629 initButtonUL(gfx, x1, y1, w, h, outline, fill, textcolor, label, textsize,
davidprentice 0:8ee30e15ac7b 1630 textsize);
davidprentice 0:8ee30e15ac7b 1631 }
davidprentice 0:8ee30e15ac7b 1632
davidprentice 0:8ee30e15ac7b 1633 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1634 /*!
davidprentice 0:8ee30e15ac7b 1635 @brief Initialize button with our desired color/size/settings, with
davidprentice 0:8ee30e15ac7b 1636 upper-left coordinates
davidprentice 0:8ee30e15ac7b 1637 @param gfx Pointer to our display so we can draw to it!
davidprentice 0:8ee30e15ac7b 1638 @param x1 The X coordinate of the Upper-Left corner of the button
davidprentice 0:8ee30e15ac7b 1639 @param y1 The Y coordinate of the Upper-Left corner of the button
davidprentice 0:8ee30e15ac7b 1640 @param w Width of the buttton
davidprentice 0:8ee30e15ac7b 1641 @param h Height of the buttton
davidprentice 0:8ee30e15ac7b 1642 @param outline Color of the outline (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1643 @param fill Color of the button fill (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1644 @param textcolor Color of the button label (16-bit 5-6-5 standard)
davidprentice 0:8ee30e15ac7b 1645 @param label Ascii string of the text inside the button
davidprentice 0:8ee30e15ac7b 1646 @param textsize_x The font magnification in X-axis of the label text
davidprentice 0:8ee30e15ac7b 1647 @param textsize_y The font magnification in Y-axis of the label text
davidprentice 0:8ee30e15ac7b 1648 */
davidprentice 0:8ee30e15ac7b 1649 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1650 void Adafruit_GFX_Button::initButtonUL(Adafruit_GFX *gfx, int16_t x1,
davidprentice 0:8ee30e15ac7b 1651 int16_t y1, uint16_t w, uint16_t h,
davidprentice 0:8ee30e15ac7b 1652 uint16_t outline, uint16_t fill,
davidprentice 0:8ee30e15ac7b 1653 uint16_t textcolor, char *label,
davidprentice 0:8ee30e15ac7b 1654 uint8_t textsize_x, uint8_t textsize_y) {
davidprentice 0:8ee30e15ac7b 1655 _x1 = x1;
davidprentice 0:8ee30e15ac7b 1656 _y1 = y1;
davidprentice 0:8ee30e15ac7b 1657 _w = w;
davidprentice 0:8ee30e15ac7b 1658 _h = h;
davidprentice 0:8ee30e15ac7b 1659 _outlinecolor = outline;
davidprentice 0:8ee30e15ac7b 1660 _fillcolor = fill;
davidprentice 0:8ee30e15ac7b 1661 _textcolor = textcolor;
davidprentice 0:8ee30e15ac7b 1662 _textsize_x = textsize_x;
davidprentice 0:8ee30e15ac7b 1663 _textsize_y = textsize_y;
davidprentice 0:8ee30e15ac7b 1664 _gfx = gfx;
davidprentice 0:8ee30e15ac7b 1665 strncpy(_label, label, 9);
davidprentice 0:8ee30e15ac7b 1666 }
davidprentice 0:8ee30e15ac7b 1667
davidprentice 0:8ee30e15ac7b 1668 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1669 /*!
davidprentice 0:8ee30e15ac7b 1670 @brief Draw the button on the screen
davidprentice 0:8ee30e15ac7b 1671 @param inverted Whether to draw with fill/text swapped to indicate
davidprentice 0:8ee30e15ac7b 1672 'pressed'
davidprentice 0:8ee30e15ac7b 1673 */
davidprentice 0:8ee30e15ac7b 1674 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1675 void Adafruit_GFX_Button::drawButton(bool inverted) {
davidprentice 0:8ee30e15ac7b 1676 uint16_t fill, outline, text;
davidprentice 0:8ee30e15ac7b 1677
davidprentice 0:8ee30e15ac7b 1678 if (!inverted) {
davidprentice 0:8ee30e15ac7b 1679 fill = _fillcolor;
davidprentice 0:8ee30e15ac7b 1680 outline = _outlinecolor;
davidprentice 0:8ee30e15ac7b 1681 text = _textcolor;
davidprentice 0:8ee30e15ac7b 1682 } else {
davidprentice 0:8ee30e15ac7b 1683 fill = _textcolor;
davidprentice 0:8ee30e15ac7b 1684 outline = _outlinecolor;
davidprentice 0:8ee30e15ac7b 1685 text = _fillcolor;
davidprentice 0:8ee30e15ac7b 1686 }
davidprentice 0:8ee30e15ac7b 1687
davidprentice 0:8ee30e15ac7b 1688 uint8_t r = min(_w, _h) / 4; // Corner radius
davidprentice 0:8ee30e15ac7b 1689 _gfx->fillRoundRect(_x1, _y1, _w, _h, r, fill);
davidprentice 0:8ee30e15ac7b 1690 _gfx->drawRoundRect(_x1, _y1, _w, _h, r, outline);
davidprentice 0:8ee30e15ac7b 1691
davidprentice 0:8ee30e15ac7b 1692 _gfx->setCursor(_x1 + (_w / 2) - (strlen(_label) * 3 * _textsize_x),
davidprentice 0:8ee30e15ac7b 1693 _y1 + (_h / 2) - (4 * _textsize_y));
davidprentice 0:8ee30e15ac7b 1694 _gfx->setTextColor(text);
davidprentice 0:8ee30e15ac7b 1695 _gfx->setTextSize(_textsize_x, _textsize_y);
davidprentice 0:8ee30e15ac7b 1696 _gfx->print(_label);
davidprentice 0:8ee30e15ac7b 1697 }
davidprentice 0:8ee30e15ac7b 1698
davidprentice 0:8ee30e15ac7b 1699 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1700 /*!
davidprentice 0:8ee30e15ac7b 1701 @brief Helper to let us know if a coordinate is within the bounds of the
davidprentice 0:8ee30e15ac7b 1702 button
davidprentice 0:8ee30e15ac7b 1703 @param x The X coordinate to check
davidprentice 0:8ee30e15ac7b 1704 @param y The Y coordinate to check
davidprentice 0:8ee30e15ac7b 1705 @returns True if within button graphics outline
davidprentice 0:8ee30e15ac7b 1706 */
davidprentice 0:8ee30e15ac7b 1707 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1708 bool Adafruit_GFX_Button::contains(int16_t x, int16_t y) {
davidprentice 0:8ee30e15ac7b 1709 return ((x >= _x1) && (x < (int16_t)(_x1 + _w)) && (y >= _y1) &&
davidprentice 0:8ee30e15ac7b 1710 (y < (int16_t)(_y1 + _h)));
davidprentice 0:8ee30e15ac7b 1711 }
davidprentice 0:8ee30e15ac7b 1712
davidprentice 0:8ee30e15ac7b 1713 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1714 /*!
davidprentice 0:8ee30e15ac7b 1715 @brief Query whether the button was pressed since we last checked state
davidprentice 0:8ee30e15ac7b 1716 @returns True if was not-pressed before, now is.
davidprentice 0:8ee30e15ac7b 1717 */
davidprentice 0:8ee30e15ac7b 1718 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1719 bool Adafruit_GFX_Button::justPressed() { return (currstate && !laststate); }
davidprentice 0:8ee30e15ac7b 1720
davidprentice 0:8ee30e15ac7b 1721 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1722 /*!
davidprentice 0:8ee30e15ac7b 1723 @brief Query whether the button was released since we last checked state
davidprentice 0:8ee30e15ac7b 1724 @returns True if was pressed before, now is not.
davidprentice 0:8ee30e15ac7b 1725 */
davidprentice 0:8ee30e15ac7b 1726 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1727 bool Adafruit_GFX_Button::justReleased() { return (!currstate && laststate); }
davidprentice 0:8ee30e15ac7b 1728
davidprentice 0:8ee30e15ac7b 1729 // -------------------------------------------------------------------------
davidprentice 0:8ee30e15ac7b 1730
davidprentice 0:8ee30e15ac7b 1731 // GFXcanvas1, GFXcanvas8 and GFXcanvas16 (currently a WIP, don't get too
davidprentice 0:8ee30e15ac7b 1732 // comfy with the implementation) provide 1-, 8- and 16-bit offscreen
davidprentice 0:8ee30e15ac7b 1733 // canvases, the address of which can be passed to drawBitmap() or
davidprentice 0:8ee30e15ac7b 1734 // pushColors() (the latter appears only in a couple of GFX-subclassed TFT
davidprentice 0:8ee30e15ac7b 1735 // libraries at this time). This is here mostly to help with the recently-
davidprentice 0:8ee30e15ac7b 1736 // added proportionally-spaced fonts; adds a way to refresh a section of the
davidprentice 0:8ee30e15ac7b 1737 // screen without a massive flickering clear-and-redraw...but maybe you'll
davidprentice 0:8ee30e15ac7b 1738 // find other uses too. VERY RAM-intensive, since the buffer is in MCU
davidprentice 0:8ee30e15ac7b 1739 // memory and not the display driver...GXFcanvas1 might be minimally useful
davidprentice 0:8ee30e15ac7b 1740 // on an Uno-class board, but this and the others are much more likely to
davidprentice 0:8ee30e15ac7b 1741 // require at least a Mega or various recent ARM-type boards (recommended,
davidprentice 0:8ee30e15ac7b 1742 // as the text+bitmap draw can be pokey). GFXcanvas1 requires 1 bit per
davidprentice 0:8ee30e15ac7b 1743 // pixel (rounded up to nearest byte per scanline), GFXcanvas8 is 1 byte
davidprentice 0:8ee30e15ac7b 1744 // per pixel (no scanline pad), and GFXcanvas16 uses 2 bytes per pixel (no
davidprentice 0:8ee30e15ac7b 1745 // scanline pad).
davidprentice 0:8ee30e15ac7b 1746 // NOT EXTENSIVELY TESTED YET. MAY CONTAIN WORST BUGS KNOWN TO HUMANKIND.
davidprentice 0:8ee30e15ac7b 1747
davidprentice 0:8ee30e15ac7b 1748 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 1749 // Bitmask tables of 0x80>>X and ~(0x80>>X), because X>>Y is slow on AVR
davidprentice 0:8ee30e15ac7b 1750 const uint8_t PROGMEM GFXcanvas1::GFXsetBit[] = {0x80, 0x40, 0x20, 0x10,
davidprentice 0:8ee30e15ac7b 1751 0x08, 0x04, 0x02, 0x01};
davidprentice 0:8ee30e15ac7b 1752 const uint8_t PROGMEM GFXcanvas1::GFXclrBit[] = {0x7F, 0xBF, 0xDF, 0xEF,
davidprentice 0:8ee30e15ac7b 1753 0xF7, 0xFB, 0xFD, 0xFE};
davidprentice 0:8ee30e15ac7b 1754 #endif
davidprentice 0:8ee30e15ac7b 1755
davidprentice 0:8ee30e15ac7b 1756 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1757 /*!
davidprentice 0:8ee30e15ac7b 1758 @brief Instatiate a GFX 1-bit canvas context for graphics
davidprentice 0:8ee30e15ac7b 1759 @param w Display width, in pixels
davidprentice 0:8ee30e15ac7b 1760 @param h Display height, in pixels
davidprentice 0:8ee30e15ac7b 1761 */
davidprentice 0:8ee30e15ac7b 1762 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1763 GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
davidprentice 0:8ee30e15ac7b 1764 uint16_t bytes = ((w + 7) / 8) * h;
davidprentice 0:8ee30e15ac7b 1765 if ((buffer = (uint8_t *)malloc(bytes))) {
davidprentice 0:8ee30e15ac7b 1766 memset(buffer, 0, bytes);
davidprentice 0:8ee30e15ac7b 1767 }
davidprentice 0:8ee30e15ac7b 1768 }
davidprentice 0:8ee30e15ac7b 1769
davidprentice 0:8ee30e15ac7b 1770 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1771 /*!
davidprentice 0:8ee30e15ac7b 1772 @brief Delete the canvas, free memory
davidprentice 0:8ee30e15ac7b 1773 */
davidprentice 0:8ee30e15ac7b 1774 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1775 GFXcanvas1::~GFXcanvas1(void) {
davidprentice 0:8ee30e15ac7b 1776 if (buffer)
davidprentice 0:8ee30e15ac7b 1777 free(buffer);
davidprentice 0:8ee30e15ac7b 1778 }
davidprentice 0:8ee30e15ac7b 1779
davidprentice 0:8ee30e15ac7b 1780 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1781 /*!
davidprentice 0:8ee30e15ac7b 1782 @brief Draw a pixel to the canvas framebuffer
davidprentice 0:8ee30e15ac7b 1783 @param x x coordinate
davidprentice 0:8ee30e15ac7b 1784 @param y y coordinate
davidprentice 0:8ee30e15ac7b 1785 @param color Binary (on or off) color to fill with
davidprentice 0:8ee30e15ac7b 1786 */
davidprentice 0:8ee30e15ac7b 1787 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1788 void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) {
davidprentice 0:8ee30e15ac7b 1789 if (buffer) {
davidprentice 0:8ee30e15ac7b 1790 if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
davidprentice 0:8ee30e15ac7b 1791 return;
davidprentice 0:8ee30e15ac7b 1792
davidprentice 0:8ee30e15ac7b 1793 int16_t t;
davidprentice 0:8ee30e15ac7b 1794 switch (rotation) {
davidprentice 0:8ee30e15ac7b 1795 case 1:
davidprentice 0:8ee30e15ac7b 1796 t = x;
davidprentice 0:8ee30e15ac7b 1797 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 1798 y = t;
davidprentice 0:8ee30e15ac7b 1799 break;
davidprentice 0:8ee30e15ac7b 1800 case 2:
davidprentice 0:8ee30e15ac7b 1801 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 1802 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 1803 break;
davidprentice 0:8ee30e15ac7b 1804 case 3:
davidprentice 0:8ee30e15ac7b 1805 t = x;
davidprentice 0:8ee30e15ac7b 1806 x = y;
davidprentice 0:8ee30e15ac7b 1807 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 1808 break;
davidprentice 0:8ee30e15ac7b 1809 }
davidprentice 0:8ee30e15ac7b 1810
davidprentice 0:8ee30e15ac7b 1811 uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)];
davidprentice 0:8ee30e15ac7b 1812 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 1813 if (color)
davidprentice 0:8ee30e15ac7b 1814 *ptr |= pgm_read_byte(&GFXsetBit[x & 7]);
davidprentice 0:8ee30e15ac7b 1815 else
davidprentice 0:8ee30e15ac7b 1816 *ptr &= pgm_read_byte(&GFXclrBit[x & 7]);
davidprentice 0:8ee30e15ac7b 1817 #else
davidprentice 0:8ee30e15ac7b 1818 if (color)
davidprentice 0:8ee30e15ac7b 1819 *ptr |= 0x80 >> (x & 7);
davidprentice 0:8ee30e15ac7b 1820 else
davidprentice 0:8ee30e15ac7b 1821 *ptr &= ~(0x80 >> (x & 7));
davidprentice 0:8ee30e15ac7b 1822 #endif
davidprentice 0:8ee30e15ac7b 1823 }
davidprentice 0:8ee30e15ac7b 1824 }
davidprentice 0:8ee30e15ac7b 1825
davidprentice 0:8ee30e15ac7b 1826 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 1827 /*!
davidprentice 0:8ee30e15ac7b 1828 @brief Get the pixel color value at a given coordinate
davidprentice 0:8ee30e15ac7b 1829 @param x x coordinate
davidprentice 0:8ee30e15ac7b 1830 @param y y coordinate
davidprentice 0:8ee30e15ac7b 1831 @returns The desired pixel's binary color value, either 0x1 (on) or 0x0
davidprentice 0:8ee30e15ac7b 1832 (off)
davidprentice 0:8ee30e15ac7b 1833 */
davidprentice 0:8ee30e15ac7b 1834 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 1835 bool GFXcanvas1::getPixel(int16_t x, int16_t y) const {
davidprentice 0:8ee30e15ac7b 1836 int16_t t;
davidprentice 0:8ee30e15ac7b 1837 switch (rotation) {
davidprentice 0:8ee30e15ac7b 1838 case 1:
davidprentice 0:8ee30e15ac7b 1839 t = x;
davidprentice 0:8ee30e15ac7b 1840 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 1841 y = t;
davidprentice 0:8ee30e15ac7b 1842 break;
davidprentice 0:8ee30e15ac7b 1843 case 2:
davidprentice 0:8ee30e15ac7b 1844 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 1845 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 1846 break;
davidprentice 0:8ee30e15ac7b 1847 case 3:
davidprentice 0:8ee30e15ac7b 1848 t = x;
davidprentice 0:8ee30e15ac7b 1849 x = y;
davidprentice 0:8ee30e15ac7b 1850 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 1851 break;
davidprentice 0:8ee30e15ac7b 1852 }
davidprentice 0:8ee30e15ac7b 1853 return getRawPixel(x, y);
davidprentice 0:8ee30e15ac7b 1854 }
davidprentice 0:8ee30e15ac7b 1855
davidprentice 0:8ee30e15ac7b 1856 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 1857 /*!
davidprentice 0:8ee30e15ac7b 1858 @brief Get the pixel color value at a given, unrotated coordinate.
davidprentice 0:8ee30e15ac7b 1859 This method is intended for hardware drivers to get pixel value
davidprentice 0:8ee30e15ac7b 1860 in physical coordinates.
davidprentice 0:8ee30e15ac7b 1861 @param x x coordinate
davidprentice 0:8ee30e15ac7b 1862 @param y y coordinate
davidprentice 0:8ee30e15ac7b 1863 @returns The desired pixel's binary color value, either 0x1 (on) or 0x0
davidprentice 0:8ee30e15ac7b 1864 (off)
davidprentice 0:8ee30e15ac7b 1865 */
davidprentice 0:8ee30e15ac7b 1866 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 1867 bool GFXcanvas1::getRawPixel(int16_t x, int16_t y) const {
davidprentice 0:8ee30e15ac7b 1868 if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT))
davidprentice 0:8ee30e15ac7b 1869 return 0;
davidprentice 0:8ee30e15ac7b 1870 if (this->getBuffer()) {
davidprentice 0:8ee30e15ac7b 1871 uint8_t *buffer = this->getBuffer();
davidprentice 0:8ee30e15ac7b 1872 uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)];
davidprentice 0:8ee30e15ac7b 1873
davidprentice 0:8ee30e15ac7b 1874 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 1875 return ((*ptr) & pgm_read_byte(&GFXsetBit[x & 7])) != 0;
davidprentice 0:8ee30e15ac7b 1876 #else
davidprentice 0:8ee30e15ac7b 1877 return ((*ptr) & (0x80 >> (x & 7))) != 0;
davidprentice 0:8ee30e15ac7b 1878 #endif
davidprentice 0:8ee30e15ac7b 1879 }
davidprentice 0:8ee30e15ac7b 1880 return 0;
davidprentice 0:8ee30e15ac7b 1881 }
davidprentice 0:8ee30e15ac7b 1882
davidprentice 0:8ee30e15ac7b 1883 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1884 /*!
davidprentice 0:8ee30e15ac7b 1885 @brief Fill the framebuffer completely with one color
davidprentice 0:8ee30e15ac7b 1886 @param color Binary (on or off) color to fill with
davidprentice 0:8ee30e15ac7b 1887 */
davidprentice 0:8ee30e15ac7b 1888 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1889 void GFXcanvas1::fillScreen(uint16_t color) {
davidprentice 0:8ee30e15ac7b 1890 if (buffer) {
davidprentice 0:8ee30e15ac7b 1891 uint16_t bytes = ((WIDTH + 7) / 8) * HEIGHT;
davidprentice 0:8ee30e15ac7b 1892 memset(buffer, color ? 0xFF : 0x00, bytes);
davidprentice 0:8ee30e15ac7b 1893 }
davidprentice 0:8ee30e15ac7b 1894 }
davidprentice 0:8ee30e15ac7b 1895
davidprentice 0:8ee30e15ac7b 1896 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1897 /*!
davidprentice 0:8ee30e15ac7b 1898 @brief Speed optimized vertical line drawing
davidprentice 0:8ee30e15ac7b 1899 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 1900 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 1901 @param h Length of vertical line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 1902 @param color Color to fill with
davidprentice 0:8ee30e15ac7b 1903 */
davidprentice 0:8ee30e15ac7b 1904 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1905 void GFXcanvas1::drawFastVLine(int16_t x, int16_t y, int16_t h,
davidprentice 0:8ee30e15ac7b 1906 uint16_t color) {
davidprentice 0:8ee30e15ac7b 1907
davidprentice 0:8ee30e15ac7b 1908 if (h < 0) { // Convert negative heights to positive equivalent
davidprentice 0:8ee30e15ac7b 1909 h *= -1;
davidprentice 0:8ee30e15ac7b 1910 y -= h - 1;
davidprentice 0:8ee30e15ac7b 1911 if (y < 0) {
davidprentice 0:8ee30e15ac7b 1912 h += y;
davidprentice 0:8ee30e15ac7b 1913 y = 0;
davidprentice 0:8ee30e15ac7b 1914 }
davidprentice 0:8ee30e15ac7b 1915 }
davidprentice 0:8ee30e15ac7b 1916
davidprentice 0:8ee30e15ac7b 1917 // Edge rejection (no-draw if totally off canvas)
davidprentice 0:8ee30e15ac7b 1918 if ((x < 0) || (x >= width()) || (y >= height()) || ((y + h - 1) < 0)) {
davidprentice 0:8ee30e15ac7b 1919 return;
davidprentice 0:8ee30e15ac7b 1920 }
davidprentice 0:8ee30e15ac7b 1921
davidprentice 0:8ee30e15ac7b 1922 if (y < 0) { // Clip top
davidprentice 0:8ee30e15ac7b 1923 h += y;
davidprentice 0:8ee30e15ac7b 1924 y = 0;
davidprentice 0:8ee30e15ac7b 1925 }
davidprentice 0:8ee30e15ac7b 1926 if (y + h > height()) { // Clip bottom
davidprentice 0:8ee30e15ac7b 1927 h = height() - y;
davidprentice 0:8ee30e15ac7b 1928 }
davidprentice 0:8ee30e15ac7b 1929
davidprentice 0:8ee30e15ac7b 1930 if (getRotation() == 0) {
davidprentice 0:8ee30e15ac7b 1931 drawFastRawVLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 1932 } else if (getRotation() == 1) {
davidprentice 0:8ee30e15ac7b 1933 int16_t t = x;
davidprentice 0:8ee30e15ac7b 1934 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 1935 y = t;
davidprentice 0:8ee30e15ac7b 1936 x -= h - 1;
davidprentice 0:8ee30e15ac7b 1937 drawFastRawHLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 1938 } else if (getRotation() == 2) {
davidprentice 0:8ee30e15ac7b 1939 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 1940 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 1941
davidprentice 0:8ee30e15ac7b 1942 y -= h - 1;
davidprentice 0:8ee30e15ac7b 1943 drawFastRawVLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 1944 } else if (getRotation() == 3) {
davidprentice 0:8ee30e15ac7b 1945 int16_t t = x;
davidprentice 0:8ee30e15ac7b 1946 x = y;
davidprentice 0:8ee30e15ac7b 1947 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 1948 drawFastRawHLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 1949 }
davidprentice 0:8ee30e15ac7b 1950 }
davidprentice 0:8ee30e15ac7b 1951
davidprentice 0:8ee30e15ac7b 1952 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1953 /*!
davidprentice 0:8ee30e15ac7b 1954 @brief Speed optimized horizontal line drawing
davidprentice 0:8ee30e15ac7b 1955 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 1956 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 1957 @param w Length of horizontal line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 1958 @param color Color to fill with
davidprentice 0:8ee30e15ac7b 1959 */
davidprentice 0:8ee30e15ac7b 1960 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 1961 void GFXcanvas1::drawFastHLine(int16_t x, int16_t y, int16_t w,
davidprentice 0:8ee30e15ac7b 1962 uint16_t color) {
davidprentice 0:8ee30e15ac7b 1963 if (w < 0) { // Convert negative widths to positive equivalent
davidprentice 0:8ee30e15ac7b 1964 w *= -1;
davidprentice 0:8ee30e15ac7b 1965 x -= w - 1;
davidprentice 0:8ee30e15ac7b 1966 if (x < 0) {
davidprentice 0:8ee30e15ac7b 1967 w += x;
davidprentice 0:8ee30e15ac7b 1968 x = 0;
davidprentice 0:8ee30e15ac7b 1969 }
davidprentice 0:8ee30e15ac7b 1970 }
davidprentice 0:8ee30e15ac7b 1971
davidprentice 0:8ee30e15ac7b 1972 // Edge rejection (no-draw if totally off canvas)
davidprentice 0:8ee30e15ac7b 1973 if ((y < 0) || (y >= height()) || (x >= width()) || ((x + w - 1) < 0)) {
davidprentice 0:8ee30e15ac7b 1974 return;
davidprentice 0:8ee30e15ac7b 1975 }
davidprentice 0:8ee30e15ac7b 1976
davidprentice 0:8ee30e15ac7b 1977 if (x < 0) { // Clip left
davidprentice 0:8ee30e15ac7b 1978 w += x;
davidprentice 0:8ee30e15ac7b 1979 x = 0;
davidprentice 0:8ee30e15ac7b 1980 }
davidprentice 0:8ee30e15ac7b 1981 if (x + w >= width()) { // Clip right
davidprentice 0:8ee30e15ac7b 1982 w = width() - x;
davidprentice 0:8ee30e15ac7b 1983 }
davidprentice 0:8ee30e15ac7b 1984
davidprentice 0:8ee30e15ac7b 1985 if (getRotation() == 0) {
davidprentice 0:8ee30e15ac7b 1986 drawFastRawHLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 1987 } else if (getRotation() == 1) {
davidprentice 0:8ee30e15ac7b 1988 int16_t t = x;
davidprentice 0:8ee30e15ac7b 1989 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 1990 y = t;
davidprentice 0:8ee30e15ac7b 1991 drawFastRawVLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 1992 } else if (getRotation() == 2) {
davidprentice 0:8ee30e15ac7b 1993 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 1994 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 1995
davidprentice 0:8ee30e15ac7b 1996 x -= w - 1;
davidprentice 0:8ee30e15ac7b 1997 drawFastRawHLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 1998 } else if (getRotation() == 3) {
davidprentice 0:8ee30e15ac7b 1999 int16_t t = x;
davidprentice 0:8ee30e15ac7b 2000 x = y;
davidprentice 0:8ee30e15ac7b 2001 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 2002 y -= w - 1;
davidprentice 0:8ee30e15ac7b 2003 drawFastRawVLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 2004 }
davidprentice 0:8ee30e15ac7b 2005 }
davidprentice 0:8ee30e15ac7b 2006
davidprentice 0:8ee30e15ac7b 2007 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2008 /*!
davidprentice 0:8ee30e15ac7b 2009 @brief Speed optimized vertical line drawing into the raw canvas buffer
davidprentice 0:8ee30e15ac7b 2010 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2011 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2012 @param h length of vertical line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 2013 @param color Binary (on or off) color to fill with
davidprentice 0:8ee30e15ac7b 2014 */
davidprentice 0:8ee30e15ac7b 2015 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2016 void GFXcanvas1::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
davidprentice 0:8ee30e15ac7b 2017 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2018 // x & y already in raw (rotation 0) coordinates, no need to transform.
davidprentice 0:8ee30e15ac7b 2019 int16_t row_bytes = ((WIDTH + 7) / 8);
davidprentice 0:8ee30e15ac7b 2020 uint8_t *buffer = this->getBuffer();
davidprentice 0:8ee30e15ac7b 2021 uint8_t *ptr = &buffer[(x / 8) + y * row_bytes];
davidprentice 0:8ee30e15ac7b 2022
davidprentice 0:8ee30e15ac7b 2023 if (color > 0) {
davidprentice 0:8ee30e15ac7b 2024 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 2025 uint8_t bit_mask = pgm_read_byte(&GFXsetBit[x & 7]);
davidprentice 0:8ee30e15ac7b 2026 #else
davidprentice 0:8ee30e15ac7b 2027 uint8_t bit_mask = (0x80 >> (x & 7));
davidprentice 0:8ee30e15ac7b 2028 #endif
davidprentice 0:8ee30e15ac7b 2029 for (int16_t i = 0; i < h; i++) {
davidprentice 0:8ee30e15ac7b 2030 *ptr |= bit_mask;
davidprentice 0:8ee30e15ac7b 2031 ptr += row_bytes;
davidprentice 0:8ee30e15ac7b 2032 }
davidprentice 0:8ee30e15ac7b 2033 } else {
davidprentice 0:8ee30e15ac7b 2034 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 2035 uint8_t bit_mask = pgm_read_byte(&GFXclrBit[x & 7]);
davidprentice 0:8ee30e15ac7b 2036 #else
davidprentice 0:8ee30e15ac7b 2037 uint8_t bit_mask = ~(0x80 >> (x & 7));
davidprentice 0:8ee30e15ac7b 2038 #endif
davidprentice 0:8ee30e15ac7b 2039 for (int16_t i = 0; i < h; i++) {
davidprentice 0:8ee30e15ac7b 2040 *ptr &= bit_mask;
davidprentice 0:8ee30e15ac7b 2041 ptr += row_bytes;
davidprentice 0:8ee30e15ac7b 2042 }
davidprentice 0:8ee30e15ac7b 2043 }
davidprentice 0:8ee30e15ac7b 2044 }
davidprentice 0:8ee30e15ac7b 2045
davidprentice 0:8ee30e15ac7b 2046 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2047 /*!
davidprentice 0:8ee30e15ac7b 2048 @brief Speed optimized horizontal line drawing into the raw canvas buffer
davidprentice 0:8ee30e15ac7b 2049 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2050 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2051 @param w length of horizontal line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 2052 @param color Binary (on or off) color to fill with
davidprentice 0:8ee30e15ac7b 2053 */
davidprentice 0:8ee30e15ac7b 2054 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2055 void GFXcanvas1::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
davidprentice 0:8ee30e15ac7b 2056 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2057 // x & y already in raw (rotation 0) coordinates, no need to transform.
davidprentice 0:8ee30e15ac7b 2058 int16_t rowBytes = ((WIDTH + 7) / 8);
davidprentice 0:8ee30e15ac7b 2059 uint8_t *buffer = this->getBuffer();
davidprentice 0:8ee30e15ac7b 2060 uint8_t *ptr = &buffer[(x / 8) + y * rowBytes];
davidprentice 0:8ee30e15ac7b 2061 size_t remainingWidthBits = w;
davidprentice 0:8ee30e15ac7b 2062
davidprentice 0:8ee30e15ac7b 2063 // check to see if first byte needs to be partially filled
davidprentice 0:8ee30e15ac7b 2064 if ((x & 7) > 0) {
davidprentice 0:8ee30e15ac7b 2065 // create bit mask for first byte
davidprentice 0:8ee30e15ac7b 2066 uint8_t startByteBitMask = 0x00;
davidprentice 0:8ee30e15ac7b 2067 for (int8_t i = (x & 7); ((i < 8) && (remainingWidthBits > 0)); i++) {
davidprentice 0:8ee30e15ac7b 2068 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 2069 startByteBitMask |= pgm_read_byte(&GFXsetBit[i]);
davidprentice 0:8ee30e15ac7b 2070 #else
davidprentice 0:8ee30e15ac7b 2071 startByteBitMask |= (0x80 >> i);
davidprentice 0:8ee30e15ac7b 2072 #endif
davidprentice 0:8ee30e15ac7b 2073 remainingWidthBits--;
davidprentice 0:8ee30e15ac7b 2074 }
davidprentice 0:8ee30e15ac7b 2075 if (color > 0) {
davidprentice 0:8ee30e15ac7b 2076 *ptr |= startByteBitMask;
davidprentice 0:8ee30e15ac7b 2077 } else {
davidprentice 0:8ee30e15ac7b 2078 *ptr &= ~startByteBitMask;
davidprentice 0:8ee30e15ac7b 2079 }
davidprentice 0:8ee30e15ac7b 2080
davidprentice 0:8ee30e15ac7b 2081 ptr++;
davidprentice 0:8ee30e15ac7b 2082 }
davidprentice 0:8ee30e15ac7b 2083
davidprentice 0:8ee30e15ac7b 2084 // do the next remainingWidthBits bits
davidprentice 0:8ee30e15ac7b 2085 if (remainingWidthBits > 0) {
davidprentice 0:8ee30e15ac7b 2086 size_t remainingWholeBytes = remainingWidthBits / 8;
davidprentice 0:8ee30e15ac7b 2087 size_t lastByteBits = remainingWidthBits % 8;
davidprentice 0:8ee30e15ac7b 2088 uint8_t wholeByteColor = color > 0 ? 0xFF : 0x00;
davidprentice 0:8ee30e15ac7b 2089
davidprentice 0:8ee30e15ac7b 2090 memset(ptr, wholeByteColor, remainingWholeBytes);
davidprentice 0:8ee30e15ac7b 2091
davidprentice 0:8ee30e15ac7b 2092 if (lastByteBits > 0) {
davidprentice 0:8ee30e15ac7b 2093 uint8_t lastByteBitMask = 0x00;
davidprentice 0:8ee30e15ac7b 2094 for (size_t i = 0; i < lastByteBits; i++) {
davidprentice 0:8ee30e15ac7b 2095 #ifdef __AVR__
davidprentice 0:8ee30e15ac7b 2096 lastByteBitMask |= pgm_read_byte(&GFXsetBit[i]);
davidprentice 0:8ee30e15ac7b 2097 #else
davidprentice 0:8ee30e15ac7b 2098 lastByteBitMask |= (0x80 >> i);
davidprentice 0:8ee30e15ac7b 2099 #endif
davidprentice 0:8ee30e15ac7b 2100 }
davidprentice 0:8ee30e15ac7b 2101 ptr += remainingWholeBytes;
davidprentice 0:8ee30e15ac7b 2102
davidprentice 0:8ee30e15ac7b 2103 if (color > 0) {
davidprentice 0:8ee30e15ac7b 2104 *ptr |= lastByteBitMask;
davidprentice 0:8ee30e15ac7b 2105 } else {
davidprentice 0:8ee30e15ac7b 2106 *ptr &= ~lastByteBitMask;
davidprentice 0:8ee30e15ac7b 2107 }
davidprentice 0:8ee30e15ac7b 2108 }
davidprentice 0:8ee30e15ac7b 2109 }
davidprentice 0:8ee30e15ac7b 2110 }
davidprentice 0:8ee30e15ac7b 2111
davidprentice 0:8ee30e15ac7b 2112 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2113 /*!
davidprentice 0:8ee30e15ac7b 2114 @brief Instatiate a GFX 8-bit canvas context for graphics
davidprentice 0:8ee30e15ac7b 2115 @param w Display width, in pixels
davidprentice 0:8ee30e15ac7b 2116 @param h Display height, in pixels
davidprentice 0:8ee30e15ac7b 2117 */
davidprentice 0:8ee30e15ac7b 2118 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2119 GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
davidprentice 0:8ee30e15ac7b 2120 uint32_t bytes = w * h;
davidprentice 0:8ee30e15ac7b 2121 if ((buffer = (uint8_t *)malloc(bytes))) {
davidprentice 0:8ee30e15ac7b 2122 memset(buffer, 0, bytes);
davidprentice 0:8ee30e15ac7b 2123 }
davidprentice 0:8ee30e15ac7b 2124 }
davidprentice 0:8ee30e15ac7b 2125
davidprentice 0:8ee30e15ac7b 2126 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2127 /*!
davidprentice 0:8ee30e15ac7b 2128 @brief Delete the canvas, free memory
davidprentice 0:8ee30e15ac7b 2129 */
davidprentice 0:8ee30e15ac7b 2130 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2131 GFXcanvas8::~GFXcanvas8(void) {
davidprentice 0:8ee30e15ac7b 2132 if (buffer)
davidprentice 0:8ee30e15ac7b 2133 free(buffer);
davidprentice 0:8ee30e15ac7b 2134 }
davidprentice 0:8ee30e15ac7b 2135
davidprentice 0:8ee30e15ac7b 2136 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2137 /*!
davidprentice 0:8ee30e15ac7b 2138 @brief Draw a pixel to the canvas framebuffer
davidprentice 0:8ee30e15ac7b 2139 @param x x coordinate
davidprentice 0:8ee30e15ac7b 2140 @param y y coordinate
davidprentice 0:8ee30e15ac7b 2141 @param color 8-bit Color to fill with. Only lower byte of uint16_t is used.
davidprentice 0:8ee30e15ac7b 2142 */
davidprentice 0:8ee30e15ac7b 2143 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2144 void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) {
davidprentice 0:8ee30e15ac7b 2145 if (buffer) {
davidprentice 0:8ee30e15ac7b 2146 if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
davidprentice 0:8ee30e15ac7b 2147 return;
davidprentice 0:8ee30e15ac7b 2148
davidprentice 0:8ee30e15ac7b 2149 int16_t t;
davidprentice 0:8ee30e15ac7b 2150 switch (rotation) {
davidprentice 0:8ee30e15ac7b 2151 case 1:
davidprentice 0:8ee30e15ac7b 2152 t = x;
davidprentice 0:8ee30e15ac7b 2153 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 2154 y = t;
davidprentice 0:8ee30e15ac7b 2155 break;
davidprentice 0:8ee30e15ac7b 2156 case 2:
davidprentice 0:8ee30e15ac7b 2157 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 2158 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 2159 break;
davidprentice 0:8ee30e15ac7b 2160 case 3:
davidprentice 0:8ee30e15ac7b 2161 t = x;
davidprentice 0:8ee30e15ac7b 2162 x = y;
davidprentice 0:8ee30e15ac7b 2163 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 2164 break;
davidprentice 0:8ee30e15ac7b 2165 }
davidprentice 0:8ee30e15ac7b 2166
davidprentice 0:8ee30e15ac7b 2167 buffer[x + y * WIDTH] = color;
davidprentice 0:8ee30e15ac7b 2168 }
davidprentice 0:8ee30e15ac7b 2169 }
davidprentice 0:8ee30e15ac7b 2170
davidprentice 0:8ee30e15ac7b 2171 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 2172 /*!
davidprentice 0:8ee30e15ac7b 2173 @brief Get the pixel color value at a given coordinate
davidprentice 0:8ee30e15ac7b 2174 @param x x coordinate
davidprentice 0:8ee30e15ac7b 2175 @param y y coordinate
davidprentice 0:8ee30e15ac7b 2176 @returns The desired pixel's 8-bit color value
davidprentice 0:8ee30e15ac7b 2177 */
davidprentice 0:8ee30e15ac7b 2178 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 2179 uint8_t GFXcanvas8::getPixel(int16_t x, int16_t y) const {
davidprentice 0:8ee30e15ac7b 2180 int16_t t;
davidprentice 0:8ee30e15ac7b 2181 switch (rotation) {
davidprentice 0:8ee30e15ac7b 2182 case 1:
davidprentice 0:8ee30e15ac7b 2183 t = x;
davidprentice 0:8ee30e15ac7b 2184 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 2185 y = t;
davidprentice 0:8ee30e15ac7b 2186 break;
davidprentice 0:8ee30e15ac7b 2187 case 2:
davidprentice 0:8ee30e15ac7b 2188 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 2189 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 2190 break;
davidprentice 0:8ee30e15ac7b 2191 case 3:
davidprentice 0:8ee30e15ac7b 2192 t = x;
davidprentice 0:8ee30e15ac7b 2193 x = y;
davidprentice 0:8ee30e15ac7b 2194 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 2195 break;
davidprentice 0:8ee30e15ac7b 2196 }
davidprentice 0:8ee30e15ac7b 2197 return getRawPixel(x, y);
davidprentice 0:8ee30e15ac7b 2198 }
davidprentice 0:8ee30e15ac7b 2199
davidprentice 0:8ee30e15ac7b 2200 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 2201 /*!
davidprentice 0:8ee30e15ac7b 2202 @brief Get the pixel color value at a given, unrotated coordinate.
davidprentice 0:8ee30e15ac7b 2203 This method is intended for hardware drivers to get pixel value
davidprentice 0:8ee30e15ac7b 2204 in physical coordinates.
davidprentice 0:8ee30e15ac7b 2205 @param x x coordinate
davidprentice 0:8ee30e15ac7b 2206 @param y y coordinate
davidprentice 0:8ee30e15ac7b 2207 @returns The desired pixel's 8-bit color value
davidprentice 0:8ee30e15ac7b 2208 */
davidprentice 0:8ee30e15ac7b 2209 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 2210 uint8_t GFXcanvas8::getRawPixel(int16_t x, int16_t y) const {
davidprentice 0:8ee30e15ac7b 2211 if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT))
davidprentice 0:8ee30e15ac7b 2212 return 0;
davidprentice 0:8ee30e15ac7b 2213 if (buffer) {
davidprentice 0:8ee30e15ac7b 2214 return buffer[x + y * WIDTH];
davidprentice 0:8ee30e15ac7b 2215 }
davidprentice 0:8ee30e15ac7b 2216 return 0;
davidprentice 0:8ee30e15ac7b 2217 }
davidprentice 0:8ee30e15ac7b 2218
davidprentice 0:8ee30e15ac7b 2219 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2220 /*!
davidprentice 0:8ee30e15ac7b 2221 @brief Fill the framebuffer completely with one color
davidprentice 0:8ee30e15ac7b 2222 @param color 8-bit Color to fill with. Only lower byte of uint16_t is used.
davidprentice 0:8ee30e15ac7b 2223 */
davidprentice 0:8ee30e15ac7b 2224 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2225 void GFXcanvas8::fillScreen(uint16_t color) {
davidprentice 0:8ee30e15ac7b 2226 if (buffer) {
davidprentice 0:8ee30e15ac7b 2227 memset(buffer, color, WIDTH * HEIGHT);
davidprentice 0:8ee30e15ac7b 2228 }
davidprentice 0:8ee30e15ac7b 2229 }
davidprentice 0:8ee30e15ac7b 2230
davidprentice 0:8ee30e15ac7b 2231 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2232 /*!
davidprentice 0:8ee30e15ac7b 2233 @brief Speed optimized vertical line drawing
davidprentice 0:8ee30e15ac7b 2234 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2235 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2236 @param h Length of vertical line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 2237 @param color 8-bit Color to fill with. Only lower byte of uint16_t is
davidprentice 0:8ee30e15ac7b 2238 used.
davidprentice 0:8ee30e15ac7b 2239 */
davidprentice 0:8ee30e15ac7b 2240 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2241 void GFXcanvas8::drawFastVLine(int16_t x, int16_t y, int16_t h,
davidprentice 0:8ee30e15ac7b 2242 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2243 if (h < 0) { // Convert negative heights to positive equivalent
davidprentice 0:8ee30e15ac7b 2244 h *= -1;
davidprentice 0:8ee30e15ac7b 2245 y -= h - 1;
davidprentice 0:8ee30e15ac7b 2246 if (y < 0) {
davidprentice 0:8ee30e15ac7b 2247 h += y;
davidprentice 0:8ee30e15ac7b 2248 y = 0;
davidprentice 0:8ee30e15ac7b 2249 }
davidprentice 0:8ee30e15ac7b 2250 }
davidprentice 0:8ee30e15ac7b 2251
davidprentice 0:8ee30e15ac7b 2252 // Edge rejection (no-draw if totally off canvas)
davidprentice 0:8ee30e15ac7b 2253 if ((x < 0) || (x >= width()) || (y >= height()) || ((y + h - 1) < 0)) {
davidprentice 0:8ee30e15ac7b 2254 return;
davidprentice 0:8ee30e15ac7b 2255 }
davidprentice 0:8ee30e15ac7b 2256
davidprentice 0:8ee30e15ac7b 2257 if (y < 0) { // Clip top
davidprentice 0:8ee30e15ac7b 2258 h += y;
davidprentice 0:8ee30e15ac7b 2259 y = 0;
davidprentice 0:8ee30e15ac7b 2260 }
davidprentice 0:8ee30e15ac7b 2261 if (y + h > height()) { // Clip bottom
davidprentice 0:8ee30e15ac7b 2262 h = height() - y;
davidprentice 0:8ee30e15ac7b 2263 }
davidprentice 0:8ee30e15ac7b 2264
davidprentice 0:8ee30e15ac7b 2265 if (getRotation() == 0) {
davidprentice 0:8ee30e15ac7b 2266 drawFastRawVLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 2267 } else if (getRotation() == 1) {
davidprentice 0:8ee30e15ac7b 2268 int16_t t = x;
davidprentice 0:8ee30e15ac7b 2269 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 2270 y = t;
davidprentice 0:8ee30e15ac7b 2271 x -= h - 1;
davidprentice 0:8ee30e15ac7b 2272 drawFastRawHLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 2273 } else if (getRotation() == 2) {
davidprentice 0:8ee30e15ac7b 2274 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 2275 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 2276
davidprentice 0:8ee30e15ac7b 2277 y -= h - 1;
davidprentice 0:8ee30e15ac7b 2278 drawFastRawVLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 2279 } else if (getRotation() == 3) {
davidprentice 0:8ee30e15ac7b 2280 int16_t t = x;
davidprentice 0:8ee30e15ac7b 2281 x = y;
davidprentice 0:8ee30e15ac7b 2282 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 2283 drawFastRawHLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 2284 }
davidprentice 0:8ee30e15ac7b 2285 }
davidprentice 0:8ee30e15ac7b 2286
davidprentice 0:8ee30e15ac7b 2287 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2288 /*!
davidprentice 0:8ee30e15ac7b 2289 @brief Speed optimized horizontal line drawing
davidprentice 0:8ee30e15ac7b 2290 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2291 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2292 @param w Length of horizontal line to be drawn, including 1st point
davidprentice 0:8ee30e15ac7b 2293 @param color 8-bit Color to fill with. Only lower byte of uint16_t is
davidprentice 0:8ee30e15ac7b 2294 used.
davidprentice 0:8ee30e15ac7b 2295 */
davidprentice 0:8ee30e15ac7b 2296 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2297 void GFXcanvas8::drawFastHLine(int16_t x, int16_t y, int16_t w,
davidprentice 0:8ee30e15ac7b 2298 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2299
davidprentice 0:8ee30e15ac7b 2300 if (w < 0) { // Convert negative widths to positive equivalent
davidprentice 0:8ee30e15ac7b 2301 w *= -1;
davidprentice 0:8ee30e15ac7b 2302 x -= w - 1;
davidprentice 0:8ee30e15ac7b 2303 if (x < 0) {
davidprentice 0:8ee30e15ac7b 2304 w += x;
davidprentice 0:8ee30e15ac7b 2305 x = 0;
davidprentice 0:8ee30e15ac7b 2306 }
davidprentice 0:8ee30e15ac7b 2307 }
davidprentice 0:8ee30e15ac7b 2308
davidprentice 0:8ee30e15ac7b 2309 // Edge rejection (no-draw if totally off canvas)
davidprentice 0:8ee30e15ac7b 2310 if ((y < 0) || (y >= height()) || (x >= width()) || ((x + w - 1) < 0)) {
davidprentice 0:8ee30e15ac7b 2311 return;
davidprentice 0:8ee30e15ac7b 2312 }
davidprentice 0:8ee30e15ac7b 2313
davidprentice 0:8ee30e15ac7b 2314 if (x < 0) { // Clip left
davidprentice 0:8ee30e15ac7b 2315 w += x;
davidprentice 0:8ee30e15ac7b 2316 x = 0;
davidprentice 0:8ee30e15ac7b 2317 }
davidprentice 0:8ee30e15ac7b 2318 if (x + w >= width()) { // Clip right
davidprentice 0:8ee30e15ac7b 2319 w = width() - x;
davidprentice 0:8ee30e15ac7b 2320 }
davidprentice 0:8ee30e15ac7b 2321
davidprentice 0:8ee30e15ac7b 2322 if (getRotation() == 0) {
davidprentice 0:8ee30e15ac7b 2323 drawFastRawHLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 2324 } else if (getRotation() == 1) {
davidprentice 0:8ee30e15ac7b 2325 int16_t t = x;
davidprentice 0:8ee30e15ac7b 2326 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 2327 y = t;
davidprentice 0:8ee30e15ac7b 2328 drawFastRawVLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 2329 } else if (getRotation() == 2) {
davidprentice 0:8ee30e15ac7b 2330 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 2331 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 2332
davidprentice 0:8ee30e15ac7b 2333 x -= w - 1;
davidprentice 0:8ee30e15ac7b 2334 drawFastRawHLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 2335 } else if (getRotation() == 3) {
davidprentice 0:8ee30e15ac7b 2336 int16_t t = x;
davidprentice 0:8ee30e15ac7b 2337 x = y;
davidprentice 0:8ee30e15ac7b 2338 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 2339 y -= w - 1;
davidprentice 0:8ee30e15ac7b 2340 drawFastRawVLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 2341 }
davidprentice 0:8ee30e15ac7b 2342 }
davidprentice 0:8ee30e15ac7b 2343
davidprentice 0:8ee30e15ac7b 2344 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2345 /*!
davidprentice 0:8ee30e15ac7b 2346 @brief Speed optimized vertical line drawing into the raw canvas buffer
davidprentice 0:8ee30e15ac7b 2347 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2348 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2349 @param h length of vertical line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 2350 @param color 8-bit Color to fill with. Only lower byte of uint16_t is
davidprentice 0:8ee30e15ac7b 2351 used.
davidprentice 0:8ee30e15ac7b 2352 */
davidprentice 0:8ee30e15ac7b 2353 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2354 void GFXcanvas8::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
davidprentice 0:8ee30e15ac7b 2355 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2356 // x & y already in raw (rotation 0) coordinates, no need to transform.
davidprentice 0:8ee30e15ac7b 2357 uint8_t *buffer_ptr = buffer + y * WIDTH + x;
davidprentice 0:8ee30e15ac7b 2358 for (int16_t i = 0; i < h; i++) {
davidprentice 0:8ee30e15ac7b 2359 (*buffer_ptr) = color;
davidprentice 0:8ee30e15ac7b 2360 buffer_ptr += WIDTH;
davidprentice 0:8ee30e15ac7b 2361 }
davidprentice 0:8ee30e15ac7b 2362 }
davidprentice 0:8ee30e15ac7b 2363
davidprentice 0:8ee30e15ac7b 2364 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2365 /*!
davidprentice 0:8ee30e15ac7b 2366 @brief Speed optimized horizontal line drawing into the raw canvas buffer
davidprentice 0:8ee30e15ac7b 2367 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2368 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2369 @param w length of horizontal line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 2370 @param color 8-bit Color to fill with. Only lower byte of uint16_t is
davidprentice 0:8ee30e15ac7b 2371 used.
davidprentice 0:8ee30e15ac7b 2372 */
davidprentice 0:8ee30e15ac7b 2373 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2374 void GFXcanvas8::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
davidprentice 0:8ee30e15ac7b 2375 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2376 // x & y already in raw (rotation 0) coordinates, no need to transform.
davidprentice 0:8ee30e15ac7b 2377 memset(buffer + y * WIDTH + x, color, w);
davidprentice 0:8ee30e15ac7b 2378 }
davidprentice 0:8ee30e15ac7b 2379
davidprentice 0:8ee30e15ac7b 2380 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2381 /*!
davidprentice 0:8ee30e15ac7b 2382 @brief Instatiate a GFX 16-bit canvas context for graphics
davidprentice 0:8ee30e15ac7b 2383 @param w Display width, in pixels
davidprentice 0:8ee30e15ac7b 2384 @param h Display height, in pixels
davidprentice 0:8ee30e15ac7b 2385 */
davidprentice 0:8ee30e15ac7b 2386 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2387 GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
davidprentice 0:8ee30e15ac7b 2388 uint32_t bytes = w * h * 2;
davidprentice 0:8ee30e15ac7b 2389 if ((buffer = (uint16_t *)malloc(bytes))) {
davidprentice 0:8ee30e15ac7b 2390 memset(buffer, 0, bytes);
davidprentice 0:8ee30e15ac7b 2391 }
davidprentice 0:8ee30e15ac7b 2392 }
davidprentice 0:8ee30e15ac7b 2393
davidprentice 0:8ee30e15ac7b 2394 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2395 /*!
davidprentice 0:8ee30e15ac7b 2396 @brief Delete the canvas, free memory
davidprentice 0:8ee30e15ac7b 2397 */
davidprentice 0:8ee30e15ac7b 2398 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2399 GFXcanvas16::~GFXcanvas16(void) {
davidprentice 0:8ee30e15ac7b 2400 if (buffer)
davidprentice 0:8ee30e15ac7b 2401 free(buffer);
davidprentice 0:8ee30e15ac7b 2402 }
davidprentice 0:8ee30e15ac7b 2403
davidprentice 0:8ee30e15ac7b 2404 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2405 /*!
davidprentice 0:8ee30e15ac7b 2406 @brief Draw a pixel to the canvas framebuffer
davidprentice 0:8ee30e15ac7b 2407 @param x x coordinate
davidprentice 0:8ee30e15ac7b 2408 @param y y coordinate
davidprentice 0:8ee30e15ac7b 2409 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 2410 */
davidprentice 0:8ee30e15ac7b 2411 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2412 void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) {
davidprentice 0:8ee30e15ac7b 2413 if (buffer) {
davidprentice 0:8ee30e15ac7b 2414 if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
davidprentice 0:8ee30e15ac7b 2415 return;
davidprentice 0:8ee30e15ac7b 2416
davidprentice 0:8ee30e15ac7b 2417 int16_t t;
davidprentice 0:8ee30e15ac7b 2418 switch (rotation) {
davidprentice 0:8ee30e15ac7b 2419 case 1:
davidprentice 0:8ee30e15ac7b 2420 t = x;
davidprentice 0:8ee30e15ac7b 2421 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 2422 y = t;
davidprentice 0:8ee30e15ac7b 2423 break;
davidprentice 0:8ee30e15ac7b 2424 case 2:
davidprentice 0:8ee30e15ac7b 2425 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 2426 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 2427 break;
davidprentice 0:8ee30e15ac7b 2428 case 3:
davidprentice 0:8ee30e15ac7b 2429 t = x;
davidprentice 0:8ee30e15ac7b 2430 x = y;
davidprentice 0:8ee30e15ac7b 2431 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 2432 break;
davidprentice 0:8ee30e15ac7b 2433 }
davidprentice 0:8ee30e15ac7b 2434
davidprentice 0:8ee30e15ac7b 2435 buffer[x + y * WIDTH] = color;
davidprentice 0:8ee30e15ac7b 2436 }
davidprentice 0:8ee30e15ac7b 2437 }
davidprentice 0:8ee30e15ac7b 2438
davidprentice 0:8ee30e15ac7b 2439 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 2440 /*!
davidprentice 0:8ee30e15ac7b 2441 @brief Get the pixel color value at a given coordinate
davidprentice 0:8ee30e15ac7b 2442 @param x x coordinate
davidprentice 0:8ee30e15ac7b 2443 @param y y coordinate
davidprentice 0:8ee30e15ac7b 2444 @returns The desired pixel's 16-bit 5-6-5 color value
davidprentice 0:8ee30e15ac7b 2445 */
davidprentice 0:8ee30e15ac7b 2446 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 2447 uint16_t GFXcanvas16::getPixel(int16_t x, int16_t y) const {
davidprentice 0:8ee30e15ac7b 2448 int16_t t;
davidprentice 0:8ee30e15ac7b 2449 switch (rotation) {
davidprentice 0:8ee30e15ac7b 2450 case 1:
davidprentice 0:8ee30e15ac7b 2451 t = x;
davidprentice 0:8ee30e15ac7b 2452 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 2453 y = t;
davidprentice 0:8ee30e15ac7b 2454 break;
davidprentice 0:8ee30e15ac7b 2455 case 2:
davidprentice 0:8ee30e15ac7b 2456 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 2457 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 2458 break;
davidprentice 0:8ee30e15ac7b 2459 case 3:
davidprentice 0:8ee30e15ac7b 2460 t = x;
davidprentice 0:8ee30e15ac7b 2461 x = y;
davidprentice 0:8ee30e15ac7b 2462 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 2463 break;
davidprentice 0:8ee30e15ac7b 2464 }
davidprentice 0:8ee30e15ac7b 2465 return getRawPixel(x, y);
davidprentice 0:8ee30e15ac7b 2466 }
davidprentice 0:8ee30e15ac7b 2467
davidprentice 0:8ee30e15ac7b 2468 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 2469 /*!
davidprentice 0:8ee30e15ac7b 2470 @brief Get the pixel color value at a given, unrotated coordinate.
davidprentice 0:8ee30e15ac7b 2471 This method is intended for hardware drivers to get pixel value
davidprentice 0:8ee30e15ac7b 2472 in physical coordinates.
davidprentice 0:8ee30e15ac7b 2473 @param x x coordinate
davidprentice 0:8ee30e15ac7b 2474 @param y y coordinate
davidprentice 0:8ee30e15ac7b 2475 @returns The desired pixel's 16-bit 5-6-5 color value
davidprentice 0:8ee30e15ac7b 2476 */
davidprentice 0:8ee30e15ac7b 2477 /**********************************************************************/
davidprentice 0:8ee30e15ac7b 2478 uint16_t GFXcanvas16::getRawPixel(int16_t x, int16_t y) const {
davidprentice 0:8ee30e15ac7b 2479 if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT))
davidprentice 0:8ee30e15ac7b 2480 return 0;
davidprentice 0:8ee30e15ac7b 2481 if (buffer) {
davidprentice 0:8ee30e15ac7b 2482 return buffer[x + y * WIDTH];
davidprentice 0:8ee30e15ac7b 2483 }
davidprentice 0:8ee30e15ac7b 2484 return 0;
davidprentice 0:8ee30e15ac7b 2485 }
davidprentice 0:8ee30e15ac7b 2486
davidprentice 0:8ee30e15ac7b 2487 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2488 /*!
davidprentice 0:8ee30e15ac7b 2489 @brief Fill the framebuffer completely with one color
davidprentice 0:8ee30e15ac7b 2490 @param color 16-bit 5-6-5 Color to fill with
davidprentice 0:8ee30e15ac7b 2491 */
davidprentice 0:8ee30e15ac7b 2492 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2493 void GFXcanvas16::fillScreen(uint16_t color) {
davidprentice 0:8ee30e15ac7b 2494 if (buffer) {
davidprentice 0:8ee30e15ac7b 2495 uint8_t hi = color >> 8, lo = color & 0xFF;
davidprentice 0:8ee30e15ac7b 2496 if (hi == lo) {
davidprentice 0:8ee30e15ac7b 2497 memset(buffer, lo, WIDTH * HEIGHT * 2);
davidprentice 0:8ee30e15ac7b 2498 } else {
davidprentice 0:8ee30e15ac7b 2499 uint32_t i, pixels = WIDTH * HEIGHT;
davidprentice 0:8ee30e15ac7b 2500 for (i = 0; i < pixels; i++)
davidprentice 0:8ee30e15ac7b 2501 buffer[i] = color;
davidprentice 0:8ee30e15ac7b 2502 }
davidprentice 0:8ee30e15ac7b 2503 }
davidprentice 0:8ee30e15ac7b 2504 }
davidprentice 0:8ee30e15ac7b 2505
davidprentice 0:8ee30e15ac7b 2506 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2507 /*!
davidprentice 0:8ee30e15ac7b 2508 @brief Reverses the "endian-ness" of each 16-bit pixel within the
davidprentice 0:8ee30e15ac7b 2509 canvas; little-endian to big-endian, or big-endian to little.
davidprentice 0:8ee30e15ac7b 2510 Most microcontrollers (such as SAMD) are little-endian, while
davidprentice 0:8ee30e15ac7b 2511 most displays tend toward big-endianness. All the drawing
davidprentice 0:8ee30e15ac7b 2512 functions (including RGB bitmap drawing) take care of this
davidprentice 0:8ee30e15ac7b 2513 automatically, but some specialized code (usually involving
davidprentice 0:8ee30e15ac7b 2514 DMA) can benefit from having pixel data already in the
davidprentice 0:8ee30e15ac7b 2515 display-native order. Note that this does NOT convert to a
davidprentice 0:8ee30e15ac7b 2516 SPECIFIC endian-ness, it just flips the bytes within each word.
davidprentice 0:8ee30e15ac7b 2517 */
davidprentice 0:8ee30e15ac7b 2518 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2519 void GFXcanvas16::byteSwap(void) {
davidprentice 0:8ee30e15ac7b 2520 if (buffer) {
davidprentice 0:8ee30e15ac7b 2521 uint32_t i, pixels = WIDTH * HEIGHT;
davidprentice 0:8ee30e15ac7b 2522 for (i = 0; i < pixels; i++)
davidprentice 0:8ee30e15ac7b 2523 buffer[i] = __builtin_bswap16(buffer[i]);
davidprentice 0:8ee30e15ac7b 2524 }
davidprentice 0:8ee30e15ac7b 2525 }
davidprentice 0:8ee30e15ac7b 2526
davidprentice 0:8ee30e15ac7b 2527 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2528 /*!
davidprentice 0:8ee30e15ac7b 2529 @brief Speed optimized vertical line drawing
davidprentice 0:8ee30e15ac7b 2530 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2531 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2532 @param h length of vertical line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 2533 @param color color 16-bit 5-6-5 Color to draw line with
davidprentice 0:8ee30e15ac7b 2534 */
davidprentice 0:8ee30e15ac7b 2535 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2536 void GFXcanvas16::drawFastVLine(int16_t x, int16_t y, int16_t h,
davidprentice 0:8ee30e15ac7b 2537 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2538 if (h < 0) { // Convert negative heights to positive equivalent
davidprentice 0:8ee30e15ac7b 2539 h *= -1;
davidprentice 0:8ee30e15ac7b 2540 y -= h - 1;
davidprentice 0:8ee30e15ac7b 2541 if (y < 0) {
davidprentice 0:8ee30e15ac7b 2542 h += y;
davidprentice 0:8ee30e15ac7b 2543 y = 0;
davidprentice 0:8ee30e15ac7b 2544 }
davidprentice 0:8ee30e15ac7b 2545 }
davidprentice 0:8ee30e15ac7b 2546
davidprentice 0:8ee30e15ac7b 2547 // Edge rejection (no-draw if totally off canvas)
davidprentice 0:8ee30e15ac7b 2548 if ((x < 0) || (x >= width()) || (y >= height()) || ((y + h - 1) < 0)) {
davidprentice 0:8ee30e15ac7b 2549 return;
davidprentice 0:8ee30e15ac7b 2550 }
davidprentice 0:8ee30e15ac7b 2551
davidprentice 0:8ee30e15ac7b 2552 if (y < 0) { // Clip top
davidprentice 0:8ee30e15ac7b 2553 h += y;
davidprentice 0:8ee30e15ac7b 2554 y = 0;
davidprentice 0:8ee30e15ac7b 2555 }
davidprentice 0:8ee30e15ac7b 2556 if (y + h > height()) { // Clip bottom
davidprentice 0:8ee30e15ac7b 2557 h = height() - y;
davidprentice 0:8ee30e15ac7b 2558 }
davidprentice 0:8ee30e15ac7b 2559
davidprentice 0:8ee30e15ac7b 2560 if (getRotation() == 0) {
davidprentice 0:8ee30e15ac7b 2561 drawFastRawVLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 2562 } else if (getRotation() == 1) {
davidprentice 0:8ee30e15ac7b 2563 int16_t t = x;
davidprentice 0:8ee30e15ac7b 2564 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 2565 y = t;
davidprentice 0:8ee30e15ac7b 2566 x -= h - 1;
davidprentice 0:8ee30e15ac7b 2567 drawFastRawHLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 2568 } else if (getRotation() == 2) {
davidprentice 0:8ee30e15ac7b 2569 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 2570 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 2571
davidprentice 0:8ee30e15ac7b 2572 y -= h - 1;
davidprentice 0:8ee30e15ac7b 2573 drawFastRawVLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 2574 } else if (getRotation() == 3) {
davidprentice 0:8ee30e15ac7b 2575 int16_t t = x;
davidprentice 0:8ee30e15ac7b 2576 x = y;
davidprentice 0:8ee30e15ac7b 2577 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 2578 drawFastRawHLine(x, y, h, color);
davidprentice 0:8ee30e15ac7b 2579 }
davidprentice 0:8ee30e15ac7b 2580 }
davidprentice 0:8ee30e15ac7b 2581
davidprentice 0:8ee30e15ac7b 2582 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2583 /*!
davidprentice 0:8ee30e15ac7b 2584 @brief Speed optimized horizontal line drawing
davidprentice 0:8ee30e15ac7b 2585 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2586 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2587 @param w Length of horizontal line to be drawn, including 1st point
davidprentice 0:8ee30e15ac7b 2588 @param color Color 16-bit 5-6-5 Color to draw line with
davidprentice 0:8ee30e15ac7b 2589 */
davidprentice 0:8ee30e15ac7b 2590 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2591 void GFXcanvas16::drawFastHLine(int16_t x, int16_t y, int16_t w,
davidprentice 0:8ee30e15ac7b 2592 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2593 if (w < 0) { // Convert negative widths to positive equivalent
davidprentice 0:8ee30e15ac7b 2594 w *= -1;
davidprentice 0:8ee30e15ac7b 2595 x -= w - 1;
davidprentice 0:8ee30e15ac7b 2596 if (x < 0) {
davidprentice 0:8ee30e15ac7b 2597 w += x;
davidprentice 0:8ee30e15ac7b 2598 x = 0;
davidprentice 0:8ee30e15ac7b 2599 }
davidprentice 0:8ee30e15ac7b 2600 }
davidprentice 0:8ee30e15ac7b 2601
davidprentice 0:8ee30e15ac7b 2602 // Edge rejection (no-draw if totally off canvas)
davidprentice 0:8ee30e15ac7b 2603 if ((y < 0) || (y >= height()) || (x >= width()) || ((x + w - 1) < 0)) {
davidprentice 0:8ee30e15ac7b 2604 return;
davidprentice 0:8ee30e15ac7b 2605 }
davidprentice 0:8ee30e15ac7b 2606
davidprentice 0:8ee30e15ac7b 2607 if (x < 0) { // Clip left
davidprentice 0:8ee30e15ac7b 2608 w += x;
davidprentice 0:8ee30e15ac7b 2609 x = 0;
davidprentice 0:8ee30e15ac7b 2610 }
davidprentice 0:8ee30e15ac7b 2611 if (x + w >= width()) { // Clip right
davidprentice 0:8ee30e15ac7b 2612 w = width() - x;
davidprentice 0:8ee30e15ac7b 2613 }
davidprentice 0:8ee30e15ac7b 2614
davidprentice 0:8ee30e15ac7b 2615 if (getRotation() == 0) {
davidprentice 0:8ee30e15ac7b 2616 drawFastRawHLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 2617 } else if (getRotation() == 1) {
davidprentice 0:8ee30e15ac7b 2618 int16_t t = x;
davidprentice 0:8ee30e15ac7b 2619 x = WIDTH - 1 - y;
davidprentice 0:8ee30e15ac7b 2620 y = t;
davidprentice 0:8ee30e15ac7b 2621 drawFastRawVLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 2622 } else if (getRotation() == 2) {
davidprentice 0:8ee30e15ac7b 2623 x = WIDTH - 1 - x;
davidprentice 0:8ee30e15ac7b 2624 y = HEIGHT - 1 - y;
davidprentice 0:8ee30e15ac7b 2625
davidprentice 0:8ee30e15ac7b 2626 x -= w - 1;
davidprentice 0:8ee30e15ac7b 2627 drawFastRawHLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 2628 } else if (getRotation() == 3) {
davidprentice 0:8ee30e15ac7b 2629 int16_t t = x;
davidprentice 0:8ee30e15ac7b 2630 x = y;
davidprentice 0:8ee30e15ac7b 2631 y = HEIGHT - 1 - t;
davidprentice 0:8ee30e15ac7b 2632 y -= w - 1;
davidprentice 0:8ee30e15ac7b 2633 drawFastRawVLine(x, y, w, color);
davidprentice 0:8ee30e15ac7b 2634 }
davidprentice 0:8ee30e15ac7b 2635 }
davidprentice 0:8ee30e15ac7b 2636
davidprentice 0:8ee30e15ac7b 2637 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2638 /*!
davidprentice 0:8ee30e15ac7b 2639 @brief Speed optimized vertical line drawing into the raw canvas buffer
davidprentice 0:8ee30e15ac7b 2640 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2641 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2642 @param h length of vertical line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 2643 @param color color 16-bit 5-6-5 Color to draw line with
davidprentice 0:8ee30e15ac7b 2644 */
davidprentice 0:8ee30e15ac7b 2645 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2646 void GFXcanvas16::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
davidprentice 0:8ee30e15ac7b 2647 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2648 // x & y already in raw (rotation 0) coordinates, no need to transform.
davidprentice 0:8ee30e15ac7b 2649 uint16_t *buffer_ptr = buffer + y * WIDTH + x;
davidprentice 0:8ee30e15ac7b 2650 for (int16_t i = 0; i < h; i++) {
davidprentice 0:8ee30e15ac7b 2651 (*buffer_ptr) = color;
davidprentice 0:8ee30e15ac7b 2652 buffer_ptr += WIDTH;
davidprentice 0:8ee30e15ac7b 2653 }
davidprentice 0:8ee30e15ac7b 2654 }
davidprentice 0:8ee30e15ac7b 2655
davidprentice 0:8ee30e15ac7b 2656 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2657 /*!
davidprentice 0:8ee30e15ac7b 2658 @brief Speed optimized horizontal line drawing into the raw canvas buffer
davidprentice 0:8ee30e15ac7b 2659 @param x Line horizontal start point
davidprentice 0:8ee30e15ac7b 2660 @param y Line vertical start point
davidprentice 0:8ee30e15ac7b 2661 @param w length of horizontal line to be drawn, including first point
davidprentice 0:8ee30e15ac7b 2662 @param color color 16-bit 5-6-5 Color to draw line with
davidprentice 0:8ee30e15ac7b 2663 */
davidprentice 0:8ee30e15ac7b 2664 /**************************************************************************/
davidprentice 0:8ee30e15ac7b 2665 void GFXcanvas16::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
davidprentice 0:8ee30e15ac7b 2666 uint16_t color) {
davidprentice 0:8ee30e15ac7b 2667 // x & y already in raw (rotation 0) coordinates, no need to transform.
davidprentice 0:8ee30e15ac7b 2668 uint32_t buffer_index = y * WIDTH + x;
davidprentice 0:8ee30e15ac7b 2669 for (uint32_t i = buffer_index; i < buffer_index + w; i++) {
davidprentice 0:8ee30e15ac7b 2670 buffer[i] = color;
davidprentice 0:8ee30e15ac7b 2671 }
davidprentice 0:8ee30e15ac7b 2672 }