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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 Og@G5u2XS>lTt)yW$uvy> 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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 NffvLFadkmlMgV{oX3+ou 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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 Og@G5u2XS>lTt)yW$uvy> 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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 NffvLFadkmlMgV{oX3+ou 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