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 /**************************************************************************/
47 /**************************************************************************/
49 /* ----------------------- Private Methods ------------------------------ */
51 /**************************************************************************/
53 /**************************************************************************/
55 @brief Swaps values a and b
57 /**************************************************************************/
58 void drawSwap(uint32_t a
, uint32_t b
)
66 #if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1
67 /**************************************************************************/
69 @brief Draws a single smallfont character
71 /**************************************************************************/
72 void drawCharSmall(uint16_t x
, uint16_t y
, uint16_t color
, uint8_t c
, struct FONT_DEF font
)
74 uint8_t col
, column
[font
.u8Width
];
76 // Check if the requested character is available
77 if ((c
>= font
.u8FirstChar
) && (c
<= font
.u8LastChar
))
79 // Retrieve appropriate columns from font data
80 for (col
= 0; col
< font
.u8Width
; col
++)
82 column
[col
] = font
.au8FontTable
[((c
- 32) * font
.u8Width
) + col
]; // Get first column of appropriate character
87 // Requested character is not available in this font ... send a space instead
88 for (col
= 0; col
< font
.u8Width
; col
++)
90 column
[col
] = 0xFF; // Send solid space
95 uint16_t xoffset
, yoffset
;
96 for (xoffset
= 0; xoffset
< font
.u8Width
; xoffset
++)
98 for (yoffset
= 0; yoffset
< (font
.u8Height
+ 1); yoffset
++)
101 bit
= (column
[xoffset
] << (8 - (yoffset
+ 1))); // Shift current row bit left
102 bit
= (bit
>> 7); // Shift current row but right (results in 0x01 for black, and 0x00 for white)
105 drawPixel(x
+ xoffset
, y
+ yoffset
, color
);
112 /**************************************************************************/
114 @brief Helper method to accurately draw individual circle points
116 /**************************************************************************/
117 void drawCirclePoints(int cx
, int cy
, int x
, int y
, uint16_t color
)
121 drawPixel(cx
, cy
+ y
, color
);
122 drawPixel(cx
, cy
- y
, color
);
123 drawPixel(cx
+ y
, cy
, color
);
124 drawPixel(cx
- y
, cy
, color
);
128 drawPixel(cx
+ x
, cy
+ y
, color
);
129 drawPixel(cx
- x
, cy
+ y
, color
);
130 drawPixel(cx
+ x
, cy
- y
, color
);
131 drawPixel(cx
- x
, cy
- y
, color
);
135 drawPixel(cx
+ x
, cy
+ y
, color
);
136 drawPixel(cx
- x
, cy
+ y
, color
);
137 drawPixel(cx
+ x
, cy
- y
, color
);
138 drawPixel(cx
- x
, cy
- y
, color
);
139 drawPixel(cx
+ y
, cy
+ x
, color
);
140 drawPixel(cx
- y
, cy
+ x
, color
);
141 drawPixel(cx
+ y
, cy
- x
, color
);
142 drawPixel(cx
- y
, cy
- x
, color
);
146 /**************************************************************************/
148 /* ----------------------- Public Methods ------------------------------- */
150 /**************************************************************************/
152 /**************************************************************************/
154 @brief Draws a single pixel at the specified location
161 Color used when drawing
163 /**************************************************************************/
164 void drawPixel(uint16_t x
, uint16_t y
, uint16_t color
)
166 if ((x
>= lcdGetWidth()) || (y
>= lcdGetHeight()))
168 // Pixel out of range
173 lcdDrawPixel(x
, y
, color
);
176 /**************************************************************************/
178 @brief Fills the screen with the specified color
181 Color used when drawing
183 /**************************************************************************/
184 void drawFill(uint16_t color
)
189 /**************************************************************************/
191 @brief Draws a simple color test pattern
193 /**************************************************************************/
194 void drawTestPattern(void)
199 #if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1
200 /**************************************************************************/
202 @brief Draws a string using a small font (6 of 8 pixels high).
205 Starting x co-ordinate
207 Starting y co-ordinate
209 Color to use when rendering the font
213 Pointer to the FONT_DEF to use when drawing the string
219 #include "drivers/displays/fonts/smallfonts.h"
221 drawStringSmall(1, 210, COLOR_WHITE, "5x8 System (Max 40 Characters)", Font_System5x8);
222 drawStringSmall(1, 220, COLOR_WHITE, "7x8 System (Max 30 Characters)", Font_System7x8);
226 /**************************************************************************/
227 void drawStringSmall(uint16_t x
, uint16_t y
, uint16_t color
, char* text
, struct FONT_DEF font
)
230 for (l
= 0; l
< strlen(text
); l
++)
232 drawCharSmall(x
+ (l
* (font
.u8Width
+ 1)), y
, color
, text
[l
], font
);
237 /**************************************************************************/
239 @brief Draws a bresenham line
242 Starting x co-ordinate
244 Starting y co-ordinate
250 Color used when drawing
252 /**************************************************************************/
253 void drawLine ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
255 drawLineDotted(x0
, y0
, x1
, y1
, 0, 1, color
);
258 /**************************************************************************/
260 @brief Draws a bresenham line with a fixed pattern of empty
263 Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
266 Starting x co-ordinate
268 Starting y co-ordinate
274 The number of 'empty' pixels to render
276 The number of 'solid' pixels to render
278 Color used when drawing
280 /**************************************************************************/
281 void drawLineDotted ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t empty
, uint16_t solid
, uint16_t color
)
288 // If a negative y int was passed in it will overflow to 65K something
289 // Ugly, but drawCircleFilled() can pass in negative values so we need
290 // to check the values here
291 y0
= y0
> 65000 ? 0 : y0
;
292 y1
= y1
> 65000 ? 0 : y1
;
294 // Check if we can use the optimised horizontal line method
295 if ((y0
== y1
) && (empty
== 0))
297 lcdDrawHLine(x0
, x1
, y0
, color
);
301 // Check if we can use the optimised vertical line method.
302 // This can make a huge difference in performance, but may
303 // not work properly on every LCD controller:
304 if ((x0
== x1
) && (empty
== 0))
306 // Warning: This may actually be slower than drawing individual pixels on
307 // short lines ... Set a minimum line size to use the 'optimised' method
308 // (which changes the screen orientation) ?
309 lcdDrawVLine(x0
, y0
, y1
, color
);
313 // Draw non-horizontal or dotted line
317 int emptycount
, solidcount
;
319 if (dy
< 0) { dy
= -dy
; stepy
= -1; } else { stepy
= 1; }
320 if (dx
< 0) { dx
= -dx
; stepx
= -1; } else { stepx
= 1; }
321 dy
<<= 1; // dy is now 2*dy
322 dx
<<= 1; // dx is now 2*dx
327 drawPixel(x0
, y0
, color
); // always start with solid pixels
331 int fraction
= dy
- (dx
>> 1); // same as 2*dy - dx
337 fraction
-= dx
; // same as fraction -= 2*dx
340 fraction
+= dy
; // same as fraction -= 2*dy
343 // always draw a pixel ... no dotted line requested
344 drawPixel(x0
, y0
, color
);
348 // Draw solid pxiel and decrement counter
349 drawPixel(x0
, y0
, color
);
354 // Empty pixel ... don't draw anything an decrement counter
359 // Reset counters and draw solid pixel
362 drawPixel(x0
, y0
, color
);
369 int fraction
= dx
- (dy
>> 1);
381 // always draw a pixel ... no dotted line requested
382 drawPixel(x0
, y0
, color
);
386 // Draw solid pxiel and decrement counter
387 drawPixel(x0
, y0
, color
);
392 // Empty pixel ... don't draw anything an decrement counter
397 // Reset counters and draw solid pixel
400 drawPixel(x0
, y0
, color
);
407 /**************************************************************************/
409 @brief Draws a circle
411 Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture7/circle.html
414 The horizontal center of the circle
416 The vertical center of the circle
418 The circle's radius in pixels
420 Color used when drawing
422 /**************************************************************************/
423 void drawCircle (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, uint16_t color
)
427 int p
= (5 - radius
*4)/4;
429 drawCirclePoints(xCenter
, yCenter
, x
, y
, color
);
442 drawCirclePoints(xCenter
, yCenter
, x
, y
, color
);
446 /**************************************************************************/
448 @brief Draws a filled circle
451 The horizontal center of the circle
453 The vertical center of the circle
455 The circle's radius in pixels
457 Color used when drawing
459 /**************************************************************************/
460 void drawCircleFilled (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, uint16_t color
)
462 int16_t f
= 1 - radius
;
464 int16_t ddF_y
= -2 * radius
;
467 int16_t xc_px
, yc_my
, xc_mx
, xc_py
, yc_mx
, xc_my
;
468 int16_t lcdWidth
= lcdGetWidth();
470 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
-radius
, xCenter
, (yCenter
-radius
) + (2*radius
), color
);
491 // Make sure X positions are not negative or too large or the pixels will
492 // overflow. Y overflow is handled in drawLine().
493 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yc_my
, xc_px
, yc_my
+ 2*y
, color
);
494 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yc_my
, xc_mx
, yc_my
+ 2*y
, color
);
495 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yc_mx
, xc_py
, yc_mx
+ 2*x
, color
);
496 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yc_mx
, xc_my
, yc_mx
+ 2*x
, color
);
500 /**************************************************************************/
502 @brief Draws a filled rounded corner
505 The horizontal center of the circle
507 The vertical center of the circle
509 The circle's radius in pixels
511 The position of the corner, which affects how it will
514 Color used when drawing
516 /**************************************************************************/
517 void drawCornerFilled (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, drawCornerPosition_t position
, uint16_t color
)
519 int16_t f
= 1 - radius
;
521 int16_t ddF_y
= -2 * radius
;
524 int16_t xc_px
, yc_my
, xc_mx
, xc_py
, yc_mx
, xc_my
;
525 int16_t lcdWidth
= lcdGetWidth();
529 case DRAW_CORNERPOSITION_TOPRIGHT
:
530 case DRAW_CORNERPOSITION_TOPLEFT
:
531 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
-radius
, xCenter
, yCenter
, color
);
533 case DRAW_CORNERPOSITION_BOTTOMRIGHT
:
534 case DRAW_CORNERPOSITION_BOTTOMLEFT
:
535 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
, xCenter
, (yCenter
-radius
) + (2*radius
), color
);
560 case DRAW_CORNERPOSITION_TOPRIGHT
:
561 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yc_my
, xc_px
, yCenter
, color
);
562 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yc_mx
, xc_py
, yCenter
, color
);
564 case DRAW_CORNERPOSITION_BOTTOMRIGHT
:
565 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yCenter
, xc_px
, yc_my
+ 2*y
, color
);
566 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yCenter
, xc_py
, yc_mx
+ 2*x
, color
);
568 case DRAW_CORNERPOSITION_TOPLEFT
:
569 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yc_my
, xc_mx
, yCenter
, color
);
570 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yc_mx
, xc_my
, yCenter
, color
);
572 case DRAW_CORNERPOSITION_BOTTOMLEFT
:
573 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yCenter
, xc_mx
, yc_my
+ 2*y
, color
);
574 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yCenter
, xc_my
, yc_mx
+ 2*x
, color
);
580 /**************************************************************************/
582 @brief Draws a simple arrow of the specified width
585 X co-ordinate of the smallest point of the arrow
587 Y co-ordinate of the smallest point of the arrow
589 Total width/height of the arrow in pixels
591 The direction that the arrow is pointing
593 Color used when drawing
595 /**************************************************************************/
596 void drawArrow(uint16_t x
, uint16_t y
, uint16_t size
, drawDirection_t direction
, uint16_t color
)
598 drawPixel(x
, y
, color
);
608 case DRAW_DIRECTION_LEFT
:
609 for (i
= 1; i
<size
; i
++)
611 drawLine(x
+i
, y
-i
, x
+i
, y
+i
, color
);
614 case DRAW_DIRECTION_RIGHT
:
615 for (i
= 1; i
<size
; i
++)
617 drawLine(x
-i
, y
-i
, x
-i
, y
+i
, color
);
620 case DRAW_DIRECTION_UP
:
621 for (i
= 1; i
<size
; i
++)
623 drawLine(x
-i
, y
+i
, x
+i
, y
+i
, color
);
626 case DRAW_DIRECTION_DOWN
:
627 for (i
= 1; i
<size
; i
++)
629 drawLine(x
-i
, y
-i
, x
+i
, y
-i
, color
);
637 /**************************************************************************/
639 @brief Draws a simple (empty) rectangle
642 Starting x co-ordinate
644 Starting y co-ordinate
650 Color used when drawing
652 /**************************************************************************/
653 void drawRectangle ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
673 drawLine (x0
, y0
, x1
, y0
, color
);
674 drawLine (x1
, y0
, x1
, y1
, color
);
675 drawLine (x1
, y1
, x0
, y1
, color
);
676 drawLine (x0
, y1
, x0
, y0
, color
);
679 /**************************************************************************/
681 @brief Draws a filled rectangle
684 Starting x co-ordinate
686 Starting y co-ordinate
692 Color used when drawing
694 /**************************************************************************/
695 void drawRectangleFilled ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
717 for (height
= y0
; y1
> height
- 1; ++height
)
719 drawLine(x0
, height
, x1
, height
, color
);
723 /**************************************************************************/
725 @brief Draws a filled rectangle with rounded corners
728 Starting x co-ordinate
730 Starting y co-ordinate
736 Color used when drawing
738 Corner radius in pixels
740 Which corners to round
742 /**************************************************************************/
743 void drawRectangleRounded ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
, uint16_t radius
, drawRoundedCorners_t corners
)
748 if (corners
== DRAW_ROUNDEDCORNERS_NONE
)
750 drawRectangleFilled(x0
, y0
, x1
, y1
, color
);
764 if (radius
> height
/ 2)
771 drawRectangleFilled(x0
+ radius
, y0
, x1
- radius
, y1
, color
);
775 case DRAW_ROUNDEDCORNERS_ALL
:
776 drawCircleFilled(x0
+ radius
, y0
+ radius
, radius
, color
);
777 drawCircleFilled(x1
- radius
, y0
+ radius
, radius
, color
);
778 drawCircleFilled(x0
+ radius
, y1
- radius
, radius
, color
);
779 drawCircleFilled(x1
- radius
, y1
- radius
, radius
, color
);
780 if (radius
*2+1 < height
)
782 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
- radius
, color
);
783 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
- radius
, color
);
786 case DRAW_ROUNDEDCORNERS_TOP
:
787 drawCircleFilled(x0
+ radius
, y0
+ radius
, radius
, color
);
788 drawCircleFilled(x1
- radius
, y0
+ radius
, radius
, color
);
789 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
, color
);
790 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
, color
);
792 case DRAW_ROUNDEDCORNERS_BOTTOM
:
793 drawCircleFilled(x0
+ radius
, y1
- radius
, radius
, color
);
794 drawCircleFilled(x1
- radius
, y1
- radius
, radius
, color
);
795 drawRectangleFilled(x0
, y0
, x0
+ radius
, y1
- radius
, color
);
796 drawRectangleFilled(x1
- radius
, y0
, x1
, y1
- radius
, color
);
798 case DRAW_ROUNDEDCORNERS_LEFT
:
799 drawCircleFilled(x0
+ radius
, y0
+ radius
, radius
, color
);
800 drawCircleFilled(x0
+ radius
, y1
- radius
, radius
, color
);
801 if (radius
*2+1 < height
)
803 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
- radius
, color
);
805 drawRectangleFilled(x1
- radius
, y0
, x1
, y1
, color
);
807 case DRAW_ROUNDEDCORNERS_RIGHT
:
808 drawCircleFilled(x1
- radius
, y0
+ radius
, radius
, color
);
809 drawCircleFilled(x1
- radius
, y1
- radius
, radius
, color
);
810 if (radius
*2+1 < height
)
812 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
- radius
, color
);
814 drawRectangleFilled(x0
, y0
, x0
+ radius
, y1
, color
);
821 /**************************************************************************/
823 @brief Draws a gradient-filled rectangle
826 Starting x co-ordinate
828 Starting y co-ordinate
833 @param[in] startColor
834 The color at the start of the gradient
836 The color at the end of the gradient
842 #include "drivers/displays/tft/drawing.h"
843 #include "drivers/displays/tft/aafonts.h"
844 #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
846 // Draw a gradient-filled rectangle with anti-aliased text inside it
848 uint16_t btnWidth, btnHeight, btnX, btnY;
858 drawRectangle(btnX-1, btnY-1, btnX+btnWidth+1, btnY+btnHeight+1, COLOR_GRAY_80);
859 drawGradient(btnX, btnY, btnX+btnWidth, btnY+btnHeight, COLOR_WHITE, COLOR_GRAY_128);
861 // Center text vertically and horizontally
862 fntY = btnY + ((btnHeight - DejaVuSansCondensed14_AA2.fontHeight) / 2);
863 fntX = btnX + ((btnWidth - aafontsGetStringWidth(&DejaVuSansCondensed14_AA2, "Click to continue"))/2);
864 aafontsDrawString(fntX, fntY, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "Click to continue");
868 /**************************************************************************/
869 void drawGradient ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t startColor
, uint16_t endColor
)
874 int16_t rDelta
, gDelta
, bDelta
;
876 // Clear gradient steps, etc.
878 rDelta
= gDelta
= bDelta
= 0;
898 // Calculate global r/g/b changes between start and end colors
899 rDelta
= ((endColor
>> 11) & 0x1F) - ((startColor
>> 11) & 0x1F);
900 gDelta
= ((endColor
>> 5) & 0x3F) - ((startColor
>> 5) & 0x3F);
901 bDelta
= (endColor
& 0x1F) - (startColor
& 0x1F);
903 // Calculate interpolation deltas to 2 decimal places (fixed point)
904 rDelta
= (rDelta
* 100) / height
;
905 gDelta
= (gDelta
* 100) / height
;
906 bDelta
= (bDelta
* 100) / height
;
908 // Draw individual lines
909 for (height
= y0
; y1
> height
- 1; ++height
)
911 // Calculate new rgb values based on: start color + (line number * interpolation delta)
912 r
= ((startColor
>> 11) & 0x1F) + ((rDelta
* (height
- y0
)) / 100);
913 g
= ((startColor
>> 5) & 0x3F) + ((gDelta
* (height
- y0
)) / 100);
914 b
= (startColor
& 0x1F) + ((bDelta
* (height
- y0
)) / 100);
915 drawLine(x0
, height
, x1
, height
, ((r
& 0x1F) << 11) | ((g
& 0x3F) << 5) | (b
& 0x1F));
919 /**************************************************************************/
921 @brief Draws a triangle
924 x co-ordinate for point 0
926 y co-ordinate for point 0
928 x co-ordinate for point 1
930 y co-ordinate for point 1
932 x co-ordinate for point 2
934 y co-ordinate for point 2
936 Color used when drawing
938 /**************************************************************************/
939 void drawTriangle ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t x2
, uint16_t y2
, uint16_t color
)
941 drawLine(x0
, y0
, x1
, y1
, color
);
942 drawLine(x1
, y1
, x2
, y2
, color
);
943 drawLine(x2
, y2
, x0
, y0
, color
);
946 /**************************************************************************/
948 @brief Draws a filled triangle
951 x co-ordinate for point 0
953 y co-ordinate for point 0
955 x co-ordinate for point 1
957 y co-ordinate for point 1
959 x co-ordinate for point 2
961 y co-ordinate for point 2
969 // Draw a white triangle
970 drawTriangleFilled ( 100, 10, 20, 120, 230, 290, COLOR_WHITE);
971 // Draw black circles at each point of the triangle
972 drawCircleFilled(100, 10, 2, COLOR_BLACK);
973 drawCircleFilled(20, 120, 2, COLOR_BLACK);
974 drawCircleFilled(230, 290, 2, COLOR_BLACK);
978 /**************************************************************************/
979 void drawTriangleFilled ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t x2
, uint16_t y2
, uint16_t color
)
981 // Re-order vertices by ascending Y values (smallest first)
983 drawSwap(y0
, y1
); drawSwap(x0
, x1
);
986 drawSwap(y2
, y1
); drawSwap(x2
, x1
);
989 drawSwap(y0
, y1
); drawSwap(x0
, x1
);
992 int32_t dx1
, dx2
, dx3
; // Interpolation deltas
993 int32_t sx1
, sx2
, sy
; // Scanline co-ordinates
995 sx1
=sx2
=x0
* 1000; // Use fixed point math for x axis values
998 // Calculate interpolation deltas
999 if (y1
-y0
> 0) dx1
=((x1
-x0
)*1000)/(y1
-y0
);
1001 if (y2
-y0
> 0) dx2
=((x2
-x0
)*1000)/(y2
-y0
);
1003 if (y2
-y1
> 0) dx3
=((x2
-x1
)*1000)/(y2
-y1
);
1006 // Render scanlines (horizontal lines are the fastest rendering method)
1009 for(; sy
<=y1
; sy
++, sx1
+=dx2
, sx2
+=dx1
)
1011 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1015 for(; sy
<=y2
; sy
++, sx1
+=dx2
, sx2
+=dx3
)
1017 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1022 for(; sy
<=y1
; sy
++, sx1
+=dx1
, sx2
+=dx2
)
1024 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1028 for(; sy
<=y2
; sy
++, sx1
+=dx3
, sx2
+=dx2
)
1030 drawLine(sx1
/1000, sy
, sx2
/1000, sy
, color
);
1035 /**************************************************************************/
1037 @brief Draws a progress bar with rounded corners
1044 Total width of the progress bar in pixels
1046 Total height of the progress bar in pixels
1047 @param[in] borderCorners
1048 The type of rounded corners to render with the progress bar border
1049 @param[in] progressCorners
1050 The type of rounded corners to render with the inner progress bar
1051 @param[in] borderColor
1052 16-bit color for the outer border
1053 @param[in] borderFillColor
1054 16-bit color for the interior of the outer border
1055 @param[in] progressBorderColor
1056 16-bit color for the progress bar's border
1057 @param[in] progressFillColor
1058 16-bit color for the inner bar's fill
1060 Progress percentage (between 0 and 100)
1065 #include "drivers/displays/tft/drawing.h"
1067 // Draw a the progress bar (150x15 pixels large, starting at X:10, Y:195
1068 // with rounded corners on the top and showing 72% progress)
1069 drawProgressBar(10, 195, 150, 15, DRAW_ROUNDEDCORNERS_TOP, DRAW_ROUNDEDCORNERS_TOP, COLOR_DARKERGRAY, COLOR_DARKGRAY, COLOR_LIMEGREENDIM, COLOR_LIMEGREEN, 72 );
1073 /**************************************************************************/
1074 void drawProgressBar ( uint16_t x
, uint16_t y
, uint16_t width
, uint16_t height
, drawRoundedCorners_t borderCorners
, drawRoundedCorners_t progressCorners
, uint16_t borderColor
, uint16_t borderFillColor
, uint16_t progressBorderColor
, uint16_t progressFillColor
, uint8_t progress
)
1076 // Draw border with rounded corners
1077 drawRectangleRounded(x
, y
, x
+ width
, y
+ height
, borderColor
, 5, borderCorners
);
1078 drawRectangleRounded(x
+1, y
+1, x
+ width
- 1, y
+ height
- 1, borderFillColor
, 5, borderCorners
);
1081 if (progress
> 0 && progress
<= 100)
1083 // Calculate bar size
1085 bw
= (width
- 6); // bar at 100%
1086 if (progress
!= 100)
1088 bw
= (bw
* progress
) / 100;
1090 drawRectangleRounded(x
+ 3, y
+ 3, bw
+ x
+ 3, y
+ height
- 3, progressBorderColor
, 5, progressCorners
);
1091 drawRectangleRounded(x
+ 4, y
+ 4, bw
+ x
+ 3 - 1, y
+ height
- 4, progressFillColor
, 5, progressCorners
);
1095 /**************************************************************************/
1097 @brief Draws a simple button
1104 Total width of the button in pixels
1106 Total height of the button in pixels
1108 Pointer to the FONT_INFO used to render the button text
1109 @param[in] borderclr
1110 The rgb565 border color
1112 The rgb565 background color
1114 The rgb565 font color
1116 The text to render on the button
1122 #include "drivers/displays/tft/drawing.h"
1123 #include "drivers/displays/tft/fonts/dejavusans9.h"
1125 // Draw two buttons using DejaVu Sans 9
1126 drawButton(20, 195, 200, 35, &dejaVuSans9ptFontInfo, COLOR_GRAY_80, COLOR_GRAY_80, COLOR_WHITE, "System Settings");
1127 drawButton(20, 235, 200, 35, &dejaVuSans9ptFontInfo, COLOR_THEME_LIMEGREEN_DARKER, COLOR_THEME_LIMEGREEN_BASE, COLOR_BLACK, "System Settings");
1131 /**************************************************************************/
1132 void drawButton(uint16_t x
, uint16_t y
, uint16_t width
, uint16_t height
, const FONT_INFO
*fontInfo
, uint16_t borderclr
, uint16_t fillclr
, uint16_t fontclr
, char* text
)
1135 drawRectangleRounded(x
, y
, x
+ width
, y
+ height
, borderclr
, 5, DRAW_ROUNDEDCORNERS_ALL
);
1137 drawRectangleRounded(x
+2, y
+2, x
+width
-2, y
+height
-2, fillclr
, 5, DRAW_ROUNDEDCORNERS_ALL
);
1142 uint16_t textWidth
= fontsGetStringWidth(&*fontInfo
, text
);
1143 uint16_t xStart
= x
+ (width
/ 2) - (textWidth
/ 2);
1144 uint16_t yStart
= y
+ (height
/ 2) - (fontInfo
->height
/ 2) + 1;
1145 fontsDrawString(xStart
, yStart
, fontclr
, &*fontInfo
, text
);
1149 /**************************************************************************/
1151 @brief Renders a 16x16 monochrome icon using the supplied uint16_t
1155 The horizontal location to start rendering from
1157 The vertical location to start rendering from
1159 The RGB565 color to use when rendering the icon
1161 The uint16_t array containing the 16x16 image data
1167 #include "drivers/displays/tft/drawing.h"
1168 #include "drivers/displays/icons16.h"
1170 // Renders the info icon, which has two seperate parts ... the exterior
1171 // and a seperate interior mask if you want to fill the contents with a
1173 drawIcon16(132, 202, COLOR_BLUE, icons16_info);
1174 drawIcon16(132, 202, COLOR_WHITE, icons16_info_interior);
1178 /**************************************************************************/
1179 void drawIcon16(uint16_t x
, uint16_t y
, uint16_t color
, uint16_t icon
[])
1182 for (i
= 0; i
<16; i
++)
1184 if (icon
[i
] & (0X8000)) drawPixel(x
, y
+i
, color
);
1185 if (icon
[i
] & (0X4000)) drawPixel(x
+1, y
+i
, color
);
1186 if (icon
[i
] & (0X2000)) drawPixel(x
+2, y
+i
, color
);
1187 if (icon
[i
] & (0X1000)) drawPixel(x
+3, y
+i
, color
);
1188 if (icon
[i
] & (0X0800)) drawPixel(x
+4, y
+i
, color
);
1189 if (icon
[i
] & (0X0400)) drawPixel(x
+5, y
+i
, color
);
1190 if (icon
[i
] & (0X0200)) drawPixel(x
+6, y
+i
, color
);
1191 if (icon
[i
] & (0X0100)) drawPixel(x
+7, y
+i
, color
);
1192 if (icon
[i
] & (0X0080)) drawPixel(x
+8, y
+i
, color
);
1193 if (icon
[i
] & (0x0040)) drawPixel(x
+9, y
+i
, color
);
1194 if (icon
[i
] & (0X0020)) drawPixel(x
+10, y
+i
, color
);
1195 if (icon
[i
] & (0X0010)) drawPixel(x
+11, y
+i
, color
);
1196 if (icon
[i
] & (0X0008)) drawPixel(x
+12, y
+i
, color
);
1197 if (icon
[i
] & (0X0004)) drawPixel(x
+13, y
+i
, color
);
1198 if (icon
[i
] & (0X0002)) drawPixel(x
+14, y
+i
, color
);
1199 if (icon
[i
] & (0X0001)) drawPixel(x
+15, y
+i
, color
);
1204 /**************************************************************************/
1206 @brief Loads a 24-bit Windows bitmap image from an SD card and
1213 #include "drivers/displays/tft/drawing.h"
1215 // Draw image.bmp (from the root folder) starting at pixel 0,0
1216 bmp_error_t error = drawBitmapImage(0, 0, "/image.bmp");
1222 case BMP_ERROR_SDINITFAIL:
1224 case BMP_ERROR_FILENOTFOUND:
1226 case BMP_ERROR_NOTABITMAP:
1227 // First two bytes of image not 'BM'
1229 case BMP_ERROR_INVALIDBITDEPTH:
1230 // Image is not 24-bits
1232 case BMP_ERROR_COMPRESSEDDATA:
1233 // Image contains compressed data
1235 case BMP_ERROR_INVALIDDIMENSIONS:
1236 // Width or Height is > LCD size
1238 case BMP_ERROR_PREMATUREEOF:
1239 // EOF unexpectedly reached in pixel data
1246 /**************************************************************************/
1247 bmp_error_t
drawBitmapImage(uint16_t x
, uint16_t y
, char *filename
)
1249 return bmpDrawBitmap(x
, y
, filename
);