fix(color): flickering Lua widgets when full screen is refreshed (#5364)

This commit is contained in:
philmoz
2024-08-05 09:27:25 +10:00
committed by GitHub
parent af1a29de29
commit 4b978c347d
4 changed files with 66 additions and 2 deletions
+17 -2
View File
@@ -90,7 +90,7 @@ void BitmapBuffer::setData(uint16_t *d)
void BitmapBuffer::clear(LcdFlags flags)
{
drawSolidFilledRect(0, 0, _width, _height, flags);
drawSolidFilledRect(0, 0, _width - offsetX, _height - offsetY, flags);
}
void BitmapBuffer::clearClippingRect()
@@ -151,11 +151,18 @@ bool BitmapBuffer::applyClippingRect(coord_t& x, coord_t& y, coord_t& w,
return data && h > 0 && w > 0;
}
void BitmapBuffer::setOffset(coord_t offsetX, coord_t offsetY)
{
this->offsetX = offsetX;
this->offsetY = offsetY;
}
void BitmapBuffer::drawBitmap(coord_t x, coord_t y, const BitmapBuffer *bmp,
coord_t srcx, coord_t srcy, coord_t srcw,
coord_t srch, float scale)
{
if (!data || !bmp) return;
APPLY_OFFSET();
if (x >= xmax || y >= ymax) return;
coord_t bmpw = bmp->width();
@@ -292,6 +299,8 @@ void BitmapBuffer::drawHorizontalLine(coord_t x, coord_t y, coord_t w,
{
if (opacity == OPACITY_MAX) return;
APPLY_OFFSET();
coord_t h = 1;
if (!applyClippingRect(x, y, w, h)) return;
@@ -343,6 +352,8 @@ void BitmapBuffer::drawVerticalLine(coord_t x, coord_t y, coord_t h,
{
if (opacity == OPACITY_MAX) return;
APPLY_OFFSET();
coord_t w = 1;
if (!applyClippingRect(x, y, w, h)) return;
@@ -406,6 +417,7 @@ void BitmapBuffer::drawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h,
{
if (opacity == OPACITY_MAX) return;
APPLY_OFFSET();
if (!applyClippingRect(x, y, w, h)) return;
if (SOLID != pat) {
@@ -448,6 +460,7 @@ coord_t BitmapBuffer::drawSizedText(coord_t x, coord_t y, const char *s,
uint8_t len, LcdFlags flags)
{
if (!s) return x;
MOVE_OFFSET();
// LVGL does not handle non-null terminated strings
static char buffer[256];
@@ -509,9 +522,11 @@ coord_t BitmapBuffer::drawSizedText(coord_t x, coord_t y, const char *s,
}
#endif
RESTORE_OFFSET();
pos += p.x;
return ((flags & RIGHT) ? orig_pos : pos);
return ((flags & RIGHT) ? orig_pos : pos) - offsetX;
}
// Resize and convert to LVGL image data format with alpha blending to
@@ -27,6 +27,20 @@ constexpr uint8_t SOLID = 0xFF;
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 += this->offsetX; \
y += this->offsetY
#define RESTORE_OFFSET() this->offsetX = offsetX, this->offsetY = offsetY
#define MOVE_PIXEL_RIGHT(p, count) p += count
#define MOVE_TO_NEXT_RIGHT_PIXEL(p) MOVE_PIXEL_RIGHT(p, 1)
@@ -61,6 +75,8 @@ class BitmapBuffer
inline void drawPixel(coord_t x, coord_t y, pixel_t value)
{
APPLY_OFFSET();
coord_t w = 1, h = 1;
if (!applyClippingRect(x, y, w, h)) return;
@@ -72,6 +88,8 @@ class BitmapBuffer
inline void drawAlphaPixel(coord_t x, coord_t y, uint8_t opacity,
pixel_t value)
{
APPLY_OFFSET();
coord_t w = 1, h = 1;
if (!applyClippingRect(x, y, w, h)) return;
@@ -122,11 +140,20 @@ class BitmapBuffer
void clearClippingRect();
void setOffset(coord_t offsetX, coord_t offsetY);
inline void clearOffset() { setOffset(0, 0); }
inline void reset()
{
clearOffset();
clearClippingRect();
}
coord_t getOffsetX() const { return offsetX; }
coord_t getOffsetY() const { return offsetY; }
inline uint16_t width() const { return _width; }
inline uint16_t height() const { return _height; }
@@ -222,6 +249,8 @@ class BitmapBuffer
coord_t xmax;
coord_t ymin = 0;
coord_t ymax;
coord_t offsetX = 0;
coord_t offsetY = 0;
pixel_t* data;
pixel_t* data_end;
@@ -32,6 +32,8 @@
void BitmapBuffer::invertRect(coord_t x, coord_t y, coord_t w, coord_t h,
LcdFlags flags)
{
APPLY_OFFSET();
if (!applyClippingRect(x, y, w, h)) return;
// No 'opacity' here, only 'color'
@@ -331,6 +333,12 @@ bool BitmapBuffer::liangBarskyClipper(coord_t &x1, coord_t &y1, coord_t &x2,
void BitmapBuffer::drawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2,
uint8_t pat, LcdFlags flags)
{
// Offsets
x1 += offsetX;
y1 += offsetY;
x2 += offsetX;
y2 += offsetY;
if (!liangBarskyClipper(x1, y1, x2, y2)) return;
// TODO; Replace with LVGL line draw - currently does not support dotted line drawing
@@ -485,6 +493,8 @@ void BitmapBuffer::drawFilledTriangle(coord_t x0, coord_t y0, coord_t x1,
void BitmapBuffer::drawFilledCircle(coord_t x, coord_t y, coord_t radius,
LcdFlags flags)
{
APPLY_OFFSET();
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
rect_dsc.bg_opa = LV_OPA_COVER;
@@ -517,6 +527,8 @@ void BitmapBuffer::drawFilledCircle(coord_t x, coord_t y, coord_t radius,
void BitmapBuffer::drawCircle(coord_t x, coord_t y, coord_t radius,
LcdFlags flags, coord_t thickness)
{
APPLY_OFFSET();
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
rect_dsc.bg_opa = LV_OPA_TRANSP;
@@ -678,6 +690,8 @@ void BitmapBuffer::drawAnnulusSector(coord_t x, coord_t y,
coord_t externalRadius, int startAngle,
int endAngle, LcdFlags flags)
{
APPLY_OFFSET();
if (endAngle == startAngle)
endAngle += 1;
@@ -746,6 +760,8 @@ void BitmapBuffer::drawBitmapPattern(coord_t x, coord_t y, const MaskBitmap *bmp
LcdFlags flags, coord_t offset,
coord_t width)
{
APPLY_OFFSET();
coord_t bmpw = bmp->width;
coord_t bmph = bmp->height;
+4
View File
@@ -210,6 +210,10 @@ void LuaWidget::redraw_cb(lv_event_t* e)
buf.setDrawCtx(draw_ctx);
buf.setOffset(draw_ctx->clip_area->x1 - draw_ctx->buf_area->x1, draw_ctx->clip_area->y1 - draw_ctx->buf_area->y1);
buf.setClippingRect(draw_ctx->clip_area->x1 - draw_ctx->buf_area->x1, draw_ctx->clip_area->x2 - draw_ctx->buf_area->x1 + 1,
draw_ctx->clip_area->y1 - draw_ctx->buf_area->y1, draw_ctx->clip_area->y2 - draw_ctx->buf_area->y1 + 1);
widget->refresh(&buf);
}
}