Basic alpha-blending
[hackover2013-badge-firmware.git] / drivers / displays / tft / colors.c
1 /**************************************************************************/
2 /*!
3 @file colors.c
4 @author K. Townsend (microBuilder.eu)
5
6 Various helper functions to work with RGB565 colors, including
7 color conversion, color blending, and a basic set of predefined
8 color constants (see colors.h).
9
10 @section LICENSE
11
12 Software License Agreement (BSD License)
13
14 Copyright (c) 2012, Kevin Townsend
15 All rights reserved.
16
17 Redistribution and use in source and binary forms, with or without
18 modification, are permitted provided that the following conditions are met:
19 1. Redistributions of source code must retain the above copyright
20 notice, this list of conditions and the following disclaimer.
21 2. Redistributions in binary form must reproduce the above copyright
22 notice, this list of conditions and the following disclaimer in the
23 documentation and/or other materials provided with the distribution.
24 3. Neither the name of the copyright holders nor the
25 names of its contributors may be used to endorse or promote products
26 derived from this software without specific prior written permission.
27
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
29 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
32 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
39 /**************************************************************************/
40 #include <string.h>
41
42 #include "colors.h"
43
44 /**************************************************************************/
45 /* */
46 /* ----------------------- Private Methods ------------------------------ */
47 /* */
48 /**************************************************************************/
49
50 /**************************************************************************/
51 /* */
52 /* ----------------------- Public Methods ------------------------------- */
53 /* */
54 /**************************************************************************/
55
56 /**************************************************************************/
57 /*!
58 @brief Converts a 24-bit RGB color to an equivalent 16-bit RGB565 value
59
60 @param[in] r
61 8-bit red
62 @param[in] g
63 8-bit green
64 @param[in] b
65 8-bit blue
66
67 @section Example
68
69 @code
70
71 // Get 16-bit equivalent of 24-bit color
72 uint16_t gray = colorsRGB24toRGB565(0x33, 0x33, 0x33);
73
74 @endcode
75 */
76 /**************************************************************************/
77 uint16_t colorsRGB24toRGB565(uint8_t r, uint8_t g, uint8_t b)
78 {
79 return ((r / 8) << 11) | ((g / 4) << 5) | (b / 8);
80 }
81
82 /**************************************************************************/
83 /*!
84 @brief Converts a 16-bit RGB565 color to a standard 32-bit BGRA32
85 color (with alpha set to 0xFF)
86
87 @param[in] color
88 16-bit rgb565 color
89
90 @section Example
91
92 @code
93
94 // First convert 24-bit color to RGB565
95 uint16_t rgb565 = colorsRGB24toRGB565(0xFF, 0x00, 0x00);
96
97 // Convert RGB565 color back to BGRA32
98 uint32_t bgra32 = colorsRGB565toBGRA32(rgb565);
99
100 // Display results
101 printf("BGRA32: 0x%08X R: %u G: %u B: %u A: %u \r\n",
102 bgra32,
103 (bgra32 & 0x000000FF), // Blue
104 (bgra32 & 0x0000FF00) >> 8, // Green
105 (bgra32 & 0x00FF0000) >> 16, // Red
106 (bgra32 & 0xFF000000) >> 24); // Alpha
107
108 @endcode
109 */
110 /**************************************************************************/
111 uint32_t colorsRGB565toBGRA32(uint16_t color)
112 {
113 uint32_t bits = (uint32_t)color;
114 uint32_t blue = bits & 0x001F; // 5 bits blue
115 uint32_t green = bits & 0x07E0; // 6 bits green
116 uint32_t red = bits & 0xF800; // 5 bits red
117
118 // Return shifted bits with alpha set to 0xFF
119 return (red << 8) | (green << 5) | (blue << 3) | 0xFF000000;
120 }
121
122 /**************************************************************************/
123 /*!
124 @brief Reverses a 16-bit color from BGR to RGB or vice verse
125 */
126 /**************************************************************************/
127 uint16_t colorsBGR2RGB(uint16_t color)
128 {
129 uint16_t r, g, b;
130
131 b = (color>>0) & 0x1f;
132 g = (color>>5) & 0x3f;
133 r = (color>>11) & 0x1f;
134
135 return( (b<<11) + (g<<5) + (r<<0) );
136 }
137
138 /**************************************************************************/
139 /*!
140 @brief Adjusts the supplied color to have the specified intensity
141 (0..100). 100 will leave the color as is at full intensity,
142 50 will reduce the color intensity by half, and 0 will return
143 black.
144
145 This function is useful for anti-aliasing and sub-pixel
146 rendering since colors are returned as a percentage of
147 the original value, depending on the amount of space they
148 take up in the sub-pixel array.
149
150 @param[in] color
151 Base color (rgb565)
152 @param[in] intensity
153 Color intensity relative to the source (0..100)
154
155 @section Example
156
157 @code
158
159 #include "drivers/displays/tft/colors.h"
160
161 uint16_t newColor;
162
163 // Draw a pure red rectangle
164 drawRectangleFilled(10, 10, 200, 100, COLOR_RED);
165
166 // Draw a rectangle at 50% intensity red
167 newColor = colorsDim(COLOR_RED, 50);
168 drawRectangleFilled(20, 20, 190, 90, newColor);
169
170 // Draw a rectangle at 25% intensity red
171 newColor = colorsDim(COLOR_RED, 25);
172 drawRectangleFilled(30, 30, 180, 80, newColor);
173
174 // Draw a rectangle at 0% intensity red
175 newColor = colorsDim(COLOR_RED, 0);
176 drawRectangleFilled(40, 40, 170, 70, newColor);
177
178 @endcode
179 */
180 /**************************************************************************/
181 uint16_t colorsDim(uint16_t color, uint8_t intensity)
182 {
183 uint16_t r, g, b; // Individual component colors
184
185 // Add intensity adjusted forecolor
186 r = ((((color >> 11) & 0x1F) * intensity) / 100) & 0x1F;
187 g = ((((color >> 5) & 0x3F) * intensity) / 100) & 0x3F;
188 b = (((color & 0x1F) * intensity) / 100) & 0x1F;
189
190 return (r << 11) | (g << 6) | b;
191 }
192
193 /**************************************************************************/
194 /*!
195 @brief Returns an alpha-blended color based on the supplied bg color,
196 fore color, and intensity value (0..100).
197
198 This function is used when alpha-blending anti-aliased fonts
199 with an existing background image, amongst other things, and
200 can be used to create images that appear to be 'faded' or
201 semi-transparent, though at the expense of slow updates since
202 reading pixels from most LCD controllers is an extremely
203 expensive operation.
204
205 @param[in] bgColor
206 Background color (rgb565)
207 @param[in] foreColor
208 Forground color (rgb565)
209 @param[in] fadePercent
210 Visibility of the background color in percent (0..100).
211 The higher the number, the more visible the back color
212 becomes. 100% signifies that the back color is entirely
213 visible (only the BG color is shown), 0% signifies
214 that only the fore color is shown, and 25% would
215 indicate that the background is visible at approximately
216 25% intensity (combined with 75% of the fore color).
217
218 @section Example
219
220 @code
221
222 #include "drivers/displays/tft/drawing.h"
223 #include "drivers/displays/tft/colors.h"
224
225 uint16_t bg = COLOR_GREEN;
226 uint16_t fore = COLOR_WHITE;
227
228 // Calculate the intermediate color with 25% fading
229 uint16_t result = colorsAlphaBlend(bg, fore, 25);
230
231 drawRectangleFilled(10, 10, 50, 50, bg);
232 drawRectangleFilled(60, 10, 100, 50, fore);
233 drawRectangleFilled(35, 60, 75, 100, result);
234
235 @endcode
236 */
237 /**************************************************************************/
238 uint16_t colorsAlphaBlend(uint16_t bgColor, uint16_t foreColor, uint8_t fadePercent)
239 {
240 uint16_t br, bg, bb; // Background component colors
241 uint16_t fr, fg, fb; // Foreground component colors
242 uint16_t newr, newg, newb; // Blended component colors
243
244 if (fadePercent > 100)
245 {
246 fadePercent = 100;
247 }
248
249 // Short cut if the color is full intensity
250 if (fadePercent == 100)
251 return foreColor;
252
253 // Note: This algorithm can definately be optimised!
254
255 // Break out component colors
256 br = ((bgColor >> 11) & 0x1F);
257 fr = ((foreColor >> 11) & 0x1F);
258 bg = ((bgColor >> 5) & 0x3F);
259 fg = ((foreColor >> 5) & 0x3F);
260 bb = (bgColor & 0x1F);
261 fb = (foreColor & 0x1F);
262
263 // Z = intensity * bgcolor + (100 - intensity) * forecolor
264 newr = (fadePercent * br + (100 - fadePercent) * fr) / 100;
265 newg = (fadePercent * bg + (100 - fadePercent) * fg) / 200; // Need to use 5-bit green for accurate colors :(
266 newb = (fadePercent * bb + (100 - fadePercent) * fb) / 100;
267
268 return (newr << 11) | (newg << 6) | newb;
269 }
This page took 0.075665 seconds and 5 git commands to generate.