1 /**************************************************************************/
4 @author K. Townsend (microBuilder.eu)
6 drawLine and drawCircle adapted from a tutorial by Leonard McMillan:
7 http://www.cs.unc.edu/~mcmillan/
11 Software License Agreement (BSD License)
13 Copyright (c) 2010, microBuilder SARL
16 Redistribution and use in source and binary forms, with or without
17 modification, are permitted provided that the following conditions are met:
18 1. Redistributions of source code must retain the above copyright
19 notice, this list of conditions and the following disclaimer.
20 2. Redistributions in binary form must reproduce the above copyright
21 notice, this list of conditions and the following disclaimer in the
22 documentation and/or other materials provided with the distribution.
23 3. Neither the name of the copyright holders nor the
24 names of its contributors may be used to endorse or promote products
25 derived from this software without specific prior written permission.
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
28 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
31 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 /**************************************************************************/
43 /**************************************************************************/
45 /* ----------------------- Private Methods ------------------------------ */
47 /**************************************************************************/
49 /**************************************************************************/
51 @brief Swaps values a and b
53 /**************************************************************************/
54 void drawSwap(uint32_t a
, uint32_t b
)
62 #if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1
63 /**************************************************************************/
65 @brief Draws a single smallfont character
67 /**************************************************************************/
68 void drawCharSmall(uint16_t x
, uint16_t y
, uint16_t color
, uint8_t c
, struct FONT_DEF font
)
70 uint8_t col
, column
[font
.u8Width
];
72 // Check if the requested character is available
73 if ((c
>= font
.u8FirstChar
) && (c
<= font
.u8LastChar
))
75 // Retrieve appropriate columns from font data
76 for (col
= 0; col
< font
.u8Width
; col
++)
78 column
[col
] = font
.au8FontTable
[((c
- 32) * font
.u8Width
) + col
]; // Get first column of appropriate character
83 // Requested character is not available in this font ... send a space instead
84 for (col
= 0; col
< font
.u8Width
; col
++)
86 column
[col
] = 0xFF; // Send solid space
91 uint16_t xoffset
, yoffset
;
92 for (xoffset
= 0; xoffset
< font
.u8Width
; xoffset
++)
94 for (yoffset
= 0; yoffset
< (font
.u8Height
+ 1); yoffset
++)
97 bit
= (column
[xoffset
] << (8 - (yoffset
+ 1))); // Shift current row bit left
98 bit
= (bit
>> 7); // Shift current row bit right (results in 0x01 for black, and 0x00 for white)
101 drawPixel(x
+ xoffset
, y
+ yoffset
, color
);
108 /**************************************************************************/
110 /* ----------------------- Public Methods ------------------------------- */
112 /**************************************************************************/
114 /**************************************************************************/
116 @brief Draws a single pixel at the specified location
123 Color used when drawing
125 /**************************************************************************/
126 void drawPixel(uint16_t x
, uint16_t y
, uint16_t color
)
128 if ((x
< lcdGetWidth()) && (y
< lcdGetHeight()))
130 lcdDrawPixel(x
, y
, color
);
134 /**************************************************************************/
136 @brief Fills the screen with the specified color
139 Color used when drawing
141 /**************************************************************************/
142 void drawFill(uint16_t color
)
147 /**************************************************************************/
149 @brief Draws a simple color test pattern
151 /**************************************************************************/
152 void drawTestPattern(void)
157 #if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1
158 /**************************************************************************/
160 @brief Draws a string using a small font (6 of 8 pixels high).
163 Starting x co-ordinate
165 Starting y co-ordinate
167 Color to use when rendering the font
171 Pointer to the FONT_DEF to use when drawing the string
177 #include "drivers/displays/fonts/smallfonts.h"
179 drawStringSmall(1, 210, COLOR_WHITE, "5x8 System (Max 40 Characters)", Font_System5x8);
180 drawStringSmall(1, 220, COLOR_WHITE, "7x8 System (Max 30 Characters)", Font_System7x8);
184 /**************************************************************************/
185 void drawStringSmall(uint16_t x
, uint16_t y
, uint16_t color
, char* text
, struct FONT_DEF font
)
188 for (l
= 0; l
< strlen(text
); l
++)
190 drawCharSmall(x
+ (l
* (font
.u8Width
+ 1)), y
, color
, text
[l
], font
);
195 /**************************************************************************/
197 @brief Draws a bresenham line
200 Starting x co-ordinate
202 Starting y co-ordinate
208 Color used when drawing
210 /**************************************************************************/
211 void drawLine ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
213 drawLineDotted(x0
, y0
, x1
, y1
, 0, 1, color
);
216 /**************************************************************************/
218 @brief Draws a bresenham line with a fixed pattern of empty
221 Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
224 Starting x co-ordinate
226 Starting y co-ordinate
232 The number of 'empty' pixels to render
234 The number of 'solid' pixels to render
236 Color used when drawing
238 /**************************************************************************/
239 void drawLineDotted ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t empty
, uint16_t solid
, uint16_t color
)
241 lcdProperties_t properties
;
243 // Get the LCD properties (to check for HW acceleration in the driver)
244 properties
= lcdGetProperties();
251 // If a negative y int was passed in it will overflow to 65K something
252 // Ugly, but drawCircleFilled() can pass in negative values so we need
253 // to check the values here
254 y0
= y0
> 65000 ? 0 : y0
;
255 y1
= y1
> 65000 ? 0 : y1
;
257 // Check if we can use the optimised horizontal line method
258 if ((y0
== y1
) && (empty
== 0) && properties
.fastHLine
)
260 lcdDrawHLine(x0
, x1
, y0
, color
);
264 // Check if we can use the optimised vertical line method.
265 // This can make a huge difference in performance, but may
266 // not work properly on every LCD controller:
267 if ((x0
== x1
) && (empty
== 0) && properties
.fastVLine
)
269 // Warning: This may actually be slower than drawing individual pixels on
270 // short lines ... Set a minimum line size to use the 'optimised' method
271 // (which changes the screen orientation) ?
272 lcdDrawVLine(x0
, y0
, y1
, color
);
276 // Draw non-horizontal or dotted line
280 int emptycount
, solidcount
;
282 if (dy
< 0) { dy
= -dy
; stepy
= -1; } else { stepy
= 1; }
283 if (dx
< 0) { dx
= -dx
; stepx
= -1; } else { stepx
= 1; }
284 dy
<<= 1; // dy is now 2*dy
285 dx
<<= 1; // dx is now 2*dx
290 drawPixel(x0
, y0
, color
); // always start with solid pixels
294 int fraction
= dy
- (dx
>> 1); // same as 2*dy - dx
300 fraction
-= dx
; // same as fraction -= 2*dx
303 fraction
+= dy
; // same as fraction -= 2*dy
306 // always draw a pixel ... no dotted line requested
307 drawPixel(x0
, y0
, color
);
311 // Draw solid pxiel and decrement counter
312 drawPixel(x0
, y0
, color
);
317 // Empty pixel ... don't draw anything an decrement counter
322 // Reset counters and draw solid pixel
325 drawPixel(x0
, y0
, color
);
332 int fraction
= dx
- (dy
>> 1);
344 // always draw a pixel ... no dotted line requested
345 drawPixel(x0
, y0
, color
);
349 // Draw solid pxiel and decrement counter
350 drawPixel(x0
, y0
, color
);
355 // Empty pixel ... don't draw anything an decrement counter
360 // Reset counters and draw solid pixel
363 drawPixel(x0
, y0
, color
);
370 /**************************************************************************/
372 @brief Draws a circle
374 Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture7/circle.html
377 The horizontal center of the circle
379 The vertical center of the circle
381 The circle's radius in pixels
383 Color used when drawing
385 /**************************************************************************/
386 void drawCircle (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, uint16_t color
)
388 drawPixel(xCenter
, yCenter
+radius
, color
);
389 drawPixel(xCenter
, yCenter
-radius
, color
);
390 drawPixel(xCenter
+radius
, yCenter
, color
);
391 drawPixel(xCenter
-radius
, yCenter
, color
);
392 drawCorner(xCenter
, yCenter
, radius
, DRAW_CORNERS_ALL
, color
);
395 /**************************************************************************/
397 @brief Draws a filled circle
400 The horizontal center of the circle
402 The vertical center of the circle
404 The circle's radius in pixels
406 Color used when drawing
408 /**************************************************************************/
409 void drawCircleFilled (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, uint16_t color
)
411 int16_t f
= 1 - radius
;
413 int16_t ddF_y
= -2 * radius
;
416 int16_t xc_px
, yc_my
, xc_mx
, xc_py
, yc_mx
, xc_my
;
417 int16_t lcdWidth
= lcdGetWidth();
419 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
-radius
, xCenter
, (yCenter
-radius
) + (2*radius
), color
);
440 // Make sure X positions are not negative or too large or the pixels will
441 // overflow. Y overflow is handled in drawLine().
442 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yc_my
, xc_px
, yc_my
+ 2*y
, color
);
443 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yc_my
, xc_mx
, yc_my
+ 2*y
, color
);
444 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yc_mx
, xc_py
, yc_mx
+ 2*x
, color
);
445 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yc_mx
, xc_my
, yc_mx
+ 2*x
, color
);
449 /**************************************************************************/
451 @brief Draws a single 1-pixel wide corner
453 @note Code courtesy Adafruit's excellent GFX lib:
454 https://github.com/adafruit/Adafruit-GFX-Library
457 The horizontal center of the circle
459 The vertical center of the circle
461 The drawCorners_t representing the corner(s) to draw
463 Color used when drawing
469 // Draw a top-left corner with a 10 pixel radius, centered at 20, 20
470 drawCorner(20, 20, 10, DRAW_CORNER_TOPLEFT, COLOR_GRAY_128);
474 /**************************************************************************/
475 void drawCorner (uint16_t xCenter
, uint16_t yCenter
, uint16_t r
, drawCorners_t corner
, uint16_t color
)
479 int16_t ddF_y
= -2 * r
;
494 if (corner
& DRAW_CORNERS_BOTTOMRIGHT
)
496 drawPixel(xCenter
+ x
, yCenter
+ y
, color
);
497 drawPixel(xCenter
+ y
, yCenter
+ x
, color
);
499 if (corner
& DRAW_CORNERS_TOPRIGHT
)
501 drawPixel(xCenter
+ x
, yCenter
- y
, color
);
502 drawPixel(xCenter
+ y
, yCenter
- x
, color
);
504 if (corner
& DRAW_CORNERS_BOTTOMLEFT
)
506 drawPixel(xCenter
- y
, yCenter
+ x
, color
);
507 drawPixel(xCenter
- x
, yCenter
+ y
, color
);
509 if (corner
& DRAW_CORNERS_TOPLEFT
)
511 drawPixel(xCenter
- y
, yCenter
- x
, color
);
512 drawPixel(xCenter
- x
, yCenter
- y
, color
);
517 /**************************************************************************/
519 @brief Draws a filled rounded corner
522 The horizontal center of the circle
524 The vertical center of the circle
526 The circle's radius in pixels
528 The position of the corner, which affects how it will
531 Color used when drawing
533 /**************************************************************************/
534 void drawCornerFilled (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, drawCorners_t position
, uint16_t color
)
536 int16_t f
= 1 - radius
;
538 int16_t ddF_y
= -2 * radius
;
541 int16_t xc_px
, yc_my
, xc_mx
, xc_py
, yc_mx
, xc_my
;
542 int16_t lcdWidth
= lcdGetWidth();
545 if ((position
& DRAW_CORNERS_TOPRIGHT
) || (position
& DRAW_CORNERS_TOPLEFT
))
547 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
-radius
, xCenter
, yCenter
, color
);
549 if ((position
& DRAW_CORNERS_BOTTOMRIGHT
) || (position
& DRAW_CORNERS_BOTTOMLEFT
))
551 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
, xCenter
, (yCenter
-radius
) + (2*radius
), color
);
574 if (position
& DRAW_CORNERS_TOPRIGHT
)
576 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yc_my
, xc_px
, yCenter
, color
);
577 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yc_mx
, xc_py
, yCenter
, color
);
579 if (position
& DRAW_CORNERS_BOTTOMRIGHT
)
581 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yCenter
, xc_px
, yc_my
+ 2*y
, color
);
582 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yCenter
, xc_py
, yc_mx
+ 2*x
, color
);
584 if (position
& DRAW_CORNERS_TOPLEFT
)
586 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yc_my
, xc_mx
, yCenter
, color
);
587 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yc_mx
, xc_my
, yCenter
, color
);
589 if (position
& DRAW_CORNERS_BOTTOMLEFT
)
591 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yCenter
, xc_mx
, yc_my
+ 2*y
, color
);
592 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yCenter
, xc_my
, yc_mx
+ 2*x
, color
);
597 /**************************************************************************/
599 @brief Draws a simple arrow of the specified width
602 X co-ordinate of the smallest point of the arrow
604 Y co-ordinate of the smallest point of the arrow
606 Total width/height of the arrow in pixels
608 The direction that the arrow is pointing
610 Color used when drawing
612 /**************************************************************************/
613 void drawArrow(uint16_t x
, uint16_t y
, uint16_t size
, drawDirection_t direction
, uint16_t color
)
615 drawPixel(x
, y
, color
);
625 case DRAW_DIRECTION_LEFT
:
626 for (i
= 1; i
<size
; i
++)
628 drawLine(x
+i
, y
-i
, x
+i
, y
+i
, color
);
631 case DRAW_DIRECTION_RIGHT
:
632 for (i
= 1; i
<size
; i
++)
634 drawLine(x
-i
, y
-i
, x
-i
, y
+i
, color
);
637 case DRAW_DIRECTION_UP
:
638 for (i
= 1; i
<size
; i
++)
640 drawLine(x
-i
, y
+i
, x
+i
, y
+i
, color
);
643 case DRAW_DIRECTION_DOWN
:
644 for (i
= 1; i
<size
; i
++)
646 drawLine(x
-i
, y
-i
, x
+i
, y
-i
, color
);
654 /**************************************************************************/
656 @brief Draws a simple (empty) rectangle
659 Starting x co-ordinate
661 Starting y co-ordinate
667 Color used when drawing
669 /**************************************************************************/
670 void drawRectangle ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
690 drawLine (x0
, y0
, x1
, y0
, color
);
691 drawLine (x1
, y0
, x1
, y1
, color
);
692 drawLine (x1
, y1
, x0
, y1
, color
);
693 drawLine (x0
, y1
, x0
, y0
, color
);
696 /**************************************************************************/
698 @brief Draws a filled rectangle
701 Starting x co-ordinate
703 Starting y co-ordinate
709 Color used when drawing
711 /**************************************************************************/
712 void drawRectangleFilled ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
734 for (height
= y0
; y1
> height
- 1; ++height
)
736 drawLine(x0
, height
, x1
, height
, color
);
740 /**************************************************************************/
742 @brief Draws a rectangle with rounded corners
745 Starting x co-ordinate
747 Starting y co-ordinate
753 Color used when drawing
755 Corner radius in pixels
757 Which corners to round
762 drawRoundedRectangle ( 10, 10, 200, 200, COLOR_BLACK, 10, DRAW_CORNERS_ALL );
767 /**************************************************************************/
768 void drawRoundedRectangle ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
, uint16_t radius
, drawCorners_t corners
)
773 if (corners
== DRAW_CORNERS_NONE
)
775 drawRectangle(x0
, y0
, x1
, y1
, color
);
789 if (radius
> height
/ 2)
797 case DRAW_CORNERS_ALL
:
798 drawCorner(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
799 drawCorner(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
800 drawCorner(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
801 drawCorner(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
802 if (radius
*2+1 < height
)
804 drawLine(x0
, y0
+radius
, x0
, y1
-radius
, color
);
805 drawLine(x1
, y0
+radius
, x1
, y1
-radius
, color
);
807 drawLine(x0
+radius
, y0
, x1
-radius
, y0
, color
);
808 drawLine(x0
+radius
, y1
, x1
-radius
, y1
, color
);
810 case DRAW_CORNERS_TOP
:
811 drawCorner(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
812 drawCorner(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
813 drawLine(x0
, y0
+radius
, x0
, y1
, color
);
814 drawLine(x0
, y1
, x1
, y1
, color
);
815 drawLine(x1
, y1
, x1
, y0
+radius
, color
);
816 drawLine(x0
+radius
, y0
, x1
-radius
, y0
, color
);
818 case DRAW_CORNERS_BOTTOM
:
819 drawCorner(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
820 drawCorner(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
821 drawLine(x0
, y0
, x1
, y0
, color
);
822 drawLine(x1
, y0
, x1
, y1
-radius
, color
);
823 drawLine(x1
-radius
, y1
, x0
+radius
, y1
, color
);
824 drawLine(x0
, y1
-radius
, x0
, y0
, color
);
826 case DRAW_CORNERS_LEFT
:
827 drawCorner(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
828 drawCorner(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
829 if (radius
*2+1 < height
)
831 drawLine(x0
, y0
+radius
, x0
, y1
-radius
, color
);
833 drawLine(x1
, y0
, x1
, y1
, color
);
834 drawLine(x0
+radius
, y0
, x1
, y0
, color
);
835 drawLine(x0
+radius
, y1
, x1
, y1
, color
);
837 case DRAW_CORNERS_RIGHT
:
838 drawCorner(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
839 drawCorner(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
840 if (radius
*2+1 < height
)
842 drawLine(x1
, y0
+radius
, x1
, y1
-radius
, color
);
844 drawLine(x0
, y0
, x0
, y1
, color
);
845 drawLine(x0
, y0
, x1
-radius
, y0
, color
);
846 drawLine(x0
, y1
, x1
-radius
, y1
, color
);
853 /**************************************************************************/
855 @brief Draws a filled rectangle with rounded corners
858 Starting x co-ordinate
860 Starting y co-ordinate
866 Color used when drawing
868 Corner radius in pixels
870 Which corners to round
872 /**************************************************************************/
873 void drawRoundedRectangleFilled ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
, uint16_t radius
, drawCorners_t corners
)
878 if (corners
== DRAW_CORNERS_NONE
)
880 drawRectangleFilled(x0
, y0
, x1
, y1
, color
);
894 if (radius
> height
/ 2)
901 drawRectangleFilled(x0
+ radius
, y0
, x1
- radius
, y1
, color
);
905 case DRAW_CORNERS_ALL
:
906 drawCornerFilled(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
907 drawCornerFilled(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
908 drawCornerFilled(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
909 drawCornerFilled(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
910 if (radius
*2+1 < height
)
912 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
- radius
, color
);
913 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
- radius
, color
);
916 case DRAW_CORNERS_TOP
:
917 drawCornerFilled(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
918 drawCornerFilled(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
919 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
, color
);
920 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
, color
);
922 case DRAW_CORNERS_BOTTOM
:
923 drawCornerFilled(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
924 drawCornerFilled(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
925 drawRectangleFilled(x0
, y0
, x0
+ radius
, y1
- radius
, color
);
926 drawRectangleFilled(x1
- radius
, y0
, x1
, y1
- radius
, color
);
928 case DRAW_CORNERS_LEFT
:
929 drawCornerFilled(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
930 drawCornerFilled(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
931 if (radius
*2+1 < height
)
933 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
- radius
, color
);
935 drawRectangleFilled(x1
- radius
, y0
, x1
, y1
, color
);
937 case DRAW_CORNERS_RIGHT
:
938 drawCornerFilled(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
939 drawCornerFilled(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
940 if (radius
*2+1 < height
)
942 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
- radius
, color
);
944 drawRectangleFilled(x0
, y0
, x0
+ radius
, y1
, color
);
951 /**************************************************************************/
953 @brief Draws a gradient-filled rectangle
956 Starting x co-ordinate
958 Starting y co-ordinate
963 @param[in] startColor
964 The color at the start of the gradient
966 The color at the end of the gradient
972 #include "drivers/displays/tft/drawing.h"
973 #include "drivers/displays/tft/aafonts.h"
974 #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
976 // Draw a gradient-filled rectangle with anti-aliased text inside it
978 uint16_t btnWidth, btnHeight, btnX, btnY;
988 drawRectangle(btnX-1, btnY-1, btnX+btnWidth+1, btnY+btnHeight+1, COLOR_GRAY_80);
989 drawGradient(btnX, btnY, btnX+btnWidth, btnY+btnHeight, COLOR_WHITE, COLOR_GRAY_128);
991 // Center text vertically and horizontally
992 fntY = btnY + ((btnHeight - DejaVuSansCondensed14_AA2.fontHeight) / 2);
993 fntX = btnX + ((btnWidth - aafontsGetStringWidth(&DejaVuSansCondensed14_AA2, "Click to continue"))/2);
994 aafontsDrawString(fntX, fntY, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "Click to continue");
998 /**************************************************************************/
999 void drawGradient ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t startColor
, uint16_t endColor
)
1004 int16_t rDelta
, gDelta
, bDelta
;
1006 // Clear gradient steps, etc.
1008 rDelta
= gDelta
= bDelta
= 0;
1028 // Calculate global r/g/b changes between start and end colors
1029 rDelta
= ((endColor
>> 11) & 0x1F) - ((startColor
>> 11) & 0x1F);
1030 gDelta
= ((endColor
>> 5) & 0x3F) - ((startColor
>> 5) & 0x3F);
1031 bDelta
= (endColor
& 0x1F) - (startColor
& 0x1F);
1033 // Calculate interpolation deltas to 2 decimal places (fixed point)
1034 rDelta
= (rDelta
* 100) / height
;
1035 gDelta
= (gDelta
* 100) / height
;
1036 bDelta
= (bDelta
* 100) / height
;
1038 // Draw individual lines
1039 for (height
= y0
; y1
> height
- 1; ++height
)
1041 // Calculate new rgb values based on: start color + (line number * interpolation delta)
1042 r
= ((startColor
>> 11) & 0x1F) + ((rDelta
* (height
- y0
)) / 100);
1043 g
= ((startColor
>> 5) & 0x3F) + ((gDelta
* (height
- y0
)) / 100);
1044 b
= (startColor
& 0x1F) + ((bDelta
* (height
- y0
)) / 100);
1045 drawLine(x0
, height
, x1
, height
, ((r
& 0x1F) << 11) | ((g
& 0x3F) << 5) | (b
& 0x1F));
1049 /**************************************************************************/
1051 @brief Draws a triangle
1054 x co-ordinate for point 0
1056 y co-ordinate for point 0
1058 x co-ordinate for point 1
1060 y co-ordinate for point 1
1062 x co-ordinate for point 2
1064 y co-ordinate for point 2
1066 Color used when drawing
1068 /**************************************************************************/
1069 void drawTriangle ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t x2
, uint16_t y2
, uint16_t color
)
1071 drawLine(x0
, y0
, x1
, y1
, color
);
1072 drawLine(x1
, y1
, x2
, y2
, color
);
1073 drawLine(x2
, y2
, x0
, y0
, color
);
1076 /**************************************************************************/
1078 @brief Draws a filled triangle
1081 x co-ordinate for point 0
1083 y co-ordinate for point 0
1085 x co-ordinate for point 1
1087 y co-ordinate for point 1
1089 x co-ordinate for point 2
1091 y co-ordinate for point 2
1099 // Draw a white triangle
1100 drawTriangleFilled ( 100, 10, 20, 120, 230, 290, COLOR_WHITE);
1101 // Draw black circles at each point of the triangle
1102 drawCircleFilled(100, 10, 2, COLOR_BLACK);
1103 drawCircleFilled(20, 120, 2, COLOR_BLACK);
1104 drawCircleFilled(230, 290, 2, COLOR_BLACK);
1108 /**************************************************************************/
1109 void drawTriangleFilled ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t x2
, uint16_t y2
, uint16_t color
)
1111 // Re-order vertices by ascending Y values (smallest first)
1113 drawSwap(y0
, y1
); drawSwap(x0
, x1
);
1116 drawSwap(y2
, y1
); drawSwap(x2
, x1
);
1119 drawSwap(y0
, y1
); drawSwap(x0
, x1
);
1122 int32_t dx1
, dx2
, dx3
; // Interpolation deltas
1123 int32_t sx1
, sx2
, sy
; // Scanline co-ordinates
1125 sx1
=sx2
=x0
* 1000; // Use fixed point math for x axis values
1128 // Calculate interpolation deltas
1129 if (y1
-y0
> 0) dx1
=((x1
-x0
)*1000)/(y1
-y0
);
1131 if (y2
-y0
> 0) dx2
=((x2
-x0
)*1000)/(y2
-y0
);
1133 if (y2
-y1
> 0) dx3
=((x2
-x1
)*1000)/(y2
-y1
);
1136 // Render scanlines (horizontal lines are the fastest rendering method)
1139 for(; sy
<=y1
; sy
++, sx1
+=dx2
, sx2
+=dx1
)
1141 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1145 for(; sy
<=y2
; sy
++, sx1
+=dx2
, sx2
+=dx3
)
1147 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1152 for(; sy
<=y1
; sy
++, sx1
+=dx1
, sx2
+=dx2
)
1154 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1158 for(; sy
<=y2
; sy
++, sx1
+=dx3
, sx2
+=dx2
)
1160 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1165 /**************************************************************************/
1167 @brief Renders a 16x16 monochrome icon using the supplied uint16_t
1171 The horizontal location to start rendering from
1173 The vertical location to start rendering from
1175 The RGB565 color to use when rendering the icon
1177 The uint16_t array containing the 16x16 image data
1183 #include "drivers/displays/tft/drawing.h"
1184 #include "drivers/displays/icons16.h"
1186 // Renders the info icon, which has two seperate parts ... the exterior
1187 // and a seperate interior mask if you want to fill the contents with a
1189 drawIcon16(132, 202, COLOR_BLUE, icons16_info);
1190 drawIcon16(132, 202, COLOR_WHITE, icons16_info_interior);
1194 /**************************************************************************/
1195 void drawIcon16(uint16_t x
, uint16_t y
, uint16_t color
, uint16_t icon
[])
1198 for (i
= 0; i
<16; i
++)
1200 if (icon
[i
] & (0X8000)) drawPixel(x
, y
+i
, color
);
1201 if (icon
[i
] & (0X4000)) drawPixel(x
+1, y
+i
, color
);
1202 if (icon
[i
] & (0X2000)) drawPixel(x
+2, y
+i
, color
);
1203 if (icon
[i
] & (0X1000)) drawPixel(x
+3, y
+i
, color
);
1204 if (icon
[i
] & (0X0800)) drawPixel(x
+4, y
+i
, color
);
1205 if (icon
[i
] & (0X0400)) drawPixel(x
+5, y
+i
, color
);
1206 if (icon
[i
] & (0X0200)) drawPixel(x
+6, y
+i
, color
);
1207 if (icon
[i
] & (0X0100)) drawPixel(x
+7, y
+i
, color
);
1208 if (icon
[i
] & (0X0080)) drawPixel(x
+8, y
+i
, color
);
1209 if (icon
[i
] & (0x0040)) drawPixel(x
+9, y
+i
, color
);
1210 if (icon
[i
] & (0X0020)) drawPixel(x
+10, y
+i
, color
);
1211 if (icon
[i
] & (0X0010)) drawPixel(x
+11, y
+i
, color
);
1212 if (icon
[i
] & (0X0008)) drawPixel(x
+12, y
+i
, color
);
1213 if (icon
[i
] & (0X0004)) drawPixel(x
+13, y
+i
, color
);
1214 if (icon
[i
] & (0X0002)) drawPixel(x
+14, y
+i
, color
);
1215 if (icon
[i
] & (0X0001)) drawPixel(x
+15, y
+i
, color
);