diff --git a/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp b/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp index 1ad501fca..98aed34e5 100755 --- a/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp +++ b/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp @@ -201,8 +201,28 @@ void BitmapBuffer::drawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, ui if (!applyClippingRect(x, y, w, h)) return; - for (coord_t i = y; i < y + h; i++) { - drawHorizontalLineAbs(x, i, w, pat, flags, opacity); + // Use DMA instead... + if (SOLID != pat) { + for (coord_t i = y; i < y + h; i++) { + drawHorizontalLineAbs(x, i, w, pat, flags, opacity); + } + } + else { + // SOLID + + // Use the DMA2D to blend a scratch buffer filled with overlay color + BitmapBuffer scratch(BMP_ARGB4444, LCD_W, LCD_H, lcdGetScratchBuffer()); + RGB_SPLIT(COLOR_VAL(flags), r, g, b); + + LcdFlags flags = + uint32_t(ARGB((OPACITY_MAX - opacity) << 4, r << 3, g << 2, b << 3)) + << 16; + + // Fill the buffer + scratch.drawSolidFilledRect(0, 0, w, h, flags); + + // And blend + drawBitmapAbs(x, y, &scratch, 0, 0, w, h); } } diff --git a/radio/src/thirdparty/libopenui/src/bitmapbuffer.h b/radio/src/thirdparty/libopenui/src/bitmapbuffer.h index 622d9de6a..d11444086 100755 --- a/radio/src/thirdparty/libopenui/src/bitmapbuffer.h +++ b/radio/src/thirdparty/libopenui/src/bitmapbuffer.h @@ -394,6 +394,70 @@ class BitmapBuffer: public BitmapBufferBase if (x >= xmax || y >= ymax) return; + drawBitmapAbs(x, y, bmp, srcx, srcy, srcw, srch, scale); + } + + template + void drawScaledBitmap(const T * bitmap, coord_t x, coord_t y, coord_t w, coord_t h) + { + if (bitmap) { + float vscale = float(h) / bitmap->height(); + float hscale = float(w) / bitmap->width(); + float scale = vscale < hscale ? vscale : hscale; + + int xshift = (w - (bitmap->width() * scale)) / 2; + int yshift = (h - (bitmap->height() * scale)) / 2; + drawBitmap(x + xshift, y + yshift, bitmap, 0, 0, 0, 0, scale); + } + } + + BitmapBuffer * horizontalFlip() const; + + BitmapBuffer * verticalFlip() const; + + BitmapBuffer * invertMask() const; + + protected: + static BitmapBuffer * load_bmp(const char * filename); + static BitmapBuffer * load_stb(const char * filename); + + inline bool applyClippingRect(coord_t & x, coord_t & y, coord_t & w, coord_t & h) const + { + if (h < 0) { + y += h; + h = -h; + } + + if (w < 0) { + x += w; + w = -w; + } + + if (x >= xmax || y >= ymax) + return false; + + if (y < ymin) { + h += y - ymin; + y = ymin; + } + + if (x < xmin) { + w += x - xmin; + x = xmin; + } + + if (y + h > ymax) + h = ymax - y; + + if (x + w > xmax) + w = xmax - x; + + return data && h > 0 && w > 0; + } + + template + void drawBitmapAbs(coord_t x, coord_t y, const T * bmp, coord_t srcx = 0, coord_t srcy = 0, coord_t srcw = 0, coord_t srch = 0, float scale = 0) + { coord_t bmpw = bmp->width(); coord_t bmph = bmp->height(); @@ -483,64 +547,6 @@ class BitmapBuffer: public BitmapBufferBase } } - template - void drawScaledBitmap(const T * bitmap, coord_t x, coord_t y, coord_t w, coord_t h) - { - if (bitmap) { - float vscale = float(h) / bitmap->height(); - float hscale = float(w) / bitmap->width(); - float scale = vscale < hscale ? vscale : hscale; - - int xshift = (w - (bitmap->width() * scale)) / 2; - int yshift = (h - (bitmap->height() * scale)) / 2; - drawBitmap(x + xshift, y + yshift, bitmap, 0, 0, 0, 0, scale); - } - } - - BitmapBuffer * horizontalFlip() const; - - BitmapBuffer * verticalFlip() const; - - BitmapBuffer * invertMask() const; - - protected: - static BitmapBuffer * load_bmp(const char * filename); - static BitmapBuffer * load_stb(const char * filename); - - inline bool applyClippingRect(coord_t & x, coord_t & y, coord_t & w, coord_t & h) const - { - if (h < 0) { - y += h; - h = -h; - } - - if (w < 0) { - x += w; - w = -w; - } - - if (x >= xmax || y >= ymax) - return false; - - if (y < ymin) { - h += y - ymin; - y = ymin; - } - - if (x < xmin) { - w += x - xmin; - x = xmin; - } - - if (y + h > ymax) - h = ymax - y; - - if (x + w > xmax) - w = xmax - x; - - return data && h > 0 && w > 0; - } - uint8_t drawChar(coord_t x, coord_t y, const uint8_t * font, const uint16_t * spec, unsigned int index, LcdFlags flags); inline void drawPixel(pixel_t * p, pixel_t value) diff --git a/radio/src/thirdparty/libopenui/src/libopenui_depends.h b/radio/src/thirdparty/libopenui/src/libopenui_depends.h index ebcc2c3ae..4a128f75b 100644 --- a/radio/src/thirdparty/libopenui/src/libopenui_depends.h +++ b/radio/src/thirdparty/libopenui/src/libopenui_depends.h @@ -23,6 +23,7 @@ #include "libopenui_config.h" void lcdNextLayer(); +uint16_t* lcdGetScratchBuffer(); void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h); void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h); void onKeyPress();