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 but 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
)
246 // If a negative y int was passed in it will overflow to 65K something
247 // Ugly, but drawCircleFilled() can pass in negative values so we need
248 // to check the values here
249 y0
= y0
> 65000 ? 0 : y0
;
250 y1
= y1
> 65000 ? 0 : y1
;
252 // Check if we can use the optimised horizontal line method
253 if ((y0
== y1
) && (empty
== 0))
255 lcdDrawHLine(x0
, x1
, y0
, color
);
259 // Check if we can use the optimised vertical line method.
260 // This can make a huge difference in performance, but may
261 // not work properly on every LCD controller:
262 if ((x0
== x1
) && (empty
== 0))
264 // Warning: This may actually be slower than drawing individual pixels on
265 // short lines ... Set a minimum line size to use the 'optimised' method
266 // (which changes the screen orientation) ?
267 lcdDrawVLine(x0
, y0
, y1
, color
);
271 // Draw non-horizontal or dotted line
275 int emptycount
, solidcount
;
277 if (dy
< 0) { dy
= -dy
; stepy
= -1; } else { stepy
= 1; }
278 if (dx
< 0) { dx
= -dx
; stepx
= -1; } else { stepx
= 1; }
279 dy
<<= 1; // dy is now 2*dy
280 dx
<<= 1; // dx is now 2*dx
285 drawPixel(x0
, y0
, color
); // always start with solid pixels
289 int fraction
= dy
- (dx
>> 1); // same as 2*dy - dx
295 fraction
-= dx
; // same as fraction -= 2*dx
298 fraction
+= dy
; // same as fraction -= 2*dy
301 // always draw a pixel ... no dotted line requested
302 drawPixel(x0
, y0
, color
);
306 // Draw solid pxiel and decrement counter
307 drawPixel(x0
, y0
, color
);
312 // Empty pixel ... don't draw anything an decrement counter
317 // Reset counters and draw solid pixel
320 drawPixel(x0
, y0
, color
);
327 int fraction
= dx
- (dy
>> 1);
339 // always draw a pixel ... no dotted line requested
340 drawPixel(x0
, y0
, color
);
344 // Draw solid pxiel and decrement counter
345 drawPixel(x0
, y0
, color
);
350 // Empty pixel ... don't draw anything an decrement counter
355 // Reset counters and draw solid pixel
358 drawPixel(x0
, y0
, color
);
365 /**************************************************************************/
367 @brief Draws a circle
369 Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture7/circle.html
372 The horizontal center of the circle
374 The vertical center of the circle
376 The circle's radius in pixels
378 Color used when drawing
380 /**************************************************************************/
381 void drawCircle (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, uint16_t color
)
383 drawPixel(xCenter
, yCenter
+radius
, color
);
384 drawPixel(xCenter
, yCenter
-radius
, color
);
385 drawPixel(xCenter
+radius
, yCenter
, color
);
386 drawPixel(xCenter
-radius
, yCenter
, color
);
387 drawCorner(xCenter
, yCenter
, radius
, DRAW_CORNERS_ALL
, color
);
390 /**************************************************************************/
392 @brief Draws a filled circle
395 The horizontal center of the circle
397 The vertical center of the circle
399 The circle's radius in pixels
401 Color used when drawing
403 /**************************************************************************/
404 void drawCircleFilled (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, uint16_t color
)
406 int16_t f
= 1 - radius
;
408 int16_t ddF_y
= -2 * radius
;
411 int16_t xc_px
, yc_my
, xc_mx
, xc_py
, yc_mx
, xc_my
;
412 int16_t lcdWidth
= lcdGetWidth();
414 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
-radius
, xCenter
, (yCenter
-radius
) + (2*radius
), color
);
435 // Make sure X positions are not negative or too large or the pixels will
436 // overflow. Y overflow is handled in drawLine().
437 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yc_my
, xc_px
, yc_my
+ 2*y
, color
);
438 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yc_my
, xc_mx
, yc_my
+ 2*y
, color
);
439 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yc_mx
, xc_py
, yc_mx
+ 2*x
, color
);
440 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yc_mx
, xc_my
, yc_mx
+ 2*x
, color
);
444 /**************************************************************************/
446 @brief Draws a single 1-pixel wide corner
448 @note Code courtesy Adafruit's excellent GFX lib:
449 https://github.com/adafruit/Adafruit-GFX-Library
452 The horizontal center of the circle
454 The vertical center of the circle
456 The drawCorners_t representing the corner(s) to draw
458 Color used when drawing
464 // Draw a top-left corner with a 10 pixel radius, centered at 20, 20
465 drawCorner(20, 20, 10, DRAW_CORNER_TOPLEFT, COLOR_GRAY_128);
469 /**************************************************************************/
470 void drawCorner (uint16_t xCenter
, uint16_t yCenter
, uint16_t r
, drawCorners_t corner
, uint16_t color
)
474 int16_t ddF_y
= -2 * r
;
489 if (corner
& DRAW_CORNERS_BOTTOMRIGHT
)
491 drawPixel(xCenter
+ x
, yCenter
+ y
, color
);
492 drawPixel(xCenter
+ y
, yCenter
+ x
, color
);
494 if (corner
& DRAW_CORNERS_TOPRIGHT
)
496 drawPixel(xCenter
+ x
, yCenter
- y
, color
);
497 drawPixel(xCenter
+ y
, yCenter
- x
, color
);
499 if (corner
& DRAW_CORNERS_BOTTOMLEFT
)
501 drawPixel(xCenter
- y
, yCenter
+ x
, color
);
502 drawPixel(xCenter
- x
, yCenter
+ y
, color
);
504 if (corner
& DRAW_CORNERS_TOPLEFT
)
506 drawPixel(xCenter
- y
, yCenter
- x
, color
);
507 drawPixel(xCenter
- x
, yCenter
- y
, color
);
512 /**************************************************************************/
514 @brief Draws a filled rounded corner
517 The horizontal center of the circle
519 The vertical center of the circle
521 The circle's radius in pixels
523 The position of the corner, which affects how it will
526 Color used when drawing
528 /**************************************************************************/
529 void drawCornerFilled (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, drawCorners_t position
, uint16_t color
)
531 int16_t f
= 1 - radius
;
533 int16_t ddF_y
= -2 * radius
;
536 int16_t xc_px
, yc_my
, xc_mx
, xc_py
, yc_mx
, xc_my
;
537 int16_t lcdWidth
= lcdGetWidth();
540 if ((position
& DRAW_CORNERS_TOPRIGHT
) || (position
& DRAW_CORNERS_TOPLEFT
))
542 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
-radius
, xCenter
, yCenter
, color
);
544 if ((position
& DRAW_CORNERS_BOTTOMRIGHT
) || (position
& DRAW_CORNERS_BOTTOMLEFT
))
546 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
, xCenter
, (yCenter
-radius
) + (2*radius
), color
);
569 if (position
& DRAW_CORNERS_TOPRIGHT
)
571 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yc_my
, xc_px
, yCenter
, color
);
572 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yc_mx
, xc_py
, yCenter
, color
);
574 if (position
& DRAW_CORNERS_BOTTOMRIGHT
)
576 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yCenter
, xc_px
, yc_my
+ 2*y
, color
);
577 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yCenter
, xc_py
, yc_mx
+ 2*x
, color
);
579 if (position
& DRAW_CORNERS_TOPLEFT
)
581 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yc_my
, xc_mx
, yCenter
, color
);
582 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yc_mx
, xc_my
, yCenter
, color
);
584 if (position
& DRAW_CORNERS_BOTTOMLEFT
)
586 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yCenter
, xc_mx
, yc_my
+ 2*y
, color
);
587 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yCenter
, xc_my
, yc_mx
+ 2*x
, color
);
592 /**************************************************************************/
594 @brief Draws a simple arrow of the specified width
597 X co-ordinate of the smallest point of the arrow
599 Y co-ordinate of the smallest point of the arrow
601 Total width/height of the arrow in pixels
603 The direction that the arrow is pointing
605 Color used when drawing
607 /**************************************************************************/
608 void drawArrow(uint16_t x
, uint16_t y
, uint16_t size
, drawDirection_t direction
, uint16_t color
)
610 drawPixel(x
, y
, color
);
620 case DRAW_DIRECTION_LEFT
:
621 for (i
= 1; i
<size
; i
++)
623 drawLine(x
+i
, y
-i
, x
+i
, y
+i
, color
);
626 case DRAW_DIRECTION_RIGHT
:
627 for (i
= 1; i
<size
; i
++)
629 drawLine(x
-i
, y
-i
, x
-i
, y
+i
, color
);
632 case DRAW_DIRECTION_UP
:
633 for (i
= 1; i
<size
; i
++)
635 drawLine(x
-i
, y
+i
, x
+i
, y
+i
, color
);
638 case DRAW_DIRECTION_DOWN
:
639 for (i
= 1; i
<size
; i
++)
641 drawLine(x
-i
, y
-i
, x
+i
, y
-i
, color
);
649 /**************************************************************************/
651 @brief Draws a simple (empty) rectangle
654 Starting x co-ordinate
656 Starting y co-ordinate
662 Color used when drawing
664 /**************************************************************************/
665 void drawRectangle ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
685 drawLine (x0
, y0
, x1
, y0
, color
);
686 drawLine (x1
, y0
, x1
, y1
, color
);
687 drawLine (x1
, y1
, x0
, y1
, color
);
688 drawLine (x0
, y1
, x0
, y0
, color
);
691 /**************************************************************************/
693 @brief Draws a filled rectangle
696 Starting x co-ordinate
698 Starting y co-ordinate
704 Color used when drawing
706 /**************************************************************************/
707 void drawRectangleFilled ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
729 for (height
= y0
; y1
> height
- 1; ++height
)
731 drawLine(x0
, height
, x1
, height
, color
);
735 /**************************************************************************/
737 @brief Draws a rectangle with rounded corners
740 Starting x co-ordinate
742 Starting y co-ordinate
748 Color used when drawing
750 Corner radius in pixels
752 Which corners to round
757 drawRoundedRectangle ( 10, 10, 200, 200, COLOR_BLACK, 10, DRAW_CORNERS_ALL );
762 /**************************************************************************/
763 void drawRoundedRectangle ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
, uint16_t radius
, drawCorners_t corners
)
768 if (corners
== DRAW_CORNERS_NONE
)
770 drawRectangle(x0
, y0
, x1
, y1
, color
);
784 if (radius
> height
/ 2)
792 case DRAW_CORNERS_ALL
:
793 drawCorner(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
794 drawCorner(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
795 drawCorner(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
796 drawCorner(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
797 if (radius
*2+1 < height
)
799 drawLine(x0
, y0
+radius
, x0
, y1
-radius
, color
);
800 drawLine(x1
, y0
+radius
, x1
, y1
-radius
, color
);
802 drawLine(x0
+radius
, y0
, x1
-radius
, y0
, color
);
803 drawLine(x0
+radius
, y1
, x1
-radius
, y1
, color
);
805 case DRAW_CORNERS_TOP
:
806 drawCorner(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
807 drawCorner(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
808 drawLine(x0
, y0
+radius
, x0
, y1
, color
);
809 drawLine(x0
, y1
, x1
, y1
, color
);
810 drawLine(x1
, y1
, x1
, y0
+radius
, color
);
811 drawLine(x0
+radius
, y0
, x1
-radius
, y0
, color
);
813 case DRAW_CORNERS_BOTTOM
:
814 drawCorner(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
815 drawCorner(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
816 drawLine(x0
, y0
, x1
, y0
, color
);
817 drawLine(x1
, y0
, x1
, y1
-radius
, color
);
818 drawLine(x1
-radius
, y1
, x0
+radius
, y1
, color
);
819 drawLine(x0
, y1
-radius
, x0
, y0
, color
);
821 case DRAW_CORNERS_LEFT
:
822 drawCorner(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
823 drawCorner(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
824 if (radius
*2+1 < height
)
826 drawLine(x0
, y0
+radius
, x0
, y1
-radius
, color
);
828 drawLine(x1
, y0
, x1
, y1
, color
);
829 drawLine(x0
+radius
, y0
, x1
, y0
, color
);
830 drawLine(x0
+radius
, y1
, x1
, y1
, color
);
832 case DRAW_CORNERS_RIGHT
:
833 drawCorner(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
834 drawCorner(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
835 if (radius
*2+1 < height
)
837 drawLine(x1
, y0
+radius
, x1
, y1
-radius
, color
);
839 drawLine(x0
, y0
, x0
, y1
, color
);
840 drawLine(x0
, y0
, x1
-radius
, y0
, color
);
841 drawLine(x0
, y1
, x1
-radius
, y1
, color
);
848 /**************************************************************************/
850 @brief Draws a filled rectangle with rounded corners
853 Starting x co-ordinate
855 Starting y co-ordinate
861 Color used when drawing
863 Corner radius in pixels
865 Which corners to round
867 /**************************************************************************/
868 void drawRoundedRectangleFilled ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
, uint16_t radius
, drawCorners_t corners
)
873 if (corners
== DRAW_CORNERS_NONE
)
875 drawRectangleFilled(x0
, y0
, x1
, y1
, color
);
889 if (radius
> height
/ 2)
896 drawRectangleFilled(x0
+ radius
, y0
, x1
- radius
, y1
, color
);
900 case DRAW_CORNERS_ALL
:
901 drawCornerFilled(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
902 drawCornerFilled(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
903 drawCornerFilled(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
904 drawCornerFilled(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
905 if (radius
*2+1 < height
)
907 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
- radius
, color
);
908 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
- radius
, color
);
911 case DRAW_CORNERS_TOP
:
912 drawCornerFilled(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
913 drawCornerFilled(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
914 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
, color
);
915 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
, color
);
917 case DRAW_CORNERS_BOTTOM
:
918 drawCornerFilled(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
919 drawCornerFilled(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
920 drawRectangleFilled(x0
, y0
, x0
+ radius
, y1
- radius
, color
);
921 drawRectangleFilled(x1
- radius
, y0
, x1
, y1
- radius
, color
);
923 case DRAW_CORNERS_LEFT
:
924 drawCornerFilled(x0
+ radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPLEFT
, color
);
925 drawCornerFilled(x0
+ radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMLEFT
, color
);
926 if (radius
*2+1 < height
)
928 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
- radius
, color
);
930 drawRectangleFilled(x1
- radius
, y0
, x1
, y1
, color
);
932 case DRAW_CORNERS_RIGHT
:
933 drawCornerFilled(x1
- radius
, y0
+ radius
, radius
, DRAW_CORNERS_TOPRIGHT
, color
);
934 drawCornerFilled(x1
- radius
, y1
- radius
, radius
, DRAW_CORNERS_BOTTOMRIGHT
, color
);
935 if (radius
*2+1 < height
)
937 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
- radius
, color
);
939 drawRectangleFilled(x0
, y0
, x0
+ radius
, y1
, color
);
946 /**************************************************************************/
948 @brief Draws a gradient-filled rectangle
951 Starting x co-ordinate
953 Starting y co-ordinate
958 @param[in] startColor
959 The color at the start of the gradient
961 The color at the end of the gradient
967 #include "drivers/displays/tft/drawing.h"
968 #include "drivers/displays/tft/aafonts.h"
969 #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
971 // Draw a gradient-filled rectangle with anti-aliased text inside it
973 uint16_t btnWidth, btnHeight, btnX, btnY;
983 drawRectangle(btnX-1, btnY-1, btnX+btnWidth+1, btnY+btnHeight+1, COLOR_GRAY_80);
984 drawGradient(btnX, btnY, btnX+btnWidth, btnY+btnHeight, COLOR_WHITE, COLOR_GRAY_128);
986 // Center text vertically and horizontally
987 fntY = btnY + ((btnHeight - DejaVuSansCondensed14_AA2.fontHeight) / 2);
988 fntX = btnX + ((btnWidth - aafontsGetStringWidth(&DejaVuSansCondensed14_AA2, "Click to continue"))/2);
989 aafontsDrawString(fntX, fntY, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "Click to continue");
993 /**************************************************************************/
994 void drawGradient ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t startColor
, uint16_t endColor
)
999 int16_t rDelta
, gDelta
, bDelta
;
1001 // Clear gradient steps, etc.
1003 rDelta
= gDelta
= bDelta
= 0;
1023 // Calculate global r/g/b changes between start and end colors
1024 rDelta
= ((endColor
>> 11) & 0x1F) - ((startColor
>> 11) & 0x1F);
1025 gDelta
= ((endColor
>> 5) & 0x3F) - ((startColor
>> 5) & 0x3F);
1026 bDelta
= (endColor
& 0x1F) - (startColor
& 0x1F);
1028 // Calculate interpolation deltas to 2 decimal places (fixed point)
1029 rDelta
= (rDelta
* 100) / height
;
1030 gDelta
= (gDelta
* 100) / height
;
1031 bDelta
= (bDelta
* 100) / height
;
1033 // Draw individual lines
1034 for (height
= y0
; y1
> height
- 1; ++height
)
1036 // Calculate new rgb values based on: start color + (line number * interpolation delta)
1037 r
= ((startColor
>> 11) & 0x1F) + ((rDelta
* (height
- y0
)) / 100);
1038 g
= ((startColor
>> 5) & 0x3F) + ((gDelta
* (height
- y0
)) / 100);
1039 b
= (startColor
& 0x1F) + ((bDelta
* (height
- y0
)) / 100);
1040 drawLine(x0
, height
, x1
, height
, ((r
& 0x1F) << 11) | ((g
& 0x3F) << 5) | (b
& 0x1F));
1044 /**************************************************************************/
1046 @brief Draws a triangle
1049 x co-ordinate for point 0
1051 y co-ordinate for point 0
1053 x co-ordinate for point 1
1055 y co-ordinate for point 1
1057 x co-ordinate for point 2
1059 y co-ordinate for point 2
1061 Color used when drawing
1063 /**************************************************************************/
1064 void drawTriangle ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t x2
, uint16_t y2
, uint16_t color
)
1066 drawLine(x0
, y0
, x1
, y1
, color
);
1067 drawLine(x1
, y1
, x2
, y2
, color
);
1068 drawLine(x2
, y2
, x0
, y0
, color
);
1071 /**************************************************************************/
1073 @brief Draws a filled triangle
1076 x co-ordinate for point 0
1078 y co-ordinate for point 0
1080 x co-ordinate for point 1
1082 y co-ordinate for point 1
1084 x co-ordinate for point 2
1086 y co-ordinate for point 2
1094 // Draw a white triangle
1095 drawTriangleFilled ( 100, 10, 20, 120, 230, 290, COLOR_WHITE);
1096 // Draw black circles at each point of the triangle
1097 drawCircleFilled(100, 10, 2, COLOR_BLACK);
1098 drawCircleFilled(20, 120, 2, COLOR_BLACK);
1099 drawCircleFilled(230, 290, 2, COLOR_BLACK);
1103 /**************************************************************************/
1104 void drawTriangleFilled ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t x2
, uint16_t y2
, uint16_t color
)
1106 // Re-order vertices by ascending Y values (smallest first)
1108 drawSwap(y0
, y1
); drawSwap(x0
, x1
);
1111 drawSwap(y2
, y1
); drawSwap(x2
, x1
);
1114 drawSwap(y0
, y1
); drawSwap(x0
, x1
);
1117 int32_t dx1
, dx2
, dx3
; // Interpolation deltas
1118 int32_t sx1
, sx2
, sy
; // Scanline co-ordinates
1120 sx1
=sx2
=x0
* 1000; // Use fixed point math for x axis values
1123 // Calculate interpolation deltas
1124 if (y1
-y0
> 0) dx1
=((x1
-x0
)*1000)/(y1
-y0
);
1126 if (y2
-y0
> 0) dx2
=((x2
-x0
)*1000)/(y2
-y0
);
1128 if (y2
-y1
> 0) dx3
=((x2
-x1
)*1000)/(y2
-y1
);
1131 // Render scanlines (horizontal lines are the fastest rendering method)
1134 for(; sy
<=y1
; sy
++, sx1
+=dx2
, sx2
+=dx1
)
1136 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1140 for(; sy
<=y2
; sy
++, sx1
+=dx2
, sx2
+=dx3
)
1142 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1147 for(; sy
<=y1
; sy
++, sx1
+=dx1
, sx2
+=dx2
)
1149 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1153 for(; sy
<=y2
; sy
++, sx1
+=dx3
, sx2
+=dx2
)
1155 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1160 /**************************************************************************/
1162 @brief Renders a 16x16 monochrome icon using the supplied uint16_t
1166 The horizontal location to start rendering from
1168 The vertical location to start rendering from
1170 The RGB565 color to use when rendering the icon
1172 The uint16_t array containing the 16x16 image data
1178 #include "drivers/displays/tft/drawing.h"
1179 #include "drivers/displays/icons16.h"
1181 // Renders the info icon, which has two seperate parts ... the exterior
1182 // and a seperate interior mask if you want to fill the contents with a
1184 drawIcon16(132, 202, COLOR_BLUE, icons16_info);
1185 drawIcon16(132, 202, COLOR_WHITE, icons16_info_interior);
1189 /**************************************************************************/
1190 void drawIcon16(uint16_t x
, uint16_t y
, uint16_t color
, uint16_t icon
[])
1193 for (i
= 0; i
<16; i
++)
1195 if (icon
[i
] & (0X8000)) drawPixel(x
, y
+i
, color
);
1196 if (icon
[i
] & (0X4000)) drawPixel(x
+1, y
+i
, color
);
1197 if (icon
[i
] & (0X2000)) drawPixel(x
+2, y
+i
, color
);
1198 if (icon
[i
] & (0X1000)) drawPixel(x
+3, y
+i
, color
);
1199 if (icon
[i
] & (0X0800)) drawPixel(x
+4, y
+i
, color
);
1200 if (icon
[i
] & (0X0400)) drawPixel(x
+5, y
+i
, color
);
1201 if (icon
[i
] & (0X0200)) drawPixel(x
+6, y
+i
, color
);
1202 if (icon
[i
] & (0X0100)) drawPixel(x
+7, y
+i
, color
);
1203 if (icon
[i
] & (0X0080)) drawPixel(x
+8, y
+i
, color
);
1204 if (icon
[i
] & (0x0040)) drawPixel(x
+9, y
+i
, color
);
1205 if (icon
[i
] & (0X0020)) drawPixel(x
+10, y
+i
, color
);
1206 if (icon
[i
] & (0X0010)) drawPixel(x
+11, y
+i
, color
);
1207 if (icon
[i
] & (0X0008)) drawPixel(x
+12, y
+i
, color
);
1208 if (icon
[i
] & (0X0004)) drawPixel(x
+13, y
+i
, color
);
1209 if (icon
[i
] & (0X0002)) drawPixel(x
+14, y
+i
, color
);
1210 if (icon
[i
] & (0X0001)) drawPixel(x
+15, y
+i
, color
);