LCDGFX LCD display driver  1.2.0
Lightweight graphics library for SSD1306, SSD1325, SSD1327, SSD1331, SSD1351, SH1106, SH1107, IL9163, ST7735, ST7789, ILI9341, PCD8544 displays over I2C/SPI
ssd1306_8bit.inl
1 /*
2  MIT License
3 
4  Copyright (c) 2018-2020, 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 */
24 
25 #include "lcd_hal/io.h"
26 
27 #if 0
28 void ssd1306_setRgbColor(uint8_t r, uint8_t g, uint8_t b)
29 {
30  ssd1306_color = RGB_COLOR8(r,g,b);
31 }
32 
33 void ssd1306_setRgbColor8(uint8_t r, uint8_t g, uint8_t b)
34 {
35  ssd1306_color = RGB_COLOR8(r,g,b);
36 }
37 
38 static void ssd1306_drawBufferPitch8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, lcduint_t pitch, const uint8_t *data)
39 {
40  ssd1306_lcd.set_block(x, y, w);
41  while (h--)
42  {
43  lcduint_t line = w;
44  while (line--)
45  {
46  ssd1306_lcd.send_pixels8( *data );
47  data++;
48  }
49  data += pitch - w;
50  }
51  ssd1306_intf.stop();
52 }
53 
54 void ssd1306_drawBufferFast8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *data)
55 {
56  ssd1306_drawBufferPitch8( x, y, w, h, w, data );
57 }
58 
59 void ssd1306_drawBufferEx8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, lcduint_t pitch, const uint8_t *data)
60 {
61  ssd1306_drawBufferPitch8( x, y, w, h, pitch, data );
62 }
63 
64 void ssd1306_putColorPixel8(lcdint_t x, lcdint_t y, uint8_t color)
65 {
66  ssd1306_lcd.set_block(x, y, 0);
67  ssd1306_lcd.send_pixels8( color );
68  ssd1306_intf.stop();
69 }
70 
71 #endif
72 
74 //
75 // COMMON GRAPHICS
76 //
78 
79 // template class NanoDisplayOps8<I>;
80 
81 // template <class I>
82 // void NanoDisplayOps8<I>::printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style)
83 //{
84 // m_cursorX = xpos;
85 // m_cursorY = y;
86 // m_fontStyle = style;
87 // print( ch );
88 //}
89 
91 //
92 // 8-BIT GRAPHICS
93 //
95 
96 template <class I> void NanoDisplayOps8<I>::putPixel(lcdint_t x, lcdint_t y)
97 {
98  this->m_intf.startBlock(x, y, 0);
99  this->m_intf.send(this->m_color);
100  this->m_intf.endBlock();
101 }
102 
103 template <class I> void NanoDisplayOps8<I>::drawHLine(lcdint_t x1, lcdint_t y1, lcdint_t x2)
104 {
105  this->m_intf.startBlock(x1, y1, 0);
106  while ( x1 <= x2 )
107  {
108  this->m_intf.send(this->m_color);
109  x1++;
110  }
111  this->m_intf.endBlock();
112 }
113 
114 template <class I> void NanoDisplayOps8<I>::drawVLine(lcdint_t x1, lcdint_t y1, lcdint_t y2)
115 {
116  this->m_intf.startBlock(x1, y1, 1);
117  while ( y1 <= y2 )
118  {
119  this->m_intf.send(this->m_color);
120  y1++;
121  }
122  this->m_intf.endBlock();
123 }
124 
125 template <class I> void NanoDisplayOps8<I>::fillRect(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2)
126 {
127  if ( y1 > y2 )
128  {
129  ssd1306_swap_data(y1, y2, lcdint_t);
130  }
131  if ( x1 > x2 )
132  {
133  ssd1306_swap_data(x1, x2, lcdint_t);
134  }
135  this->m_intf.startBlock(x1, y1, x2 - x1 + 1);
136  uint32_t count = (x2 - x1 + 1) * (y2 - y1 + 1);
137  while ( count-- )
138  {
139  this->m_intf.send(this->m_color);
140  }
141  this->m_intf.endBlock();
142 }
143 
144 template <class I> void NanoDisplayOps8<I>::fill(uint16_t color)
145 {
146  this->m_intf.startBlock(0, 0, 0);
147  uint32_t count = (uint32_t)this->m_w * (uint32_t)this->m_h;
148  while ( count-- )
149  {
150  this->m_intf.send(color);
151  }
152  this->m_intf.endBlock();
153 }
154 
155 template <class I> void NanoDisplayOps8<I>::clear()
156 {
157  fill(0x00);
158 }
159 
160 template <class I>
161 void NanoDisplayOps8<I>::drawXBitmap(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
162 {
163  // TODO:
164 }
165 
166 template <class I>
167 void NanoDisplayOps8<I>::drawBitmap1(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
168 {
169  uint8_t bit = 1;
170  uint8_t blackColor = this->m_bgColor;
171  uint8_t color = this->m_color;
172  this->m_intf.startBlock(xpos, ypos, w);
173  while ( h-- )
174  {
175  lcduint_t wx = w;
176  while ( wx-- )
177  {
178  uint8_t data = pgm_read_byte(bitmap);
179  if ( data & bit )
180  this->m_intf.send(color);
181  else
182  this->m_intf.send(blackColor);
183  bitmap++;
184  }
185  bit <<= 1;
186  if ( bit == 0 )
187  {
188  bit = 1;
189  }
190  else
191  {
192  bitmap -= w;
193  }
194  }
195  this->m_intf.endBlock();
196 }
197 
198 template <class I>
199 void NanoDisplayOps8<I>::drawBitmap4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
200 {
201  // NOT IMPLEMENTED
202 }
203 
204 template <class I>
205 void NanoDisplayOps8<I>::drawBitmap8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
206 {
207  this->m_intf.startBlock(x, y, w);
208  uint32_t count = (w) * (h);
209  while ( count-- )
210  {
211  this->m_intf.send(pgm_read_byte(bitmap));
212  bitmap++;
213  }
214  this->m_intf.endBlock();
215 }
216 
217 template <class I>
219 {
220  // NOT IMPLEMENTED
221 }
222 
223 template <class I>
224 void NanoDisplayOps8<I>::drawBuffer1(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *buffer)
225 {
226  uint8_t bit = 1;
227  uint8_t blackColor = this->m_bgColor;
228  uint8_t color = this->m_color;
229  this->m_intf.startBlock(xpos, ypos, w);
230  while ( h-- )
231  {
232  lcduint_t wx = w;
233  while ( wx-- )
234  {
235  uint8_t data = *buffer;
236  if ( data & bit )
237  this->m_intf.send(color);
238  else
239  this->m_intf.send(blackColor);
240  buffer++;
241  }
242  bit <<= 1;
243  if ( bit == 0 )
244  {
245  bit = 1;
246  }
247  else
248  {
249  buffer -= w;
250  }
251  }
252  this->m_intf.endBlock();
253 }
254 
255 template <class I>
257 {
258  this->drawBuffer1(x, y, w, h, buf);
259 }
260 
261 template <class I>
262 void NanoDisplayOps8<I>::drawBuffer4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
263 {
264  // NOT IMPLEMENTED
265 }
266 
267 template <class I>
268 void NanoDisplayOps8<I>::drawBuffer8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
269 {
270  this->m_intf.startBlock(x, y, w);
271  uint32_t count = (w) * (h);
272  while ( count-- )
273  {
274  this->m_intf.send(*buffer);
275  buffer++;
276  }
277  this->m_intf.endBlock();
278 }
279 
280 template <class I>
282 {
283  // NOT IMPLEMENTED
284 }
285 
286 template <class I> uint8_t NanoDisplayOps8<I>::printChar(uint8_t c)
287 {
288  uint16_t unicode = this->m_font->unicode16FromUtf8(c);
289  if ( unicode == SSD1306_MORE_CHARS_REQUIRED )
290  return 0;
291  SCharInfo char_info;
292  this->m_font->getCharBitmap(unicode, &char_info);
293  uint8_t mode = this->m_textMode;
294  for ( uint8_t i = 0; i < (this->m_fontStyle == STYLE_BOLD ? 2 : 1); i++ )
295  {
296  this->drawBitmap1(this->m_cursorX + i, this->m_cursorY, char_info.width, char_info.height, char_info.glyph);
297  this->m_textMode |= CANVAS_MODE_TRANSPARENT;
298  }
299  this->m_textMode = mode;
300  this->m_cursorX += (lcdint_t)(char_info.width + char_info.spacing);
301  if ( ((this->m_textMode & CANVAS_TEXT_WRAP_LOCAL) &&
302  (this->m_cursorX > ((lcdint_t)this->m_w - (lcdint_t)this->m_font->getHeader().width))) ||
303  ((this->m_textMode & CANVAS_TEXT_WRAP) &&
304  (this->m_cursorX > ((lcdint_t)this->m_w - (lcdint_t)this->m_font->getHeader().width))) )
305  {
306  this->m_cursorY += (lcdint_t)this->m_font->getHeader().height;
307  this->m_cursorX = 0;
308  if ( (this->m_textMode & CANVAS_TEXT_WRAP_LOCAL) &&
309  (this->m_cursorY > ((lcdint_t)this->m_h - (lcdint_t)this->m_font->getHeader().height)) )
310  {
311  this->m_cursorY = 0;
312  }
313  }
314  return 1;
315 }
316 
317 template <class I> size_t NanoDisplayOps8<I>::write(uint8_t c)
318 {
319  if ( c == '\n' )
320  {
321  this->m_cursorY += (lcdint_t)this->m_font->getHeader().height;
322  this->m_cursorX = 0;
323  }
324  else if ( c == '\r' )
325  {
326  // skip non-printed char
327  }
328  else
329  {
330  return printChar(c);
331  }
332  return 1;
333 }
334 
335 template <class I> void NanoDisplayOps8<I>::printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style)
336 {
337  // TODO: fontstyle not supported
338  // m_fontStyle = style;
339  this->m_cursorX = xpos;
340  this->m_cursorY = y;
341  while ( *ch )
342  {
343  this->write(*ch);
344  ch++;
345  }
346 }
void drawBuffer4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
Draws 4-bit bitmap, located in RAM, on the display Each byte represents two pixels in 4-4 format: ref...
uint8_t height
char height in pixels
Definition: canvas_types.h:144
uint8_t lcduint_t
internal int type, used by the library.
Definition: canvas_types.h:79
void drawBitmap16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
Draw 16-bit color bitmap, located in Flash, directly to OLED display GDRAM.
Structure describes single char information.
Definition: canvas_types.h:141
If the flag is specified, text cursor is moved to new line when end of canvas is reached.
Definition: canvas_types.h:103
This flag make bitmaps transparent (Black color)
Definition: canvas_types.h:101
int8_t lcdint_t
internal int type, used by the library.
Definition: canvas_types.h:77
SSD1306 HAL IO communication functions.
#define SSD1306_MORE_CHARS_REQUIRED
Flag means that more chars are required to decode utf-8.
Definition: canvas_types.h:43
void fill(uint16_t color)
Fill screen content with specified color.
void drawBitmap8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
Draws 8-bit color bitmap in color buffer.
void drawBuffer1Fast(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
Implements the same behavior as drawBuffer1, but much faster.
uint8_t printChar(uint8_t c)
Draws single character to canvas.
void printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style=STYLE_NORMAL) __attribute__((noinline))
Print text at specified position to canvas.
void drawHLine(lcdint_t x1, lcdint_t y1, lcdint_t x2)
Draws horizontal or vertical line.
void fillRect(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2) __attribute__((noinline))
Fills rectangle area.
size_t write(uint8_t c) __attribute__((noinline))
Writes single character to canvas.
void putPixel(lcdint_t x, lcdint_t y) __attribute__((noinline))
Draws pixel on specified position.
void drawVLine(lcdint_t x1, lcdint_t y1, lcdint_t y2)
Draws horizontal or vertical line.
void drawBitmap4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap) __attribute__((noinline))
Draws 4-bit gray-color bitmap in color buffer.
If the flag is specified, text cursor is moved to new line when end of screen is reached.
Definition: canvas_types.h:99
uint8_t width
char width in pixels
Definition: canvas_types.h:143
const uint8_t * glyph
char data, located in progmem.
Definition: canvas_types.h:146
void drawXBitmap(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
Draws bitmap, located in Flash, on the display The bitmap should be in XBMP format.
#define RGB_COLOR8(r, g, b)
Macro to generate 8-bit color.
Definition: canvas_types.h:52
void clear()
Clears canvas.
void drawBitmap1(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap) __attribute__((noinline))
Draws monochrome bitmap in color buffer using color, specified via setColor() method Draws monochrome...
uint8_t spacing
additional spaces after char in pixels
Definition: canvas_types.h:145
EFontStyle
Supported font styles.
Definition: canvas_types.h:88
void drawBuffer8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
Draws 8-bit bitmap, located in RAM, on the display Each byte represents one pixel in 2-2-3 format: re...
void drawBuffer1(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
Draws bitmap, located in RAM, on the display Each byte represents 8 vertical pixels.
#define ssd1306_swap_data(a, b, type)
swaps content of a and b variables of type type
Definition: io.h:114
void drawBuffer16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
Draws 16-bit bitmap, located in RAM, on the display Each pixel occupies 2 bytes (5-6-5 format): refer...