Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add arbitrary rect drawing from bitmaps/canvases (RGB 565, RAM only) #442

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 32 additions & 7 deletions Adafruit_GFX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,37 @@ void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[],
endWrite();
}

/**************************************************************************/
/*!
@brief Draw a RAM-resident 16-bit image (RGB 5/6/5) or sub-section thereof
at the specified (x,y) position, from the specified (src_x,src_y) position.
For 16-bit display devices; no color reduction performed.
@param x Top left corner x coordinate to draw at
@param y Top left corner y coordinate to draw at
@param bitmap byte array with 16-bit color bitmap
@param w Width of the area in the bitmap to draw, in pixels
@param h Height of the area in the bitmap to draw, in pixels
@param src_x Top left corner x coordinate in the bitmap to read from
@param src_y Top left corner y coordinate in the bitmap to read from
@param src_w Width of the bitmap in pixels. Set to zero if w already
contains the bitmap's width.
*/
/**************************************************************************/
void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap,
int16_t w, int16_t h, int16_t src_x,
int16_t src_y, int16_t src_w) {
if (src_w == 0)
src_w = w;

startWrite();
for (int16_t j = 0; j < h; j++, y++) {
for (int16_t i = 0; i < w; i++) {
writePixel(x + i, y, bitmap[((j + src_y) * src_w) + src_x + i]);
}
}
endWrite();
}

/**************************************************************************/
/*!
@brief Draw a RAM-resident 16-bit image (RGB 5/6/5) at the specified (x,y)
Expand All @@ -1022,13 +1053,7 @@ void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[],
/**************************************************************************/
void Adafruit_GFX::drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap,
int16_t w, int16_t h) {
startWrite();
for (int16_t j = 0; j < h; j++, y++) {
for (int16_t i = 0; i < w; i++) {
writePixel(x + i, y, bitmap[j * w + i]);
}
}
endWrite();
drawRGBBitmap(x, y, bitmap, w, h, 0, 0, 0);
}

/**************************************************************************/
Expand Down
2 changes: 2 additions & 0 deletions Adafruit_GFX.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class Adafruit_GFX : public Print {
int16_t w, int16_t h);
void drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], int16_t w,
int16_t h);
void drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w,
int16_t h, int16_t src_x, int16_t src_y, int16_t src_w);
void drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w,
int16_t h);
void drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[],
Expand Down
64 changes: 42 additions & 22 deletions Adafruit_SPITFT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1811,58 +1811,78 @@ void Adafruit_SPITFT::pushColor(uint16_t color) {
}

/*!
@brief Draw a 16-bit image (565 RGB) at the specified (x,y) position.
For 16-bit display devices; no color reduction performed.
@brief Draw a 16-bit image (565 RGB) at the specified (x,y) position from
the specified (src_x,src_y). For 16-bit display devices; no color
reduction performed.
Adapted from https://github.com/PaulStoffregen/ILI9341_t3
by Marc MERLIN. See examples/pictureEmbed to use this.
5/6/2017: function name and arguments have changed for
compatibility with current GFX library and to avoid naming
problems in prior implementation. Formerly drawBitmap() with
arguments in different order. Handles its own transaction and
edge clipping/rejection.
@param x Top left corner horizontal coordinate.
@param y Top left corner vertical coordinate.
@param x Top left corner horizontal coordinate to draw at.
@param y Top left corner vertical coordinate to draw at.
@param pcolors Pointer to 16-bit array of pixel values.
@param w Width of bitmap in pixels.
@param h Height of bitmap in pixels.
@param w Width of the area of the bitmap to draw, in pixels.
@param h Height of the area of the bitmap to draw, in pixels.
@param src_x Top left corner horizontal coordinate to read from.
@param src_y Top left corner vertical coordinate to read from.
@param src_w Width of the source bitmap in pixels.
*/
void Adafruit_SPITFT::drawRGBBitmap(int16_t x, int16_t y, uint16_t *pcolors,
int16_t w, int16_t h) {

int16_t x2, y2; // Lower-right coord
if ((x >= _width) || // Off-edge right
(y >= _height) || // " top
((x2 = (x + w - 1)) < 0) || // " left
((y2 = (y + h - 1)) < 0))
return; // " bottom

int16_t bx1 = 0, by1 = 0, // Clipped top-left within bitmap
saveW = w; // Save original bitmap width value
if (x < 0) { // Clip left
int16_t w, int16_t h, int16_t src_x,
int16_t src_y, int16_t src_w) {
int16_t x2, y2; // Lower-right coord
if ((x >= _width) || // Off-edge right
(src_x >= src_w) || (y >= _height) || // " bottom
((x2 = (x + w - 1)) < 0) || // " left
(src_x + src_w - 1 < 0) || ((y2 = (y + h - 1)) < 0)) // " top
return; // " bottom

if (x < 0) { // Clip left
w += x;
bx1 = -x;
x = 0;
}
if (y < 0) { // Clip top
h += y;
by1 = -y;
y = 0;
}
if (src_x < 0) {
src_w += src_x;
src_x = -src_x;
}
if (src_y < 0)
src_y = -src_y;
if (x2 >= _width)
w = _width - x; // Clip right
if (y2 >= _height)
h = _height - y; // Clip bottom

pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left
pcolors += (src_y * src_w) + src_x; // Offset bitmap ptr to clipped top-left
startWrite();
setAddrWindow(x, y, w, h); // Clipped area
while (h--) { // For each (clipped) scanline...
writePixels(pcolors, w); // Push one (clipped) row
pcolors += saveW; // Advance pointer by one full (unclipped) line
pcolors += src_w; // Advance pointer by one full (unclipped) line
}
endWrite();
}

/*!
@brief Draw a 16-bit image (565 RGB) at the specified (x,y) position.
For 16-bit display devices; no color reduction performed.
@param x Top left corner horizontal coordinate.
@param y Top left corner vertical coordinate.
@param pcolors Pointer to 16-bit array of pixel values.
@param w Width of bitmap in pixels.
@param h Height of bitmap in pixels.
*/
void Adafruit_SPITFT::drawRGBBitmap(int16_t x, int16_t y, uint16_t *pcolors,
int16_t w, int16_t h) {
drawRGBBitmap(x, y, pcolors, w, h, 0, 0, w);
}

// -------------------------------------------------------------------------
// Miscellaneous class member functions that don't draw anything.

Expand Down
2 changes: 2 additions & 0 deletions Adafruit_SPITFT.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ class Adafruit_SPITFT : public Adafruit_GFX {
void pushColor(uint16_t color);

using Adafruit_GFX::drawRGBBitmap; // Check base class first
void drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w,
int16_t h, int16_t src_x, int16_t src_y, int16_t src_w);
void drawRGBBitmap(int16_t x, int16_t y, uint16_t *pcolors, int16_t w,
int16_t h);

Expand Down