From 5bb14ba2d812399148724a22636e751ed70e0a4b Mon Sep 17 00:00:00 2001 From: Bodmer Date: Sun, 10 Nov 2019 02:23:22 +0000 Subject: [PATCH] Add new callback for smooth font antialiasing Callback allows anitaliased fonts to be rendered over colour gradients or images. "Smooth_font_reading_TFT" example added "Smooth_font_gradient" example added Minor changes to avoid signed/unsigned comparison warnings. --- Extensions/Smooth_font.cpp | 2 +- Extensions/Sprite.cpp | 34 ++-- TFT_eSPI.cpp | 69 ++++++-- TFT_eSPI.h | 5 +- .../Free_Font_Demo/Free_Font_Demo.ino | 4 +- .../320 x 240/Free_Font_Demo/Free_Fonts.h | 4 +- .../Free_Font_Demo/Free_Font_Demo.ino | 4 +- .../480 x 320/Free_Font_Demo/Free_Fonts.h | 3 +- .../Smooth_font_gradient.ino | 121 +++++++++++++ .../data/NotoSansBold15.vlw | Bin 0 -> 10766 bytes .../data/NotoSansBold36.vlw | Bin 0 -> 44169 bytes .../Smooth_font_reading_TFT.ino | 165 ++++++++++++++++++ .../data/NotoSansBold15.vlw | Bin 0 -> 10766 bytes .../data/NotoSansBold36.vlw | Bin 0 -> 44169 bytes library.json | 2 +- library.properties | 2 +- 16 files changed, 369 insertions(+), 46 deletions(-) create mode 100644 examples/Smooth Fonts/Smooth_font_gradient/Smooth_font_gradient.ino create mode 100644 examples/Smooth Fonts/Smooth_font_gradient/data/NotoSansBold15.vlw create mode 100644 examples/Smooth Fonts/Smooth_font_gradient/data/NotoSansBold36.vlw create mode 100644 examples/Smooth Fonts/Smooth_font_reading_TFT/Smooth_font_reading_TFT.ino create mode 100644 examples/Smooth Fonts/Smooth_font_reading_TFT/data/NotoSansBold15.vlw create mode 100644 examples/Smooth Fonts/Smooth_font_reading_TFT/data/NotoSansBold36.vlw diff --git a/Extensions/Smooth_font.cpp b/Extensions/Smooth_font.cpp index ca1cb63..c835b48 100644 --- a/Extensions/Smooth_font.cpp +++ b/Extensions/Smooth_font.cpp @@ -370,7 +370,6 @@ uint16_t TFT_eSPI::decodeUTF8(uint8_t c) */ - /*************************************************************************************** ** Function name: alphaBlend ** Description: Blend foreground and background and return new colour @@ -509,6 +508,7 @@ void TFT_eSPI::drawGlyph(uint16_t code) else drawFastHLine( xs, y + cy, dl, fg); dl = 0; } + if (getColor) bg = getColor(x + cx, y + cy); drawPixel(x + cx, y + cy, alphaBlend(pixel, fg, bg)); } else diff --git a/Extensions/Sprite.cpp b/Extensions/Sprite.cpp index 2c8573e..6984d38 100644 --- a/Extensions/Sprite.cpp +++ b/Extensions/Sprite.cpp @@ -566,21 +566,21 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_ int32_t xs = x; int32_t ys = y; - uint32_t ws = w; - uint32_t hs = h; + int32_t ws = w; + int32_t hs = h; if (x < 0) { xo = -x; ws += x; xs = 0; } if (y < 0) { yo = -y; hs += y; ys = 0; } - if (xs + ws >= _iwidth) ws = _iwidth - xs; - if (ys + hs >= _iheight) hs = _iheight - ys; + if (xs + ws >= (int32_t)_iwidth) ws = _iwidth - xs; + if (ys + hs >= (int32_t)_iheight) hs = _iheight - ys; if (_bpp == 16) // Plot a 16 bpp image into a 16 bpp Sprite { - for (uint32_t yp = yo; yp < yo + hs; yp++) + for (int32_t yp = yo; yp < yo + hs; yp++) { x = xs; - for (uint32_t xp = xo; xp < xo + ws; xp++) + for (int32_t xp = xo; xp < xo + ws; xp++) { uint16_t color = data[xp + yp * w]; if(!_iswapBytes) color = color<<8 | color>>8; @@ -592,10 +592,10 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_ } else if (_bpp == 8) // Plot a 16 bpp image into a 8 bpp Sprite { - for (uint32_t yp = yo; yp < yo + hs; yp++) + for (int32_t yp = yo; yp < yo + hs; yp++) { x = xs; - for (uint32_t xp = xo; xp < xo + ws; xp++) + for (int32_t xp = xo; xp < xo + ws; xp++) { uint16_t color = data[xp + yp * w]; if(_iswapBytes) color = color<<8 | color>>8; @@ -662,21 +662,21 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const u int32_t xs = x; int32_t ys = y; - uint32_t ws = w; - uint32_t hs = h; + int32_t ws = w; + int32_t hs = h; if (x < 0) { xo = -x; ws += x; xs = 0; } if (y < 0) { yo = -y; hs += y; ys = 0; } - if (xs + ws >= _iwidth) ws = _iwidth - xs; - if (ys + hs >= _iheight) hs = _iheight - ys; + if (xs + ws >= (int32_t)_iwidth) ws = _iwidth - xs; + if (ys + hs >= (int32_t)_iheight) hs = _iheight - ys; if (_bpp == 16) // Plot a 16 bpp image into a 16 bpp Sprite { - for (uint32_t yp = yo; yp < yo + hs; yp++) + for (int32_t yp = yo; yp < yo + hs; yp++) { x = xs; - for (uint32_t xp = xo; xp < xo + ws; xp++) + for (int32_t xp = xo; xp < xo + ws; xp++) { uint16_t color = pgm_read_word(data + xp + yp * w); if(!_iswapBytes) color = color<<8 | color>>8; @@ -689,10 +689,10 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const u else if (_bpp == 8) // Plot a 16 bpp image into a 8 bpp Sprite { - for (uint32_t yp = yo; yp < yo + hs; yp++) + for (int32_t yp = yo; yp < yo + hs; yp++) { x = xs; - for (uint32_t xp = xo; xp < xo + ws; xp++) + for (int32_t xp = xo; xp < xo + ws; xp++) { uint16_t color = pgm_read_word(data + xp + yp * w); if(_iswapBytes) color = color<<8 | color>>8; @@ -733,7 +733,7 @@ void TFT_eSprite::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const u uint8_t pbyte = pgm_read_byte(pdata++); for (uint8_t xc = 0; xc < 8; xc++) { - if (xp+xc // Hardware-specific library #include +#include "Free_Fonts.h" // Include the header file attached to this sketch + TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height unsigned long drawTime = 0; diff --git a/examples/480 x 320/Free_Font_Demo/Free_Fonts.h b/examples/480 x 320/Free_Font_Demo/Free_Fonts.h index a87be36..7c0a264 100644 --- a/examples/480 x 320/Free_Font_Demo/Free_Fonts.h +++ b/examples/480 x 320/Free_Font_Demo/Free_Fonts.h @@ -39,7 +39,6 @@ // // tft.setFreeFont(NULL); // Set font to GLCD -#define LOAD_GFXFF #ifdef LOAD_GFXFF // Only include the fonts if LOAD_GFXFF is defined in User_Setup.h @@ -265,6 +264,8 @@ #define FONT7 7 #define FONT8 8 +#define TT1 1 + #define FF0 1 #define FF1 1 #define FF2 1 diff --git a/examples/Smooth Fonts/Smooth_font_gradient/Smooth_font_gradient.ino b/examples/Smooth Fonts/Smooth_font_gradient/Smooth_font_gradient.ino new file mode 100644 index 0000000..b545ab3 --- /dev/null +++ b/examples/Smooth Fonts/Smooth_font_gradient/Smooth_font_gradient.ino @@ -0,0 +1,121 @@ +/* + This sketch is based on Font Demo 1. It introduces a method for rendering + anti-aliased fonts on a graded background. This is acheived by telling the + TFT_eSPI library the pixel color at each point on the screen. In this sketch + a graded background is drawn, the color of each pixel can therefore be + determined. The TFT does not need to support reading of the graphics memory. + The sketch could be adapted so only part of the screen is gas a color gradient. + + The TFT_eSPI library must be given the name of the function in the sketch + that will return the pixel xolor at a position x,y on the TFT. In this + sketch that function is called gradientColor, so this line is included: + + tft.setCallback(gradientColor); + + TFT_eSPI will call this function during the rendering of the anti-aliased + font to blend the edges of each character with the returned color. + + If the TFT supports reading the screen RAM then the returned value can be + tft.readPixel(x,y) and anti-aliased text can the be drawn over any screen + image. See "Smooth_font_over_image" example. +*/ +// The fonts used are in the sketch data folder, press Ctrl+K to view. + +// Upload the fonts and icons to SPIFFS (must set at least 1M for SPIFFS) using the +// "Tools" "ESP8266 (or ESP32) Sketch Data Upload" menu option in the IDE. +// To add this option follow instructions here for the ESP8266: +// https://github.com/esp8266/arduino-esp8266fs-plugin +// or for the ESP32: +// https://github.com/me-no-dev/arduino-esp32fs-plugin + +// Close the IDE and open again to see the new menu option. + +// A processing sketch to create new fonts can be found in the Tools folder of TFT_eSPI +// https://github.com/Bodmer/TFT_eSPI/tree/master/Tools/Create_Smooth_Font/Create_font + +// This sketch uses font files created from the Noto family of fonts: +// https://www.google.com/get/noto/ + +#define AA_FONT_SMALL "NotoSansBold15" +#define AA_FONT_LARGE "NotoSansBold36" + +// Font files are stored in SPIFFS, so load the library +#include + +#include +#include // Hardware-specific library + +TFT_eSPI tft = TFT_eSPI(); + +#define TOP_COLOR TFT_RED +#define BOTTOM_COLOR TFT_BLACK + +#define GRADIENT_HEIGHT (9 + tft.fontHeight() * 5) // Gradient over 5 lines +#define OUTSIDE_GRADIENT TFT_BLUE + +uint16_t gradientColor(uint16_t x, uint16_t y) +{ + if (y > GRADIENT_HEIGHT) return OUTSIDE_GRADIENT; // Outside gradient area + uint8_t alpha = (255 * y) / GRADIENT_HEIGHT; // alpha is a value in the range 0-255 + return tft.alphaBlend(alpha, BOTTOM_COLOR, TOP_COLOR); +} + +void fillGradient() { + uint16_t w = tft.width(); + for (uint16_t y = 0; y < tft.height(); ++y) { + uint16_t color = gradientColor(0, y); // x not used here + tft.drawFastHLine(0, y, w, color); + } +} + +void setup(void) { + Serial.begin(115200); + + tft.begin(); + + tft.setCallback(gradientColor); // Switch on color callback for anti-aliased fonts + //tft.setCallback(nullptr); // Switch off callback (off by default) + + tft.setRotation(1); + + if (!SPIFFS.begin()) { + Serial.println("SPIFFS initialisation failed!"); + while (1) yield(); // Stay here twiddling thumbs waiting + } + Serial.println("\r\nSPIFFS available!"); + + // ESP32 will crash if any of the fonts are missing + bool font_missing = false; + if (SPIFFS.exists("/NotoSansBold15.vlw") == false) font_missing = true; + if (SPIFFS.exists("/NotoSansBold36.vlw") == false) font_missing = true; + + if (font_missing) + { + Serial.println("\r\nFont missing in SPIFFS, did you upload it?"); + while (1) yield(); + } + else Serial.println("\r\nFonts found OK."); +} + + +void loop() { + + // Select a font size comensurate with screen size + if (tft.width()>= 320) + tft.loadFont(AA_FONT_LARGE); + else + tft.loadFont(AA_FONT_SMALL); + + fillGradient(); // Put here after selecting the font so fontHeight() is already set + + tft.setTextColor(TFT_WHITE); // Background color is ignored in gradient area + tft.setCursor(0, 10); // Set cursor at top left of screen + + uint32_t t = millis(); + tft.println(" Ode to a small\n lump of green\n putty I found\n in my armpit\n one midsummer\n morning "); + Serial.println(t = millis()-t); + + tft.unloadFont(); // Remove the font to recover memory used + + delay(2000); +} diff --git a/examples/Smooth Fonts/Smooth_font_gradient/data/NotoSansBold15.vlw b/examples/Smooth Fonts/Smooth_font_gradient/data/NotoSansBold15.vlw new file mode 100644 index 0000000000000000000000000000000000000000..803a1bd9748c922e455e4952f08368ce634f96f4 GIT binary patch literal 10766 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 literal 0 HcmV?d00001 diff --git a/examples/Smooth Fonts/Smooth_font_gradient/data/NotoSansBold36.vlw b/examples/Smooth Fonts/Smooth_font_gradient/data/NotoSansBold36.vlw new file mode 100644 index 0000000000000000000000000000000000000000..66003f6e1c9915e71f571ade912b9eb899323db6 GIT binary patch literal 44169 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 K_&W^#+W!ZD7G}`^ literal 0 HcmV?d00001 diff --git a/examples/Smooth Fonts/Smooth_font_reading_TFT/Smooth_font_reading_TFT.ino b/examples/Smooth Fonts/Smooth_font_reading_TFT/Smooth_font_reading_TFT.ino new file mode 100644 index 0000000..c4d499c --- /dev/null +++ b/examples/Smooth Fonts/Smooth_font_reading_TFT/Smooth_font_reading_TFT.ino @@ -0,0 +1,165 @@ +/* + This sketch is based on Font Demo 1. It introduces a method for rendering + anti-aliased fonts on an arbitrary background. This is acheived by reading + the pixel color at each point on the screen. The TFT must support reading + the graphics RAM of the screen memory. This sketch has been tested with + ILI9241 and ILI9481 serial and parallel screens. Other screens may or may + not work! + + The TFT_eSPI library must be given the name of the function in the sketch + that will return the pixel color at a position x,y on the TFT. In this + sketch that function is called pixelColor, so this line is included: + + tft.setCallback(pixelColor); + + TFT_eSPI will call this function during the rendering of the anti-aliased + font and use it to blend the edges of each character with the screen color. +*/ +// The fonts used are in the sketch data folder, press Ctrl+K to view. + +// Upload the fonts and icons to SPIFFS (must set at least 1M for SPIFFS) using the +// "Tools" "ESP8266 (or ESP32) Sketch Data Upload" menu option in the IDE. +// To add this option follow instructions here for the ESP8266: +// https://github.com/esp8266/arduino-esp8266fs-plugin +// or for the ESP32: +// https://github.com/me-no-dev/arduino-esp32fs-plugin + +// Close the IDE and open again to see the new menu option. + +// A processing sketch to create new fonts can be found in the Tools folder of TFT_eSPI +// https://github.com/Bodmer/TFT_eSPI/tree/master/Tools/Create_Smooth_Font/Create_font + +// This sketch uses font files created from the Noto family of fonts: +// https://www.google.com/get/noto/ + +#define AA_FONT_SMALL "NotoSansBold15" +#define AA_FONT_LARGE "NotoSansBold36" + +// Font files are stored in SPIFFS, so load the library +#include + +#include +#include // Hardware-specific library + +TFT_eSPI tft = TFT_eSPI(); + +// Callback function to provide the pixel color at x,y +uint16_t pixelColor(uint16_t x, uint16_t y) { return tft.readPixel(x, y); } + + +void setup(void) { + Serial.begin(115200); + + tft.begin(); + + tft.setCallback(pixelColor); // The callback is only used durung font rendering + //tft.setCallback(nullptr); // Switch off callback (off by default) + + tft.setRotation(1); + + if (!SPIFFS.begin()) { + Serial.println("SPIFFS initialisation failed!"); + while (1) yield(); // Stay here twiddling thumbs waiting + } + Serial.println("\r\nSPIFFS available!"); + + // ESP32 will crash if any of the fonts are missing, so check + bool font_missing = false; + if (SPIFFS.exists("/NotoSansBold15.vlw") == false) font_missing = true; + if (SPIFFS.exists("/NotoSansBold36.vlw") == false) font_missing = true; + + if (font_missing) + { + Serial.println("\r\nFont missing in SPIFFS, did you upload it?"); + while (1) yield(); + } + else Serial.println("\r\nFonts found OK."); +} + + +void loop() { + + rainbow_fill(); // Fill the screen with rainbow colours + + // Select a font size comensurate with screen size + if (tft.width()>= 320) + tft.loadFont(AA_FONT_LARGE); + else + tft.loadFont(AA_FONT_SMALL); + + tft.setTextColor(TFT_BLACK, TFT_WHITE); // Background color is ignored if callback is set + tft.setCursor(0, 10); // Set cursor at top left of screen + + uint32_t t = millis(); + tft.println(" Ode to a small\n lump of green\n putty I found\n in my armpit\n one midsummer\n morning "); + Serial.println(t = millis()-t); + + tft.unloadFont(); // Remove the font to recover memory used + + delay(2000); +} + +// ######################################################################### +// Fill screen with a rainbow pattern +// ######################################################################### +byte red = 31; +byte green = 0; +byte blue = 0; +byte state = 0; +unsigned int colour = red << 11; // Colour order is RGB 5+6+5 bits each + +void rainbow_fill() +{ + // The colours and state are not initialised so the start colour changes each time the funtion is called + + for (int i = 319; i >= 0; i--) { + // Draw a vertical line 1 pixel wide in the selected colour + tft.drawFastHLine(0, i, tft.width(), colour); // in this example tft.width() returns the pixel width of the display + // This is a "state machine" that ramps up/down the colour brightnesses in sequence + switch (state) { + case 0: + green ++; + if (green == 64) { + green = 63; + state = 1; + } + break; + case 1: + red--; + if (red == 255) { + red = 0; + state = 2; + } + break; + case 2: + blue ++; + if (blue == 32) { + blue = 31; + state = 3; + } + break; + case 3: + green --; + if (green == 255) { + green = 0; + state = 4; + } + break; + case 4: + red ++; + if (red == 32) { + red = 31; + state = 5; + } + break; + case 5: + blue --; + if (blue == 255) { + blue = 0; + state = 0; + } + break; + } + colour = red << 11 | green << 5 | blue; + } +} diff --git a/examples/Smooth Fonts/Smooth_font_reading_TFT/data/NotoSansBold15.vlw b/examples/Smooth Fonts/Smooth_font_reading_TFT/data/NotoSansBold15.vlw new file mode 100644 index 0000000000000000000000000000000000000000..803a1bd9748c922e455e4952f08368ce634f96f4 GIT binary patch literal 10766 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 literal 0 HcmV?d00001 diff --git a/examples/Smooth Fonts/Smooth_font_reading_TFT/data/NotoSansBold36.vlw b/examples/Smooth Fonts/Smooth_font_reading_TFT/data/NotoSansBold36.vlw new file mode 100644 index 0000000000000000000000000000000000000000..66003f6e1c9915e71f571ade912b9eb899323db6 GIT binary patch literal 44169 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 K_&W^#+W!ZD7G}`^ literal 0 HcmV?d00001 diff --git a/library.json b/library.json index ac9e8b9..474ebcb 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TFT_eSPI", - "version": "1.4.20", + "version": "1.4.21", "keywords": "tft, ePaper, display, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140", "description": "A TFT and ePaper SPI graphics library for ESP8266 and ESP32", "repository": diff --git a/library.properties b/library.properties index aea4881..d7f2e39 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TFT_eSPI -version=1.4.20 +version=1.4.21 author=Bodmer maintainer=Bodmer sentence=A fast TFT graphics library for ESP8266 and ESP32 processors for the Arduino IDE