source: rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/lib/Adafruit_GFX.cpp@ 175

Last change on this file since 175 was 175, checked in by ertl-honda, 8 years ago

ライブラリを Arduino IDE 1.7.9 にupdate

File size: 15.8 KB
Line 
1/*
2This is the core graphics library for all our displays, providing a common
3set of graphics primitives (points, lines, circles, etc.). It needs to be
4paired with a hardware-specific library for each display device we carry
5(to handle the lower-level functions).
6
7Adafruit invests time and resources providing this open source code, please
8support Adafruit & open-source hardware by purchasing products from Adafruit!
9
10Copyright (c) 2013 Adafruit Industries. All rights reserved.
11
12Redistribution and use in source and binary forms, with or without
13modification, are permitted provided that the following conditions are met:
14
15- Redistributions of source code must retain the above copyright notice,
16 this list of conditions and the following disclaimer.
17- Redistributions in binary form must reproduce the above copyright notice,
18 this list of conditions and the following disclaimer in the documentation
19 and/or other materials provided with the distribution.
20
21THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31POSSIBILITY OF SUCH DAMAGE.
32*/
33
34#include "Adafruit_GFX.h"
35#include "glcdfont.c"
36#ifdef __AVR__
37 #include <avr/pgmspace.h>
38#elif defined(ESP8266)
39 #include <pgmspace.h>
40#else
41 #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
42#endif
43
44#ifndef min
45 #define min(a,b) ((a < b) ? a : b)
46#endif
47
48Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h):
49 WIDTH(w), HEIGHT(h)
50{
51 _width = WIDTH;
52 _height = HEIGHT;
53 rotation = 0;
54 cursor_y = cursor_x = 0;
55 textsize = 1;
56 textcolor = textbgcolor = 0xFFFF;
57 wrap = true;
58 _cp437 = false;
59}
60
61// Draw a circle outline
62void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
63 uint16_t color) {
64 int16_t f = 1 - r;
65 int16_t ddF_x = 1;
66 int16_t ddF_y = -2 * r;
67 int16_t x = 0;
68 int16_t y = r;
69
70 drawPixel(x0 , y0+r, color);
71 drawPixel(x0 , y0-r, color);
72 drawPixel(x0+r, y0 , color);
73 drawPixel(x0-r, y0 , color);
74
75 while (x<y) {
76 if (f >= 0) {
77 y--;
78 ddF_y += 2;
79 f += ddF_y;
80 }
81 x++;
82 ddF_x += 2;
83 f += ddF_x;
84
85 drawPixel(x0 + x, y0 + y, color);
86 drawPixel(x0 - x, y0 + y, color);
87 drawPixel(x0 + x, y0 - y, color);
88 drawPixel(x0 - x, y0 - y, color);
89 drawPixel(x0 + y, y0 + x, color);
90 drawPixel(x0 - y, y0 + x, color);
91 drawPixel(x0 + y, y0 - x, color);
92 drawPixel(x0 - y, y0 - x, color);
93 }
94}
95
96void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0,
97 int16_t r, uint8_t cornername, uint16_t color) {
98 int16_t f = 1 - r;
99 int16_t ddF_x = 1;
100 int16_t ddF_y = -2 * r;
101 int16_t x = 0;
102 int16_t y = r;
103
104 while (x<y) {
105 if (f >= 0) {
106 y--;
107 ddF_y += 2;
108 f += ddF_y;
109 }
110 x++;
111 ddF_x += 2;
112 f += ddF_x;
113 if (cornername & 0x4) {
114 drawPixel(x0 + x, y0 + y, color);
115 drawPixel(x0 + y, y0 + x, color);
116 }
117 if (cornername & 0x2) {
118 drawPixel(x0 + x, y0 - y, color);
119 drawPixel(x0 + y, y0 - x, color);
120 }
121 if (cornername & 0x8) {
122 drawPixel(x0 - y, y0 + x, color);
123 drawPixel(x0 - x, y0 + y, color);
124 }
125 if (cornername & 0x1) {
126 drawPixel(x0 - y, y0 - x, color);
127 drawPixel(x0 - x, y0 - y, color);
128 }
129 }
130}
131
132void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r,
133 uint16_t color) {
134 drawFastVLine(x0, y0-r, 2*r+1, color);
135 fillCircleHelper(x0, y0, r, 3, 0, color);
136}
137
138// Used to do circles and roundrects
139void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
140 uint8_t cornername, int16_t delta, uint16_t color) {
141
142 int16_t f = 1 - r;
143 int16_t ddF_x = 1;
144 int16_t ddF_y = -2 * r;
145 int16_t x = 0;
146 int16_t y = r;
147
148 while (x<y) {
149 if (f >= 0) {
150 y--;
151 ddF_y += 2;
152 f += ddF_y;
153 }
154 x++;
155 ddF_x += 2;
156 f += ddF_x;
157
158 if (cornername & 0x1) {
159 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
160 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
161 }
162 if (cornername & 0x2) {
163 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
164 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
165 }
166 }
167}
168
169// Bresenham's algorithm - thx wikpedia
170void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,
171 int16_t x1, int16_t y1,
172 uint16_t color) {
173 int16_t steep = abs(y1 - y0) > abs(x1 - x0);
174 if (steep) {
175 swap(x0, y0);
176 swap(x1, y1);
177 }
178
179 if (x0 > x1) {
180 swap(x0, x1);
181 swap(y0, y1);
182 }
183
184 int16_t dx, dy;
185 dx = x1 - x0;
186 dy = abs(y1 - y0);
187
188 int16_t err = dx / 2;
189 int16_t ystep;
190
191 if (y0 < y1) {
192 ystep = 1;
193 } else {
194 ystep = -1;
195 }
196
197 for (; x0<=x1; x0++) {
198 if (steep) {
199 drawPixel(y0, x0, color);
200 } else {
201 drawPixel(x0, y0, color);
202 }
203 err -= dy;
204 if (err < 0) {
205 y0 += ystep;
206 err += dx;
207 }
208 }
209}
210
211// Draw a rectangle
212void Adafruit_GFX::drawRect(int16_t x, int16_t y,
213 int16_t w, int16_t h,
214 uint16_t color) {
215 drawFastHLine(x, y, w, color);
216 drawFastHLine(x, y+h-1, w, color);
217 drawFastVLine(x, y, h, color);
218 drawFastVLine(x+w-1, y, h, color);
219}
220
221void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y,
222 int16_t h, uint16_t color) {
223 // Update in subclasses if desired!
224 drawLine(x, y, x, y+h-1, color);
225}
226
227void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y,
228 int16_t w, uint16_t color) {
229 // Update in subclasses if desired!
230 drawLine(x, y, x+w-1, y, color);
231}
232
233void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
234 uint16_t color) {
235 // Update in subclasses if desired!
236 for (int16_t i=x; i<x+w; i++) {
237 drawFastVLine(i, y, h, color);
238 }
239}
240
241void Adafruit_GFX::fillScreen(uint16_t color) {
242 fillRect(0, 0, _width, _height, color);
243}
244
245// Draw a rounded rectangle
246void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w,
247 int16_t h, int16_t r, uint16_t color) {
248 // smarter version
249 drawFastHLine(x+r , y , w-2*r, color); // Top
250 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom
251 drawFastVLine(x , y+r , h-2*r, color); // Left
252 drawFastVLine(x+w-1, y+r , h-2*r, color); // Right
253 // draw four corners
254 drawCircleHelper(x+r , y+r , r, 1, color);
255 drawCircleHelper(x+w-r-1, y+r , r, 2, color);
256 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
257 drawCircleHelper(x+r , y+h-r-1, r, 8, color);
258}
259
260// Fill a rounded rectangle
261void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w,
262 int16_t h, int16_t r, uint16_t color) {
263 // smarter version
264 fillRect(x+r, y, w-2*r, h, color);
265
266 // draw four corners
267 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
268 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color);
269}
270
271// Draw a triangle
272void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0,
273 int16_t x1, int16_t y1,
274 int16_t x2, int16_t y2, uint16_t color) {
275 drawLine(x0, y0, x1, y1, color);
276 drawLine(x1, y1, x2, y2, color);
277 drawLine(x2, y2, x0, y0, color);
278}
279
280// Fill a triangle
281void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0,
282 int16_t x1, int16_t y1,
283 int16_t x2, int16_t y2, uint16_t color) {
284
285 int16_t a, b, y, last;
286
287 // Sort coordinates by Y order (y2 >= y1 >= y0)
288 if (y0 > y1) {
289 swap(y0, y1); swap(x0, x1);
290 }
291 if (y1 > y2) {
292 swap(y2, y1); swap(x2, x1);
293 }
294 if (y0 > y1) {
295 swap(y0, y1); swap(x0, x1);
296 }
297
298 if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
299 a = b = x0;
300 if(x1 < a) a = x1;
301 else if(x1 > b) b = x1;
302 if(x2 < a) a = x2;
303 else if(x2 > b) b = x2;
304 drawFastHLine(a, y0, b-a+1, color);
305 return;
306 }
307
308 int16_t
309 dx01 = x1 - x0,
310 dy01 = y1 - y0,
311 dx02 = x2 - x0,
312 dy02 = y2 - y0,
313 dx12 = x2 - x1,
314 dy12 = y2 - y1;
315 int32_t
316 sa = 0,
317 sb = 0;
318
319 // For upper part of triangle, find scanline crossings for segments
320 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
321 // is included here (and second loop will be skipped, avoiding a /0
322 // error there), otherwise scanline y1 is skipped here and handled
323 // in the second loop...which also avoids a /0 error here if y0=y1
324 // (flat-topped triangle).
325 if(y1 == y2) last = y1; // Include y1 scanline
326 else last = y1-1; // Skip it
327
328 for(y=y0; y<=last; y++) {
329 a = x0 + sa / dy01;
330 b = x0 + sb / dy02;
331 sa += dx01;
332 sb += dx02;
333 /* longhand:
334 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
335 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
336 */
337 if(a > b) swap(a,b);
338 drawFastHLine(a, y, b-a+1, color);
339 }
340
341 // For lower part of triangle, find scanline crossings for segments
342 // 0-2 and 1-2. This loop is skipped if y1=y2.
343 sa = dx12 * (y - y1);
344 sb = dx02 * (y - y0);
345 for(; y<=y2; y++) {
346 a = x1 + sa / dy12;
347 b = x0 + sb / dy02;
348 sa += dx12;
349 sb += dx02;
350 /* longhand:
351 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
352 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
353 */
354 if(a > b) swap(a,b);
355 drawFastHLine(a, y, b-a+1, color);
356 }
357}
358
359void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
360 const uint8_t *bitmap, int16_t w, int16_t h,
361 uint16_t color) {
362
363 int16_t i, j, byteWidth = (w + 7) / 8;
364
365 for(j=0; j<h; j++) {
366 for(i=0; i<w; i++ ) {
367 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) {
368 drawPixel(x+i, y+j, color);
369 }
370 }
371 }
372}
373
374// Draw a 1-bit color bitmap at the specified x, y position from the
375// provided bitmap buffer (must be PROGMEM memory) using color as the
376// foreground color and bg as the background color.
377void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
378 const uint8_t *bitmap, int16_t w, int16_t h,
379 uint16_t color, uint16_t bg) {
380
381 int16_t i, j, byteWidth = (w + 7) / 8;
382
383 for(j=0; j<h; j++) {
384 for(i=0; i<w; i++ ) {
385 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) {
386 drawPixel(x+i, y+j, color);
387 }
388 else {
389 drawPixel(x+i, y+j, bg);
390 }
391 }
392 }
393}
394
395//Draw XBitMap Files (*.xbm), exported from GIMP,
396//Usage: Export from GIMP to *.xbm, rename *.xbm to *.c and open in editor.
397//C Array can be directly used with this function
398void Adafruit_GFX::drawXBitmap(int16_t x, int16_t y,
399 const uint8_t *bitmap, int16_t w, int16_t h,
400 uint16_t color) {
401
402 int16_t i, j, byteWidth = (w + 7) / 8;
403
404 for(j=0; j<h; j++) {
405 for(i=0; i<w; i++ ) {
406 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (1 << (i % 8))) {
407 drawPixel(x+i, y+j, color);
408 }
409 }
410 }
411}
412
413#if ARDUINO >= 100
414size_t Adafruit_GFX::write(uint8_t c) {
415#else
416void Adafruit_GFX::write(uint8_t c) {
417#endif
418 if (c == '\n') {
419 cursor_y += textsize*8;
420 cursor_x = 0;
421 } else if (c == '\r') {
422 // skip em
423 } else {
424 drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
425 cursor_x += textsize*6;
426 if (wrap && (cursor_x > (_width - textsize*6))) {
427 cursor_y += textsize*8;
428 cursor_x = 0;
429 }
430 }
431#if ARDUINO >= 100
432 return 1;
433#endif
434}
435
436// Draw a character
437void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
438 uint16_t color, uint16_t bg, uint8_t size) {
439
440 if((x >= _width) || // Clip right
441 (y >= _height) || // Clip bottom
442 ((x + 6 * size - 1) < 0) || // Clip left
443 ((y + 8 * size - 1) < 0)) // Clip top
444 return;
445
446 if(!_cp437 && (c >= 176)) c++; // Handle 'classic' charset behavior
447
448 for (int8_t i=0; i<6; i++ ) {
449 uint8_t line;
450 if (i == 5)
451 line = 0x0;
452 else
453 line = pgm_read_byte(font+(c*5)+i);
454 for (int8_t j = 0; j<8; j++) {
455 if (line & 0x1) {
456 if (size == 1) // default size
457 drawPixel(x+i, y+j, color);
458 else { // big size
459 fillRect(x+(i*size), y+(j*size), size, size, color);
460 }
461 } else if (bg != color) {
462 if (size == 1) // default size
463 drawPixel(x+i, y+j, bg);
464 else { // big size
465 fillRect(x+i*size, y+j*size, size, size, bg);
466 }
467 }
468 line >>= 1;
469 }
470 }
471}
472
473void Adafruit_GFX::setCursor(int16_t x, int16_t y) {
474 cursor_x = x;
475 cursor_y = y;
476}
477
478int16_t Adafruit_GFX::getCursorX(void) const {
479 return cursor_x;
480}
481
482int16_t Adafruit_GFX::getCursorY(void) const {
483 return cursor_y;
484}
485
486void Adafruit_GFX::setTextSize(uint8_t s) {
487 textsize = (s > 0) ? s : 1;
488}
489
490void Adafruit_GFX::setTextColor(uint16_t c) {
491 // For 'transparent' background, we'll set the bg
492 // to the same as fg instead of using a flag
493 textcolor = textbgcolor = c;
494}
495
496void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
497 textcolor = c;
498 textbgcolor = b;
499}
500
501void Adafruit_GFX::setTextWrap(boolean w) {
502 wrap = w;
503}
504
505uint8_t Adafruit_GFX::getRotation(void) const {
506 return rotation;
507}
508
509void Adafruit_GFX::setRotation(uint8_t x) {
510 rotation = (x & 3);
511 switch(rotation) {
512 case 0:
513 case 2:
514 _width = WIDTH;
515 _height = HEIGHT;
516 break;
517 case 1:
518 case 3:
519 _width = HEIGHT;
520 _height = WIDTH;
521 break;
522 }
523}
524
525// Enable (or disable) Code Page 437-compatible charset.
526// There was an error in glcdfont.c for the longest time -- one character
527// (#176, the 'light shade' block) was missing -- this threw off the index
528// of every character that followed it. But a TON of code has been written
529// with the erroneous character indices. By default, the library uses the
530// original 'wrong' behavior and old sketches will still work. Pass 'true'
531// to this function to use correct CP437 character values in your code.
532void Adafruit_GFX::cp437(boolean x) {
533 _cp437 = x;
534}
535
536// Return the size of the display (per current rotation)
537int16_t Adafruit_GFX::width(void) const {
538 return _width;
539}
540
541int16_t Adafruit_GFX::height(void) const {
542 return _height;
543}
544
545void Adafruit_GFX::invertDisplay(boolean i) {
546 // Do nothing, must be subclassed if supported
547}
548
549/***************************************************************************/
550// code for the GFX button UI element
551
552Adafruit_GFX_Button::Adafruit_GFX_Button(void) {
553 _gfx = 0;
554}
555
556void Adafruit_GFX_Button::initButton(Adafruit_GFX *gfx,
557 int16_t x, int16_t y,
558 uint8_t w, uint8_t h,
559 uint16_t outline, uint16_t fill,
560 uint16_t textcolor,
561 char *label, uint8_t textsize)
562{
563 _x = x;
564 _y = y;
565 _w = w;
566 _h = h;
567 _outlinecolor = outline;
568 _fillcolor = fill;
569 _textcolor = textcolor;
570 _textsize = textsize;
571 _gfx = gfx;
572 strncpy(_label, label, 9);
573 _label[9] = 0;
574}
575
576
577
578 void Adafruit_GFX_Button::drawButton(boolean inverted) {
579 uint16_t fill, outline, text;
580
581 if (! inverted) {
582 fill = _fillcolor;
583 outline = _outlinecolor;
584 text = _textcolor;
585 } else {
586 fill = _textcolor;
587 outline = _outlinecolor;
588 text = _fillcolor;
589 }
590
591 _gfx->fillRoundRect(_x - (_w/2), _y - (_h/2), _w, _h, min(_w,_h)/4, fill);
592 _gfx->drawRoundRect(_x - (_w/2), _y - (_h/2), _w, _h, min(_w,_h)/4, outline);
593
594
595 _gfx->setCursor(_x - strlen(_label)*3*_textsize, _y-4*_textsize);
596 _gfx->setTextColor(text);
597 _gfx->setTextSize(_textsize);
598 _gfx->print(_label);
599 }
600
601boolean Adafruit_GFX_Button::contains(int16_t x, int16_t y) {
602 if ((x < (_x - _w/2)) || (x > (_x + _w/2))) return false;
603 if ((y < (_y - _h/2)) || (y > (_y + _h/2))) return false;
604 return true;
605 }
606
607
608 void Adafruit_GFX_Button::press(boolean p) {
609 laststate = currstate;
610 currstate = p;
611 }
612
613 boolean Adafruit_GFX_Button::isPressed() { return currstate; }
614 boolean Adafruit_GFX_Button::justPressed() { return (currstate && !laststate); }
615 boolean Adafruit_GFX_Button::justReleased() { return (!currstate && laststate); }
Note: See TracBrowser for help on using the repository browser.