Add the possibility to draw a bitmap through a mask

This commit is contained in:
Bertrand Songis
2020-04-21 23:05:25 +02:00
parent 588c326cfc
commit 8511939801
4 changed files with 86 additions and 9 deletions
+62 -3
View File
@@ -377,7 +377,7 @@ void BitmapBuffer::drawAnnulusSector(coord_t x, coord_t y, coord_t internalRadiu
}
}
void BitmapBuffer::drawMask(coord_t x, coord_t y, const BitmapBuffer * mask, LcdFlags flags, coord_t offset, coord_t width)
void BitmapBuffer::drawMask(coord_t x, coord_t y, const BitmapBuffer * mask, LcdFlags flags, coord_t offsetX, coord_t width)
{
if (!mask)
return;
@@ -397,7 +397,7 @@ void BitmapBuffer::drawMask(coord_t x, coord_t y, const BitmapBuffer * mask, Lcd
if (x < xmin) {
width += x - xmin;
offset -= x - xmin;
offsetX -= x - xmin;
x = xmin;
}
@@ -410,7 +410,7 @@ void BitmapBuffer::drawMask(coord_t x, coord_t y, const BitmapBuffer * mask, Lcd
if (y + row < ymin || y + row >= ymax)
continue;
pixel_t * p = getPixelPtr(x, y + row);
const pixel_t * q = mask->getPixelPtr(offset, row);
const pixel_t * q = mask->getPixelPtr(offsetX, row);
for (coord_t col = 0; col < width; col++) {
drawAlphaPixel(p, *((uint8_t *)q), color);
MOVE_TO_NEXT_RIGHT_PIXEL(p);
@@ -419,6 +419,50 @@ void BitmapBuffer::drawMask(coord_t x, coord_t y, const BitmapBuffer * mask, Lcd
}
}
void BitmapBuffer::drawMask(coord_t x, coord_t y, const BitmapBuffer * mask, const BitmapBuffer * srcBitmap, coord_t offsetX, coord_t offsetY, coord_t width, coord_t height)
{
if (!mask || !srcBitmap)
return;
APPLY_OFFSET();
coord_t maskWidth = mask->width();
coord_t maskHeight = mask->height();
if (!width || width > maskWidth) {
width = maskWidth;
}
if (!height || height > maskHeight) {
height = maskHeight;
}
if (x + width > xmax) {
width = xmax - x;
}
if (x < xmin) {
width += x - xmin;
offsetX -= x - xmin;
x = xmin;
}
if (y >= ymax || x >= xmax || width <= 0 || x + width < xmin || y + height < ymin)
return;
for (coord_t row = 0; row < height; row++) {
if (y + row < ymin || y + row >= ymax)
continue;
pixel_t * p = getPixelPtr(x, y + row);
const pixel_t * q = mask->getPixelPtr(offsetX, offsetY + row);
for (coord_t col = 0; col < width; col++) {
drawAlphaPixel(p, *((uint8_t *)q), *srcBitmap->getPixelPtr(row, col));
MOVE_TO_NEXT_RIGHT_PIXEL(p);
MOVE_TO_NEXT_RIGHT_PIXEL(q);
}
}
}
void BitmapBuffer::drawBitmapPattern(coord_t x, coord_t y, const uint8_t * bmp, LcdFlags flags, coord_t offset, coord_t width)
{
APPLY_OFFSET();
@@ -676,6 +720,21 @@ BitmapBuffer * BitmapBuffer::loadMask(const char * filename)
return bitmap;
}
BitmapBuffer * BitmapBuffer::invertMask() const
{
BitmapBuffer * result = new BitmapBuffer(format, width(), height());
pixel_t * srcData = data;
pixel_t * destData = result->data;
for (auto y = 0; y < height(); y++) {
for (auto x = 0; x < width(); x++) {
destData[x] = OPACITY_MAX - (uint8_t)srcData[x];
}
srcData += width();
destData += width();
}
return result;
}
BitmapBuffer * BitmapBuffer::horizontalFlip() const
{
BitmapBuffer * result = new BitmapBuffer(format, width(), height());
+6 -2
View File
@@ -33,7 +33,7 @@ constexpr uint8_t DOTTED = 0x55;
constexpr uint8_t STASHED = 0x33;
#define MOVE_OFFSET() coord_t offsetX = this->offsetX; x += offsetX; this->offsetX = 0; coord_t offsetY = this->offsetY; y += offsetY; this->offsetY = 0
#define APPLY_OFFSET() x += offsetX; y += offsetY
#define APPLY_OFFSET() x += this->offsetX; y += this->offsetY
#define RESTORE_OFFSET() this->offsetX = offsetX, this->offsetY = offsetY
#if defined(LCD_VERTICAL_INVERT)
@@ -369,7 +369,9 @@ class BitmapBuffer: public BitmapBufferBase<pixel_t>
static BitmapBuffer * loadMaskOnBackground(const char * filename, LcdFlags foreground, LcdFlags background);
void drawMask(coord_t x, coord_t y, const BitmapBuffer * mask, LcdFlags flags, coord_t offset=0, coord_t width=0);
void drawMask(coord_t x, coord_t y, const BitmapBuffer * mask, LcdFlags flags, coord_t offsetX = 0, coord_t width = 0);
void drawMask(coord_t x, coord_t y, const BitmapBuffer * mask, const BitmapBuffer * srcBitmap, coord_t offsetX = 0, coord_t offsetY = 0, coord_t width = 0, coord_t height = 0);
void drawBitmapPattern(coord_t x, coord_t y, const uint8_t * bmp, LcdFlags flags, coord_t offset=0, coord_t width=0);
@@ -506,6 +508,8 @@ class BitmapBuffer: public BitmapBufferBase<pixel_t>
BitmapBuffer * verticalFlip() const;
BitmapBuffer * invertMask() const;
protected:
static BitmapBuffer * load_bmp(const char * filename);
static BitmapBuffer * load_stb(const char * filename);
+1 -1
View File
@@ -76,7 +76,7 @@ void MenuBody::paint(BitmapBuffer * dc)
for (unsigned i = 0; i < lines.size(); i++) {
auto & line = lines[i];
LcdFlags flags = MENU_COLOR | MENU_FONT;
if (selectedIndex == i) {
if (selectedIndex == (int)i) {
flags = MENU_HIGHLIGHT_COLOR | MENU_FONT;
if (MENU_HIGHLIGHT_BGCOLOR != MENU_BGCOLOR) {
dc->drawSolidFilledRect(0, i * MENUS_LINE_HEIGHT, width(), MENUS_LINE_HEIGHT, MENU_HIGHLIGHT_BGCOLOR);
+17 -3
View File
@@ -46,6 +46,14 @@ class Roller: public Choice {
lastScrollPositionY = scrollPositionY;
}
#if defined(DEBUG_WINDOWS)
std::string getName() const override
{
return "Roller";
}
#endif
void paint(BitmapBuffer * dc) override
{
int32_t value = getValue();
@@ -85,20 +93,26 @@ class Roller: public Choice {
{
Window::checkEvents();
if (lastEditMode != editMode) {
setScrollPositionY(ROLLER_LINE_HEIGHT * (this->getValue() - vmin - 1));
lastScrollPositionY = scrollPositionY;
lastEditMode = editMode;
}
#if defined(HARDWARE_TOUCH)
if (touchState.event != TE_SLIDE) {
if (scrollPositionY != lastScrollPositionY) {
updateScrollPosition();
updateValueFromScrollPosition();
}
}
#endif
}
protected:
coord_t lastScrollPositionY = 0;
bool lastEditMode = false;
void updateScrollPosition()
void updateValueFromScrollPosition()
{
lastScrollPositionY = scrollPositionY;