mirror of
https://github.com/adafruit/Adafruit-GFX-Library.git
synced 2026-07-27 20:05:52 +00:00
Put canvases back in order :/
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/***
|
||||
This example is intended to demonstrate the use of getPixel() versus
|
||||
getRawPixel() and the fast horizontal and vertical drawing routines
|
||||
getPixelRaw() and the fast horizontal and vertical drawing routines
|
||||
in the GFXcanvas family of classes,
|
||||
|
||||
When using the GFXcanvas* classes as the image buffer for a hardware driver,
|
||||
@@ -11,7 +11,7 @@ GFXcanvas* classes that allow fetching of specific pixel values.
|
||||
|
||||
* getPixel(x, y) : Gets the pixel color value at the rotated coordinates in
|
||||
the image.
|
||||
* getRawPixel(x,y) : Gets the pixel color value at the unrotated coordinates
|
||||
* getPixelRaw(x,y) : Gets the pixel color value at the unrotated coordinates
|
||||
in the image. This is useful for getting the pixel value to map to a hardware
|
||||
pixel location. This method was made protected as only the hardware driver
|
||||
should be accessing it.
|
||||
|
||||
@@ -22,7 +22,7 @@ void GFXcanvas1SerialDemo::print(bool rotated) {
|
||||
if (rotated) {
|
||||
pixel = this->getPixel(x, y);
|
||||
} else {
|
||||
pixel = this->getRawPixel(x, y);
|
||||
pixel = this->getPixelRaw(x, y);
|
||||
}
|
||||
sprintf(pixel_buffer, " %d", pixel);
|
||||
Serial.print(pixel_buffer);
|
||||
@@ -52,7 +52,7 @@ void GFXcanvas8SerialDemo::print(bool rotated) {
|
||||
if (rotated) {
|
||||
pixel = this->getPixel(x, y);
|
||||
} else {
|
||||
pixel = this->getRawPixel(x, y);
|
||||
pixel = this->getPixelRaw(x, y);
|
||||
}
|
||||
sprintf(pixel_buffer, " %02x", pixel);
|
||||
Serial.print(pixel_buffer);
|
||||
@@ -82,7 +82,7 @@ void GFXcanvas16SerialDemo::print(bool rotated) {
|
||||
if (rotated) {
|
||||
pixel = this->getPixel(x, y);
|
||||
} else {
|
||||
pixel = this->getRawPixel(x, y);
|
||||
pixel = this->getPixelRaw(x, y);
|
||||
}
|
||||
sprintf(pixel_buffer, " %04x", pixel);
|
||||
Serial.print(pixel_buffer);
|
||||
|
||||
+4
-4
@@ -52,11 +52,11 @@ public:
|
||||
virtual void startWrite(void);
|
||||
virtual void writePixel(int16_t x, int16_t y, uint16_t color);
|
||||
virtual void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h,
|
||||
uint16_t color);
|
||||
uint16_t color);
|
||||
virtual void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
virtual void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
virtual void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
|
||||
uint16_t color);
|
||||
uint16_t color);
|
||||
virtual void endWrite(void);
|
||||
|
||||
// CONTROL API
|
||||
@@ -77,9 +77,9 @@ public:
|
||||
virtual void fillScreen(uint16_t color);
|
||||
// Optional and probably not necessary to change
|
||||
virtual void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
|
||||
uint16_t color);
|
||||
uint16_t color);
|
||||
virtual void drawRect(int16_t x, int16_t y, int16_t w, int16_t h,
|
||||
uint16_t color);
|
||||
uint16_t color);
|
||||
|
||||
// These exist only with Adafruit_GFX (no subclass overrides)
|
||||
void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
||||
|
||||
+201
-155
@@ -31,92 +31,109 @@ const uint8_t PROGMEM GFXcanvas1::GFXclrBit[] = {0x7F, 0xBF, 0xDF, 0xEF,
|
||||
@param h Canvas height in pixels.
|
||||
*/
|
||||
GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
|
||||
buffer = (uint8_t *)calloc(((w + 7) / 8) * h, 1); // Rows are byte aligned
|
||||
// Rows are byte-aligned. If allocation fails, no special action is
|
||||
// performed here. Drawing functions check for valid buffer.
|
||||
pixbuf = (uint8_t *)calloc(((w + 7) / 8) * h, 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Delete canvas, free memory.
|
||||
@brief GFXcanvas1 destructor. Frees memory associated with canvas.
|
||||
*/
|
||||
GFXcanvas1::~GFXcanvas1(void) {
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
}
|
||||
if (pixbuf) {
|
||||
free(pixbuf);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
@brief Draw a pixel to the canvas framebuffer, applying clipping and/or
|
||||
rotation as appropriate.
|
||||
@param x Pixel column (horizonal pos).
|
||||
@param y Pixel row (vertical pos).
|
||||
@param color Binary (on or off) color to set pixel.
|
||||
@param color Pixel draw color. Range depends on canvas depth.
|
||||
*/
|
||||
void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
// Validate canvas buffer is valid & point is in bounds
|
||||
if (buffer && (x >= 0) && (x < _width) && (y >= 0) && (y < _height)) {
|
||||
// Apply 'soft' rotation if needed
|
||||
if (pixbuf && (x >= 0) && (x < _width) && (y >= 0) && (y < _height)) {
|
||||
// Point is valid. Apply 'soft' rotation if needed.
|
||||
int16_t t;
|
||||
switch (rotation) {
|
||||
case 1:
|
||||
switch (rotation) { // 0 can be ignored
|
||||
case 1: // 90 degrees CW
|
||||
t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
break;
|
||||
case 2:
|
||||
case 2: // 180 degrees
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
break;
|
||||
case 3:
|
||||
case 3: // 90 degrees CCW
|
||||
t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
break;
|
||||
}
|
||||
|
||||
// (x, y) now known in-bounds and in native coordinate system.
|
||||
uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)];
|
||||
#ifdef __AVR__
|
||||
if (color)
|
||||
*ptr |= pgm_read_byte(&GFXsetBit[x & 7]);
|
||||
else
|
||||
*ptr &= pgm_read_byte(&GFXclrBit[x & 7]);
|
||||
#else
|
||||
if (color)
|
||||
*ptr |= 0x80 >> (x & 7);
|
||||
else
|
||||
*ptr &= ~(0x80 >> (x & 7));
|
||||
#endif
|
||||
// (x, y) now known in-bounds and in canvas-native coordinate system.
|
||||
drawPixelRaw(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Draw a pixel to the canvas framebuffer. NO CLIPPING, ROTATION OR
|
||||
VALIDATION OF CANVAS BUFFER IS PERFORMED, calling function must be
|
||||
AWARE and WELL-BEHAVED. This is a protected function intended for
|
||||
related class code, not user-facing.
|
||||
@param x Pixel column (horizonal pos).
|
||||
@param y Pixel row (vertical pos).
|
||||
@param color Pixel draw color; thresholded to 0 or 1 (any nonzero input).
|
||||
*/
|
||||
void GFXcanvas1::drawPixelRaw(int16_t x, int16_t y, uint16_t color) {
|
||||
uint8_t *ptr = &pixbuf[(x / 8) + y * ((WIDTH + 7) / 8)];
|
||||
#ifdef __AVR__
|
||||
if (color)
|
||||
*ptr |= pgm_read_byte(&GFXsetBit[x & 7]);
|
||||
else
|
||||
*ptr &= pgm_read_byte(&GFXclrBit[x & 7]);
|
||||
#else
|
||||
if (color)
|
||||
*ptr |= 0x80 >> (x & 7);
|
||||
else
|
||||
*ptr &= ~(0x80 >> (x & 7));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Retrieve pixel value from the canvas framebuffer, applying
|
||||
clipping and/or rotation as appropriate.
|
||||
@param x Pixel column (horizonal pos).
|
||||
@param y Pixel row (vertical pos).
|
||||
@return Pixel value (0 or 1) if coordinate is in-bounds. 0 if out-of-
|
||||
bounds or if canvas buffer previously failed to allocate.
|
||||
@return Pixel value if coordinate is in-bounds. 0 if out-of-bounds
|
||||
or if canvas buffer previously failed to allocate.
|
||||
*/
|
||||
bool GFXcanvas1::getPixel(int16_t x, int16_t y) const {
|
||||
if (buffer && (x >= 0) && (x < _width) && (y >= 0) && (y < _height)) {
|
||||
// Validate canvas buffer is valid & point is in bounds
|
||||
if (pixbuf && (x >= 0) && (x < _width) && (y >= 0) && (y < _height)) {
|
||||
// Point is valid. Apply 'soft' rotation if needed.
|
||||
int16_t t;
|
||||
switch (rotation) {
|
||||
case 1:
|
||||
switch (rotation) { // 0 can be ignored
|
||||
case 1: // 90 degrees CW
|
||||
t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
break;
|
||||
case 2:
|
||||
case 2: // 180 degrees
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
break;
|
||||
case 3:
|
||||
case 3: // 90 degrees CCW
|
||||
t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
break;
|
||||
}
|
||||
// (x, y) now known in-bounds and in native coordinate system.
|
||||
return getRawPixel(x, y);
|
||||
// (x, y) now known in-bounds and in canvas-native coordinate system.
|
||||
return getPixelRaw(x, y);
|
||||
}
|
||||
return 0; // Coord out of bounds, or canvas buffer is invalid
|
||||
}
|
||||
@@ -124,14 +141,15 @@ bool GFXcanvas1::getPixel(int16_t x, int16_t y) const {
|
||||
/*!
|
||||
@brief Retrieve pixel value from the canvas framebuffer, where inputs
|
||||
are known valid in-bounds and in native unrotated coordinates.
|
||||
NO CLIPPING OR VALIDATION OF CANVAS BUFFER IS PERFORMED,
|
||||
calling function must be AWARE and WELL-BEHAVED.
|
||||
NO CLIPPING, ROTATION OR VALIDATION OF CANVAS BUFFER IS PERFORMED,
|
||||
calling function must be AWARE and WELL-BEHAVED. This is a
|
||||
protected function intended for driver code, not user-facing.
|
||||
@param x Pixel column (horizonal pos).
|
||||
@param y Pixel row (vertical pos).
|
||||
@return Pixel value (0 or 1).
|
||||
*/
|
||||
bool GFXcanvas1::getRawPixel(int16_t x, int16_t y) const {
|
||||
uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)];
|
||||
bool GFXcanvas1::getPixelRaw(int16_t x, int16_t y) const {
|
||||
uint8_t *ptr = &pixbuf[(x / 8) + y * ((WIDTH + 7) / 8)];
|
||||
#ifdef __AVR__
|
||||
return ((*ptr) & pgm_read_byte(&GFXsetBit[x & 7])) != 0;
|
||||
#else
|
||||
@@ -141,142 +159,78 @@ bool GFXcanvas1::getRawPixel(int16_t x, int16_t y) const {
|
||||
|
||||
/*!
|
||||
@brief Fill canvas completely with one color.
|
||||
@param color Binary (on or off) color to fill with.
|
||||
@param color Canvas fill color; thresholded to 0 or 1 (any nonzero input).
|
||||
*/
|
||||
void GFXcanvas1::fillScreen(uint16_t color) {
|
||||
if (buffer) {
|
||||
memset(buffer, color ? 0xFF : 0x00, ((WIDTH + 7) / 8) * HEIGHT);
|
||||
if (pixbuf) {
|
||||
memset(pixbuf, color ? 0xFF : 0x00, ((WIDTH + 7) / 8) * HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Draw vertical line. May allow for optimizations compared to the
|
||||
generalized drawLine().
|
||||
generalized drawLine() function.
|
||||
@param x Column (horizontal position of start and end points)
|
||||
@param y Row (vertical pos) of start point.
|
||||
@param h Length of vertical line to be drawn, including first point.
|
||||
@param color Binary (on or off) color to draw.
|
||||
@param color Line draw color; thresholded to 0 or 1 (any nonzero input).
|
||||
*/
|
||||
void GFXcanvas1::drawFastVLine(int16_t x, int16_t y, int16_t h,
|
||||
uint16_t color) {
|
||||
|
||||
if (h < 0) { // Convert negative heights to positive equivalent
|
||||
h = -h;
|
||||
y -= h - 1;
|
||||
if (y < 0) {
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Edge rejection (no-draw if totally off canvas)
|
||||
if ((x >= 0) && (x < _width) && (y < _height) && ((y + h - 1) >= 0)) {
|
||||
if (y < 0) { // Clip top
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
if (y + h > height()) { // Clip bottom
|
||||
h = height() - y;
|
||||
}
|
||||
|
||||
int16_t t;
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
drawFastRawVLine(x, y, h, color);
|
||||
break;
|
||||
case 1:
|
||||
t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
x -= h - 1;
|
||||
drawFastRawHLine(x, y, h, color);
|
||||
break;
|
||||
case 2:
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
if (pixbuf) {
|
||||
if (h < 0) { // Convert negative heights to positive equivalent
|
||||
h = -h;
|
||||
y -= h - 1;
|
||||
drawFastRawVLine(x, y, h, color);
|
||||
break;
|
||||
case 3:
|
||||
t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
drawFastRawHLine(x, y, h, color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Draw horizontal line. May allow for optimizations compared to the
|
||||
generalized drawLine().
|
||||
@param x Column (horizontal position) of start point.
|
||||
@param y Row (vertical position of start and end points)
|
||||
@param w Width of vertical line to be drawn, including first point.
|
||||
@param color Binary (on or off) color to draw.
|
||||
*/
|
||||
void GFXcanvas1::drawFastHLine(int16_t x, int16_t y, int16_t w,
|
||||
uint16_t color) {
|
||||
if (w < 0) { // Convert negative widths to positive equivalent
|
||||
w *= -1;
|
||||
x -= w - 1;
|
||||
if (x < 0) {
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Edge rejection (no-draw if totally off canvas)
|
||||
if ((y >= 0) && (y < _height) && (x < _width) && ((x + w - 1) >= 0)) {
|
||||
if (x < 0) { // Clip left
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if (x + w >= width()) { // Clip right
|
||||
w = width() - x;
|
||||
if (y < 0) {
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t t;
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
drawFastRawHLine(x, y, w, color);
|
||||
break;
|
||||
case 1:
|
||||
t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
drawFastRawVLine(x, y, w, color);
|
||||
break;
|
||||
case 2:
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
x -= w - 1;
|
||||
drawFastRawHLine(x, y, w, color);
|
||||
break;
|
||||
case 3:
|
||||
t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
y -= w - 1;
|
||||
drawFastRawVLine(x, y, w, color);
|
||||
break;
|
||||
// Reject off-canvas and zero-height lines
|
||||
if ((h > 0) && (x >= 0) && (x < _width) && (y < _height) &&
|
||||
((y + h - 1) >= 0)) {
|
||||
if (y < 0) { // Clip top
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
if ((y + h) > _height) { // Clip bottom
|
||||
h = _height - y;
|
||||
}
|
||||
|
||||
switch (rotation) {
|
||||
case 0: // No rotation
|
||||
drawFastVLineRaw(x, y, h, color);
|
||||
break;
|
||||
case 1: // 90 degrees CW
|
||||
drawFastHLineRaw(WIDTH - y - h, x, h, color);
|
||||
break;
|
||||
case 2: // 180 degrees
|
||||
drawFastVLineRaw(WIDTH - 1 - x, HEIGHT - y - h, h, color);
|
||||
break;
|
||||
case 3: // 90 degrees CCW
|
||||
drawFastHLineRaw(y, HEIGHT - 1 - x, h, color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Draw vertical line into 'raw' canvas buffer. Inputs are assumed
|
||||
valid and in native coordinates; NO CLIPPING, ROTATION OR BUFFER
|
||||
VALIDATION IS PERFORMED.
|
||||
valid and in native coordinates. NO CLIPPING, ROTATION OR
|
||||
VALIDATION OF CANVAS BUFFER IS PERFORMED, calling function must
|
||||
be AWARE and WELL-BEHAVED. This is a protected function intended
|
||||
for related class code, not user-facing.
|
||||
@param x Column (horizontal position of start and end points)
|
||||
@param y Row (vertical pos) of start point.
|
||||
@param h Length of vertical line to be drawn, including first point.
|
||||
@param color Binary (on or off) color to draw.
|
||||
@param color Line draw color; thresholded to 0 or 1 (any nonzero input).
|
||||
*/
|
||||
void GFXcanvas1::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
|
||||
void GFXcanvas1::drawFastVLineRaw(int16_t x, int16_t y, int16_t h,
|
||||
uint16_t color) {
|
||||
int16_t row_bytes = ((WIDTH + 7) / 8); // Row-to-row increment
|
||||
uint8_t *ptr = &buffer[(x / 8) + y * row_bytes];
|
||||
uint8_t *ptr = &pixbuf[(x / 8) + y * row_bytes];
|
||||
|
||||
if (color > 0) {
|
||||
#ifdef __AVR__
|
||||
@@ -303,21 +257,112 @@ void GFXcanvas1::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
|
||||
|
||||
/*!
|
||||
@brief Draw horizontal line. May allow for optimizations compared to the
|
||||
generalized drawLine().
|
||||
@brief Draw horizontal line into 'raw' canvas buffer. Inputs are assumed
|
||||
valid and in native coordinates; NO CLIPPING, ROTATION OR BUFFER
|
||||
VALIDATION IS PERFORMED.
|
||||
generalized drawLine() function.
|
||||
@param x Column (horizontal position) of start point.
|
||||
@param y Row (vertical position of start and end points)
|
||||
@param w Width of vertical line to be drawn, including first point.
|
||||
@param color Binary (on or off) color to draw.
|
||||
@param color Line draw color; thresholded to 0 or 1 (any nonzero input).
|
||||
*/
|
||||
void GFXcanvas1::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
|
||||
void GFXcanvas1::drawFastHLine(int16_t x, int16_t y, int16_t w,
|
||||
uint16_t color) {
|
||||
if (pixbuf) {
|
||||
if (w < 0) { // Convert negative widths to positive equivalent
|
||||
w = -w;
|
||||
x -= w - 1;
|
||||
if (x < 0) {
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Reject off-canvas and zero-width lines
|
||||
if ((w > 0) && (y >= 0) && (y < _height) && (x < _width) &&
|
||||
((x + w - 1) >= 0)) {
|
||||
if (x < 0) { // Clip left
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if ((x + w) >= _width) { // Clip right
|
||||
w = _width - x;
|
||||
}
|
||||
|
||||
switch (rotation) {
|
||||
case 0: // No rotation
|
||||
drawFastHLineRaw(x, y, w, color);
|
||||
break;
|
||||
case 1: // 90 degrees CW
|
||||
drawFastVLineRaw(WIDTH - 1 - y, x, w, color);
|
||||
break;
|
||||
case 2: // 180 degrees
|
||||
drawFastHLineRaw(WIDTH - x - w, HEIGHT - 1 - y, w, color);
|
||||
break;
|
||||
case 3: // 90 degrees CCW
|
||||
drawFastVLineRaw(y, HEIGHT - x - w, w, color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Draw horizontal line into 'raw' canvas buffer. Inputs are assumed
|
||||
valid and in native coordinates. NO CLIPPING, ROTATION OR
|
||||
VALIDATION OF CANVAS BUFFER IS PERFORMED, calling function must
|
||||
be AWARE and WELL-BEHAVED. This is a protected function intended
|
||||
for related class code, not user-facing.
|
||||
@param x Column (horizontal position) of start point.
|
||||
@param y Row (vertical position of start and end points)
|
||||
@param w Width of vertical line to be drawn, including first point.
|
||||
@param color Line draw color; thresholded to 0 or 1 (any nonzero input).
|
||||
*/
|
||||
void GFXcanvas1::drawFastHLineRaw(int16_t x, int16_t y, int16_t w,
|
||||
uint16_t color) {
|
||||
int16_t rowBytes = ((WIDTH + 7) / 8);
|
||||
uint8_t *ptr = &buffer[(x / 8) + y * rowBytes];
|
||||
uint8_t *ptr = &pixbuf[(x / 8) + y * ((WIDTH + 7) / 8)];
|
||||
|
||||
#if 0
|
||||
// Do partial fill on first byte; may be only byte needed
|
||||
// If more bytes...
|
||||
// Fill the solid ones.
|
||||
// If a lingering byte...
|
||||
// Do partial fill on that
|
||||
if (x & 7) { // Partial fill on first byte?
|
||||
|
||||
x & 7 = first bit set in first byte
|
||||
(w & 7) + 1 ??? = number of bits set in first byte
|
||||
|
||||
|
||||
mask = (0xFF >> (7 - (w & 7))) << (x & 7);
|
||||
if ((color)) {
|
||||
*ptr |= mask;
|
||||
} else {
|
||||
*ptr &= ~mask;
|
||||
}
|
||||
ptr++;
|
||||
w -=
|
||||
|
||||
if (x & 7) { // Partial fill on first byte?
|
||||
uint8_t mask = 0xFF >> mod; // Consider bits from mod to end of 1st byte
|
||||
foo = 8 - mod; // Bits to end of 1st byte
|
||||
if (w < foo) { // If line width is less than this,
|
||||
mask &= (0xFF << (foo - w));
|
||||
}
|
||||
// wait - wh if I started with mask of w&7 bits?
|
||||
|
||||
*
|
||||
|
||||
if (w < mod) {
|
||||
mask &= 0xFF << (mod - w);
|
||||
}
|
||||
|
||||
w -= mod;
|
||||
}
|
||||
|
||||
|
||||
if width is less than remainder, mask the mask
|
||||
|
||||
|
||||
|
||||
|
||||
if ((x & 7) > 0) { // Partial fill on first byte?
|
||||
// create bit mask for first byte
|
||||
uint8_t startByteBitMask = 0x00;
|
||||
for (int8_t i = (x & 7); ((i < 8) && (w > 0)); i++) {
|
||||
@@ -360,4 +405,5 @@ void GFXcanvas1::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+9
-12
@@ -18,30 +18,27 @@
|
||||
|
||||
#include "Adafruit_GFX.h"
|
||||
|
||||
/// A GFX 1-bit canvas context for graphics
|
||||
// A 1-bit canvas for offscreen graphics in RAM.
|
||||
class GFXcanvas1 : public Adafruit_GFX {
|
||||
public:
|
||||
GFXcanvas1(uint16_t w, uint16_t h);
|
||||
~GFXcanvas1(void);
|
||||
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
void fillScreen(uint16_t color);
|
||||
bool getPixel(int16_t x, int16_t y) const;
|
||||
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
bool getPixel(int16_t x, int16_t y) const;
|
||||
void fillScreen(uint16_t color);
|
||||
/*!
|
||||
@brief Get pointer to internal canvas memory.
|
||||
@return Pointer (uint8_t *) to start of canvas buffer.
|
||||
*/
|
||||
uint8_t *getBuffer(void) const { return buffer; }
|
||||
|
||||
uint8_t *getBuffer(void) const { return pixbuf; };
|
||||
protected:
|
||||
bool getRawPixel(int16_t x, int16_t y) const;
|
||||
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
|
||||
private:
|
||||
uint8_t *buffer;
|
||||
|
||||
uint8_t *pixbuf = NULL;
|
||||
void drawPixelRaw(int16_t x, int16_t y, uint16_t color);
|
||||
bool getPixelRaw(int16_t x, int16_t y) const;
|
||||
void drawFastVLineRaw(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastHLineRaw(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
#ifdef __AVR__
|
||||
// Bitmask tables of 0x80>>X and ~(0x80>>X), because X>>Y is slow on AVR
|
||||
static const uint8_t PROGMEM GFXsetBit[], GFXclrBit[];
|
||||
|
||||
+35
-33
@@ -24,21 +24,19 @@
|
||||
*/
|
||||
/**************************************************************************/
|
||||
GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
|
||||
uint32_t bytes = w * h * 2;
|
||||
if ((buffer = (uint16_t *)malloc(bytes))) {
|
||||
memset(buffer, 0, bytes);
|
||||
}
|
||||
// If allocation fails, no special action is performed here.
|
||||
// Drawing functions check for valid buffer.
|
||||
pixbuf = (uint16_t *)calloc(w * h * 2, 0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Delete the canvas, free memory
|
||||
@brief GFXcanvas16 destructor. Frees memory associated with canvas.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
GFXcanvas16::~GFXcanvas16(void) {
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
}
|
||||
if (pixbuf) {
|
||||
free(pixbuf);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@@ -49,7 +47,7 @@ GFXcanvas16::~GFXcanvas16(void) {
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
if (buffer) {
|
||||
if (pixbuf) {
|
||||
if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
|
||||
return;
|
||||
|
||||
@@ -71,10 +69,14 @@ void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
break;
|
||||
}
|
||||
|
||||
buffer[x + y * WIDTH] = color;
|
||||
pixbuf[x + y * WIDTH] = color;
|
||||
}
|
||||
}
|
||||
|
||||
void GFXcanvas16::drawPixelRaw(int16_t x, int16_t y, uint16_t color) {
|
||||
pixbuf[x + y * WIDTH] = color;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/*!
|
||||
@brief Get the pixel color value at a given coordinate
|
||||
@@ -101,7 +103,7 @@ uint16_t GFXcanvas16::getPixel(int16_t x, int16_t y) const {
|
||||
y = HEIGHT - 1 - t;
|
||||
break;
|
||||
}
|
||||
return getRawPixel(x, y);
|
||||
return getPixelRaw(x, y);
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
@@ -114,11 +116,11 @@ uint16_t GFXcanvas16::getPixel(int16_t x, int16_t y) const {
|
||||
@returns The desired pixel's 16-bit 5-6-5 color value
|
||||
*/
|
||||
/**********************************************************************/
|
||||
uint16_t GFXcanvas16::getRawPixel(int16_t x, int16_t y) const {
|
||||
uint16_t GFXcanvas16::getPixelRaw(int16_t x, int16_t y) const {
|
||||
if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT))
|
||||
return 0;
|
||||
if (buffer) {
|
||||
return buffer[x + y * WIDTH];
|
||||
if (pixbuf) {
|
||||
return pixbuf[x + y * WIDTH];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -130,14 +132,14 @@ uint16_t GFXcanvas16::getRawPixel(int16_t x, int16_t y) const {
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas16::fillScreen(uint16_t color) {
|
||||
if (buffer) {
|
||||
if (pixbuf) {
|
||||
uint8_t hi = color >> 8, lo = color & 0xFF;
|
||||
if (hi == lo) {
|
||||
memset(buffer, lo, WIDTH * HEIGHT * 2);
|
||||
memset(pixbuf, lo, WIDTH * HEIGHT * 2);
|
||||
} else {
|
||||
uint32_t i, pixels = WIDTH * HEIGHT;
|
||||
for (i = 0; i < pixels; i++)
|
||||
buffer[i] = color;
|
||||
pixbuf[i] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,10 +158,10 @@ void GFXcanvas16::fillScreen(uint16_t color) {
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas16::byteSwap(void) {
|
||||
if (buffer) {
|
||||
if (pixbuf) {
|
||||
uint32_t i, pixels = WIDTH * HEIGHT;
|
||||
for (i = 0; i < pixels; i++)
|
||||
buffer[i] = __builtin_bswap16(buffer[i]);
|
||||
pixbuf[i] = __builtin_bswap16(pixbuf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,24 +199,24 @@ void GFXcanvas16::drawFastVLine(int16_t x, int16_t y, int16_t h,
|
||||
}
|
||||
|
||||
if (getRotation() == 0) {
|
||||
drawFastRawVLine(x, y, h, color);
|
||||
drawFastVLineRaw(x, y, h, color);
|
||||
} else if (getRotation() == 1) {
|
||||
int16_t t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
x -= h - 1;
|
||||
drawFastRawHLine(x, y, h, color);
|
||||
drawFastHLineRaw(x, y, h, color);
|
||||
} else if (getRotation() == 2) {
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
|
||||
y -= h - 1;
|
||||
drawFastRawVLine(x, y, h, color);
|
||||
drawFastVLineRaw(x, y, h, color);
|
||||
} else if (getRotation() == 3) {
|
||||
int16_t t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
drawFastRawHLine(x, y, h, color);
|
||||
drawFastHLineRaw(x, y, h, color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,24 +254,24 @@ void GFXcanvas16::drawFastHLine(int16_t x, int16_t y, int16_t w,
|
||||
}
|
||||
|
||||
if (getRotation() == 0) {
|
||||
drawFastRawHLine(x, y, w, color);
|
||||
drawFastHLineRaw(x, y, w, color);
|
||||
} else if (getRotation() == 1) {
|
||||
int16_t t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
drawFastRawVLine(x, y, w, color);
|
||||
drawFastVLineRaw(x, y, w, color);
|
||||
} else if (getRotation() == 2) {
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
|
||||
x -= w - 1;
|
||||
drawFastRawHLine(x, y, w, color);
|
||||
drawFastHLineRaw(x, y, w, color);
|
||||
} else if (getRotation() == 3) {
|
||||
int16_t t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
y -= w - 1;
|
||||
drawFastRawVLine(x, y, w, color);
|
||||
drawFastVLineRaw(x, y, w, color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,10 +284,10 @@ void GFXcanvas16::drawFastHLine(int16_t x, int16_t y, int16_t w,
|
||||
@param color color 16-bit 5-6-5 Color to draw line with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas16::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
|
||||
void GFXcanvas16::drawFastVLineRaw(int16_t x, int16_t y, int16_t h,
|
||||
uint16_t color) {
|
||||
// x & y already in raw (rotation 0) coordinates, no need to transform.
|
||||
uint16_t *buffer_ptr = buffer + y * WIDTH + x;
|
||||
uint16_t *buffer_ptr = &pixbuf[y * WIDTH + x];
|
||||
for (int16_t i = 0; i < h; i++) {
|
||||
(*buffer_ptr) = color;
|
||||
buffer_ptr += WIDTH;
|
||||
@@ -301,11 +303,11 @@ void GFXcanvas16::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
|
||||
@param color color 16-bit 5-6-5 Color to draw line with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas16::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
|
||||
void GFXcanvas16::drawFastHLineRaw(int16_t x, int16_t y, int16_t w,
|
||||
uint16_t color) {
|
||||
// x & y already in raw (rotation 0) coordinates, no need to transform.
|
||||
uint32_t buffer_index = y * WIDTH + x;
|
||||
for (uint32_t i = buffer_index; i < buffer_index + w; i++) {
|
||||
buffer[i] = color;
|
||||
pixbuf[i] = color;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-16
@@ -18,30 +18,26 @@
|
||||
|
||||
#include "Adafruit_GFX.h"
|
||||
|
||||
/// A GFX 16-bit canvas context for graphics
|
||||
// A 16-bit canvas for offscreen graphics in RAM.
|
||||
class GFXcanvas16 : public Adafruit_GFX {
|
||||
public:
|
||||
GFXcanvas16(uint16_t w, uint16_t h);
|
||||
~GFXcanvas16(void);
|
||||
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
void fillScreen(uint16_t color);
|
||||
void byteSwap(void);
|
||||
uint16_t getPixel(int16_t x, int16_t y) const;
|
||||
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
uint16_t getPixel(int16_t x, int16_t y) const;
|
||||
/**********************************************************************/
|
||||
void fillScreen(uint16_t color);
|
||||
/*!
|
||||
@brief Get a pointer to the internal buffer memory
|
||||
@returns A pointer to the allocated buffer
|
||||
@brief Get pointer to internal canvas memory.
|
||||
@return Pointer (uint16_t *) to start of canvas buffer.
|
||||
*/
|
||||
/**********************************************************************/
|
||||
uint16_t *getBuffer(void) const { return buffer; }
|
||||
|
||||
uint16_t *getBuffer(void) const { return pixbuf; };
|
||||
void byteSwap(void);
|
||||
protected:
|
||||
uint16_t getRawPixel(int16_t x, int16_t y) const;
|
||||
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
|
||||
private:
|
||||
uint16_t *buffer;
|
||||
uint16_t *pixbuf = NULL;
|
||||
void drawPixelRaw(int16_t x, int16_t y, uint16_t color);
|
||||
uint16_t getPixelRaw(int16_t x, int16_t y) const;
|
||||
void drawFastVLineRaw(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastHLineRaw(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
};
|
||||
|
||||
+47
-36
@@ -24,21 +24,19 @@
|
||||
*/
|
||||
/**************************************************************************/
|
||||
GFXcanvas4::GFXcanvas4(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
|
||||
uint16_t bytes = ((w + 1) / 2) * h; // Scanlines are byte-aligned
|
||||
if ((buffer = (uint8_t *)malloc(bytes))) {
|
||||
memset(buffer, 0, bytes);
|
||||
}
|
||||
// Rows are byte-aligned. If allocation fails, no special action is
|
||||
// performed here. Drawing functions check for valid buffer.
|
||||
pixbuf = (uint8_t *)calloc(((w + 1) / 2) * h, 1);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Delete the canvas, free memory
|
||||
@brief GFXcanvas4 destructor. Frees memory associated with canvas.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
GFXcanvas4::~GFXcanvas4(void) {
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
}
|
||||
if (pixbuf) {
|
||||
free(pixbuf);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@@ -49,7 +47,7 @@ GFXcanvas4::~GFXcanvas4(void) {
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas4::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
if (buffer) {
|
||||
if (pixbuf) {
|
||||
if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
|
||||
return;
|
||||
|
||||
@@ -71,16 +69,29 @@ void GFXcanvas4::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t *ptr = &buffer[(x / 2) + y * ((WIDTH + 1) / 2)];
|
||||
if (x & 1) { // Odd column - lower nybble
|
||||
*ptr = (*ptr & 0xF0) | (color & 0xF);
|
||||
} else { // Even column - upper nybble
|
||||
*ptr = (*ptr & 0x0F) | (color << 4);
|
||||
}
|
||||
drawPixelRaw(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
bool GFXcanvas4::getPixel(int16_t x, int16_t y) const {
|
||||
/*!
|
||||
@brief Draw a pixel to the canvas framebuffer. NO CLIPPING, ROTATION OR
|
||||
VALIDATION OF CANVAS BUFFER IS PERFORMED, calling function must be
|
||||
AWARE and WELL-BEHAVED. This is a protected function intended for
|
||||
related class code, not user-facing.
|
||||
@param x Pixel column (horizonal pos).
|
||||
@param y Pixel row (vertical pos).
|
||||
@param color Pixel draw color; thresholded to 0 or 1 (any nonzero input).
|
||||
*/
|
||||
void GFXcanvas4::drawPixelRaw(int16_t x, int16_t y, uint16_t color) {
|
||||
uint8_t *ptr = &pixbuf[(x / 2) + y * ((WIDTH + 1) / 2)];
|
||||
if (x & 1) { // Odd column - lower nybble
|
||||
*ptr = (*ptr & 0xF0) | (color & 0xF);
|
||||
} else { // Even column - upper nybble
|
||||
*ptr = (*ptr & 0x0F) | (color << 4);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GFXcanvas4::getPixel(int16_t x, int16_t y) const {
|
||||
int16_t t;
|
||||
switch (rotation) {
|
||||
case 1:
|
||||
@@ -98,14 +109,14 @@ bool GFXcanvas4::getPixel(int16_t x, int16_t y) const {
|
||||
y = HEIGHT - 1 - t;
|
||||
break;
|
||||
}
|
||||
return getRawPixel(x, y);
|
||||
return getPixelRaw(x, y);
|
||||
}
|
||||
|
||||
bool GFXcanvas4::getRawPixel(int16_t x, int16_t y) const {
|
||||
uint8_t GFXcanvas4::getPixelRaw(int16_t x, int16_t y) const {
|
||||
if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT))
|
||||
return 0;
|
||||
if (buffer) {
|
||||
uint8_t *ptr = &buffer[(x / 2) + y * ((WIDTH + 1) / 2)];
|
||||
if (pixbuf) {
|
||||
uint8_t *ptr = &pixbuf[(x / 2) + y * ((WIDTH + 1) / 2)];
|
||||
if (x & 1) { // Odd column - lower nybble
|
||||
return *ptr & 0xF;
|
||||
} else { // Even column - upper nybble
|
||||
@@ -122,8 +133,8 @@ bool GFXcanvas4::getRawPixel(int16_t x, int16_t y) const {
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas4::fillScreen(uint16_t color) {
|
||||
if (buffer) {
|
||||
memset(buffer, (color & 0xF) * 0x11, ((WIDTH + 1) / 2) * HEIGHT);
|
||||
if (pixbuf) {
|
||||
memset(pixbuf, (color & 0xF) * 0x11, ((WIDTH + 1) / 2) * HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,24 +173,24 @@ void GFXcanvas4::drawFastVLine(int16_t x, int16_t y, int16_t h,
|
||||
}
|
||||
|
||||
if (getRotation() == 0) {
|
||||
drawFastRawVLine(x, y, h, color);
|
||||
drawFastVLineRaw(x, y, h, color);
|
||||
} else if (getRotation() == 1) {
|
||||
int16_t t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
x -= h - 1;
|
||||
drawFastRawHLine(x, y, h, color);
|
||||
drawFastHLineRaw(x, y, h, color);
|
||||
} else if (getRotation() == 2) {
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
|
||||
y -= h - 1;
|
||||
drawFastRawVLine(x, y, h, color);
|
||||
drawFastVLineRaw(x, y, h, color);
|
||||
} else if (getRotation() == 3) {
|
||||
int16_t t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
drawFastRawHLine(x, y, h, color);
|
||||
drawFastHLineRaw(x, y, h, color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,24 +228,24 @@ void GFXcanvas4::drawFastHLine(int16_t x, int16_t y, int16_t w,
|
||||
}
|
||||
|
||||
if (getRotation() == 0) {
|
||||
drawFastRawHLine(x, y, w, color);
|
||||
drawFastHLineRaw(x, y, w, color);
|
||||
} else if (getRotation() == 1) {
|
||||
int16_t t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
drawFastRawVLine(x, y, w, color);
|
||||
drawFastVLineRaw(x, y, w, color);
|
||||
} else if (getRotation() == 2) {
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
|
||||
x -= w - 1;
|
||||
drawFastRawHLine(x, y, w, color);
|
||||
drawFastHLineRaw(x, y, w, color);
|
||||
} else if (getRotation() == 3) {
|
||||
int16_t t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
y -= w - 1;
|
||||
drawFastRawVLine(x, y, w, color);
|
||||
drawFastVLineRaw(x, y, w, color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,11 +258,11 @@ void GFXcanvas4::drawFastHLine(int16_t x, int16_t y, int16_t w,
|
||||
@param color Color to fill with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas4::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
|
||||
void GFXcanvas4::drawFastVLineRaw(int16_t x, int16_t y, int16_t h,
|
||||
uint16_t color) {
|
||||
// x & y already in raw (rotation 0) coordinates, no need to transform.
|
||||
int16_t row_bytes = ((WIDTH + 1) / 2);
|
||||
uint8_t *ptr = &buffer[(x / 2) + y * row_bytes];
|
||||
uint8_t *ptr = &pixbuf[(x / 2) + y * row_bytes];
|
||||
uint8_t mask;
|
||||
|
||||
if (x & 1) { // Odd column - lower nybble
|
||||
@@ -276,11 +287,11 @@ void GFXcanvas4::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
|
||||
@param color Binary (on or off) color to fill with
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas4::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
|
||||
void GFXcanvas4::drawFastHLineRaw(int16_t x, int16_t y, int16_t w,
|
||||
uint16_t color) {
|
||||
// x & y already in raw (rotation 0) coordinates, no need to transform.
|
||||
int16_t rowBytes = ((WIDTH + 1) / 2);
|
||||
uint8_t *ptr = &buffer[(x / 2) + y * rowBytes];
|
||||
uint8_t *ptr = &pixbuf[(x / 2) + y * rowBytes];
|
||||
color &= 0xF;
|
||||
|
||||
// check to see if first byte needs to be partially filled
|
||||
|
||||
+11
-27
@@ -18,41 +18,25 @@
|
||||
|
||||
#include "Adafruit_GFX.h"
|
||||
|
||||
/// A GFX 4-bit canvas context for graphics
|
||||
// A 4-bit canvas for offscreen graphics in RAM.
|
||||
class GFXcanvas4 : public Adafruit_GFX {
|
||||
public:
|
||||
GFXcanvas4(uint16_t w, uint16_t h);
|
||||
~GFXcanvas4(void);
|
||||
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
void fillScreen(uint16_t color);
|
||||
uint8_t getPixel(int16_t x, int16_t y) const;
|
||||
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
void fillScreen(uint16_t color);
|
||||
/*!
|
||||
@brief Get the pixel color value at a given coordinate
|
||||
@param x x coordinate
|
||||
@param y y coordinate
|
||||
@returns The pixel's color value, 0 to 15
|
||||
@brief Get pointer to internal canvas memory.
|
||||
@return Pointer (uint8_t *) to start of canvas buffer.
|
||||
*/
|
||||
bool getPixel(int16_t x, int16_t y) const;
|
||||
/*!
|
||||
@brief Get a pointer to the internal buffer memory
|
||||
@returns A pointer to the allocated buffer
|
||||
*/
|
||||
uint8_t *getBuffer(void) const { return buffer; }
|
||||
|
||||
uint8_t *getBuffer(void) const { return pixbuf; };
|
||||
protected:
|
||||
/*!
|
||||
@brief Get the pixel color value at a given, unrotated coordinate.
|
||||
This method is intended for hardware drivers to get pixel value
|
||||
in native physical coordinates.
|
||||
@param x x coordinate
|
||||
@param y y coordinate
|
||||
@returns The pixel's color value, 0 to 15
|
||||
*/
|
||||
bool getRawPixel(int16_t x, int16_t y) const;
|
||||
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
|
||||
private:
|
||||
uint8_t *buffer;
|
||||
uint8_t *pixbuf = NULL;
|
||||
void drawPixelRaw(int16_t x, int16_t y, uint16_t color);
|
||||
uint8_t getPixelRaw(int16_t x, int16_t y) const;
|
||||
void drawFastVLineRaw(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastHLineRaw(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
};
|
||||
|
||||
+32
-30
@@ -24,21 +24,19 @@
|
||||
*/
|
||||
/**************************************************************************/
|
||||
GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
|
||||
uint32_t bytes = w * h;
|
||||
if ((buffer = (uint8_t *)malloc(bytes))) {
|
||||
memset(buffer, 0, bytes);
|
||||
}
|
||||
// If allocation fails, no special action is performed here.
|
||||
// Drawing functions check for valid buffer.
|
||||
pixbuf = (uint8_t *)calloc(w * h, 1);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Delete the canvas, free memory
|
||||
@brief GFXcanvas8 destructor. Frees memory associated with canvas.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
GFXcanvas8::~GFXcanvas8(void) {
|
||||
if (buffer)
|
||||
free(buffer);
|
||||
}
|
||||
if (pixbuf) {
|
||||
free(pixbuf);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@@ -49,7 +47,7 @@ GFXcanvas8::~GFXcanvas8(void) {
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
if (buffer) {
|
||||
if (pixbuf) {
|
||||
if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
|
||||
return;
|
||||
|
||||
@@ -71,10 +69,14 @@ void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
break;
|
||||
}
|
||||
|
||||
buffer[x + y * WIDTH] = color;
|
||||
pixbuf[x + y * WIDTH] = color;
|
||||
}
|
||||
}
|
||||
|
||||
void GFXcanvas8::drawPixelRaw(int16_t x, int16_t y, uint16_t color) {
|
||||
pixbuf[x + y * WIDTH] = color;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/*!
|
||||
@brief Get the pixel color value at a given coordinate
|
||||
@@ -101,7 +103,7 @@ uint8_t GFXcanvas8::getPixel(int16_t x, int16_t y) const {
|
||||
y = HEIGHT - 1 - t;
|
||||
break;
|
||||
}
|
||||
return getRawPixel(x, y);
|
||||
return getPixelRaw(x, y);
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
@@ -114,11 +116,11 @@ uint8_t GFXcanvas8::getPixel(int16_t x, int16_t y) const {
|
||||
@returns The desired pixel's 8-bit color value
|
||||
*/
|
||||
/**********************************************************************/
|
||||
uint8_t GFXcanvas8::getRawPixel(int16_t x, int16_t y) const {
|
||||
uint8_t GFXcanvas8::getPixelRaw(int16_t x, int16_t y) const {
|
||||
if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT))
|
||||
return 0;
|
||||
if (buffer) {
|
||||
return buffer[x + y * WIDTH];
|
||||
if (pixbuf) {
|
||||
return pixbuf[x + y * WIDTH];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -130,8 +132,8 @@ uint8_t GFXcanvas8::getRawPixel(int16_t x, int16_t y) const {
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas8::fillScreen(uint16_t color) {
|
||||
if (buffer) {
|
||||
memset(buffer, color, WIDTH * HEIGHT);
|
||||
if (pixbuf) {
|
||||
memset(pixbuf, color, WIDTH * HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,24 +172,24 @@ void GFXcanvas8::drawFastVLine(int16_t x, int16_t y, int16_t h,
|
||||
}
|
||||
|
||||
if (getRotation() == 0) {
|
||||
drawFastRawVLine(x, y, h, color);
|
||||
drawFastVLineRaw(x, y, h, color);
|
||||
} else if (getRotation() == 1) {
|
||||
int16_t t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
x -= h - 1;
|
||||
drawFastRawHLine(x, y, h, color);
|
||||
drawFastHLineRaw(x, y, h, color);
|
||||
} else if (getRotation() == 2) {
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
|
||||
y -= h - 1;
|
||||
drawFastRawVLine(x, y, h, color);
|
||||
drawFastVLineRaw(x, y, h, color);
|
||||
} else if (getRotation() == 3) {
|
||||
int16_t t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
drawFastRawHLine(x, y, h, color);
|
||||
drawFastHLineRaw(x, y, h, color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,24 +229,24 @@ void GFXcanvas8::drawFastHLine(int16_t x, int16_t y, int16_t w,
|
||||
}
|
||||
|
||||
if (getRotation() == 0) {
|
||||
drawFastRawHLine(x, y, w, color);
|
||||
drawFastHLineRaw(x, y, w, color);
|
||||
} else if (getRotation() == 1) {
|
||||
int16_t t = x;
|
||||
x = WIDTH - 1 - y;
|
||||
y = t;
|
||||
drawFastRawVLine(x, y, w, color);
|
||||
drawFastVLineRaw(x, y, w, color);
|
||||
} else if (getRotation() == 2) {
|
||||
x = WIDTH - 1 - x;
|
||||
y = HEIGHT - 1 - y;
|
||||
|
||||
x -= w - 1;
|
||||
drawFastRawHLine(x, y, w, color);
|
||||
drawFastHLineRaw(x, y, w, color);
|
||||
} else if (getRotation() == 3) {
|
||||
int16_t t = x;
|
||||
x = y;
|
||||
y = HEIGHT - 1 - t;
|
||||
y -= w - 1;
|
||||
drawFastRawVLine(x, y, w, color);
|
||||
drawFastVLineRaw(x, y, w, color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,10 +260,10 @@ void GFXcanvas8::drawFastHLine(int16_t x, int16_t y, int16_t w,
|
||||
used.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas8::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
|
||||
void GFXcanvas8::drawFastVLineRaw(int16_t x, int16_t y, int16_t h,
|
||||
uint16_t color) {
|
||||
// x & y already in raw (rotation 0) coordinates, no need to transform.
|
||||
uint8_t *buffer_ptr = buffer + y * WIDTH + x;
|
||||
uint8_t *buffer_ptr = &pixbuf[y * WIDTH + x];
|
||||
for (int16_t i = 0; i < h; i++) {
|
||||
(*buffer_ptr) = color;
|
||||
buffer_ptr += WIDTH;
|
||||
@@ -278,8 +280,8 @@ void GFXcanvas8::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
|
||||
used.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void GFXcanvas8::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
|
||||
void GFXcanvas8::drawFastHLineRaw(int16_t x, int16_t y, int16_t w,
|
||||
uint16_t color) {
|
||||
// x & y already in raw (rotation 0) coordinates, no need to transform.
|
||||
memset(buffer + y * WIDTH + x, color, w);
|
||||
memset(pixbuf + y * WIDTH + x, color, w);
|
||||
}
|
||||
|
||||
+11
-15
@@ -18,29 +18,25 @@
|
||||
|
||||
#include "Adafruit_GFX.h"
|
||||
|
||||
/// A GFX 8-bit canvas context for graphics
|
||||
// An 8-bit canvas for offscreen graphics in RAM.
|
||||
class GFXcanvas8 : public Adafruit_GFX {
|
||||
public:
|
||||
GFXcanvas8(uint16_t w, uint16_t h);
|
||||
~GFXcanvas8(void);
|
||||
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
void fillScreen(uint16_t color);
|
||||
uint8_t getPixel(int16_t x, int16_t y) const;
|
||||
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
uint8_t getPixel(int16_t x, int16_t y) const;
|
||||
/**********************************************************************/
|
||||
void fillScreen(uint16_t color);
|
||||
/*!
|
||||
@brief Get a pointer to the internal buffer memory
|
||||
@returns A pointer to the allocated buffer
|
||||
@brief Get pointer to internal canvas memory.
|
||||
@return Pointer (uint8_t *) to start of canvas buffer.
|
||||
*/
|
||||
/**********************************************************************/
|
||||
uint8_t *getBuffer(void) const { return buffer; }
|
||||
|
||||
uint8_t *getBuffer(void) const { return pixbuf; };
|
||||
protected:
|
||||
uint8_t getRawPixel(int16_t x, int16_t y) const;
|
||||
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
|
||||
private:
|
||||
uint8_t *buffer;
|
||||
uint8_t *pixbuf = NULL;
|
||||
void drawPixelRaw(int16_t x, int16_t y, uint16_t color);
|
||||
uint8_t getPixelRaw(int16_t x, int16_t y) const;
|
||||
void drawFastVLineRaw(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||
void drawFastHLineRaw(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user