SSD1306 I2C Display Driver  1.1.0
This library is developed to control SSD1306 I2C 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_inverseByte)
32  {
33  m_bytes[YADDR(y) + x] &= ((1 << (y & 0x7))^m_inverseByte);
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_inverseByte;
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; bank2<=(y2 >> 3); 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_inverseByte;
110  }
111 }
112 
113 
114 void NanoCanvas::charF6x8(uint8_t x, uint8_t y, const char ch[], EFontStyle style)
115 {
116  uint8_t c, i, j;
117  if (y>=m_h) return;
118  j = 0;
119  while(ch[j] != '\0')
120  {
121  c = ch[j] - 32;
122  uint8_t ldata = 0;
123  for(i=0;i<6;i++)
124  {
125  if (x>=m_w) return;
126  uint8_t data;
127  if ( style == STYLE_NORMAL )
128  {
129  data = pgm_read_byte(&s_font6x8[c*6+i]);
130  }
131  else if ( style == STYLE_BOLD )
132  {
133  data = pgm_read_byte(&s_font6x8[c*6+i]);
134  uint8_t temp = data | ldata;
135  ldata = data;
136  data = temp;
137  }
138  else
139  {
140  data = pgm_read_byte(&s_font6x8[c*6+i + 1]);
141  uint8_t temp = (data & 0xF0) | ldata;
142  ldata = (data & 0x0F);
143  data = temp;
144  }
145  m_bytes[YADDR(y) + x] |= (data << (y & 0x7));
146  if (y+8 < m_h)
147  m_bytes[YADDR(y) + m_w + x] |= (data >> (8 - (y & 0x7)));
148  x++;
149  }
150  j++;
151  }
152 }
153 
154 
155 void NanoCanvas::drawSpritePgm(uint8_t x, uint8_t y, const uint8_t sprite[])
156 {
157  uint8_t i;
158  for(i=0;i<8;i++)
159  {
160  if (x >= m_w) { x++; continue; }
161  uint8_t d = pgm_read_byte(&sprite[i]);
162  if (y < m_h)
163  m_bytes[YADDR(y) + x] |= (d << (y & 0x7));
164  if ((uint8_t)(y + 8) < m_h)
165  m_bytes[YADDR((uint8_t)(y + 8)) + x] |= (d >> (8 - (y & 0x7)));
166  x++;
167  }
168 };
169 
170 
171 void NanoCanvas::drawSprite(uint8_t x, uint8_t y, const uint8_t sprite[])
172 {
173  uint8_t i;
174  for(i=0;i<8;i++)
175  {
176  if (x>=m_w) { x++; continue; }
177  uint8_t d = sprite[i];
178  if (uint8_t(y) < m_h)
179  m_bytes[YADDR(y) + x] |= (d << (y & 0x7));
180  if ((uint8_t)(y+8) < m_h)
181  m_bytes[YADDR((uint8_t)(y + 8)) + x] |= (d >> (8 - (y & 0x7)));
182  x++;
183  }
184 };
185 
187 {
188  uint8_t i;
189  for(i = 0; i < sprite->w; i++)
190  {
191  if ((sprite->x + i) >= m_w) { continue; }
192  uint8_t d = pgm_read_byte(&sprite->data[i]);
193  if (sprite->y < m_h)
194  m_bytes[YADDR(sprite->y) + sprite->x + i] |= (d << (sprite->y & 0x7));
195  if (uint8_t(sprite->y + 8) < m_h)
196  m_bytes[YADDR(uint8_t(sprite->y + 8)) + sprite->x + i] |= (d >> (8 - (sprite->y & 0x7)));
197  }
198 }
199 
200 void NanoCanvas::blt(uint8_t x, uint8_t y)
201 {
202  ssd1306_drawBuffer(x, y, m_w, m_h, m_bytes);
203 }
204 
206 {
207  for(uint16_t i=0; i<m_w* (m_h >> 3); i++)
208  m_bytes[i] = ~m_bytes[i];
209 }
210 
212 {
213  for (uint8_t y=0; y<(m_h>>3); y++)
214  for (uint8_t x=0; x<m_w>>1; x++)
215  {
216  uint8_t temp = m_bytes[YADDR(y) + x];
217  m_bytes[YADDR(y) + x] = m_bytes[YADDR(y) + m_w - x -1];
218  m_bytes[YADDR(y) + m_w - x -1] = temp;
219  }
220 }
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:155
void drawSprite(uint8_t x, uint8_t y, const uint8_t sprite[])
Definition: nano_gfx.cpp:171
void invert()
Definition: nano_gfx.cpp:205
void flipH()
Definition: nano_gfx.cpp:211
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:237
uint8_t w
sprite width
void blt(uint8_t x, uint8_t y)
Definition: nano_gfx.cpp:200
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