Skip to content

Commit 868d3ed

Browse files
Add 8-bit canvas type, because reasons. Also some 1- and 16-bit canvas cleanup.
1 parent 4b1a8a6 commit 868d3ed

File tree

2 files changed

+90
-23
lines changed

2 files changed

+90
-23
lines changed

Adafruit_GFX.cpp

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,19 +1071,21 @@ boolean Adafruit_GFX_Button::justReleased() { return (!currstate && laststate);
10711071

10721072
// -------------------------------------------------------------------------
10731073

1074-
// GFXcanvas1 and GFXcanvas16 (currently a WIP, don't get too comfy with the
1075-
// implementation) provide 1- and 16-bit offscreen canvases, the address of
1076-
// which can be passed to drawBitmap() or pushColors() (the latter appears
1077-
// to only be in Adafruit_TFTLCD at this time). This is here mostly to
1078-
// help with the recently-added proportionally-spaced fonts; adds a way to
1079-
// refresh a section of the screen without a massive flickering clear-and-
1080-
// redraw...but maybe you'll find other uses too. VERY RAM-intensive, since
1081-
// the buffer is in MCU memory and not the display driver...GXFcanvas1 might
1082-
// be minimally useful on an Uno-class board, but this and GFXcanvas16 are
1083-
// much more likely to require at least a Mega or various recent ARM-type
1084-
// boards (recommended, as the text+bitmap draw can be pokey). GFXcanvas1
1085-
// requires 1 bit per pixel (rounded up to nearest byte per scanline),
1086-
// GFXcanvas16 requires 2 bytes per pixel (no scanline pad).
1074+
// GFXcanvas1, GFXcanvas8 and GFXcanvas16 (currently a WIP, don't get too
1075+
// comfy with the implementation) provide 1-, 8- and 16-bit offscreen
1076+
// canvases, the address of which can be passed to drawBitmap() or
1077+
// pushColors() (the latter appears only in a couple of GFX-subclassed TFT
1078+
// libraries at this time). This is here mostly to help with the recently-
1079+
// added proportionally-spaced fonts; adds a way to refresh a section of the
1080+
// screen without a massive flickering clear-and-redraw...but maybe you'll
1081+
// find other uses too. VERY RAM-intensive, since the buffer is in MCU
1082+
// memory and not the display driver...GXFcanvas1 might be minimally useful
1083+
// on an Uno-class board, but this and the others are much more likely to
1084+
// require at least a Mega or various recent ARM-type boards (recommended,
1085+
// as the text+bitmap draw can be pokey). GFXcanvas1 requires 1 bit per
1086+
// pixel (rounded up to nearest byte per scanline), GFXcanvas8 is 1 byte
1087+
// per pixel (no scanline pad), and GFXcanvas16 uses 2 bytes per pixel (no
1088+
// scanline pad).
10871089
// NOT EXTENSIVELY TESTED YET. MAY CONTAIN WORST BUGS KNOWN TO HUMANKIND.
10881090

10891091
GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
@@ -1101,11 +1103,13 @@ uint8_t* GFXcanvas1::getBuffer(void) {
11011103
return buffer;
11021104
}
11031105

1104-
void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) {
1106+
void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint8_t color) {
1107+
#ifdef __AVR__
11051108
// Bitmask tables of 0x80>>X and ~(0x80>>X), because X>>Y is slow on AVR
11061109
static const uint8_t PROGMEM
1107-
GFXsetBit[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 },
1108-
GFXclrBit[] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE };
1110+
GFXsetBit[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 },
1111+
GFXclrBit[] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE };
1112+
#endif
11091113

11101114
if(buffer) {
11111115
if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return;
@@ -1128,21 +1132,73 @@ void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) {
11281132
break;
11291133
}
11301134

1131-
uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)];
1135+
uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)];
1136+
#ifdef __AVR__
11321137
if(color) *ptr |= pgm_read_byte(&GFXsetBit[x & 7]);
11331138
else *ptr &= pgm_read_byte(&GFXclrBit[x & 7]);
1139+
#else
1140+
if(color) *ptr |= 0x80 >> (x & 7);
1141+
else *ptr &= ~(0x80 >> (x & 7));
1142+
#endif
11341143
}
11351144
}
11361145

