|
| 1 | +/* |
| 2 | + * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry). |
| 3 | + * This product is licensed under an Apache license, see the LICENSE file in the top-level directory. |
| 4 | + */ |
1 | 5 |
|
2 | 6 | #ifndef TC_UNICODE_FONTHELPER_H |
3 | 7 | #define TC_UNICODE_FONTHELPER_H |
|
7 | 11 | #include "Utf8TextProcessor.h" |
8 | 12 | #include "UnicodeFontDefs.h" |
9 | 13 |
|
| 14 | +#define TCUNICODE_API_VERSION 2 |
| 15 | + |
10 | 16 | #if !defined(pgm_read_dword) && defined(__MBED__) |
11 | 17 | #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) |
12 | 18 | #define pgm_read_word(addr) (*(const unsigned short *)(addr)) |
@@ -59,89 +65,37 @@ namespace tcgfx { |
59 | 65 |
|
60 | 66 | using namespace tcgfx; |
61 | 67 |
|
| 68 | +/** |
| 69 | + * A plot pipeline takes care of actually drawing the font glyphs in terms of pixels and cursor positions, it allows |
| 70 | + * for independent implementation on many different graphics libraries. There are ready made implementation for U8G2, |
| 71 | + * Adafruit_GFX, tcMenu Drawable and TFT_eSPI. Should you wish to create one for another display, follow one of the |
| 72 | + * example device includes such as `tcUnicodeU8G2.h`. |
| 73 | + */ |
62 | 74 | class TextPlotPipeline { |
63 | 75 | public: |
64 | 76 | virtual ~TextPlotPipeline() = default; |
| 77 | + /** |
| 78 | + * Draw a pixel onto the device at the given coordinates |
| 79 | + * @param x the x position increases left to right |
| 80 | + * @param y the y position increases top to bottom |
| 81 | + * @param color the color in whatever format the device uses |
| 82 | + */ |
65 | 83 | virtual void drawPixel(uint16_t x, uint16_t y, uint32_t color) = 0; |
| 84 | + /** |
| 85 | + * Set the position that the next text will be printed at, handling of offscreen is minimal, and just stops rendering |
| 86 | + * @param where the coordinate to draw at |
| 87 | + */ |
66 | 88 | virtual void setCursor(const Coord& where) = 0; |
| 89 | + /** |
| 90 | + * @return the current coordinates for print |
| 91 | + */ |
67 | 92 | virtual Coord getCursor() = 0; |
| 93 | + /** |
| 94 | + * @return the dimensions of the underlying display object |
| 95 | + */ |
68 | 96 | virtual Coord getDimensions() = 0; |
69 | 97 | }; |
70 | 98 |
|
71 | | -#if __has_include (<graphics/DeviceDrawable.h>) || __has_include (<graphics/GraphicsDeviceRenderer.h>) || defined(TC_HARDWIRE_TCMENU_RENDER) |
72 | | -#if __has_include (<graphics/DeviceDrawable.h>) || defined(TC_HARDWIRE_TCMENU_RENDER) |
73 | | -# include <graphics/DeviceDrawable.h> |
74 | | -#else |
75 | | -# include <graphics/GraphicsDeviceRenderer.h> |
76 | | -#endif |
77 | | -#define UNICODE_TCMENU_GRAPHIC_DEVICE_AVAILABLE |
78 | | -class DrawableTextPlotPipeline : public TextPlotPipeline { |
79 | | -private: |
80 | | - tcgfx::DeviceDrawable *drawable; |
81 | | - Coord cursor; |
82 | | -public: |
83 | | - explicit DrawableTextPlotPipeline(tcgfx::DeviceDrawable *drawable) : drawable(drawable) {} |
84 | | - void drawPixel(uint16_t x, uint16_t y, uint32_t color) override { |
85 | | - drawable->setDrawColor(color); |
86 | | - drawable->drawPixel(x, y); |
87 | | - } |
88 | | - void setCursor(const Coord& where) override { cursor = where; } |
89 | | - Coord getCursor() override { return cursor; } |
90 | | - Coord getDimensions() override { return drawable->getDisplayDimensions(); } |
91 | | -}; |
92 | | -#endif // GraphicsDevice available |
93 | | - |
94 | | -#if __has_include (<U8g2lib.h>) || defined(TC_HARDWIRE_USING_U8G2) |
95 | | -#include <U8g2lib.h> |
96 | | -#define UNICODE_U8G2_AVAILABLE |
97 | | -class U8g2TextPlotPipeline : public TextPlotPipeline { |
98 | | -private: |
99 | | - U8G2* u8g2; |
100 | | - Coord cursor; |
101 | | -public: |
102 | | - explicit U8g2TextPlotPipeline(U8G2* gfx): u8g2(gfx) {} |
103 | | - ~U8g2TextPlotPipeline() = default; |
104 | | - void drawPixel(uint16_t x, uint16_t y, uint32_t color) override { u8g2->setColorIndex(color); u8g2->drawPixel(x, y); } |
105 | | - Coord getDimensions() override { return Coord(u8g2->getWidth(), u8g2->getHeight()); } |
106 | | - void setCursor(const Coord& where) override { cursor = where; } |
107 | | - Coord getCursor() override { return cursor; } |
108 | | -}; |
109 | | -#endif // u8g2 included |
110 | | - |
111 | | -#if __has_include (<Adafruit_GFX.h>) || defined(TC_HARDWIRE_USING_ADAGFX) |
112 | | -#include <Adafruit_GFX.h> |
113 | | -#define UNICODE_ADAGFX_AVAILABLE |
114 | | -class AdafruitTextPlotPipeline : public TextPlotPipeline { |
115 | | -private: |
116 | | - Adafruit_GFX *gfx; |
117 | | -public: |
118 | | - explicit AdafruitTextPlotPipeline(Adafruit_GFX *gfx) : gfx(gfx) { |
119 | | - } |
120 | | - ~AdafruitTextPlotPipeline() = default; |
121 | | - void drawPixel(uint16_t x, uint16_t y, uint32_t dc) override { return gfx->drawPixel(x, y, dc); } |
122 | | - void setCursor(const Coord &where) override { gfx->setCursor(where.x, where.y); } |
123 | | - Coord getCursor() override {return Coord(gfx->getCursorX(), gfx->getCursorY()); } |
124 | | - Coord getDimensions() override { return Coord(gfx->width(), gfx->height());} |
125 | | -}; |
126 | | -#endif // Adafruit included |
127 | | - |
128 | | -#if __has_include (<TFT_eSPI.h>) || defined(TC_HARDWIRE_USING_TFT_ESPI) |
129 | | -#include <TFT_eSPI.h> |
130 | | -#define UNICODE_TFT_ESPI_AVAILABLE |
131 | | -class TftSpiTextPlotPipeline : public TextPlotPipeline { |
132 | | -private: |
133 | | - TFT_eSPI* tft; |
134 | | - Coord cursor; |
135 | | -public: |
136 | | - TftSpiTextPlotPipeline(TFT_eSPI* tft) : tft(tft) {} |
137 | | - ~TftSpiTextPlotPipeline()=default; |
138 | | - void drawPixel(uint16_t x, uint16_t y, uint32_t dc) override { return tft->drawPixel(x, y, dc); } |
139 | | - Coord getDimensions() override { return Coord(tft->width(), tft->height());} |
140 | | - void setCursor(const Coord& where) override { cursor = where; } |
141 | | - Coord getCursor() override { return cursor; } |
142 | | -}; |
143 | | -#endif // TFT_eSPI included |
144 | | - |
145 | 99 | #define TC_UNICODE_CHAR_ERROR 0xffffffff |
146 | 100 |
|
147 | 101 | /** |
@@ -205,37 +159,21 @@ class UnicodeFontHandler { |
205 | 159 | int16_t calculatedBaseline = -1; |
206 | 160 | uint32_t drawColor = 0; |
207 | 161 | public: |
| 162 | + /** |
| 163 | + * Create a UnicodeFontHandler with a given pipeline, the pipeline interfaces with the underlying library and provides |
| 164 | + * the drawing support. It is the minimum possible code to draw text. It also takes an encoding mode which is passed |
| 165 | + * to the underlying UTF-8 encoder, either `ENCMODE_UTF8` or `ENCMODE_EXT_ASCII`. This object will not delete the |
| 166 | + * underlying plotter that you pass in, you must do that yourself if this object is not global in scope. See the examples |
| 167 | + * for more details on usage with libraries. |
| 168 | + * |
| 169 | + * @param plotter the pipeline plotter pointer |
| 170 | + * @param mode the encoding mode |
| 171 | + */ |
208 | 172 | explicit UnicodeFontHandler(TextPlotPipeline *plotter, tccore::UnicodeEncodingMode mode) : utf8(handleUtf8Drawing, this, mode), |
209 | 173 | plotter(plotter), |
210 | 174 | unicodeFont(nullptr) {} |
211 | 175 | virtual ~UnicodeFontHandler() = default; |
212 | 176 |
|
213 | | -#ifdef UNICODE_TCMENU_GRAPHIC_DEVICE_AVAILABLE |
214 | | - explicit UnicodeFontHandler(DeviceDrawable *gfx, tccore::UnicodeEncodingMode mode) : utf8(handleUtf8Drawing, this, mode), |
215 | | - unicodeFont(nullptr) { |
216 | | - plotter = new DrawableTextPlotPipeline(gfx); |
217 | | - } |
218 | | -#endif |
219 | | - |
220 | | -#ifdef UNICODE_ADAGFX_AVAILABLE |
221 | | - explicit UnicodeFontHandler(Adafruit_GFX *gfx, tccore::UnicodeEncodingMode mode) : utf8(handleUtf8Drawing, this, mode), |
222 | | - unicodeFont(nullptr) { |
223 | | - plotter = new AdafruitTextPlotPipeline(gfx); |
224 | | - } |
225 | | -#endif |
226 | | - |
227 | | -#ifdef UNICODE_TFT_ESPI_AVAILABLE |
228 | | - explicit UnicodeFontHandler(TFT_eSPI* gfx, tccore::UnicodeEncodingMode mode): utf8(handleUtf8Drawing, this, mode), unicodeFont(nullptr) { |
229 | | - plotter = new TftSpiTextPlotPipeline(gfx); |
230 | | - } |
231 | | -#endif |
232 | | - |
233 | | -#ifdef UNICODE_U8G2_AVAILABLE |
234 | | - explicit UnicodeFontHandler(U8G2* gfx, tccore::UnicodeEncodingMode mode): utf8(handleUtf8Drawing, this, mode), unicodeFont(nullptr) { |
235 | | - plotter = new U8g2TextPlotPipeline(gfx); |
236 | | - } |
237 | | -#endif |
238 | | - |
239 | 177 | /** |
240 | 178 | * Plotter pipelines allow the rendering of fonts to be customized to a greater extent, for example a transformation |
241 | 179 | * pipeline could be added as a kind of passthrough. |
|
0 commit comments