SSD1306 OLED display driver 1.7.8 This library is developed to control SSD1306/SSD1331/SSD1351/IL9163/PCD8554 RGB i2c/spi LED displays

tiler.h
Go to the documentation of this file.
1 /*
2 MIT License
3
4 Copyright (c) 2018, Alexey Dynda
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
29 #ifndef _NANO_ENGINE_TILER_H_
30 #define _NANO_ENGINE_TILER_H_
31
32 #include "canvas.h"
33 #include "lcd/lcd_common.h"
34
44 extern "C" SFixedFontInfo s_fixedFont;
45
46 /* The table below defines arguments for NanoEngineTiler. *
47 * canvas width height bits */
48 // Tiles for monochrome displays
49 #define TILE_128x64_MONO NanoCanvas1, 128, 64, 7
50 #define TILE_8x8_MONO NanoCanvas1, 8, 8, 3
51 #define TILE_16x16_MONO NanoCanvas1, 16, 16, 4
52 #define TILE_32x32_MONO NanoCanvas1, 32, 32, 4
53 // Tiles for 8-bit displays
54 #define TILE_8x8_RGB8 NanoCanvas8, 8, 8, 3
55 #define TILE_16x16_RGB8 NanoCanvas8, 16, 16, 4
56 #define TILE_32x32_RGB8 NanoCanvas8, 32, 32, 5
57 #define TILE_8x8_MONO_8 NanoCanvas1_8,8, 8, 3
58 // Tiles for 16-bit displays
59 #define TILE_8x8_RGB16 NanoCanvas16, 8, 8, 3
60 // Adafruit tiles
61 #define ADATILE_8x8_MONO AdafruitCanvas1, 8, 8, 3
62 #define ADATILE_8x8_RGB8 AdafruitCanvas8, 8, 8, 3
63 #define ADATILE_8x8_RGB16 AdafruitCanvas16, 8, 8, 3
64
65
68 typedef bool (*TNanoEngineOnDraw)(void);
69
79 template<class C, uint8_t W, uint8_t H, uint8_t B>
80 class NanoEngineTiler
81 {
82 protected:
84 NanoEngineTiler()
85 {
86 refresh();
87 };
88
89 public:
91 static const uint8_t NE_TILE_SIZE_BITS = B;
93 static const uint8_t NE_TILE_WIDTH = W;
95 static const uint8_t NE_TILE_HEIGHT = H;
97 static const uint8_t NE_MAX_TILES_NUM = 16 >> (B - 3);
98
100 static C canvas;
101
105 static void refresh()
106 {
107 memset(m_refreshFlags,0xFF,sizeof(uint16_t) * NanoEngineTiler<C,W,H,B>::NE_MAX_TILES_NUM);
108 }
109
115 static void refresh(const NanoRect &rect)
116 {
117 refresh(rect.p1.x, rect.p1.y, rect.p2.x, rect.p2.y);
118 }
119
124 static void refresh(const NanoPoint &point)
125 {
126 if ((point.y<0) || ((point.y>>B)>=NE_MAX_TILES_NUM)) return;
127 m_refreshFlags[(point.y>>B)] |= (1<<(point.x>>B));
128 }
129
134 static void refresh(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
135 {
136 if (y2 < 0) return;
137 if (y1 < 0) y1 = 0;
138 if (x1 < 0) x1 = 0;
139 y1 = y1>>B;
140 y2 = min((y2>>B), NE_MAX_TILES_NUM - 1);
141 for (uint8_t y=y1; y<=y2; y++)
142 {
143 for(uint8_t x=x1>>B; x<=(x2>>B); x++)
144 {
145 m_refreshFlags[y] |= (1<<x);
146 }
147 }
148 }
149
155 static void refreshWorld(const NanoRect &rect)
156 {
157 refreshWorld(rect.p1.x, rect.p1.y, rect.p2.x, rect.p2.y);
158 }
159
165 static void refreshWorld(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
166 {
167 refresh(x1 - offset.x, y1 - offset.y, x2 - offset.x, y2 - offset.y);
168 }
169
174 static void refreshWorld(const NanoPoint &point)
175 {
176 refresh( point - offset );
177 }
178
184 static void localCoordinates()
185 {
186 canvas.offset -= offset;
187 }
188
194 static void worldCoordinates()
195 {
196 canvas.offset += offset;
197 }
198
202 static void moveTo(const NanoPoint & position)
203 {
204 offset = position;
205 }
206
211 static void moveToAndRefresh(const NanoPoint & position)
212 {
213 moveTo(position);
214 refresh();
215 }
216
220 const NanoPoint & getPosition() const
221 {
222 return offset;
223 }
224
240 static void drawCallback(TNanoEngineOnDraw callback)
241 {
242 m_onDraw = callback;
243 }
244
252 static bool collision(NanoPoint &p, NanoRect &rect) { return rect.collision( p ); }
253
254 protected:
259 static uint16_t m_refreshFlags[NE_MAX_TILES_NUM];
260
262 static TNanoEngineOnDraw m_onDraw;
263
270 static void displayBuffer();
271
277 static void displayPopup(const char *msg);
278 private:
280 static uint8_t m_buffer[W * H * C::BITS_PER_PIXEL / 8];
281
282 static NanoPoint offset;
283 };
284
285 template<class C, uint8_t W, uint8_t H, uint8_t B>
286 uint16_t NanoEngineTiler<C,W,H,B>::m_refreshFlags[NE_MAX_TILES_NUM];
287
288 template<class C, uint8_t W, uint8_t H, uint8_t B>
289 uint8_t NanoEngineTiler<C,W,H,B>::m_buffer[W * H * C::BITS_PER_PIXEL / 8];
290
291 template<class C, uint8_t W, uint8_t H, uint8_t B>
292 C NanoEngineTiler<C,W,H,B>::canvas(W, H, m_buffer);
293
294 template<class C, uint8_t W, uint8_t H, uint8_t B>
295 NanoPoint NanoEngineTiler<C,W,H,B>::offset = {0, 0};
296
297 template<class C, uint8_t W, uint8_t H, uint8_t B>
298 TNanoEngineOnDraw NanoEngineTiler<C,W,H,B>::m_onDraw = nullptr;
299
300 template<class C, uint8_t W, uint8_t H, uint8_t B>
301 void NanoEngineTiler<C,W,H,B>::displayBuffer()
302 {
303 if (!m_onDraw) // If onDraw handler is not set, just output current canvas
304 {
305 canvas.blt();
306 return;
307 }
308 for (uint8_t y = 0; y < ssd1306_lcd.height; y = y + NE_TILE_HEIGHT)
309 {
310 uint16_t flag = m_refreshFlags[y >> NE_TILE_SIZE_BITS];
311 m_refreshFlags[y >> NE_TILE_SIZE_BITS] = 0;
312 for (uint8_t x = 0; x < ssd1306_lcd.width; x = x + NE_TILE_WIDTH)
313 {
314 if (flag & 0x01)
315 {
316 canvas.setOffset(x, y);
317 if (m_onDraw())
318 {
319 canvas.setOffset(x, y);
320 canvas.blt();
321 }
322 }
323 flag >>=1;
324 }
325 }
326 }
327
328 template<class C, uint8_t W, uint8_t H, uint8_t B>
329 void NanoEngineTiler<C,W,H,B>::displayPopup(const char *msg)
330 {
331 NanoRect rect = { {8, (ssd1306_lcd.height>>1) - 8}, {ssd1306_lcd.width - 8, (ssd1306_lcd.height>>1) + 8} };
332 // TODO: It would be nice to calculate message height
333 NanoPoint textPos = { (ssd1306_lcd.width - (lcdint_t)strlen(msg)*s_fixedFont.h.width) >> 1, (ssd1306_lcd.height>>1) - 4 };
334 refresh(rect);
335 for (uint8_t y = 0; y < ssd1306_lcd.height; y = y + NE_TILE_HEIGHT)
336 {
337 uint16_t flag = m_refreshFlags[y >> NE_TILE_SIZE_BITS];
338 m_refreshFlags[y >> NE_TILE_SIZE_BITS] = 0;
339 for (uint8_t x = 0; x < ssd1306_lcd.width; x = x + NE_TILE_WIDTH)
340 {
341 if (flag & 0x01)
342 {
343 canvas.setOffset(x, y);
344 if (m_onDraw) m_onDraw();
345 canvas.setOffset(x, y);
346 canvas.setColor(RGB_COLOR8(0,0,0));
347 canvas.fillRect(rect);
348 canvas.setColor(RGB_COLOR8(192,192,192));
349 canvas.drawRect(rect);
350 canvas.printFixed( textPos.x, textPos.y, msg);
351
352 canvas.blt();
353 }
354 flag >>=1;
355 }
356 }
357 }
358
363 #endif
364
NanoEngineTiler::NE_TILE_SIZE_BITS
static const uint8_t NE_TILE_SIZE_BITS
Definition: tiler.h:91
NanoEngineTiler::moveToAndRefresh
static void moveToAndRefresh(const NanoPoint &position)
Definition: tiler.h:211
_NanoPoint
Definition: point.h:40
lcd_common.h
_NanoRect
Definition: rect.h:42
NanoEngineTiler::getPosition
const NanoPoint & getPosition() const
Definition: tiler.h:220
NanoEngineTiler::NanoEngineTiler
NanoEngineTiler()
Definition: tiler.h:84
NanoEngineTiler::refresh
static void refresh(const NanoPoint &point)
Definition: tiler.h:124
NanoEngineTiler::refreshWorld
static void refreshWorld(const NanoPoint &point)
Definition: tiler.h:174
SFontHeaderRecord::width
uint8_t width
width in pixels
Definition: nano_gfx_types.h:79
lcdint_t
int lcdint_t
Definition: io.h:63
RGB_COLOR8
#define RGB_COLOR8(r, g, b)
Definition: nano_gfx_types.h:44
_NanoRect::p2
NanoPoint p2
Definition: rect.h:48
NanoEngineTiler::refresh
static void refresh()
Definition: tiler.h:105
canvas.h
_NanoPoint::y
lcdint_t y
Definition: point.h:45
NanoEngineTiler::collision
static bool collision(NanoPoint &p, NanoRect &rect)
Returns true if point is inside the rectangle area. Returns true if point is inside the rectangle are...
Definition: tiler.h:252
_NanoRect::collision
bool collision(const NanoPoint &p) const
Definition: rect.h:143
SFixedFontInfo
Definition: nano_gfx_types.h:94
ssd1306_lcd
ssd1306_lcd_t ssd1306_lcd
Definition: lcd_common.c:32
NanoEngineTiler::refresh
static void refresh(const NanoRect &rect)
Definition: tiler.h:115
NanoEngineTiler
Definition: tiler.h:80
min
#define min(a, b)
Definition: nano_gfx_types.h:35
NanoEngineTiler::worldCoordinates
static void worldCoordinates()
Definition: tiler.h:194
NanoEngineTiler::drawCallback
static void drawCallback(TNanoEngineOnDraw callback)
Definition: tiler.h:240
ssd1306_lcd_t::height
lcduint_t height
Definition: lcd_common.h:97
NanoEngineTiler::localCoordinates
static void localCoordinates()
Definition: tiler.h:184
NanoEngineTiler::NE_TILE_HEIGHT
static const uint8_t NE_TILE_HEIGHT
Definition: tiler.h:95
NanoEngineTiler::displayBuffer
static void displayBuffer()
refreshes content on oled display. Refreshes content on oled display. Call it, if you want to update ...
Definition: tiler.h:301
s_fixedFont
SFixedFontInfo s_fixedFont
Definition: tiler.h:44
SFixedFontInfo::h
SFontHeaderRecord h
record, containing information on font
Definition: nano_gfx_types.h:96
NanoEngineTiler::refreshWorld
static void refreshWorld(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
Definition: tiler.h:165
NanoEngineTiler::displayPopup
static void displayPopup(const char *msg)
prints popup message over display content prints popup message over display content ...
Definition: tiler.h:329
NanoEngineTiler::refreshWorld
static void refreshWorld(const NanoRect &rect)
Definition: tiler.h:155
NanoEngineTiler::m_onDraw
static TNanoEngineOnDraw m_onDraw
Definition: tiler.h:262
NanoEngineTiler::canvas
static C canvas
Definition: tiler.h:100
NanoEngineTiler::refresh
static void refresh(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
Definition: tiler.h:134
NanoEngineTiler::moveTo
static void moveTo(const NanoPoint &position)
Definition: tiler.h:202
TNanoEngineOnDraw
bool(* TNanoEngineOnDraw)(void)
Definition: tiler.h:68
ssd1306_lcd_t::width
lcduint_t width
Definition: lcd_common.h:94
_NanoRect::p1
NanoPoint p1
Definition: rect.h:45
_NanoPoint::x
lcdint_t x
Definition: point.h:43
NanoEngineTiler::NE_MAX_TILES_NUM
static const uint8_t NE_MAX_TILES_NUM
Definition: tiler.h:97
NanoEngineTiler::m_refreshFlags
static uint16_t m_refreshFlags[NE_MAX_TILES_NUM]
Definition: tiler.h:259
NanoEngineTiler::NE_TILE_WIDTH
static const uint8_t NE_TILE_WIDTH
Definition: tiler.h:93