Clone of the Adafruit Graphics Library

Fork of Adafruit_GFX by justin kim

Committer:
justinkim
Date:
Thu Jul 30 05:20:08 2015 +0000
Revision:
4:256d9b541ab0
Parent:
2:a7d4ac7ed08a
Child:
5:ba163fcbfbf1
first release Shield

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SomeRandomBloke 2:a7d4ac7ed08a 1 /*
SomeRandomBloke 2:a7d4ac7ed08a 2 This is the core graphics library for all our displays, providing a common
SomeRandomBloke 2:a7d4ac7ed08a 3 set of graphics primitives (points, lines, circles, etc.). It needs to be
SomeRandomBloke 2:a7d4ac7ed08a 4 paired with a hardware-specific library for each display device we carry
SomeRandomBloke 2:a7d4ac7ed08a 5 (to handle the lower-level functions).
SomeRandomBloke 2:a7d4ac7ed08a 6
SomeRandomBloke 2:a7d4ac7ed08a 7 Adafruit invests time and resources providing this open source code, please
SomeRandomBloke 2:a7d4ac7ed08a 8 support Adafruit & open-source hardware by purchasing products from Adafruit!
SomeRandomBloke 0:08cfbae05724 9
SomeRandomBloke 2:a7d4ac7ed08a 10 Copyright (c) 2013 Adafruit Industries. All rights reserved.
SomeRandomBloke 2:a7d4ac7ed08a 11
SomeRandomBloke 2:a7d4ac7ed08a 12 Redistribution and use in source and binary forms, with or without
SomeRandomBloke 2:a7d4ac7ed08a 13 modification, are permitted provided that the following conditions are met:
SomeRandomBloke 2:a7d4ac7ed08a 14
SomeRandomBloke 2:a7d4ac7ed08a 15 - Redistributions of source code must retain the above copyright notice,
SomeRandomBloke 2:a7d4ac7ed08a 16 this list of conditions and the following disclaimer.
SomeRandomBloke 2:a7d4ac7ed08a 17 - Redistributions in binary form must reproduce the above copyright notice,
SomeRandomBloke 2:a7d4ac7ed08a 18 this list of conditions and the following disclaimer in the documentation
SomeRandomBloke 2:a7d4ac7ed08a 19 and/or other materials provided with the distribution.
SomeRandomBloke 2:a7d4ac7ed08a 20
SomeRandomBloke 2:a7d4ac7ed08a 21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
SomeRandomBloke 2:a7d4ac7ed08a 22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
SomeRandomBloke 2:a7d4ac7ed08a 23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
SomeRandomBloke 2:a7d4ac7ed08a 24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
SomeRandomBloke 2:a7d4ac7ed08a 25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
SomeRandomBloke 2:a7d4ac7ed08a 26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SomeRandomBloke 2:a7d4ac7ed08a 27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
SomeRandomBloke 2:a7d4ac7ed08a 28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
SomeRandomBloke 2:a7d4ac7ed08a 29 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
SomeRandomBloke 2:a7d4ac7ed08a 30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
SomeRandomBloke 2:a7d4ac7ed08a 31 POSSIBILITY OF SUCH DAMAGE.
SomeRandomBloke 2:a7d4ac7ed08a 32 */
SomeRandomBloke 0:08cfbae05724 33
SomeRandomBloke 0:08cfbae05724 34 #include "mbed.h"
SomeRandomBloke 0:08cfbae05724 35 #include "Adafruit_GFX.h"
SomeRandomBloke 0:08cfbae05724 36 #include "glcdfont.h"
SomeRandomBloke 0:08cfbae05724 37
SomeRandomBloke 1:e67555532f16 38 Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h): WIDTH(w), HEIGHT(h) {
SomeRandomBloke 1:e67555532f16 39
SomeRandomBloke 1:e67555532f16 40 _width = WIDTH;
SomeRandomBloke 1:e67555532f16 41 _height = HEIGHT;
SomeRandomBloke 0:08cfbae05724 42
SomeRandomBloke 0:08cfbae05724 43 rotation = 0;
SomeRandomBloke 0:08cfbae05724 44 cursor_y = cursor_x = 0;
SomeRandomBloke 0:08cfbae05724 45 textsize = 1;
SomeRandomBloke 0:08cfbae05724 46 textcolor = textbgcolor = 0xFFFF;
SomeRandomBloke 0:08cfbae05724 47 wrap = true;
SomeRandomBloke 0:08cfbae05724 48 }
SomeRandomBloke 0:08cfbae05724 49
SomeRandomBloke 0:08cfbae05724 50
SomeRandomBloke 0:08cfbae05724 51 // draw a circle outline
SomeRandomBloke 0:08cfbae05724 52 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
SomeRandomBloke 0:08cfbae05724 53 uint16_t color) {
SomeRandomBloke 0:08cfbae05724 54 int16_t f = 1 - r;
SomeRandomBloke 0:08cfbae05724 55 int16_t ddF_x = 1;
SomeRandomBloke 0:08cfbae05724 56 int16_t ddF_y = -2 * r;
SomeRandomBloke 0:08cfbae05724 57 int16_t x = 0;
SomeRandomBloke 0:08cfbae05724 58 int16_t y = r;
SomeRandomBloke 0:08cfbae05724 59
SomeRandomBloke 0:08cfbae05724 60 drawPixel(x0, y0+r, color);
SomeRandomBloke 0:08cfbae05724 61 drawPixel(x0, y0-r, color);
SomeRandomBloke 0:08cfbae05724 62 drawPixel(x0+r, y0, color);
SomeRandomBloke 0:08cfbae05724 63 drawPixel(x0-r, y0, color);
SomeRandomBloke 0:08cfbae05724 64
SomeRandomBloke 0:08cfbae05724 65 while (x<y) {
SomeRandomBloke 0:08cfbae05724 66 if (f >= 0) {
SomeRandomBloke 0:08cfbae05724 67 y--;
SomeRandomBloke 0:08cfbae05724 68 ddF_y += 2;
SomeRandomBloke 0:08cfbae05724 69 f += ddF_y;
SomeRandomBloke 0:08cfbae05724 70 }
SomeRandomBloke 0:08cfbae05724 71 x++;
SomeRandomBloke 0:08cfbae05724 72 ddF_x += 2;
SomeRandomBloke 0:08cfbae05724 73 f += ddF_x;
SomeRandomBloke 0:08cfbae05724 74
SomeRandomBloke 0:08cfbae05724 75 drawPixel(x0 + x, y0 + y, color);
SomeRandomBloke 0:08cfbae05724 76 drawPixel(x0 - x, y0 + y, color);
SomeRandomBloke 0:08cfbae05724 77 drawPixel(x0 + x, y0 - y, color);
SomeRandomBloke 0:08cfbae05724 78 drawPixel(x0 - x, y0 - y, color);
SomeRandomBloke 0:08cfbae05724 79 drawPixel(x0 + y, y0 + x, color);
SomeRandomBloke 0:08cfbae05724 80 drawPixel(x0 - y, y0 + x, color);
SomeRandomBloke 0:08cfbae05724 81 drawPixel(x0 + y, y0 - x, color);
SomeRandomBloke 0:08cfbae05724 82 drawPixel(x0 - y, y0 - x, color);
SomeRandomBloke 0:08cfbae05724 83
SomeRandomBloke 0:08cfbae05724 84 }
SomeRandomBloke 0:08cfbae05724 85 }
SomeRandomBloke 0:08cfbae05724 86
SomeRandomBloke 0:08cfbae05724 87 void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0,
SomeRandomBloke 0:08cfbae05724 88 int16_t r, uint8_t cornername, uint16_t color) {
SomeRandomBloke 0:08cfbae05724 89 int16_t f = 1 - r;
SomeRandomBloke 0:08cfbae05724 90 int16_t ddF_x = 1;
SomeRandomBloke 0:08cfbae05724 91 int16_t ddF_y = -2 * r;
SomeRandomBloke 0:08cfbae05724 92 int16_t x = 0;
SomeRandomBloke 0:08cfbae05724 93 int16_t y = r;
SomeRandomBloke 0:08cfbae05724 94
SomeRandomBloke 0:08cfbae05724 95 while (x<y) {
SomeRandomBloke 0:08cfbae05724 96 if (f >= 0) {
SomeRandomBloke 0:08cfbae05724 97 y--;
SomeRandomBloke 0:08cfbae05724 98 ddF_y += 2;
SomeRandomBloke 0:08cfbae05724 99 f += ddF_y;
SomeRandomBloke 0:08cfbae05724 100 }
SomeRandomBloke 0:08cfbae05724 101 x++;
SomeRandomBloke 0:08cfbae05724 102 ddF_x += 2;
SomeRandomBloke 0:08cfbae05724 103 f += ddF_x;
SomeRandomBloke 0:08cfbae05724 104 if (cornername & 0x4) {
SomeRandomBloke 0:08cfbae05724 105 drawPixel(x0 + x, y0 + y, color);
SomeRandomBloke 0:08cfbae05724 106 drawPixel(x0 + y, y0 + x, color);
SomeRandomBloke 0:08cfbae05724 107 }
SomeRandomBloke 0:08cfbae05724 108 if (cornername & 0x2) {
SomeRandomBloke 0:08cfbae05724 109 drawPixel(x0 + x, y0 - y, color);
SomeRandomBloke 0:08cfbae05724 110 drawPixel(x0 + y, y0 - x, color);
SomeRandomBloke 0:08cfbae05724 111 }
SomeRandomBloke 0:08cfbae05724 112 if (cornername & 0x8) {
SomeRandomBloke 0:08cfbae05724 113 drawPixel(x0 - y, y0 + x, color);
SomeRandomBloke 0:08cfbae05724 114 drawPixel(x0 - x, y0 + y, color);
SomeRandomBloke 0:08cfbae05724 115 }
SomeRandomBloke 0:08cfbae05724 116 if (cornername & 0x1) {
SomeRandomBloke 0:08cfbae05724 117 drawPixel(x0 - y, y0 - x, color);
SomeRandomBloke 0:08cfbae05724 118 drawPixel(x0 - x, y0 - y, color);
SomeRandomBloke 0:08cfbae05724 119 }
SomeRandomBloke 0:08cfbae05724 120 }
SomeRandomBloke 0:08cfbae05724 121 }
SomeRandomBloke 0:08cfbae05724 122
SomeRandomBloke 0:08cfbae05724 123 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r,
SomeRandomBloke 0:08cfbae05724 124 uint16_t color) {
SomeRandomBloke 0:08cfbae05724 125 drawFastVLine(x0, y0-r, 2*r+1, color);
SomeRandomBloke 0:08cfbae05724 126 fillCircleHelper(x0, y0, r, 3, 0, color);
SomeRandomBloke 0:08cfbae05724 127 }
SomeRandomBloke 0:08cfbae05724 128
SomeRandomBloke 0:08cfbae05724 129 // used to do circles and roundrects!
SomeRandomBloke 0:08cfbae05724 130 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
SomeRandomBloke 0:08cfbae05724 131 uint8_t cornername, int16_t delta, uint16_t color) {
SomeRandomBloke 0:08cfbae05724 132
SomeRandomBloke 0:08cfbae05724 133 int16_t f = 1 - r;
SomeRandomBloke 0:08cfbae05724 134 int16_t ddF_x = 1;
SomeRandomBloke 0:08cfbae05724 135 int16_t ddF_y = -2 * r;
SomeRandomBloke 0:08cfbae05724 136 int16_t x = 0;
SomeRandomBloke 0:08cfbae05724 137 int16_t y = r;
SomeRandomBloke 0:08cfbae05724 138
SomeRandomBloke 0:08cfbae05724 139 while (x<y) {
SomeRandomBloke 0:08cfbae05724 140 if (f >= 0) {
SomeRandomBloke 0:08cfbae05724 141 y--;
SomeRandomBloke 0:08cfbae05724 142 ddF_y += 2;
SomeRandomBloke 0:08cfbae05724 143 f += ddF_y;
SomeRandomBloke 0:08cfbae05724 144 }
SomeRandomBloke 0:08cfbae05724 145 x++;
SomeRandomBloke 0:08cfbae05724 146 ddF_x += 2;
SomeRandomBloke 0:08cfbae05724 147 f += ddF_x;
SomeRandomBloke 0:08cfbae05724 148
SomeRandomBloke 0:08cfbae05724 149 if (cornername & 0x1) {
SomeRandomBloke 0:08cfbae05724 150 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
SomeRandomBloke 0:08cfbae05724 151 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
SomeRandomBloke 0:08cfbae05724 152 }
SomeRandomBloke 0:08cfbae05724 153 if (cornername & 0x2) {
SomeRandomBloke 0:08cfbae05724 154 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
SomeRandomBloke 0:08cfbae05724 155 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
SomeRandomBloke 0:08cfbae05724 156 }
SomeRandomBloke 0:08cfbae05724 157 }
SomeRandomBloke 0:08cfbae05724 158 }
SomeRandomBloke 0:08cfbae05724 159
SomeRandomBloke 0:08cfbae05724 160 // bresenham's algorithm - thx wikpedia
SomeRandomBloke 0:08cfbae05724 161 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,
SomeRandomBloke 0:08cfbae05724 162 int16_t x1, int16_t y1,
SomeRandomBloke 0:08cfbae05724 163 uint16_t color) {
SomeRandomBloke 0:08cfbae05724 164 int16_t steep = abs(y1 - y0) > abs(x1 - x0);
SomeRandomBloke 0:08cfbae05724 165 if (steep) {
SomeRandomBloke 0:08cfbae05724 166 swap(x0, y0);
SomeRandomBloke 0:08cfbae05724 167 swap(x1, y1);
SomeRandomBloke 0:08cfbae05724 168 }
SomeRandomBloke 0:08cfbae05724 169
SomeRandomBloke 0:08cfbae05724 170 if (x0 > x1) {
SomeRandomBloke 0:08cfbae05724 171 swap(x0, x1);
SomeRandomBloke 0:08cfbae05724 172 swap(y0, y1);
SomeRandomBloke 0:08cfbae05724 173 }
SomeRandomBloke 0:08cfbae05724 174
SomeRandomBloke 0:08cfbae05724 175 int16_t dx, dy;
SomeRandomBloke 0:08cfbae05724 176 dx = x1 - x0;
SomeRandomBloke 0:08cfbae05724 177 dy = abs(y1 - y0);
SomeRandomBloke 0:08cfbae05724 178
SomeRandomBloke 0:08cfbae05724 179 int16_t err = dx / 2;
SomeRandomBloke 0:08cfbae05724 180 int16_t ystep;
SomeRandomBloke 0:08cfbae05724 181
SomeRandomBloke 0:08cfbae05724 182 if (y0 < y1) {
SomeRandomBloke 0:08cfbae05724 183 ystep = 1;
SomeRandomBloke 0:08cfbae05724 184 } else {
SomeRandomBloke 0:08cfbae05724 185 ystep = -1;
SomeRandomBloke 0:08cfbae05724 186 }
SomeRandomBloke 0:08cfbae05724 187
SomeRandomBloke 0:08cfbae05724 188 for (; x0<=x1; x0++) {
SomeRandomBloke 0:08cfbae05724 189 if (steep) {
SomeRandomBloke 0:08cfbae05724 190 drawPixel(y0, x0, color);
SomeRandomBloke 0:08cfbae05724 191 } else {
SomeRandomBloke 0:08cfbae05724 192 drawPixel(x0, y0, color);
SomeRandomBloke 0:08cfbae05724 193 }
SomeRandomBloke 0:08cfbae05724 194 err -= dy;
SomeRandomBloke 0:08cfbae05724 195 if (err < 0) {
SomeRandomBloke 0:08cfbae05724 196 y0 += ystep;
SomeRandomBloke 0:08cfbae05724 197 err += dx;
SomeRandomBloke 0:08cfbae05724 198 }
SomeRandomBloke 0:08cfbae05724 199 }
SomeRandomBloke 0:08cfbae05724 200 }
SomeRandomBloke 0:08cfbae05724 201
SomeRandomBloke 0:08cfbae05724 202
SomeRandomBloke 0:08cfbae05724 203 // draw a rectangle
SomeRandomBloke 0:08cfbae05724 204 void Adafruit_GFX::drawRect(int16_t x, int16_t y,
SomeRandomBloke 0:08cfbae05724 205 int16_t w, int16_t h,
SomeRandomBloke 0:08cfbae05724 206 uint16_t color) {
SomeRandomBloke 0:08cfbae05724 207 drawFastHLine(x, y, w, color);
SomeRandomBloke 0:08cfbae05724 208 drawFastHLine(x, y+h-1, w, color);
SomeRandomBloke 0:08cfbae05724 209 drawFastVLine(x, y, h, color);
SomeRandomBloke 0:08cfbae05724 210 drawFastVLine(x+w-1, y, h, color);
SomeRandomBloke 0:08cfbae05724 211 }
SomeRandomBloke 0:08cfbae05724 212
SomeRandomBloke 0:08cfbae05724 213 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y,
SomeRandomBloke 0:08cfbae05724 214 int16_t h, uint16_t color) {
SomeRandomBloke 0:08cfbae05724 215 // stupidest version - update in subclasses if desired!
SomeRandomBloke 0:08cfbae05724 216 drawLine(x, y, x, y+h-1, color);
SomeRandomBloke 0:08cfbae05724 217 }
SomeRandomBloke 0:08cfbae05724 218
SomeRandomBloke 0:08cfbae05724 219
SomeRandomBloke 0:08cfbae05724 220 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y,
SomeRandomBloke 0:08cfbae05724 221 int16_t w, uint16_t color) {
SomeRandomBloke 0:08cfbae05724 222 // stupidest version - update in subclasses if desired!
SomeRandomBloke 0:08cfbae05724 223 drawLine(x, y, x+w-1, y, color);
SomeRandomBloke 0:08cfbae05724 224 }
SomeRandomBloke 0:08cfbae05724 225
SomeRandomBloke 0:08cfbae05724 226 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
SomeRandomBloke 0:08cfbae05724 227 uint16_t color) {
SomeRandomBloke 0:08cfbae05724 228 // stupidest version - update in subclasses if desired!
SomeRandomBloke 0:08cfbae05724 229 for (int16_t i=x; i<x+w; i++) {
SomeRandomBloke 0:08cfbae05724 230 drawFastVLine(i, y, h, color);
SomeRandomBloke 0:08cfbae05724 231 }
SomeRandomBloke 0:08cfbae05724 232 }
SomeRandomBloke 0:08cfbae05724 233
SomeRandomBloke 0:08cfbae05724 234
SomeRandomBloke 0:08cfbae05724 235 void Adafruit_GFX::fillScreen(uint16_t color) {
SomeRandomBloke 0:08cfbae05724 236 fillRect(0, 0, _width, _height, color);
SomeRandomBloke 0:08cfbae05724 237 }
SomeRandomBloke 0:08cfbae05724 238
SomeRandomBloke 0:08cfbae05724 239 // draw a rounded rectangle!
SomeRandomBloke 0:08cfbae05724 240 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w,
SomeRandomBloke 0:08cfbae05724 241 int16_t h, int16_t r, uint16_t color) {
SomeRandomBloke 0:08cfbae05724 242 // smarter version
SomeRandomBloke 0:08cfbae05724 243 drawFastHLine(x+r , y , w-2*r, color); // Top
SomeRandomBloke 0:08cfbae05724 244 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom
SomeRandomBloke 0:08cfbae05724 245 drawFastVLine( x , y+r , h-2*r, color); // Left
SomeRandomBloke 0:08cfbae05724 246 drawFastVLine( x+w-1, y+r , h-2*r, color); // Right
SomeRandomBloke 0:08cfbae05724 247 // draw four corners
SomeRandomBloke 0:08cfbae05724 248 drawCircleHelper(x+r , y+r , r, 1, color);
SomeRandomBloke 0:08cfbae05724 249 drawCircleHelper(x+w-r-1, y+r , r, 2, color);
SomeRandomBloke 0:08cfbae05724 250 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
SomeRandomBloke 0:08cfbae05724 251 drawCircleHelper(x+r , y+h-r-1, r, 8, color);
SomeRandomBloke 0:08cfbae05724 252 }
SomeRandomBloke 0:08cfbae05724 253
SomeRandomBloke 0:08cfbae05724 254 // fill a rounded rectangle!
SomeRandomBloke 0:08cfbae05724 255 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w,
SomeRandomBloke 0:08cfbae05724 256 int16_t h, int16_t r, uint16_t color) {
SomeRandomBloke 0:08cfbae05724 257 // smarter version
SomeRandomBloke 0:08cfbae05724 258 fillRect(x+r, y, w-2*r, h, color);
SomeRandomBloke 0:08cfbae05724 259
SomeRandomBloke 0:08cfbae05724 260 // draw four corners
SomeRandomBloke 0:08cfbae05724 261 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
SomeRandomBloke 0:08cfbae05724 262 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color);
SomeRandomBloke 0:08cfbae05724 263 }
SomeRandomBloke 0:08cfbae05724 264
SomeRandomBloke 0:08cfbae05724 265 // draw a triangle!
SomeRandomBloke 0:08cfbae05724 266 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0,
SomeRandomBloke 0:08cfbae05724 267 int16_t x1, int16_t y1,
SomeRandomBloke 0:08cfbae05724 268 int16_t x2, int16_t y2, uint16_t color) {
SomeRandomBloke 0:08cfbae05724 269 drawLine(x0, y0, x1, y1, color);
SomeRandomBloke 0:08cfbae05724 270 drawLine(x1, y1, x2, y2, color);
SomeRandomBloke 0:08cfbae05724 271 drawLine(x2, y2, x0, y0, color);
SomeRandomBloke 0:08cfbae05724 272 }
SomeRandomBloke 0:08cfbae05724 273
SomeRandomBloke 0:08cfbae05724 274 // fill a triangle!
SomeRandomBloke 0:08cfbae05724 275 void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0,
SomeRandomBloke 0:08cfbae05724 276 int16_t x1, int16_t y1,
SomeRandomBloke 0:08cfbae05724 277 int16_t x2, int16_t y2, uint16_t color) {
SomeRandomBloke 0:08cfbae05724 278
SomeRandomBloke 0:08cfbae05724 279 int16_t a, b, y, last;
SomeRandomBloke 0:08cfbae05724 280
SomeRandomBloke 0:08cfbae05724 281 // Sort coordinates by Y order (y2 >= y1 >= y0)
SomeRandomBloke 0:08cfbae05724 282 if (y0 > y1) {
SomeRandomBloke 0:08cfbae05724 283 swap(y0, y1); swap(x0, x1);
SomeRandomBloke 0:08cfbae05724 284 }
SomeRandomBloke 0:08cfbae05724 285 if (y1 > y2) {
SomeRandomBloke 0:08cfbae05724 286 swap(y2, y1); swap(x2, x1);
SomeRandomBloke 0:08cfbae05724 287 }
SomeRandomBloke 0:08cfbae05724 288 if (y0 > y1) {
SomeRandomBloke 0:08cfbae05724 289 swap(y0, y1); swap(x0, x1);
SomeRandomBloke 0:08cfbae05724 290 }
SomeRandomBloke 0:08cfbae05724 291
SomeRandomBloke 0:08cfbae05724 292 if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
SomeRandomBloke 0:08cfbae05724 293 a = b = x0;
SomeRandomBloke 0:08cfbae05724 294 if(x1 < a) a = x1;
SomeRandomBloke 0:08cfbae05724 295 else if(x1 > b) b = x1;
SomeRandomBloke 0:08cfbae05724 296 if(x2 < a) a = x2;
SomeRandomBloke 0:08cfbae05724 297 else if(x2 > b) b = x2;
SomeRandomBloke 0:08cfbae05724 298 drawFastHLine(a, y0, b-a+1, color);
SomeRandomBloke 0:08cfbae05724 299 return;
SomeRandomBloke 0:08cfbae05724 300 }
SomeRandomBloke 0:08cfbae05724 301
SomeRandomBloke 0:08cfbae05724 302 int16_t
SomeRandomBloke 0:08cfbae05724 303 dx01 = x1 - x0,
SomeRandomBloke 0:08cfbae05724 304 dy01 = y1 - y0,
SomeRandomBloke 0:08cfbae05724 305 dx02 = x2 - x0,
SomeRandomBloke 0:08cfbae05724 306 dy02 = y2 - y0,
SomeRandomBloke 0:08cfbae05724 307 dx12 = x2 - x1,
SomeRandomBloke 0:08cfbae05724 308 dy12 = y2 - y1,
SomeRandomBloke 0:08cfbae05724 309 sa = 0,
SomeRandomBloke 0:08cfbae05724 310 sb = 0;
SomeRandomBloke 0:08cfbae05724 311
SomeRandomBloke 0:08cfbae05724 312 // For upper part of triangle, find scanline crossings for segments
SomeRandomBloke 0:08cfbae05724 313 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
SomeRandomBloke 0:08cfbae05724 314 // is included here (and second loop will be skipped, avoiding a /0
SomeRandomBloke 0:08cfbae05724 315 // error there), otherwise scanline y1 is skipped here and handled
SomeRandomBloke 0:08cfbae05724 316 // in the second loop...which also avoids a /0 error here if y0=y1
SomeRandomBloke 0:08cfbae05724 317 // (flat-topped triangle).
SomeRandomBloke 0:08cfbae05724 318 if(y1 == y2) last = y1; // Include y1 scanline
SomeRandomBloke 0:08cfbae05724 319 else last = y1-1; // Skip it
SomeRandomBloke 0:08cfbae05724 320
SomeRandomBloke 0:08cfbae05724 321 for(y=y0; y<=last; y++) {
SomeRandomBloke 0:08cfbae05724 322 a = x0 + sa / dy01;
SomeRandomBloke 0:08cfbae05724 323 b = x0 + sb / dy02;
SomeRandomBloke 0:08cfbae05724 324 sa += dx01;
SomeRandomBloke 0:08cfbae05724 325 sb += dx02;
SomeRandomBloke 0:08cfbae05724 326 /* longhand:
SomeRandomBloke 0:08cfbae05724 327 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
SomeRandomBloke 0:08cfbae05724 328 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
SomeRandomBloke 0:08cfbae05724 329 */
SomeRandomBloke 0:08cfbae05724 330 if(a > b) swap(a,b);
SomeRandomBloke 0:08cfbae05724 331 drawFastHLine(a, y, b-a+1, color);
SomeRandomBloke 0:08cfbae05724 332 }
SomeRandomBloke 0:08cfbae05724 333
SomeRandomBloke 0:08cfbae05724 334 // For lower part of triangle, find scanline crossings for segments
SomeRandomBloke 0:08cfbae05724 335 // 0-2 and 1-2. This loop is skipped if y1=y2.
SomeRandomBloke 0:08cfbae05724 336 sa = dx12 * (y - y1);
SomeRandomBloke 0:08cfbae05724 337 sb = dx02 * (y - y0);
SomeRandomBloke 0:08cfbae05724 338 for(; y<=y2; y++) {
SomeRandomBloke 0:08cfbae05724 339 a = x1 + sa / dy12;
SomeRandomBloke 0:08cfbae05724 340 b = x0 + sb / dy02;
SomeRandomBloke 0:08cfbae05724 341 sa += dx12;
SomeRandomBloke 0:08cfbae05724 342 sb += dx02;
SomeRandomBloke 0:08cfbae05724 343 /* longhand:
SomeRandomBloke 0:08cfbae05724 344 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
SomeRandomBloke 0:08cfbae05724 345 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
SomeRandomBloke 0:08cfbae05724 346 */
SomeRandomBloke 0:08cfbae05724 347 if(a > b) swap(a,b);
SomeRandomBloke 0:08cfbae05724 348 drawFastHLine(a, y, b-a+1, color);
SomeRandomBloke 0:08cfbae05724 349 }
SomeRandomBloke 0:08cfbae05724 350 }
SomeRandomBloke 0:08cfbae05724 351
SomeRandomBloke 0:08cfbae05724 352 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
SomeRandomBloke 0:08cfbae05724 353 const uint8_t *bitmap, int16_t w, int16_t h,
SomeRandomBloke 0:08cfbae05724 354 uint16_t color) {
SomeRandomBloke 0:08cfbae05724 355
SomeRandomBloke 0:08cfbae05724 356 int16_t i, j, byteWidth = (w + 7) / 8;
SomeRandomBloke 0:08cfbae05724 357
SomeRandomBloke 0:08cfbae05724 358 for(j=0; j<h; j++) {
SomeRandomBloke 0:08cfbae05724 359 for(i=0; i<w; i++ ) {
SomeRandomBloke 0:08cfbae05724 360 // if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) {
SomeRandomBloke 0:08cfbae05724 361 if(bitmap[ j * byteWidth + i / 8] & (128 >> (i & 7))) {
SomeRandomBloke 0:08cfbae05724 362 drawPixel(x+i, y+j, color);
SomeRandomBloke 0:08cfbae05724 363 }
SomeRandomBloke 0:08cfbae05724 364 }
SomeRandomBloke 0:08cfbae05724 365 }
SomeRandomBloke 0:08cfbae05724 366 }
SomeRandomBloke 0:08cfbae05724 367
SomeRandomBloke 0:08cfbae05724 368 int Adafruit_GFX::_putc(int c) {
SomeRandomBloke 0:08cfbae05724 369 if (c == '\n') {
SomeRandomBloke 0:08cfbae05724 370 cursor_y += textsize*8;
SomeRandomBloke 0:08cfbae05724 371 cursor_x = 0;
SomeRandomBloke 0:08cfbae05724 372 } else if (c == '\r') {
SomeRandomBloke 0:08cfbae05724 373 // skip em
SomeRandomBloke 0:08cfbae05724 374 } else {
SomeRandomBloke 0:08cfbae05724 375 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
SomeRandomBloke 0:08cfbae05724 376 cursor_x += textsize*6;
SomeRandomBloke 0:08cfbae05724 377 if (wrap && (cursor_x > (_width - textsize*6))) {
SomeRandomBloke 0:08cfbae05724 378 cursor_y += textsize*8;
SomeRandomBloke 0:08cfbae05724 379 cursor_x = 0;
SomeRandomBloke 0:08cfbae05724 380 }
SomeRandomBloke 0:08cfbae05724 381 }
SomeRandomBloke 0:08cfbae05724 382
SomeRandomBloke 0:08cfbae05724 383 return c;
SomeRandomBloke 0:08cfbae05724 384 }
SomeRandomBloke 0:08cfbae05724 385 int Adafruit_GFX::_getc() {
SomeRandomBloke 0:08cfbae05724 386 return -1;
SomeRandomBloke 0:08cfbae05724 387 }
SomeRandomBloke 0:08cfbae05724 388
SomeRandomBloke 0:08cfbae05724 389 // draw a character
SomeRandomBloke 0:08cfbae05724 390 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
SomeRandomBloke 0:08cfbae05724 391 uint16_t color, uint16_t bg, uint8_t size) {
SomeRandomBloke 0:08cfbae05724 392
SomeRandomBloke 0:08cfbae05724 393 if((x >= _width) || // Clip right
SomeRandomBloke 0:08cfbae05724 394 (y >= _height) || // Clip bottom
SomeRandomBloke 1:e67555532f16 395 ((x + 6 * size - 1) < 0) || // Clip left
SomeRandomBloke 0:08cfbae05724 396 ((y + 8 * size - 1) < 0)) // Clip top
SomeRandomBloke 0:08cfbae05724 397 return;
SomeRandomBloke 0:08cfbae05724 398
SomeRandomBloke 0:08cfbae05724 399 for (int8_t i=0; i<6; i++ ) {
SomeRandomBloke 0:08cfbae05724 400 uint8_t line;
SomeRandomBloke 0:08cfbae05724 401 if (i == 5)
SomeRandomBloke 0:08cfbae05724 402 line = 0x0;
SomeRandomBloke 0:08cfbae05724 403 else
SomeRandomBloke 0:08cfbae05724 404 line = font[(c*5)+i];
SomeRandomBloke 0:08cfbae05724 405 for (int8_t j = 0; j<8; j++) {
SomeRandomBloke 0:08cfbae05724 406 if (line & 0x1) {
SomeRandomBloke 0:08cfbae05724 407 if (size == 1) // default size
SomeRandomBloke 0:08cfbae05724 408 drawPixel(x+i, y+j, color);
SomeRandomBloke 0:08cfbae05724 409 else { // big size
SomeRandomBloke 0:08cfbae05724 410 fillRect(x+(i*size), y+(j*size), size, size, color);
SomeRandomBloke 0:08cfbae05724 411 }
SomeRandomBloke 0:08cfbae05724 412 } else if (bg != color) {
SomeRandomBloke 0:08cfbae05724 413 if (size == 1) // default size
SomeRandomBloke 0:08cfbae05724 414 drawPixel(x+i, y+j, bg);
SomeRandomBloke 0:08cfbae05724 415 else { // big size
SomeRandomBloke 0:08cfbae05724 416 fillRect(x+i*size, y+j*size, size, size, bg);
SomeRandomBloke 0:08cfbae05724 417 }
SomeRandomBloke 0:08cfbae05724 418 }
SomeRandomBloke 0:08cfbae05724 419 line >>= 1;
SomeRandomBloke 0:08cfbae05724 420 }
SomeRandomBloke 0:08cfbae05724 421 }
SomeRandomBloke 0:08cfbae05724 422 }
SomeRandomBloke 0:08cfbae05724 423
SomeRandomBloke 0:08cfbae05724 424 void Adafruit_GFX::setCursor(int16_t x, int16_t y) {
SomeRandomBloke 0:08cfbae05724 425 cursor_x = x;
SomeRandomBloke 0:08cfbae05724 426 cursor_y = y;
SomeRandomBloke 0:08cfbae05724 427 }
SomeRandomBloke 0:08cfbae05724 428
SomeRandomBloke 0:08cfbae05724 429
SomeRandomBloke 0:08cfbae05724 430 void Adafruit_GFX::setTextSize(uint8_t s) {
SomeRandomBloke 0:08cfbae05724 431 textsize = (s > 0) ? s : 1;
SomeRandomBloke 0:08cfbae05724 432 }
SomeRandomBloke 0:08cfbae05724 433
SomeRandomBloke 0:08cfbae05724 434
SomeRandomBloke 0:08cfbae05724 435 void Adafruit_GFX::setTextColor(uint16_t c) {
SomeRandomBloke 0:08cfbae05724 436 textcolor = c;
SomeRandomBloke 0:08cfbae05724 437 textbgcolor = c;
SomeRandomBloke 0:08cfbae05724 438 // for 'transparent' background, we'll set the bg
SomeRandomBloke 0:08cfbae05724 439 // to the same as fg instead of using a flag
SomeRandomBloke 0:08cfbae05724 440 }
SomeRandomBloke 0:08cfbae05724 441
SomeRandomBloke 0:08cfbae05724 442 void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
SomeRandomBloke 0:08cfbae05724 443 textcolor = c;
SomeRandomBloke 0:08cfbae05724 444 textbgcolor = b;
SomeRandomBloke 0:08cfbae05724 445 }
SomeRandomBloke 0:08cfbae05724 446
SomeRandomBloke 0:08cfbae05724 447 void Adafruit_GFX::setTextWrap(boolean w) {
SomeRandomBloke 0:08cfbae05724 448 wrap = w;
SomeRandomBloke 0:08cfbae05724 449 }
SomeRandomBloke 0:08cfbae05724 450
SomeRandomBloke 0:08cfbae05724 451 uint8_t Adafruit_GFX::getRotation(void) {
SomeRandomBloke 0:08cfbae05724 452 rotation %= 4;
SomeRandomBloke 0:08cfbae05724 453 return rotation;
SomeRandomBloke 0:08cfbae05724 454 }
SomeRandomBloke 0:08cfbae05724 455
SomeRandomBloke 0:08cfbae05724 456 void Adafruit_GFX::setRotation(uint8_t x) {
SomeRandomBloke 0:08cfbae05724 457 x %= 4; // cant be higher than 3
SomeRandomBloke 0:08cfbae05724 458 rotation = x;
SomeRandomBloke 0:08cfbae05724 459 switch (x) {
SomeRandomBloke 0:08cfbae05724 460 case 0:
SomeRandomBloke 0:08cfbae05724 461 case 2:
SomeRandomBloke 0:08cfbae05724 462 _width = WIDTH;
SomeRandomBloke 0:08cfbae05724 463 _height = HEIGHT;
SomeRandomBloke 0:08cfbae05724 464 break;
SomeRandomBloke 0:08cfbae05724 465 case 1:
SomeRandomBloke 0:08cfbae05724 466 case 3:
SomeRandomBloke 0:08cfbae05724 467 _width = HEIGHT;
SomeRandomBloke 0:08cfbae05724 468 _height = WIDTH;
SomeRandomBloke 0:08cfbae05724 469 break;
SomeRandomBloke 0:08cfbae05724 470 }
SomeRandomBloke 0:08cfbae05724 471 }
SomeRandomBloke 0:08cfbae05724 472
SomeRandomBloke 0:08cfbae05724 473
SomeRandomBloke 0:08cfbae05724 474 void Adafruit_GFX::invertDisplay(boolean i) {
SomeRandomBloke 0:08cfbae05724 475 // do nothing, can be subclassed
SomeRandomBloke 0:08cfbae05724 476 }
SomeRandomBloke 0:08cfbae05724 477
SomeRandomBloke 0:08cfbae05724 478
SomeRandomBloke 0:08cfbae05724 479 // return the size of the display which depends on the rotation!
SomeRandomBloke 0:08cfbae05724 480 int16_t Adafruit_GFX::width(void) {
SomeRandomBloke 0:08cfbae05724 481 return _width;
SomeRandomBloke 0:08cfbae05724 482 }
SomeRandomBloke 0:08cfbae05724 483
SomeRandomBloke 0:08cfbae05724 484 int16_t Adafruit_GFX::height(void) {
SomeRandomBloke 0:08cfbae05724 485 return _height;
SomeRandomBloke 0:08cfbae05724 486 }
justinkim 4:256d9b541ab0 487