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/
9 drawString based on an example from Eran Duchan:
10 http://www.pavius.net/downloads/tools/53-the-dot-factory
14 Software License Agreement (BSD License)
16 Copyright (c) 2010, microBuilder SARL
19 Redistribution and use in source and binary forms, with or without
20 modification, are permitted provided that the following conditions are met:
21 1. Redistributions of source code must retain the above copyright
22 notice, this list of conditions and the following disclaimer.
23 2. Redistributions in binary form must reproduce the above copyright
24 notice, this list of conditions and the following disclaimer in the
25 documentation and/or other materials provided with the distribution.
26 3. Neither the name of the copyright holders nor the
27 names of its contributors may be used to endorse or promote products
28 derived from this software without specific prior written permission.
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
31 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 /**************************************************************************/
50 /**************************************************************************/
52 /* ----------------------- Private Methods ------------------------------ */
54 /**************************************************************************/
56 /**************************************************************************/
58 @brief Draws a single bitmap character
60 /**************************************************************************/
61 void drawCharBitmap(const uint16_t xPixel
, const uint16_t yPixel
, uint16_t color
, const uint8_t *glyph
, uint8_t glyphHeightPages
, uint8_t glyphWidthBits
)
63 uint16_t verticalPage
, horizBit
, currentY
, currentX
;
64 uint16_t indexIntoGlyph
;
66 // set initial current y
70 // for each page of the glyph
71 for (verticalPage
= glyphHeightPages
; verticalPage
> 0; --verticalPage
)
73 // for each horizontol bit
74 for (horizBit
= 0; horizBit
< glyphWidthBits
; ++horizBit
)
77 indexIntoGlyph
= (glyphHeightPages
* horizBit
) + verticalPage
- 1;
79 currentX
= xPixel
+ (horizBit
);
81 if (glyph
[indexIntoGlyph
] & (0X80)) drawPixel(currentX
, currentY
, color
);
82 if (glyph
[indexIntoGlyph
] & (0X40)) drawPixel(currentX
, currentY
- 1, color
);
83 if (glyph
[indexIntoGlyph
] & (0X20)) drawPixel(currentX
, currentY
- 2, color
);
84 if (glyph
[indexIntoGlyph
] & (0X10)) drawPixel(currentX
, currentY
- 3, color
);
85 if (glyph
[indexIntoGlyph
] & (0X08)) drawPixel(currentX
, currentY
- 4, color
);
86 if (glyph
[indexIntoGlyph
] & (0X04)) drawPixel(currentX
, currentY
- 5, color
);
87 if (glyph
[indexIntoGlyph
] & (0X02)) drawPixel(currentX
, currentY
- 6, color
);
88 if (glyph
[indexIntoGlyph
] & (0X01)) drawPixel(currentX
, currentY
- 7, color
);
95 #if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1
96 /**************************************************************************/
98 @brief Draws a single smallfont character
100 /**************************************************************************/
101 void drawCharSmall(uint16_t x
, uint16_t y
, uint16_t color
, uint8_t c
, struct FONT_DEF font
)
103 uint8_t col
, column
[font
.u8Width
];
105 // Check if the requested character is available
106 if ((c
>= font
.u8FirstChar
) && (c
<= font
.u8LastChar
))
108 // Retrieve appropriate columns from font data
109 for (col
= 0; col
< font
.u8Width
; col
++)
111 column
[col
] = font
.au8FontTable
[((c
- 32) * font
.u8Width
) + col
]; // Get first column of appropriate character
116 // Requested character is not available in this font ... send a space instead
117 for (col
= 0; col
< font
.u8Width
; col
++)
119 column
[col
] = 0xFF; // Send solid space
123 // Render each column
124 uint16_t xoffset
, yoffset
;
125 for (xoffset
= 0; xoffset
< font
.u8Width
; xoffset
++)
127 for (yoffset
= 0; yoffset
< (font
.u8Height
+ 1); yoffset
++)
130 bit
= (column
[xoffset
] << (8 - (yoffset
+ 1))); // Shift current row bit left
131 bit
= (bit
>> 7); // Shift current row but right (results in 0x01 for black, and 0x00 for white)
134 drawPixel(x
+ xoffset
, y
+ yoffset
, color
);
141 /**************************************************************************/
143 @brief Helper method to accurately draw individual circle points
145 /**************************************************************************/
146 void drawCirclePoints(int cx
, int cy
, int x
, int y
, uint16_t color
)
150 drawPixel(cx
, cy
+ y
, color
);
151 drawPixel(cx
, cy
- y
, color
);
152 drawPixel(cx
+ y
, cy
, color
);
153 drawPixel(cx
- y
, cy
, color
);
157 drawPixel(cx
+ x
, cy
+ y
, color
);
158 drawPixel(cx
- x
, cy
+ y
, color
);
159 drawPixel(cx
+ x
, cy
- y
, color
);
160 drawPixel(cx
- x
, cy
- y
, color
);
164 drawPixel(cx
+ x
, cy
+ y
, color
);
165 drawPixel(cx
- x
, cy
+ y
, color
);
166 drawPixel(cx
+ x
, cy
- y
, color
);
167 drawPixel(cx
- x
, cy
- y
, color
);
168 drawPixel(cx
+ y
, cy
+ x
, color
);
169 drawPixel(cx
- y
, cy
+ x
, color
);
170 drawPixel(cx
+ y
, cy
- x
, color
);
171 drawPixel(cx
- y
, cy
- x
, color
);
175 /**************************************************************************/
177 /* ----------------------- Public Methods ------------------------------- */
179 /**************************************************************************/
181 /**************************************************************************/
183 @brief Draws a single pixel at the specified location
190 Color used when drawing
192 /**************************************************************************/
193 void drawPixel(uint16_t x
, uint16_t y
, uint16_t color
)
195 if ((x
>= lcdGetWidth()) || (y
>= lcdGetHeight()))
197 // Pixel out of range
202 lcdDrawPixel(x
, y
, color
);
205 /**************************************************************************/
207 @brief Fills the screen with the specified color
210 Color used when drawing
212 /**************************************************************************/
213 void drawFill(uint16_t color
)
218 /**************************************************************************/
220 @brief Draws a simple color test pattern
222 /**************************************************************************/
223 void drawTestPattern(void)
228 #if defined CFG_TFTLCD_INCLUDESMALLFONTS & CFG_TFTLCD_INCLUDESMALLFONTS == 1
229 /**************************************************************************/
231 @brief Draws a string using a small font (6 of 8 pixels high).
234 Starting x co-ordinate
236 Starting y co-ordinate
238 Color to use when rendering the font
242 Pointer to the FONT_DEF to use when drawing the string
248 #include "drivers/lcd/fonts/smallfonts.h"
250 drawStringSmall(1, 210, COLOR_WHITE, "5x8 System (Max 40 Characters)", Font_System5x8);
251 drawStringSmall(1, 220, COLOR_WHITE, "7x8 System (Max 30 Characters)", Font_System7x8);
255 /**************************************************************************/
256 void drawStringSmall(uint16_t x
, uint16_t y
, uint16_t color
, char* text
, struct FONT_DEF font
)
259 for (l
= 0; l
< strlen(text
); l
++)
261 drawCharSmall(x
+ (l
* (font
.u8Width
+ 1)), y
, color
, text
[l
], font
);
266 /**************************************************************************/
268 @brief Draws a string using the supplied font
271 Starting x co-ordinate
273 Starting y co-ordinate
275 Color to use when rendering the font
277 Pointer to the FONT_INFO to use when drawing the string
285 #include "drivers/lcd/tft/fonts/veramono9.h"
287 drawString(0, 90, COLOR_BLACK, &bitstreamVeraSansMono9ptFontInfo, "Vera Mono 9 (30 chars wide)");
288 drawString(0, 105, COLOR_BLACK, &bitstreamVeraSansMono9ptFontInfo, "123456789012345678901234567890");
292 /**************************************************************************/
293 void drawString(uint16_t x
, uint16_t y
, uint16_t color
, const FONT_INFO
*fontInfo
, char *str
)
295 uint16_t currentX
, charWidth
, characterToOutput
;
296 const FONT_CHAR_INFO
*charInfo
;
299 // set current x, y to that of requested
305 // get character to output
306 characterToOutput
= *str
;
309 charInfo
= fontInfo
->charInfo
;
311 // some fonts have character descriptors, some don't
312 if (charInfo
!= NULL
)
314 // get correct char offset
315 charInfo
+= (characterToOutput
- fontInfo
->startChar
);
317 // get width from char info
318 charWidth
= charInfo
->widthBits
;
320 // get offset from char info
321 charOffset
= charInfo
->offset
;
325 // if no char info, char width is always 5
328 // char offset - assume 5 * letter offset
329 charOffset
= (characterToOutput
- fontInfo
->startChar
) * 5;
332 // Send individual characters
333 drawCharBitmap(currentX
, y
, color
, &fontInfo
->data
[charOffset
], fontInfo
->heightPages
, charWidth
);
336 currentX
+= charWidth
+ 1;
343 /**************************************************************************/
345 @brief Returns the width in pixels of a string when it is rendered
347 This method can be used to determine whether a string will fit
348 inside a specific area, or if it needs to be broken up into multiple
349 lines to be properly rendered on the screen.
351 This function only applied to bitmap fonts (which can have variable
352 widths). All smallfonts (if available) are fixed width and can
353 easily have their width calculated without costly functions like
357 Pointer to the FONT_INFO for the font that will be used
359 The string that will be rendered
361 /**************************************************************************/
362 uint16_t drawGetStringWidth(const FONT_INFO
*fontInfo
, char *str
)
366 uint32_t startChar
= fontInfo
->startChar
;
369 for (currChar
= *str
; currChar
; currChar
= *(++str
))
371 // if char info exists for the font, use width from there
372 if (fontInfo
->charInfo
!= NULL
)
374 width
+= fontInfo
->charInfo
[currChar
- startChar
].widthBits
+ 1;
382 /* return the wdith */
386 /**************************************************************************/
388 @brief Draws a bresenham line
391 Starting x co-ordinate
393 Starting y co-ordinate
399 Color used when drawing
401 /**************************************************************************/
402 void drawLine ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
404 drawLineDotted(x0
, y0
, x1
, y1
, 0, 1, color
);
407 /**************************************************************************/
409 @brief Draws a bresenham line with a fixed pattern of empty
412 Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
415 Starting x co-ordinate
417 Starting y co-ordinate
423 The number of 'empty' pixels to render
425 The number of 'solid' pixels to render
427 Color used when drawing
429 /**************************************************************************/
430 void drawLineDotted ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t empty
, uint16_t solid
, uint16_t color
)
437 // If a negative y int was passed in it will overflow to 65K something
438 // Ugly, but drawCircleFilled() can pass in negative values so we need
439 // to check the values here
440 y0
= y0
> 65000 ? 0 : y0
;
441 y1
= y1
> 65000 ? 0 : y1
;
443 // Check if we can use the optimised horizontal line method
444 if ((y0
== y1
) && (empty
== 0))
446 lcdDrawHLine(x0
, x1
, y0
, color
);
450 // Check if we can use the optimised vertical line method.
451 // This can make a huge difference in performance, but may
452 // not work properly on every LCD controller:
453 // ex.: drawCircleFilled(120, 160, 50, COLOR_RED);
454 // = 678834 cycles using lcdDrawVLine w/ILI9328 = 9.43mS @ 72MHz
455 // = 7546261 w/o lcdDrawVLine, setting each pixel = 104.8mS @ 72MHz
456 if ((x0
== x1
) && (empty
== 0))
458 // Warning: This may actually be slower than drawing individual pixels on
459 // short lines ... Set a minimum line size to use the 'optimised' method
460 // (which changes the screen orientation) ?
461 lcdDrawVLine(x0
, y0
, y1
, color
);
465 // Draw non-horizontal or dotted line
469 int emptycount
, solidcount
;
471 if (dy
< 0) { dy
= -dy
; stepy
= -1; } else { stepy
= 1; }
472 if (dx
< 0) { dx
= -dx
; stepx
= -1; } else { stepx
= 1; }
473 dy
<<= 1; // dy is now 2*dy
474 dx
<<= 1; // dx is now 2*dx
479 drawPixel(x0
, y0
, color
); // always start with solid pixels
483 int fraction
= dy
- (dx
>> 1); // same as 2*dy - dx
489 fraction
-= dx
; // same as fraction -= 2*dx
492 fraction
+= dy
; // same as fraction -= 2*dy
495 // always draw a pixel ... no dotted line requested
496 drawPixel(x0
, y0
, color
);
500 // Draw solid pxiel and decrement counter
501 drawPixel(x0
, y0
, color
);
506 // Empty pixel ... don't draw anything an decrement counter
511 // Reset counters and draw solid pixel
514 drawPixel(x0
, y0
, color
);
521 int fraction
= dx
- (dy
>> 1);
533 // always draw a pixel ... no dotted line requested
534 drawPixel(x0
, y0
, color
);
538 // Draw solid pxiel and decrement counter
539 drawPixel(x0
, y0
, color
);
544 // Empty pixel ... don't draw anything an decrement counter
549 // Reset counters and draw solid pixel
552 drawPixel(x0
, y0
, color
);
559 /**************************************************************************/
561 @brief Draws a circle
563 Based on: http://www.cs.unc.edu/~mcmillan/comp136/Lecture7/circle.html
566 The horizontal center of the circle
568 The vertical center of the circle
570 The circle's radius in pixels
572 Color used when drawing
574 /**************************************************************************/
575 void drawCircle (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, uint16_t color
)
579 int p
= (5 - radius
*4)/4;
581 drawCirclePoints(xCenter
, yCenter
, x
, y
, color
);
594 drawCirclePoints(xCenter
, yCenter
, x
, y
, color
);
598 /**************************************************************************/
600 @brief Draws a filled circle
603 The horizontal center of the circle
605 The vertical center of the circle
607 The circle's radius in pixels
609 Color used when drawing
611 /**************************************************************************/
612 void drawCircleFilled (uint16_t xCenter
, uint16_t yCenter
, uint16_t radius
, uint16_t color
)
614 int16_t f
= 1 - radius
;
616 int16_t ddF_y
= -2 * radius
;
619 int16_t xc_px
, yc_my
, xc_mx
, xc_py
, yc_mx
, xc_my
;
620 int16_t lcdWidth
= lcdGetWidth();
622 if (xCenter
< lcdWidth
) drawLine(xCenter
, yCenter
-radius
< 0 ? 0 : yCenter
-radius
, xCenter
, (yCenter
-radius
) + (2*radius
), color
);
643 // Make sure X positions are not negative or too large or the pixels will
644 // overflow. Y overflow is handled in drawLine().
645 if ((xc_px
< lcdWidth
) && (xc_px
>= 0)) drawLine(xc_px
, yc_my
, xc_px
, yc_my
+ 2*y
, color
);
646 if ((xc_mx
< lcdWidth
) && (xc_mx
>= 0)) drawLine(xc_mx
, yc_my
, xc_mx
, yc_my
+ 2*y
, color
);
647 if ((xc_py
< lcdWidth
) && (xc_py
>= 0)) drawLine(xc_py
, yc_mx
, xc_py
, yc_mx
+ 2*x
, color
);
648 if ((xc_my
< lcdWidth
) && (xc_my
>= 0)) drawLine(xc_my
, yc_mx
, xc_my
, yc_mx
+ 2*x
, color
);
652 /**************************************************************************/
654 @brief Draws a simple arrow of the specified width
657 X co-ordinate of the smallest point of the arrow
659 Y co-ordinate of the smallest point of the arrow
661 Total width/height of the arrow in pixels
663 The direction that the arrow is pointing
665 Color used when drawing
667 /**************************************************************************/
668 void drawArrow(uint16_t x
, uint16_t y
, uint16_t size
, drawDirection_t direction
, uint16_t color
)
670 drawPixel(x
, y
, color
);
680 case DRAW_DIRECTION_LEFT
:
681 for (i
= 1; i
<size
; i
++)
683 drawLine(x
+i
, y
-i
, x
+i
, y
+i
, color
);
686 case DRAW_DIRECTION_RIGHT
:
687 for (i
= 1; i
<size
; i
++)
689 drawLine(x
-i
, y
-i
, x
-i
, y
+i
, color
);
692 case DRAW_DIRECTION_UP
:
693 for (i
= 1; i
<size
; i
++)
695 drawLine(x
-i
, y
+i
, x
+i
, y
+i
, color
);
698 case DRAW_DIRECTION_DOWN
:
699 for (i
= 1; i
<size
; i
++)
701 drawLine(x
-i
, y
-i
, x
+i
, y
-i
, color
);
709 /**************************************************************************/
711 @brief Draws a simple (empty) rectangle
714 Starting x co-ordinate
716 Starting y co-ordinate
722 Color used when drawing
724 /**************************************************************************/
725 void drawRectangle ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
745 drawLine (x0
, y0
, x1
, y0
, color
);
746 drawLine (x1
, y0
, x1
, y1
, color
);
747 drawLine (x1
, y1
, x0
, y1
, color
);
748 drawLine (x0
, y1
, x0
, y0
, color
);
751 /**************************************************************************/
753 @brief Draws a filled rectangle
756 Starting x co-ordinate
758 Starting y co-ordinate
764 Color used when drawing
766 /**************************************************************************/
767 void drawRectangleFilled ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
)
789 for (height
= y0
; y1
> height
- 1; ++height
)
791 drawLine(x0
, height
, x1
, height
, color
);
795 /**************************************************************************/
797 @brief Draws a filled rectangle with rounded corners
800 Starting x co-ordinate
802 Starting y co-ordinate
808 Color used when drawing
810 Corner radius in pixels
812 Which corners to round
814 /**************************************************************************/
815 void drawRectangleRounded ( uint16_t x0
, uint16_t y0
, uint16_t x1
, uint16_t y1
, uint16_t color
, uint16_t radius
, drawRoundedCorners_t corners
)
820 if (corners
== DRAW_ROUNDEDCORNERS_NONE
)
822 drawRectangleFilled(x0
, y0
, x1
, y1
, color
);
836 if (radius
> height
/ 2)
843 drawRectangleFilled(x0
+ radius
, y0
, x1
- radius
, y1
, color
);
847 case DRAW_ROUNDEDCORNERS_ALL
:
848 drawCircleFilled(x0
+ radius
, y0
+ radius
, radius
, color
);
849 drawCircleFilled(x1
- radius
, y0
+ radius
, radius
, color
);
850 drawCircleFilled(x0
+ radius
, y1
- radius
, radius
, color
);
851 drawCircleFilled(x1
- radius
, y1
- radius
, radius
, color
);
852 if (radius
*2+1 < height
)
854 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
- radius
, color
);
855 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
- radius
, color
);
858 case DRAW_ROUNDEDCORNERS_TOP
:
859 drawCircleFilled(x0
+ radius
, y0
+ radius
, radius
, color
);
860 drawCircleFilled(x1
- radius
, y0
+ radius
, radius
, color
);
861 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
, color
);
862 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
, color
);
864 case DRAW_ROUNDEDCORNERS_BOTTOM
:
865 drawCircleFilled(x0
+ radius
, y1
- radius
, radius
, color
);
866 drawCircleFilled(x1
- radius
, y1
- radius
, radius
, color
);
867 drawRectangleFilled(x0
, y0
, x0
+ radius
, y1
- radius
, color
);
868 drawRectangleFilled(x1
- radius
, y0
, x1
, y1
- radius
, color
);
870 case DRAW_ROUNDEDCORNERS_LEFT
:
871 drawCircleFilled(x0
+ radius
, y0
+ radius
, radius
, color
);
872 drawCircleFilled(x0
+ radius
, y1
- radius
, radius
, color
);
873 if (radius
*2+1 < height
)
875 drawRectangleFilled(x0
, y0
+ radius
, x0
+ radius
, y1
- radius
, color
);
877 drawRectangleFilled(x1
- radius
, y0
, x1
, y1
, color
);
879 case DRAW_ROUNDEDCORNERS_RIGHT
:
880 drawCircleFilled(x1
- radius
, y0
+ radius
, radius
, color
);
881 drawCircleFilled(x1
- radius
, y1
- radius
, radius
, color
);
882 if (radius
*2+1 < height
)
884 drawRectangleFilled(x1
- radius
, y0
+ radius
, x1
, y1
- radius
, color
);
886 drawRectangleFilled(x0
, y0
, x0
+ radius
, y1
, color
);
893 /**************************************************************************/
895 @brief Converts a 24-bit RGB color to an equivalent 16-bit RGB565 value
908 // Get 16-bit equivalent of 24-bit color
909 uint16_t gray = drawRGB24toRGB565(0x33, 0x33, 0x33);
913 /**************************************************************************/
914 uint16_t drawRGB24toRGB565(uint8_t r
, uint8_t g
, uint8_t b
)
916 return ((r
/ 8) << 11) | ((g
/ 4) << 5) | (b
/ 8);
919 /**************************************************************************/
921 @brief Converts a 16-bit RGB565 color to a standard 32-bit BGRA32
922 color (with alpha set to 0xFF)
931 // First convert 24-bit color to RGB565
932 uint16_t rgb565 = drawRGB24toRGB565(0xFF, 0x00, 0x00);
934 // Convert RGB565 color back to BGRA32
935 uint32_t bgra32 = drawRGB565toBGRA32(rgb565);
938 printf("BGRA32: 0x%08X R: %u G: %u B: %u A: %u \r\n",
940 (bgra32 & 0x000000FF), // Blue
941 (bgra32 & 0x0000FF00) >> 8, // Green
942 (bgra32 & 0x00FF0000) >> 16, // Red
943 (bgra32 & 0xFF000000) >> 24); // Alpha
947 /**************************************************************************/
948 uint32_t drawRGB565toBGRA32(uint16_t color
)
950 uint32_t bits
= (uint32_t)color
;
951 uint32_t blue
= bits
& 0x001F; // 5 bits blue
952 uint32_t green
= bits
& 0x07E0; // 6 bits green
953 uint32_t red
= bits
& 0xF800; // 5 bits red
955 // Return shifted bits with alpha set to 0xFF
956 return (red
<< 8) | (green
<< 5) | (blue
<< 3) | 0xFF000000;
959 /**************************************************************************/
961 @brief Reverses a 16-bit color from BGR to RGB
963 /**************************************************************************/
964 uint16_t drawBGR2RGB(uint16_t color
)
968 b
= (color
>>0) & 0x1f;
969 g
= (color
>>5) & 0x3f;
970 r
= (color
>>11) & 0x1f;
972 return( (b
<<11) + (g
<<5) + (r
<<0) );
975 /**************************************************************************/
977 @brief Draws a progress bar with rounded corners
984 Total width of the progress bar in pixels
986 Total height of the progress bar in pixels
987 @param[in] borderCorners
988 The type of rounded corners to render with the progress bar border
989 @param[in] progressCorners
990 The type of rounded corners to render with the inner progress bar
991 @param[in] borderColor
992 16-bit color for the outer border
993 @param[in] borderFillColor
994 16-bit color for the interior of the outer border
995 @param[in] progressBorderColor
996 16-bit color for the progress bar's border
997 @param[in] progressFillColor
998 16-bit color for the inner bar's fill
1000 Progress percentage (between 0 and 100)
1005 #include "drivers/lcd/tft/drawing.h"
1007 // Draw a the progress bar (150x15 pixels large, starting at X:10, Y:195
1008 // with rounded corners on the top and showing 72% progress)
1009 drawProgressBar(10, 195, 150, 15, DRAW_ROUNDEDCORNERS_TOP, DRAW_ROUNDEDCORNERS_TOP, COLOR_DARKERGRAY, COLOR_DARKGRAY, COLOR_LIMEGREENDIM, COLOR_LIMEGREEN, 72 );
1013 /**************************************************************************/
1014 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
)
1016 // Draw border with rounded corners
1017 drawRectangleRounded(x
, y
, x
+ width
, y
+ height
, borderColor
, 5, borderCorners
);
1018 drawRectangleRounded(x
+1, y
+1, x
+ width
- 1, y
+ height
- 1, borderFillColor
, 5, borderCorners
);
1021 if (progress
> 0 && progress
<= 100)
1023 // Calculate bar size
1025 bw
= (width
- 6); // bar at 100%
1026 if (progress
!= 100)
1028 bw
= (bw
* progress
) / 100;
1030 drawRectangleRounded(x
+ 3, y
+ 3, bw
+ x
+ 3, y
+ height
- 3, progressBorderColor
, 5, progressCorners
);
1031 drawRectangleRounded(x
+ 4, y
+ 4, bw
+ x
+ 3 - 1, y
+ height
- 4, progressFillColor
, 5, progressCorners
);
1035 /**************************************************************************/
1037 @brief Draws a simple button
1044 Total width of the button in pixels
1046 Total height of the button in pixels
1048 Pointer to the FONT_INFO used to render the button text
1049 @param[in] fontHeight
1050 The height in pixels of the font (used for centering)
1051 @param[in] borderclr
1052 The rgb565 border color
1054 The rgb565 background color
1056 The rgb565 font color
1058 The text to render on the button
1064 #include "drivers/lcd/tft/drawing.h"
1065 #include "drivers/lcd/tft/fonts/dejavusansbold9.h"
1067 // Draw two buttons using Vera Sans Bold 9
1068 drawButton(20, 195, 200, 35, &dejaVuSansBold9ptFontInfo, 7, COLOR_DARKERGRAY, COLOR_DARKERGRAY, COLOR_WHITE, "System Settings");
1069 drawButton(20, 235, 200, 35, &dejaVuSansBold9ptFontInfo, 7, COLOR_LIMEGREENDIM, COLOR_LIMEGREEN, COLOR_BLACK, "System Settings");
1073 /**************************************************************************/
1074 void drawButton(uint16_t x
, uint16_t y
, uint16_t width
, uint16_t height
, const FONT_INFO
*fontInfo
, uint16_t fontHeight
, uint16_t borderclr
, uint16_t fillclr
, uint16_t fontclr
, char* text
)
1076 uint16_t border
, fill
, font
, activeborder
, activefill
, activefont
;
1079 border
= COLOR_GRAY_30
;
1080 fill
= COLOR_GRAY_30
;
1082 activeborder
= COLOR_THEME_DEFAULT_DARKER
;
1083 activefill
= COLOR_THEME_DEFAULT_BASE
;
1084 activefont
= COLOR_BLACK
;
1087 drawRectangleRounded(x
, y
, x
+ width
, y
+ height
, borderclr
, 5, DRAW_ROUNDEDCORNERS_ALL
);
1089 drawRectangleRounded(x
+2, y
+2, x
+width
-2, y
+height
-2, fillclr
, 5, DRAW_ROUNDEDCORNERS_ALL
);
1094 uint16_t textWidth
= drawGetStringWidth(&*fontInfo
, text
);
1095 uint16_t xStart
= x
+ (width
/ 2) - (textWidth
/ 2);
1096 uint16_t yStart
= y
+ (height
/ 2) - (fontHeight
/ 2) + 1;
1097 drawString(xStart
, yStart
, fontclr
, &*fontInfo
, text
);
1101 /**************************************************************************/
1103 @brief Renders a 16x16 monochrome icon using the supplied uint16_t
1107 The horizontal location to start rendering from
1109 The vertical location to start rendering from
1111 The RGB565 color to use when rendering the icon
1113 The uint16_t array containing the 16x16 image data
1119 #include "drivers/lcd/tft/drawing.h"
1120 #include "drivers/lcd/icons16.h"
1122 // Renders the info icon, which has two seperate parts ... the exterior
1123 // and a seperate interior mask if you want to fill the contents with a
1125 drawIcon16(132, 202, COLOR_BLUE, icons16_info);
1126 drawIcon16(132, 202, COLOR_WHITE, icons16_info_interior);
1130 /**************************************************************************/
1131 void drawIcon16(uint16_t x
, uint16_t y
, uint16_t color
, uint16_t icon
[])
1135 for (i
= 0; i
<16; i
++)
1137 if (icon
[i
] & (0X8000)) drawPixel(x
, y
+i
, color
);
1138 if (icon
[i
] & (0X4000)) drawPixel(x
+1, y
+i
, color
);
1139 if (icon
[i
] & (0X2000)) drawPixel(x
+2, y
+i
, color
);
1140 if (icon
[i
] & (0X1000)) drawPixel(x
+3, y
+i
, color
);
1141 if (icon
[i
] & (0X0800)) drawPixel(x
+4, y
+i
, color
);
1142 if (icon
[i
] & (0X0400)) drawPixel(x
+5, y
+i
, color
);
1143 if (icon
[i
] & (0X0200)) drawPixel(x
+6, y
+i
, color
);
1144 if (icon
[i
] & (0X0100)) drawPixel(x
+7, y
+i
, color
);
1145 if (icon
[i
] & (0X0080)) drawPixel(x
+8, y
+i
, color
);
1146 if (icon
[i
] & (0x0040)) drawPixel(x
+9, y
+i
, color
);
1147 if (icon
[i
] & (0X0020)) drawPixel(x
+10, y
+i
, color
);
1148 if (icon
[i
] & (0X0010)) drawPixel(x
+11, y
+i
, color
);
1149 if (icon
[i
] & (0X0008)) drawPixel(x
+12, y
+i
, color
);
1150 if (icon
[i
] & (0X0004)) drawPixel(x
+13, y
+i
, color
);
1151 if (icon
[i
] & (0X0002)) drawPixel(x
+14, y
+i
, color
);
1152 if (icon
[i
] & (0X0001)) drawPixel(x
+15, y
+i
, color
);
1157 /**************************************************************************/
1159 @brief Loads a 24-bit Windows bitmap image from an SD card and
1166 #include "drivers/lcd/tft/drawing.h"
1168 // Draw image.bmp (from the root folder) starting at pixel 0,0
1169 bmp_error_t error = drawBitmapImage(0, 0, "/image.bmp");
1175 case BMP_ERROR_SDINITFAIL:
1177 case BMP_ERROR_FILENOTFOUND:
1179 case BMP_ERROR_NOTABITMAP:
1180 // First two bytes of image not 'BM'
1182 case BMP_ERROR_INVALIDBITDEPTH:
1183 // Image is not 24-bits
1185 case BMP_ERROR_COMPRESSEDDATA:
1186 // Image contains compressed data
1188 case BMP_ERROR_INVALIDDIMENSIONS:
1189 // Width or Height is > LCD size
1191 case BMP_ERROR_PREMATUREEOF:
1192 // EOF unexpectedly reached in pixel data
1199 /**************************************************************************/
1200 bmp_error_t
drawBitmapImage(uint16_t x
, uint16_t y
, char *filename
)
1202 return bmpDrawBitmap(x
, y
, filename
);