SSD1306 OLED display driver  1.3.3
This library is developed to control SSD1306 i2c/spi OLED display
nano_gfx.cpp
1 /*
2  Copyright (C) 2016-2017 Alexey Dynda
3 
4  This file is part of SSD1306 library.
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "nano_gfx.h"
21 #include "ssd1306.h"
22 
23 extern const uint8_t *s_font6x8;
24 
25 #define YADDR(y) (((y) >> 3) << m_p)
26 #define BADDR(b) ((b) << m_p)
27 
28 void NanoCanvas::putPixel(uint8_t x, uint8_t y)
29 {
30  if ((x>=m_w) || (y>=m_h)) return;
31  if (m_invertByte)
32  {
33  m_bytes[YADDR(y) + x] &= ((1 << (y & 0x7))^m_invertByte);
34  }
35  else
36  {
37  m_bytes[YADDR(y) + x] |= (1 << (y & 0x7));
38  }
39 };
40 
41 void NanoCanvas::drawHLine(uint8_t x1, uint8_t y1, uint8_t x2)
42 {
43  if (y1 >= m_h) return;
44  if (x2 < x1) x1 = 0;
45  if (x1 >= m_w) return;
46  if (x2 >= m_w) x2 = m_w - 1;
47  for(uint8_t x = x1; x<=x2; x++)
48  m_bytes[YADDR(y1) + x] |= (1 << (y1 & 0x7));
49 };
50 
51 void NanoCanvas::drawVLine(uint8_t x1, uint8_t y1, uint8_t y2)
52 {
53  if (x1 >= m_w) return;
54  if (y2 < y1) y1 = 0;
55  if (y1 >= m_h) return;
56  if (y2 >= m_h) y2 = m_h - 1;
57  for(uint8_t y = y1; y<=y2; y++)
58  m_bytes[YADDR(y) + x1] |= (1 << (y & 0x7));
59 };
60 
61 void NanoCanvas::drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
62 {
63  drawHLine(x1, y1, x2);
64  drawHLine(x1, y2, x2);
65  drawVLine(x1, y1, y2);
66  drawVLine(x2, y1, y2);
67 };
68 
69 
70 void NanoCanvas::fillRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t templ)
71 {
72  templ ^= m_invertByte;
73  if ((x1 < x2) && (x1 >= m_w)) return;
74  if ((y1 < y2) && (y1 >= m_h)) return;
75  if (x1 > x2) x1 = 0;
76  if (y1 > y2) y1 = 0;
77  if (x2 >= m_w) x2 = m_w -1;
78  if (y2 >= m_h) y2 = m_h -1;
79  uint8_t bank1 = (y1 >> 3);
80  uint8_t bank2 = (y2 >> 3);
81  for (uint8_t bank = bank1; bank<=bank2; bank++)
82  {
83  uint8_t mask = 0xFF;
84  if (bank1 == bank2)
85  {
86  mask = (mask >> ((y1 & 7) + 7 - (y2 & 7))) << (7 - (y2 & 7));
87  }
88  else if (bank1 == bank)
89  {
90  mask = (mask << (y1 & 7));
91  }
92  else if (bank2 == bank)
93  {
94  mask = (mask >> (7 - (y2 & 7)));
95  }
96  for (uint8_t x=x1; x<x2; x++)
97  {
98  m_bytes[BADDR(bank) + x] &= ~mask;
99  m_bytes[BADDR(bank) + x] |= (templ & mask);
100  }
101  }
102 };
103 
104 
106 {
107  for(uint16_t i=0; i<m_w* (m_h >> 3); i++)
108  {
109  m_bytes[i] = m_invertByte;
110  }
111 }
112 
113 
114 void NanoCanvas::charF6x8(uint8_t x, uint8_t y, const char ch[], EFontStyle style)
115 {
116  uint8_t i, j, topMask, bottomMask;
117  if (y>=m_h) return;
118  j = 0;
119  topMask = (0xFF >> (8 - (y & 0x7)));
120  bottomMask = (0xFF << (y & 0x7));
121  while(ch[j] != '\0')
122  {
123  uint8_t c = ch[j] - 32;
124  uint8_t ldata = 0;
125  for(i=0;i<6;i++)
126  {
127  if (x>=m_w) return;
128  uint8_t data;
129  if ( style == STYLE_NORMAL )
130  {
131  data = pgm_read_byte(&s_font6x8[c*6+i]);
132  }
133  else if ( style == STYLE_BOLD )
134  {
135  data = pgm_read_byte(&s_font6x8[c*6+i]);
136  uint8_t temp = data | ldata;
137  ldata = data;
138  data = temp;
139  }
140  else
141  {
142  data = pgm_read_byte(&s_font6x8[c*6+i + 1]);
143  uint8_t temp = (data & 0xF0) | ldata;
144  ldata = (data & 0x0F);
145  data = temp;
146  }
147  m_bytes[YADDR(y) + x] &= topMask;
148  m_bytes[YADDR(y) + x] |= (data << (y & 0x7));
149  if (y+8 < m_h)
150  {
151  m_bytes[YADDR(y) + m_w + x] &= bottomMask;
152  m_bytes[YADDR(y) + m_w + x] |= (data >> (8 - (y & 0x7)));
153  }
154  x++;
155  }
156  j++;
157  }
158 }
159 
160 
161 void NanoCanvas::drawSpritePgm(uint8_t x, uint8_t y, const uint8_t sprite[])
162 {
163  uint8_t i;
164  for(i=0;i<8;i++)
165  {
166  if (x >= m_w) { x++; continue; }
167  uint8_t d = pgm_read_byte(&sprite[i]);
168  if (y < m_h)
169  m_bytes[YADDR(y) + x] |= (d << (y & 0x7));
170  if ((uint8_t)(y + 8) < m_h)
171  m_bytes[YADDR((uint8_t)(y + 8)) + x] |= (d >> (8 - (y & 0x7)));
172  x++;
173  }
174 };
175 
176 
177 void NanoCanvas::drawSprite(uint8_t x, uint8_t y, const uint8_t sprite[])
178 {
179  uint8_t i;
180  for(i=0;i<8;i++)
181  {
182  if (x>=m_w) { x++; continue; }
183  uint8_t d = sprite[i];
184  if (uint8_t(y) < m_h)
185  m_bytes[YADDR(y) + x] |= (d << (y & 0x7));
186  if ((uint8_t)(y+8) < m_h)
187  m_bytes[YADDR((uint8_t)(y + 8)) + x] |= (d >> (8 - (y & 0x7)));
188  x++;
189  }
190 };
191 
193 {
194  uint8_t i;
195  for(i = 0; i < sprite->w; i++)
196  {
197  if ((sprite->x + i) >= m_w) { continue; }
198  uint8_t d = pgm_read_byte(&sprite->data[i]);
199  if (sprite->y < m_h)
200  m_bytes[YADDR(sprite->y) + sprite->x + i] |= (d << (sprite->y & 0x7));
201  if (uint8_t(sprite->y + 8) < m_h)
202  m_bytes[YADDR(uint8_t(sprite->y + 8)) + sprite->x + i] |= (d >> (8 - (sprite->y & 0x7)));
203  }
204 }
205 
206 void NanoCanvas::blt(uint8_t x, uint8_t y)
207 {
208  ssd1306_drawBuffer(x, y, m_w, m_h, m_bytes);
209 }
210 
212 {
213  for(uint16_t i=0; i<m_w* (m_h >> 3); i++)
214  m_bytes[i] = ~m_bytes[i];
215 }
216 
218 {
219  for (uint8_t y=0; y<(m_h>>3); y++)
220  for (uint8_t x=0; x<m_w>>1; x++)
221  {
222  uint8_t temp = m_bytes[YADDR(y) + x];
223  m_bytes[YADDR(y) + x] = m_bytes[YADDR(y) + m_w - x -1];
224  m_bytes[YADDR(y) + m_w - x -1] = temp;
225  }
226 }
void charF6x8(uint8_t x, uint8_t y, const char ch[], EFontStyle style=STYLE_NORMAL)
Definition: nano_gfx.cpp:114
void fillRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t templ)
Definition: nano_gfx.cpp:70
void clear()
Definition: nano_gfx.cpp:105
const uint8_t * data
Pointer to PROGMEM data, representing sprite image.
void drawSpritePgm(uint8_t x, uint8_t y, const uint8_t sprite[])
Definition: nano_gfx.cpp:161
void drawSprite(uint8_t x, uint8_t y, const uint8_t sprite[])
Definition: nano_gfx.cpp:177
void invert()
Definition: nano_gfx.cpp:211
void flipH()
Definition: nano_gfx.cpp:217
void drawVLine(uint8_t x1, uint8_t y1, uint8_t y2)
Definition: nano_gfx.cpp:51
uint8_t y
draw position Y on the screen
void drawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
Definition: nano_gfx.cpp:61
uint8_t x
draw position X on the screen
void ssd1306_drawBuffer(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
Definition: ssd1306.cpp:278
uint8_t w
sprite width
void blt(uint8_t x, uint8_t y)
Definition: nano_gfx.cpp:206
void putPixel(uint8_t x, uint8_t y)
Definition: nano_gfx.cpp:28
EFontStyle
void drawHLine(uint8_t x1, uint8_t y1, uint8_t x2)
Definition: nano_gfx.cpp:41