Basic alpha-blending
[hackover2013-badge-firmware.git] / drivers / displays / tft / aafonts.c
1 /**************************************************************************/
2 /*!
3 @file aafonts.c
4 @author K. Townsend (microBuilder.eu)
5
6 @section LICENSE
7
8 Software License Agreement (BSD License)
9
10 Copyright (c) 2012, microBuilder SARL
11 All rights reserved.
12
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions are met:
15 1. Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
17 2. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
20 3. Neither the name of the copyright holders nor the
21 names of its contributors may be used to endorse or promote products
22 derived from this software without specific prior written permission.
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 /**************************************************************************/
36 #include "aafonts.h"
37
38 #include "drivers/displays/tft/lcd.h"
39 #include "drivers/displays/tft/drawing.h"
40
41 // Common color lookup tables for AA2 (4-color anti-aliased) fonts
42 const uint16_t COLORTABLE_AA2_WHITEONBLACK[4] = { 0x0000, 0x52AA, 0xAD55, 0xFFFF};
43 const uint16_t COLORTABLE_AA2_BLACKONWHITE[4] = { 0xFFFF, 0xAD55, 0x52AA, 0x0000};
44
45 // Common color lookup tables for AA4 (16-color anti-aliased) fonts
46 const uint16_t COLORTABLE_AA4_WHITEONBLACK[16] = { 0x0000, 0x1082, 0x2104, 0x3186, 0x4208, 0x528A, 0x630C, 0x738E, 0x8410, 0x9492, 0xA514, 0xB596, 0xC618, 0xD69A, 0xE71C, 0xFFFF};
47 const uint16_t COLORTABLE_AA4_BLACKONWHITE[16] = { 0xFFFF, 0xE71C, 0xD69A, 0xC618, 0xB596, 0xA514, 0x9492, 0x8410, 0x738E, 0x630C, 0x528A, 0x4208, 0x3186, 0x2104, 0x1082, 0x0000};
48
49 /**************************************************************************/
50 /* */
51 /* ----------------------- Private Methods ------------------------------ */
52 /* */
53 /**************************************************************************/
54
55 /**************************************************************************/
56 /*!
57 @brief Renders a single AA2 character on the screen
58
59 This text rendering method used a lookup table of pre-calculated
60 colors, and doesn't require any reads from the LCD (not all displays
61 support reading pixels back). This offers the best performance and
62 high-quality text, but can only be used on solid backgrounds where
63 the bgcolor is known.
64
65 @param[in] x
66 Top-left x position
67 @param[in] y
68 Top-left y position
69 @param[in] height
70 Font height in pixels
71 @param[in] character
72 Pointer to the aafontsCharInfo_t array with the char data
73 @param[in] colorTable
74 Pointer to the 4 element color lookup table
75 */
76 /**************************************************************************/
77 void aafontsDrawCharAA2( uint16_t x, uint16_t y, uint16_t height, aafontsCharInfo_t character, const uint16_t * colorTable)
78 {
79 uint16_t w, h, pos;
80 uint8_t color;
81
82 for (h = 0; h < height; h++)
83 {
84 pos = 0;
85 for (w = 0; w < character.width; w++)
86 {
87 color = character.charData[h*character.bytesPerRow + w/4];
88 switch (pos)
89 {
90 case 0:
91 color = (color >> 6) & 0x03;
92 break;
93 case 1:
94 color = (color >> 4) & 0x03;
95 break;
96 case 2:
97 color = (color >> 2) & 0x03;
98 break;
99 case 3:
100 color = color & 0x03;
101 break;
102 }
103 if (color) lcdDrawPixel(x+w, y+h, colorTable[color & 0xF]);
104 pos++;
105 if (pos == 4) pos = 0;
106 }
107 }
108 }
109
110 /**************************************************************************/
111 /*!
112 @brief Renders a single AA4 character on the screen
113
114 This text rendering method used a lookup table of pre-calculated
115 colors, and doesn't require any reads from the LCD (not all displays
116 support reading pixels back). This offers the best performance and
117 high-quality text, but can only be used on solid backgrounds where
118 the bgcolor is known.
119
120 @param[in] x
121 Top-left x position
122 @param[in] y
123 Top-left y position
124 @param[in] height
125 Font height in pixels
126 @param[in] character
127 Pointer to the aafontsCharInfo_t array with the char data
128 @param[in] colorTable
129 Pointer to the 16 element color lookup table
130 */
131 /**************************************************************************/
132 void aafontsDrawCharAA4( uint16_t x, uint16_t y, uint16_t height, aafontsCharInfo_t character, const uint16_t * colorTable)
133 {
134 uint16_t w, h;
135 uint8_t color;
136
137 for (h = 0; h < height; h++)
138 {
139 for (w = 0; w < character.width; w++)
140 {
141 color = character.charData[h*character.bytesPerRow + w/2];
142 if (!(w % 2)) color = (color >> 4);
143 if (color) lcdDrawPixel(x+w, y+h, colorTable[color & 0xF]);
144 }
145 }
146 }
147
148 /**************************************************************************/
149 /* */
150 /* ----------------------- Public Methods ------------------------------- */
151 /* */
152 /**************************************************************************/
153
154 /**************************************************************************/
155 /*!
156 @brief Draws a string using the supplied anti-aliased font
157
158 @param[in] x
159 Starting x co-ordinate
160 @param[in] y
161 Starting y co-ordinate
162 @param[in] colorTable
163 The color lookup table to use for the antialiased pixels
164 @param[in] font
165 Pointer to the aafontsFont_t to use when drawing the string
166 @param[in] str
167 The string to render
168
169 @section Example
170
171 @code
172
173 #include "drivers/displays/tft/aafonts.h"
174 #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
175 #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensedBold14_AA2.h"
176
177 // Fill screen with white (so that we can use the pre-defined color tables in aafonts.h)
178 lcdFillRGB(COLOR_WHITE);
179
180 aafontsDrawString(10, 100, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "1234567890");
181 aafontsDrawString(10, 120, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
182 aafontsDrawString(10, 140, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "abcdefghijklmnopqrstuvwxyz");
183 aafontsDrawString(10, 160, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "!\"#$%&'()*+,-./ :;<=>?");
184 aafontsDrawString(10, 180, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensed14_AA2, "@ [\\]^_ {|}~");
185
186 aafontsDrawString(10, 215, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "1234567890");
187 aafontsDrawString(10, 235, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
188 aafontsDrawString(10, 255, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "abcdefghijklmnopqrstuvwxyz");
189 aafontsDrawString(10, 275, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "!\"#$%&'()*+,-./ :;<=>?");
190 aafontsDrawString(10, 295, COLORTABLE_AA2_BLACKONWHITE, &DejaVuSansCondensedBold14_AA2, "@ [\\]^_ {|}~");
191
192 @endcode
193 */
194 /**************************************************************************/
195 void aafontsDrawString(uint16_t x, uint16_t y, const uint16_t * colorTable, const aafontsFont_t *font, char *str)
196 {
197 uint16_t currentX, charWidth, characterToOutput;
198 const aafontsCharInfo_t *charInfo;
199
200 // set current x, y to that of requested
201 currentX = x;
202
203 // while not NULL
204 while (*str != '\0')
205 {
206 // get character to output
207 characterToOutput = *str;
208
209 // Check if the character is within the font boundaries
210 if ((characterToOutput > font->lastChar) || (characterToOutput < font->firstChar))
211 {
212 // Character is out of bounds
213 // Insert space instead
214 charWidth = font->unknownCharWidth;
215 }
216 else
217 {
218 // get char info
219 charInfo = &(font->charTable[characterToOutput - font->firstChar]);
220 // get width from char info
221 charWidth = charInfo->width;
222 // Send individual characters
223 switch (font->fontType)
224 {
225 case AAFONTS_FONTTYPE_AA2:
226 aafontsDrawCharAA2(currentX, y, font->fontHeight, *charInfo, &colorTable[0]);
227 break;
228 case AAFONTS_FONTTYPE_AA4:
229 aafontsDrawCharAA4(currentX, y, font->fontHeight, *charInfo, &colorTable[0]);
230 break;
231 }
232 }
233
234 // Adjust x for the next character
235 currentX += charWidth;
236
237 // next char in string
238 str++;
239 }
240 }
241
242 /**************************************************************************/
243 /*!
244 @brief Returns the width in pixels of a string when it is rendered
245
246 This method can be used to determine whether a string will fit
247 inside a specific area, or if it needs to be broken up into multiple
248 lines to be properly rendered on the screen.
249
250 @param[in] font
251 Pointer to aafontsFont_t of the font that will be used
252 @param[in] str
253 The string that will be rendered
254
255 @section Example
256
257 @code
258
259 #include "drivers/displays/tft/aafonts.h"
260 #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
261
262 uint32_t w = aafontsGetStringWidth(&DejaVuSansCondensed14_AA2, "This is a simple test 123!!! (AA2)");
263
264 @endcode
265 */
266 /**************************************************************************/
267 uint16_t aafontsGetStringWidth(const aafontsFont_t *font, char *str)
268 {
269 uint16_t width = 0;
270 const aafontsCharInfo_t *charInfo;
271 uint32_t currChar;
272
273 // until termination
274 for (currChar = *str; currChar; currChar = *(++str))
275 {
276 // Check if the character is within the font boundaries
277 if ((currChar > font->lastChar) || (currChar < font->firstChar))
278 {
279 // Character is out of bounds
280 width += font->unknownCharWidth;
281 }
282 else
283 {
284 // get char info
285 charInfo = &(font->charTable[currChar - font->firstChar]);
286 // get width from char info
287 width += charInfo->width;
288 }
289 }
290
291 /* return the string width */
292 return width;
293 }
294
295 /**************************************************************************/
296 /*!
297 @brief Creates a 4 or 16 shade color between the specified bg and
298 fore color for use with anti-aliased fonts.
299
300 @note This method can be used to place anti-aliased in any color on
301 any known, solid-colored background.
302
303 You can get slightly higher-quality results by calculating
304 the color tables by hand, but this method is a convenient
305 method to create text in a variety of colors or on a variety
306 of backgrounds. Please note, though, that the visual quality
307 of the text heavily on the colors being used.
308
309 @param[in] bgColor
310 The RGB565 color of the background
311 @param[in] foreColor
312 The RGB565 fore color for the anti-aliased text
313 @param[in] colorTable
314 Pointer to the 4 or 16 element array that will be
315 populated with the individual color values
316 @param[in] tableSize
317 The number of elements in the colorTable array (acceptable
318 values are 4 for AA2 or 16 for AA4).
319
320 @section Example
321
322 @code
323
324 #include "drivers/displays/tft/colors.h"
325 #include "drivers/displays/tft/drawing.h"
326 #include "drivers/displays/tft/aafonts.h"
327 #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensed14_AA2.h"
328 #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensedBold14_AA2.h"
329
330 uint16_t bgColor = COLOR_RED;
331 uint16_t foreColor = COLOR_YELLOW;
332 uint16_t ctable[4];
333
334 // Calculate a 4 color lookup table using the fore and bg colors
335 aafontsCalculateColorTable(bgColor, foreColor, &ctable[0], 4);
336
337 // Render a solid rectangle for the background
338 drawRectangleFilled(10, 10, 200, 50, bgColor);
339
340 // Draw some AA2 anti-aliased text using the generated color table
341 aafontsDrawString(10, 13, ctable, &DejaVuSansCondensed14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
342 aafontsDrawString(10, 33, ctable, &DejaVuSansCondensedBold14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
343
344 @endcode
345 */
346 /**************************************************************************/
347 void aafontsCalculateColorTable(uint16_t bgColor, uint16_t foreColor, uint16_t *colorTable, size_t tableSize)
348 {
349 uint16_t i, stepsize;
350
351 if ((tableSize != 4) && (tableSize != 16))
352 return;
353
354 colorTable[0] = bgColor;
355 colorTable[tableSize - 1] = foreColor;
356
357 stepsize = 100/(tableSize-1);
358
359 for (i = 1; i < tableSize - 1; i++)
360 {
361 // Gradually decrease the amount of alpha-blending from high to low
362 colorTable[i] = colorsAlphaBlend(bgColor, foreColor, 100-i*stepsize);
363 }
364 }
This page took 0.066351 seconds and 5 git commands to generate.