1137-
void GFXcanvas1::fillScreen(uint16_t color) {
1146+
void GFXcanvas1::fillScreen(uint8_t color) {
11381147
if(buffer) {
11391148
uint16_t bytes = ((WIDTH + 7) / 8) * HEIGHT;
11401149
memset(buffer, color ? 0xFF : 0x00, bytes);
11411150
}
11421151
}
11431152

1153+
GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
1154+
uint32_t bytes = w * h;
1155+
if((buffer = (uint8_t *)malloc(bytes))) {
1156+
memset(buffer, 0, bytes);
1157+
}
1158+
}
1159+
1160+
GFXcanvas8::~GFXcanvas8(void) {
1161+
if(buffer) free(buffer);
1162+
}
1163+
1164+
uint8_t* GFXcanvas8::getBuffer(void) {
1165+
return buffer;
1166+
}
1167+
1168+
void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint8_t color) {
1169+
if(buffer) {
1170+
if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return;
1171+
1172+
int16_t t;
1173+
switch(rotation) {
1174+
case 1:
1175+
t = x;
1176+
x = WIDTH - 1 - y;
1177+
y = t;
1178+
break;
1179+
case 2:
1180+
x = WIDTH - 1 - x;
1181+
y = HEIGHT - 1 - y;
1182+
break;
1183+
case 3:
1184+
t = x;
1185+
x = y;
1186+
y = HEIGHT - 1 - t;
1187+
break;
1188+
}
1189+
1190+
buffer[x + y * WIDTH] = color;
1191+
}
1192+
}
1193+
1194+
void GFXcanvas8::fillScreen(uint8_t color) {
1195+
if(buffer) {
1196+
memset(buffer, color, WIDTH * HEIGHT);
1197+
}
1198+
}
1199+
11441200
GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
1145-
uint16_t bytes = w * h * 2;
1201+
uint32_t bytes = w * h * 2;
11461202
if((buffer = (uint16_t *)malloc(bytes))) {
11471203
memset(buffer, 0, bytes);
11481204
}
@@ -1188,7 +1244,7 @@ void GFXcanvas16::fillScreen(uint16_t color) {
11881244
if(hi == lo) {
11891245
memset(buffer, lo, WIDTH * HEIGHT * 2);
11901246
} else {
1191-
uint16_t i, pixels = WIDTH * HEIGHT;
1247+
uint32_t i, pixels = WIDTH * HEIGHT;
11921248
for(i=0; i<pixels; i++) buffer[i] = color;
11931249
}
11941250
}

Adafruit_GFX.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,18 +155,29 @@ class Adafruit_GFX_Button {
155155
};
156156

157157
class GFXcanvas1 : public Adafruit_GFX {
158-
159158
public:
160159
GFXcanvas1(uint16_t w, uint16_t h);
161160
~GFXcanvas1(void);
162-
void drawPixel(int16_t x, int16_t y, uint16_t color),
163-
fillScreen(uint16_t color);
161+
void drawPixel(int16_t x, int16_t y, uint8_t color),
162+
fillScreen(uint8_t color);
163+
uint8_t *getBuffer(void);
164+
private:
165+
uint8_t *buffer;
166+
};
167+
168+
class GFXcanvas8 : public Adafruit_GFX {
169+
public:
170+
GFXcanvas8(uint16_t w, uint16_t h);
171+
~GFXcanvas8(void);
172+
void drawPixel(int16_t x, int16_t y, uint8_t color),
173+
fillScreen(uint8_t color);
164174
uint8_t *getBuffer(void);
165175
private:
166176
uint8_t *buffer;
167177
};
168178

169179
class GFXcanvas16 : public Adafruit_GFX {
180+
public:
170181
GFXcanvas16(uint16_t w, uint16_t h);
171182
~GFXcanvas16(void);
172183
void drawPixel(int16_t x, int16_t y, uint16_t color),

0 commit comments

Comments
 (0)