LCDGFX LCD display driver  2.0.1
This library is developed to control SSD1306/SSD1325/SSD1327/SSD1331/SSD1351/IL9163/PCD8554 RGB i2c/spi LED displays
ssd1306_1bit.inl
1 /*
2  MIT License
3 
4  Copyright (c) 2016-2019, 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 
28 
29 #include "lcd_hal/io.h"
30 
32 //
33 // 1-BIT GRAPHICS
34 //
36 
37 template <class I>
38 void NanoDisplayOps1<I>::printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style)
39 {
40  uint8_t i, j=0;
41  uint8_t text_index = 0;
42  uint8_t page_offset = 0;
43  uint8_t x = xpos;
44  y >>= 3;
45  this->m_intf.startBlock(xpos, y, this->m_w - xpos);
46  for(;;)
47  {
48  uint8_t ldata;
49  if ( (x > this->m_w - this->m_font->getHeader().width) || (ch[j] == '\0') )
50  {
51  x = xpos;
52  y++;
53  if (y >= (lcdint_t)( this->m_h >> 3))
54  {
55  break;
56  }
57  page_offset++;
58  if (page_offset == this->m_font->getPages())
59  {
60  text_index = j;
61  page_offset = 0;
62  if (ch[j] == '\0')
63  {
64  break;
65  }
66  }
67  else
68  {
69  j = text_index;
70  }
71  this->m_intf.endBlock();
72  this->m_intf.startBlock(xpos, y, this->m_w - xpos);
73  }
74  uint16_t unicode;
75  do
76  {
77  unicode = this->m_font->unicode16FromUtf8(ch[j]);
78  j++;
79  } while ( unicode == SSD1306_MORE_CHARS_REQUIRED );
80  SCharInfo char_info;
81  this->m_font->getCharBitmap(unicode, &char_info);
82  ldata = 0;
83  x += char_info.width + char_info.spacing;
84  if (char_info.height > page_offset * 8)
85  {
86  char_info.glyph += page_offset * char_info.width;
87  for( i = char_info.width; i>0; i--)
88  {
89  uint8_t data;
90  if ( style == STYLE_NORMAL )
91  {
92  data = pgm_read_byte(&char_info.glyph[0]);
93  }
94  else if ( style == STYLE_BOLD )
95  {
96  uint8_t temp = pgm_read_byte(&char_info.glyph[0]);
97  data = temp | ldata;
98  ldata = temp;
99  }
100  else
101  {
102  uint8_t temp = pgm_read_byte(&char_info.glyph[1]);
103  data = (temp & 0xF0) | ldata;
104  ldata = (temp & 0x0F);
105  }
106  this->m_intf.send(data^s_ssd1306_invertByte);
107  char_info.glyph++;
108  }
109  }
110  else
111  {
112  char_info.spacing += char_info.width;
113  }
114  for (i = 0; i < char_info.spacing; i++)
115  this->m_intf.send(s_ssd1306_invertByte);
116  }
117  this->m_intf.endBlock();
118 }
119 
120 #ifndef DOXYGEN_SHOULD_SKIP_THIS
121 template <class I>
122 void NanoDisplayOps1<I>::printFixed_oldStyle(uint8_t xpos, uint8_t y, const char *ch, EFontStyle style)
123 {
124  uint8_t i, j=0;
125  uint8_t text_index = 0;
126  uint8_t page_offset = 0;
127  uint8_t x = xpos;
128  y >>= 3;
129  this->m_intf.startBlock(xpos, y, this->m_w - xpos);
130  for(;;)
131  {
132  uint8_t c;
133  uint8_t ldata;
134  uint16_t offset;
135  if( (x > this->m_w - this->m_font->getHeader().width) || (ch[j] == '\0') )
136  {
137  x = xpos;
138  y++;
139  if (y >= (this->m_h >> 3))
140  {
141  break;
142  }
143  page_offset++;
144  if (page_offset == this->m_font->getPages())
145  {
146  text_index = j;
147  page_offset = 0;
148  if (ch[j] == '\0')
149  {
150  break;
151  }
152  }
153  else
154  {
155  j = text_index;
156  }
157  this->m_intf.endBlock();
158  this->m_intf.startBlock(xpos, y, this->m_w - xpos);
159  }
160  c = ch[j];
161  if ( c >= this->m_font->getHeader().ascii_offset )
162  {
163  c -= this->m_font->getHeader().ascii_offset;
164  }
165  ldata = 0;
166  offset = (c * this->m_font->getPages() + page_offset) * this->m_font->getHeader().width;
167  for( i=this->m_font->getHeader().width; i>0; i--)
168  {
169  uint8_t data;
170  if ( style == STYLE_NORMAL )
171  {
172  data = pgm_read_byte(&this->m_font->getPrimaryTable()[offset]);
173  }
174  else if ( style == STYLE_BOLD )
175  {
176  uint8_t temp = pgm_read_byte(&this->m_font->getPrimaryTable()[offset]);
177  data = temp | ldata;
178  ldata = temp;
179  }
180  else
181  {
182  uint8_t temp = pgm_read_byte(&this->m_font->getPrimaryTable()[offset + 1]);
183  data = (temp & 0xF0) | ldata;
184  ldata = (temp & 0x0F);
185  }
186  this->m_intf.send(data^s_ssd1306_invertByte);
187  offset++;
188  }
189  x += this->m_font->getHeader().width;
190  j++;
191  }
192  this->m_intf.endBlock();
193 }
194 #endif
195 
196 template <class I>
197 void NanoDisplayOps1<I>::printFixedN(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style, uint8_t factor)
198 {
199  uint8_t i, j=0;
200  uint8_t text_index = 0;
201  uint8_t page_offset = 0;
202  uint8_t x = xpos;
203  y >>= 3;
204  this->m_intf.startBlock(xpos, y, this->m_w - xpos);
205  for(;;)
206  {
207  uint8_t ldata;
208  if( (x > this->m_w - (this->m_font->getHeader().width << factor)) || (ch[j] == '\0') )
209  {
210  x = xpos;
211  y++;
212  if (y >= (this->m_h >> 3))
213  {
214  break;
215  }
216  page_offset++;
217  if (page_offset == (this->m_font->getPages() << factor))
218  {
219  text_index = j;
220  page_offset = 0;
221  if (ch[j] == '\0')
222  {
223  break;
224  }
225  }
226  else
227  {
228  j = text_index;
229  }
230  this->m_intf.endBlock();
231  this->m_intf.startBlock(xpos, y, this->m_w - xpos);
232  }
233  uint16_t unicode;
234  do
235  {
236  unicode = this->m_font->unicode16FromUtf8(ch[j]);
237  j++;
238  } while ( unicode == SSD1306_MORE_CHARS_REQUIRED );
239  SCharInfo char_info;
240  this->m_font->getCharBitmap(unicode, &char_info);
241  ldata = 0;
242  x += ((char_info.width + char_info.spacing) << factor);
243  if (char_info.height > (page_offset >> factor) * 8)
244  {
245  char_info.glyph += (page_offset >> factor) * char_info.width;
246  for( i=char_info.width; i>0; i--)
247  {
248  uint8_t data;
249  if ( style == STYLE_NORMAL )
250  {
251  data = pgm_read_byte(char_info.glyph);
252  }
253  else if ( style == STYLE_BOLD )
254  {
255  uint8_t temp = pgm_read_byte(char_info.glyph);
256  data = temp | ldata;
257  ldata = temp;
258  }
259  else
260  {
261  uint8_t temp = pgm_read_byte(char_info.glyph+1);
262  data = (temp & 0xF0) | ldata;
263  ldata = (temp & 0x0F);
264  }
265  if ( factor > 0 )
266  {
267  uint8_t accum = 0;
268  uint8_t mask = ~((0xFF) << (1<<factor));
269  // N=0 -> right shift is always 0
270  // N=1 -> right shift goes through 0, 4
271  // N=2 -> right shift goes through 0, 2, 4, 6
272  // N=3 -> right shift goes through 0, 1, 2, 3, 4, 5, 6, 7
273  data >>= ((page_offset & ((1<<factor) - 1))<<(3-factor));
274  for (uint8_t idx = 0; idx < 1<<(3-factor); idx++)
275  {
276  accum |= (((data>>idx) & 0x01) ? (mask<<(idx<<factor)) : 0);
277  }
278  data = accum;
279  }
280  for (uint8_t z=(1<<factor); z>0; z--)
281  {
282  this->m_intf.send(data^s_ssd1306_invertByte);
283  }
284  char_info.glyph++;
285  }
286  }
287  else
288  {
289  char_info.spacing += char_info.width;
290  }
291  for (i = 0; i < (char_info.spacing << factor); i++)
292  this->m_intf.send(s_ssd1306_invertByte);
293  }
294  this->m_intf.stop();
295 }
296 
297 template <class I>
299 {
300  this->m_intf.startBlock(x, y >> 3, 1);
301  this->m_intf.send((1 << (y & 0x07))^s_ssd1306_invertByte);
302  this->m_intf.endBlock();
303 }
304 
305 template <class I>
307 {
308  this->m_intf.startBlock(x1, y1 >> 3, x2 - x1 + 1);
309  for (uint8_t x = x1; x <= x2; x++)
310  {
311  this->m_intf.send((1 << (y1 & 0x07))^s_ssd1306_invertByte);
312  }
313  this->m_intf.endBlock();
314 }
315 
316 template <class I>
318 {
319  uint8_t topPage = y1 >> 3;
320  uint8_t bottomPage = y2 >> 3;
321  uint8_t height = y2-y1;
322  uint8_t y;
323  this->m_intf.startBlock(x1, topPage, 1);
324  if (topPage == bottomPage)
325  {
326  this->m_intf.send( ((0xFF >> (0x07 - height)) << (y1 & 0x07))^s_ssd1306_invertByte );
327  this->m_intf.endBlock();
328  return;
329  }
330  this->m_intf.send( (0xFF << (y1 & 0x07))^s_ssd1306_invertByte );
331  for ( y = (topPage + 1); y <= (bottomPage - 1); y++)
332  {
333  this->m_intf.nextBlock();
334  this->m_intf.send( 0xFF^s_ssd1306_invertByte );
335  }
336  this->m_intf.nextBlock();
337  this->m_intf.send( (0xFF >> (0x07 - (y2 & 0x07)))^s_ssd1306_invertByte );
338  this->m_intf.endBlock();
339 }
340 
341 template <class I>
343 {
344  uint8_t templ = this->m_color^s_ssd1306_invertByte;
345  if (x1 > x2) return;
346  if (y1 > y2) return;
347  if ((lcduint_t)x2 >= this->m_w) x2 = (lcdint_t)this->m_w -1;
348  if ((lcduint_t)y2 >= this->m_h) y2 = (lcdint_t)this->m_h -1;
349  uint8_t bank1 = (y1 >> 3);
350  uint8_t bank2 = (y2 >> 3);
351  this->m_intf.startBlock(x1, bank1, x2 - x1 + 1);
352  for (uint8_t bank = bank1; bank<=bank2; bank++)
353  {
354  uint8_t mask = 0xFF;
355  if (bank1 == bank2)
356  {
357  mask = (mask >> ((y1 & 7) + 7 - (y2 & 7))) << (y1 & 7);
358  }
359  else if (bank1 == bank)
360  {
361  mask = (mask << (y1 & 7));
362  }
363  else if (bank2 == bank)
364  {
365  mask = (mask >> (7 - (y2 & 7)));
366  }
367  for (uint8_t x=x1; x<=x2; x++)
368  {
369 // m_bytes[BADDR(bank) + x] &= ~mask;
370 // m_bytes[BADDR(bank) + x] |= (templ & mask);
371  this->m_intf.send(templ & mask);
372  }
373  this->m_intf.nextBlock();
374  }
375  this->m_intf.endBlock();
376 }
377 
378 template <class I>
380 {
381  this->fill(0);
382 /* this->m_intf.startBlock(0, 0, 0);
383  for(uint8_t m=(this->m_h >> 3); m>0; m--)
384  {
385  for(uint8_t n=this->m_w; n>0; n--)
386  {
387  this->m_intf.send( s_ssd1306_invertByte );
388  }
389  this->m_intf.nextBlock();
390  }
391  this->m_intf.endBlock(); */
392 }
393 
394 template <class I>
395 void NanoDisplayOps1<I>::drawXBitmap(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
396 {
397  uint8_t i, j;
398  lcduint_t pitch = (w + 7) >> 3;
399  this->m_intf.startBlock(x, y, w);
400  for(j=(h >> 3); j>0; j--)
401  {
402  uint8_t bit = 0;
403  for(i=w;i>0;i--)
404  {
405  uint8_t data = 0;
406  for (uint8_t k = 0; k<8; k++)
407  {
408  data |= ( ((pgm_read_byte(&bitmap[k*pitch]) >> bit) & 0x01) << k );
409  }
410  this->m_intf.send( s_ssd1306_invertByte^data );
411  bit++;
412  if (bit >= 8)
413  {
414  bitmap++;
415  bit=0;
416  }
417  }
418  if (bit)
419  {
420  bitmap++;
421  }
422  bitmap += pitch * 7;
423  this->m_intf.nextBlock();
424  }
425  this->m_intf.endBlock();
426 }
427 
428 template <class I>
429 void NanoDisplayOps1<I>::drawBitmap1(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
430 {
431  lcduint_t origin_width = w;
432  uint8_t offset = y & 0x07;
433  uint8_t complexFlag = 0;
434  uint8_t mainFlag = 1;
435  uint8_t max_pages;
436  uint8_t pages;
437  lcduint_t i, j;
438  if (y + (lcdint_t)h <= 0) return;
439  if (y >= (lcdint_t)this->m_h) return;
440  if (x + (lcdint_t)w <= 0) return;
441  if (x >= (lcdint_t)this->m_w) return;
442  if (y < 0)
443  {
444  bitmap += ((lcduint_t)((-y) + 7) >> 3) * w;
445  h += y;
446  y = 0;
447  complexFlag = 1;
448  }
449  if (x < 0)
450  {
451  bitmap += -x;
452  w += x;
453  x = 0;
454  }
455  max_pages = (lcduint_t)(h + 15 - offset) >> 3;
456  if ((lcduint_t)((lcduint_t)y + h) > (lcduint_t)this->m_h)
457  {
458  h = (lcduint_t)(this->m_h - (lcduint_t)y);
459  }
460  if ((lcduint_t)((lcduint_t)x + w) > (lcduint_t)this->m_w)
461  {
462  w = (lcduint_t)(this->m_w - (lcduint_t)x);
463  }
464  pages = ((y + h - 1) >> 3) - (y >> 3) + 1;
465 
466  uint8_t color = this->m_color ? 0xFF: 0x00;
467  this->m_intf.startBlock(x, y >> 3, w);
468  for(j=0; j < pages; j++)
469  {
470  if ( j == (lcduint_t)(max_pages - 1) ) mainFlag = !offset;
471  for( i=w; i > 0; i--)
472  {
473  uint8_t data = 0;
474  if ( mainFlag ) data |= ((pgm_read_byte(bitmap) << offset) & color);
475  if ( complexFlag ) data |= ((pgm_read_byte(bitmap - origin_width) >> (8 - offset)) & color);
476  bitmap++;
477  this->m_intf.send(s_ssd1306_invertByte^data);
478  }
479  bitmap += origin_width - w;
480  complexFlag = offset;
481  this->m_intf.nextBlock();
482  }
483  this->m_intf.endBlock();
484 }
485 
486 template <class I>
488 {
489  lcduint_t origin_width = w;
490  uint8_t offset = y & 0x07;
491  uint8_t complexFlag = 0;
492  uint8_t mainFlag = 1;
493  uint8_t max_pages;
494  uint8_t pages;
495  lcduint_t i, j;
496  if (y + (lcdint_t)h <= 0) return;
497  if (y >= (lcdint_t)this->m_h) return;
498  if (x + (lcdint_t)w <= 0) return;
499  if (x >= (lcdint_t)this->m_w) return;
500  if (y < 0)
501  {
502  buf += ((lcduint_t)((-y) + 7) >> 3) * w;
503  h += y;
504  y = 0;
505  complexFlag = 1;
506  }
507  if (x < 0)
508  {
509  buf += -x;
510  w += x;
511  x = 0;
512  }
513  max_pages = (lcduint_t)(h + 15 - offset) >> 3;
514  if ((lcduint_t)((lcduint_t)y + h) > (lcduint_t)this->m_h)
515  {
516  h = (lcduint_t)(this->m_h - (lcduint_t)y);
517  }
518  if ((lcduint_t)((lcduint_t)x + w) > (lcduint_t)this->m_w)
519  {
520  w = (lcduint_t)(this->m_w - (lcduint_t)x);
521  }
522  pages = ((y + h - 1) >> 3) - (y >> 3) + 1;
523 
524  uint8_t color = this->m_color ? 0xFF: 0x00;
525  this->m_intf.startBlock(x, y >> 3, w);
526  for(j=0; j < pages; j++)
527  {
528  if ( j == (lcduint_t)(max_pages - 1) ) mainFlag = !offset;
529  for( i=w; i > 0; i--)
530  {
531  uint8_t data = 0;
532  if ( mainFlag ) data |= ((pgm_read_byte(buf) << offset) & color);
533  if ( complexFlag ) data |= ((pgm_read_byte(buf - origin_width) >> (8 - offset)) & color);
534  buf++;
535  this->m_intf.send(s_ssd1306_invertByte^data);
536  }
537  buf += origin_width - w;
538  complexFlag = offset;
539  this->m_intf.nextBlock();
540  }
541  this->m_intf.endBlock();
542 }
543 
544 template <class I>
545 void NanoDisplayOps1<I>::drawBitmap4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
546 {
547  // NOT IMPLEMENTED
548 }
549 
550 template <class I>
551 void NanoDisplayOps1<I>::drawBitmap8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
552 {
553  // NOT IMPLEMENTED
554 }
555 
556 template <class I>
558 {
559  // NOT IMPLEMENTED
560 }
561 
562 template <class I>
563 void NanoDisplayOps1<I>::drawBuffer1(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
564 {
565  lcduint_t origin_width = w;
566  uint8_t offset = y & 0x07;
567  uint8_t complexFlag = 0;
568  uint8_t mainFlag = 1;
569  uint8_t max_pages;
570  uint8_t pages;
571  lcduint_t i, j;
572  if (y + (lcdint_t)h <= 0) return;
573  if (y >= (lcdint_t)this->m_h) return;
574  if (x + (lcdint_t)w <= 0) return;
575  if (x >= (lcdint_t)this->m_w) return;
576  if (y < 0)
577  {
578  buffer += ((lcduint_t)((-y) + 7) >> 3) * w;
579  h += y;
580  y = 0;
581  complexFlag = 1;
582  }
583  if (x < 0)
584  {
585  buffer += -x;
586  w += x;
587  x = 0;
588  }
589  max_pages = (lcduint_t)(h + 15 - offset) >> 3;
590  if ((lcduint_t)((lcduint_t)y + h) > (lcduint_t)this->m_h)
591  {
592  h = (lcduint_t)(this->m_h - (lcduint_t)y);
593  }
594  if ((lcduint_t)((lcduint_t)x + w) > (lcduint_t)this->m_w)
595  {
596  w = (lcduint_t)(this->m_w - (lcduint_t)x);
597  }
598  pages = ((y + h - 1) >> 3) - (y >> 3) + 1;
599 
600  this->m_intf.startBlock(x, y >> 3, w);
601  for(j=0; j < pages; j++)
602  {
603  if ( j == (lcduint_t)(max_pages - 1) ) mainFlag = !offset;
604  for( i=w; i > 0; i--)
605  {
606  uint8_t data = 0;
607  if ( mainFlag ) data |= ((*buffer << offset) & this->m_color);
608  if ( complexFlag ) data |= ((*(buffer - origin_width) >> (8 - offset)) & this->m_color);
609  buffer++;
610  this->m_intf.send(s_ssd1306_invertByte^data);
611  }
612  buffer += origin_width - w;
613  complexFlag = offset;
614  this->m_intf.nextBlock();
615  }
616  this->m_intf.endBlock();
617 }
618 
619 template <class I>
621 {
622  uint8_t j;
623  this->m_intf.startBlock(x, y >> 3, w);
624  for(j=(h >> 3); j>0; j--)
625  {
626  this->m_intf.sendBuffer( buf, w );
627  buf+=w;
628  this->m_intf.nextBlock();
629  }
630  this->m_intf.endBlock();
631 }
632 
633 template <class I>
634 void NanoDisplayOps1<I>::drawBuffer4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
635 {
636  // NOT IMPLEMENTED
637 }
638 
639 template <class I>
640 void NanoDisplayOps1<I>::drawBuffer8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
641 {
642  // NOT IMPLEMENTED
643 }
644 
645 template <class I>
647 {
648  // NOT IMPLEMENTED
649 }
650 
651 template <class I>
652 void NanoDisplayOps1<I>::fill(uint16_t color)
653 {
654  color ^= s_ssd1306_invertByte;
655  this->m_intf.startBlock(0, 0, 0);
656  for(uint8_t m=(this->m_h >> 3); m>0; m--)
657  {
658  for(uint8_t n=this->m_w; n>0; n--)
659  {
660  this->m_intf.send(color);
661  }
662  this->m_intf.nextBlock();
663  }
664  this->m_intf.endBlock();
665 }
666 
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. Draws 8-bit color bitmap in color buffer.
void fill(uint16_t color)
void drawBitmap16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
uint8_t height
char height in pixels
Definition: canvas_types.h:145
uint8_t lcduint_t
Definition: canvas_types.h:81
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...
void drawBuffer4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
lcduint_t width()
Definition: display_base.h:94
int8_t lcdint_t
Definition: canvas_types.h:79
void fillRect(lcdint_t x1, lcdint_t y1, lcdint_t x2, lcdint_t y2) __attribute__((noinline))
#define SSD1306_MORE_CHARS_REQUIRED
Definition: canvas_types.h:43
void gfx_drawMonoBitmap(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buf)
void drawBuffer1(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
void drawBuffer1Fast(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer)
void drawXBitmap(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
void putPixel(lcdint_t x, lcdint_t y) __attribute__((noinline))
uint8_t width
char width in pixels
Definition: canvas_types.h:144
void printFixedN(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style, uint8_t factor) __attribute__((noinline))
void drawBuffer8(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))
const uint8_t * glyph
char data, located in progmem.
Definition: canvas_types.h:147
void printFixed(lcdint_t xpos, lcdint_t y, const char *ch, EFontStyle style=STYLE_NORMAL) __attribute__((noinline))
void drawBitmap4(lcdint_t x, lcdint_t y, lcduint_t w, lcduint_t h, const uint8_t *bitmap)
Draws 4-bit gray-color bitmap in color buffer. Draws 4-bit gray-color bitmap in color buffer...
uint8_t spacing
additional spaces after char in pixels
Definition: canvas_types.h:146
void drawVLine(lcdint_t x1, lcdint_t y1, lcdint_t y2)
EFontStyle
Definition: canvas_types.h:90
void drawHLine(lcdint_t x1, lcdint_t y1, lcdint_t x2)
void drawBuffer16(lcdint_t xpos, lcdint_t ypos, lcduint_t w, lcduint_t h, const uint8_t *buffer) __attribute__((noinline))