From 9e04bf6c52ed702ff98f18fc7d5508bc5f453767 Mon Sep 17 00:00:00 2001 From: Kevin Townsend Date: Sun, 25 Mar 2012 05:37:14 +0200 Subject: [PATCH] Basic alpha-blending --- drivers/displays/tft/aafonts.c | 79 ++++++++++++++++++++++++++++++++-- drivers/displays/tft/aafonts.h | 11 +++-- drivers/displays/tft/colors.c | 41 ++++++++++++------ drivers/displays/tft/colors.h | 2 +- 4 files changed, 111 insertions(+), 22 deletions(-) diff --git a/drivers/displays/tft/aafonts.c b/drivers/displays/tft/aafonts.c index dc400b5..c425bf9 100644 --- a/drivers/displays/tft/aafonts.c +++ b/drivers/displays/tft/aafonts.c @@ -39,12 +39,12 @@ #include "drivers/displays/tft/drawing.h" // Common color lookup tables for AA2 (4-color anti-aliased) fonts -static const uint16_t COLORTABLE_AA2_WHITEONBLACK[4] = { 0x0000, 0x52AA, 0xAD55, 0xFFFF}; -static const uint16_t COLORTABLE_AA2_BLACKONWHITE[4] = { 0xFFFF, 0xAD55, 0x52AA, 0x0000}; +const uint16_t COLORTABLE_AA2_WHITEONBLACK[4] = { 0x0000, 0x52AA, 0xAD55, 0xFFFF}; +const uint16_t COLORTABLE_AA2_BLACKONWHITE[4] = { 0xFFFF, 0xAD55, 0x52AA, 0x0000}; // Common color lookup tables for AA4 (16-color anti-aliased) fonts -static const uint16_t COLORTABLE_AA4_WHITEONBLACK[16] = { 0x0000, 0x1082, 0x2104, 0x3186, 0x4208, 0x528A, 0x630C, 0x738E, 0x8410, 0x9492, 0xA514, 0xB596, 0xC618, 0xD69A, 0xE71C, 0xFFFF}; -static const uint16_t COLORTABLE_AA4_BLACKONWHITE[16] = { 0xFFFF, 0xE71C, 0xD69A, 0xC618, 0xB596, 0xA514, 0x9492, 0x8410, 0x738E, 0x630C, 0x528A, 0x4208, 0x3186, 0x2104, 0x1082, 0x0000}; +const uint16_t COLORTABLE_AA4_WHITEONBLACK[16] = { 0x0000, 0x1082, 0x2104, 0x3186, 0x4208, 0x528A, 0x630C, 0x738E, 0x8410, 0x9492, 0xA514, 0xB596, 0xC618, 0xD69A, 0xE71C, 0xFFFF}; +const uint16_t COLORTABLE_AA4_BLACKONWHITE[16] = { 0xFFFF, 0xE71C, 0xD69A, 0xC618, 0xB596, 0xA514, 0x9492, 0x8410, 0x738E, 0x630C, 0x528A, 0x4208, 0x3186, 0x2104, 0x1082, 0x0000}; /**************************************************************************/ /* */ @@ -291,3 +291,74 @@ uint16_t aafontsGetStringWidth(const aafontsFont_t *font, char *str) /* return the string width */ return width; } + +/**************************************************************************/ +/*! + @brief Creates a 4 or 16 shade color between the specified bg and + fore color for use with anti-aliased fonts. + + @note This method can be used to place anti-aliased in any color on + any known, solid-colored background. + + You can get slightly higher-quality results by calculating + the color tables by hand, but this method is a convenient + method to create text in a variety of colors or on a variety + of backgrounds. Please note, though, that the visual quality + of the text heavily on the colors being used. + + @param[in] bgColor + The RGB565 color of the background + @param[in] foreColor + The RGB565 fore color for the anti-aliased text + @param[in] colorTable + Pointer to the 4 or 16 element array that will be + populated with the individual color values + @param[in] tableSize + The number of elements in the colorTable array (acceptable + values are 4 for AA2 or 16 for AA4). + + @section Example + + @code + + #include "drivers/displays/tft/colors.h" + #include "drivers/displays/tft/drawing.h" + #include "drivers/displays/tft/aafonts.h" + #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensed14_AA2.h" + #include "drivers/displays/tft/aafonts/aa2/DejaVuSansCondensedBold14_AA2.h" + + uint16_t bgColor = COLOR_RED; + uint16_t foreColor = COLOR_YELLOW; + uint16_t ctable[4]; + + // Calculate a 4 color lookup table using the fore and bg colors + aafontsCalculateColorTable(bgColor, foreColor, &ctable[0], 4); + + // Render a solid rectangle for the background + drawRectangleFilled(10, 10, 200, 50, bgColor); + + // Draw some AA2 anti-aliased text using the generated color table + aafontsDrawString(10, 13, ctable, &DejaVuSansCondensed14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + aafontsDrawString(10, 33, ctable, &DejaVuSansCondensedBold14_AA2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + @endcode +*/ +/**************************************************************************/ +void aafontsCalculateColorTable(uint16_t bgColor, uint16_t foreColor, uint16_t *colorTable, size_t tableSize) +{ + uint16_t i, stepsize; + + if ((tableSize != 4) && (tableSize != 16)) + return; + + colorTable[0] = bgColor; + colorTable[tableSize - 1] = foreColor; + + stepsize = 100/(tableSize-1); + + for (i = 1; i < tableSize - 1; i++) + { + // Gradually decrease the amount of alpha-blending from high to low + colorTable[i] = colorsAlphaBlend(bgColor, foreColor, 100-i*stepsize); + } +} diff --git a/drivers/displays/tft/aafonts.h b/drivers/displays/tft/aafonts.h index c510eaf..7d0ec34 100644 --- a/drivers/displays/tft/aafonts.h +++ b/drivers/displays/tft/aafonts.h @@ -64,8 +64,13 @@ typedef struct aafontsFont_s const aafontsCharInfo_t *charTable; /* Pointer to the aafontsCharInfo_t array containing the char data */ } aafontsFont_t; -uint16_t aafontsBlendColor ( uint16_t bgColor, uint16_t foreColor, uint8_t intensity ); -void aafontsDrawString( uint16_t x, uint16_t y, const uint16_t * colorTable, const aafontsFont_t *font, char *str ); -uint16_t aafontsGetStringWidth( const aafontsFont_t *font, char *str ); +extern const uint16_t COLORTABLE_AA2_WHITEONBLACK[4]; +extern const uint16_t COLORTABLE_AA2_BLACKONWHITE[4]; +extern const uint16_t COLORTABLE_AA4_WHITEONBLACK[16]; +extern const uint16_t COLORTABLE_AA4_BLACKONWHITE[16]; + +void aafontsDrawString ( uint16_t x, uint16_t y, const uint16_t * colorTable, const aafontsFont_t *font, char *str ); +uint16_t aafontsGetStringWidth ( const aafontsFont_t *font, char *str ); +void aafontsCalculateColorTable ( uint16_t bgColor, uint16_t foreColor, uint16_t *colorTable, size_t tableSize ); #endif diff --git a/drivers/displays/tft/colors.c b/drivers/displays/tft/colors.c index 74fdf00..7451264 100644 --- a/drivers/displays/tft/colors.c +++ b/drivers/displays/tft/colors.c @@ -206,40 +206,52 @@ uint16_t colorsDim(uint16_t color, uint8_t intensity) Background color (rgb565) @param[in] foreColor Forground color (rgb565) - @param[in] intensity - Intensity of the fore color for alpha-blending (0..100) + @param[in] fadePercent + Visibility of the background color in percent (0..100). + The higher the number, the more visible the back color + becomes. 100% signifies that the back color is entirely + visible (only the BG color is shown), 0% signifies + that only the fore color is shown, and 25% would + indicate that the background is visible at approximately + 25% intensity (combined with 75% of the fore color). @section Example @code + #include "drivers/displays/tft/drawing.h" #include "drivers/displays/tft/colors.h" - uint16_t mixedColor; + uint16_t bg = COLOR_GREEN; + uint16_t fore = COLOR_WHITE; + + // Calculate the intermediate color with 25% fading + uint16_t result = colorsAlphaBlend(bg, fore, 25); - // Alpha-blend white onto a black background at 50% intensity - mixedColor = colorsBlend(COLOR_BLACK, COLOR_WHITE, 50); + drawRectangleFilled(10, 10, 50, 50, bg); + drawRectangleFilled(60, 10, 100, 50, fore); + drawRectangleFilled(35, 60, 75, 100, result); @endcode */ /**************************************************************************/ -uint16_t colorsBlend(uint16_t bgColor, uint16_t foreColor, uint8_t intensity) +uint16_t colorsAlphaBlend(uint16_t bgColor, uint16_t foreColor, uint8_t fadePercent) { - // Note: This algorithm is buggy and needs to be redone! - uint16_t br, bg, bb; // Background component colors uint16_t fr, fg, fb; // Foreground component colors uint16_t newr, newg, newb; // Blended component colors - if (intensity > 100) + if (fadePercent > 100) { - intensity = 100; + fadePercent = 100; } // Short cut if the color is full intensity - if (intensity == 100) + if (fadePercent == 100) return foreColor; + // Note: This algorithm can definately be optimised! + // Break out component colors br = ((bgColor >> 11) & 0x1F); fr = ((foreColor >> 11) & 0x1F); @@ -248,9 +260,10 @@ uint16_t colorsBlend(uint16_t bgColor, uint16_t foreColor, uint8_t intensity) bb = (bgColor & 0x1F); fb = (foreColor & 0x1F); - newr = (((fr-br) * intensity) / 100 + br) & 0x1F; - newg = (((fg-bg) * intensity) / 100 + bg) & 0x3F; - newb = (((fb-bb) * intensity) / 100 + bb) & 0x1F; + // Z = intensity * bgcolor + (100 - intensity) * forecolor + newr = (fadePercent * br + (100 - fadePercent) * fr) / 100; + newg = (fadePercent * bg + (100 - fadePercent) * fg) / 200; // Need to use 5-bit green for accurate colors :( + newb = (fadePercent * bb + (100 - fadePercent) * fb) / 100; return (newr << 11) | (newg << 6) | newb; } diff --git a/drivers/displays/tft/colors.h b/drivers/displays/tft/colors.h index 22f996a..b2bb641 100644 --- a/drivers/displays/tft/colors.h +++ b/drivers/displays/tft/colors.h @@ -95,6 +95,6 @@ uint16_t colorsRGB24toRGB565 ( uint8_t r, uint8_t g, uint8_t b ); uint32_t colorsRGB565toBGRA32 ( uint16_t color ); uint16_t colorsBGR2RGB ( uint16_t color ); uint16_t colorsDim ( uint16_t color, uint8_t intensity ); -uint16_t colorsBlend ( uint16_t bgColor, uint16_t foreColor, uint8_t intensity ); +uint16_t colorsAlphaBlend ( uint16_t bgColor, uint16_t foreColor, uint8_t fadePercent ); #endif -- 2.20.1