From f503b118547e2c32f816337c78cca6edd42f6cb7 Mon Sep 17 00:00:00 2001 From: philmoz Date: Sat, 4 Jul 2026 18:47:02 +1000 Subject: [PATCH] fix(color): improve bitmap error handling (#7509) --- radio/src/gui/colorlcd/libui/bitmapbuffer.cpp | 52 +++++++++++-------- radio/src/gui/colorlcd/libui/bitmapbuffer.h | 34 +++++------- .../colorlcd/libui/bitmapbuffer_fileio.cpp | 4 +- radio/src/gui/colorlcd/libui/file_preview.cpp | 13 ++++- radio/src/gui/colorlcd/libui/file_preview.h | 3 ++ radio/src/gui/colorlcd/libui/mainwindow.cpp | 15 +++--- radio/src/gui/colorlcd/libui/mainwindow.h | 3 +- radio/src/gui/colorlcd/libui/static.cpp | 17 +++--- radio/src/gui/colorlcd/libui/static.h | 1 - .../gui/colorlcd/model/function_switches.h | 1 - .../gui/colorlcd/radio/radio_sdmanager.cpp | 1 + radio/src/gui/colorlcd/standalone_lua.cpp | 6 +-- radio/src/gui/colorlcd/startup_shutdown.cpp | 14 ++--- radio/src/sdcard.h | 5 +- radio/src/tests/lcd_480x272.cpp | 22 +++++++- 15 files changed, 105 insertions(+), 86 deletions(-) diff --git a/radio/src/gui/colorlcd/libui/bitmapbuffer.cpp b/radio/src/gui/colorlcd/libui/bitmapbuffer.cpp index 0d6531390..1962e6fef 100644 --- a/radio/src/gui/colorlcd/libui/bitmapbuffer.cpp +++ b/radio/src/gui/colorlcd/libui/bitmapbuffer.cpp @@ -19,16 +19,17 @@ #include "bitmapbuffer.h" #include - #include #include "bitmaps.h" #include "board.h" #include "dma2d.h" #include "fonts.h" -#include "lvgl/src/draw/sw/lv_draw_sw.h" #include "edgetx_helpers.h" #include "strhelpers.h" +#if !defined(BOOT) +#include "window.h" +#endif BitmapBuffer::BitmapBuffer(uint8_t format, uint16_t width, uint16_t height) : format(format), @@ -44,12 +45,6 @@ BitmapBuffer::BitmapBuffer(uint8_t format, uint16_t width, uint16_t height) : { data = (uint16_t *)malloc(align32(width * height * sizeof(uint16_t))); data_end = data + (width * height); - -#if !defined(BOOT) - // Assume we need a canvas here - canvas = lv_canvas_create(nullptr); - lv_canvas_set_buffer(canvas, data, width, height, LV_IMG_CF_TRUE_COLOR); -#endif } BitmapBuffer::BitmapBuffer(uint8_t format, uint16_t width, uint16_t height, @@ -71,15 +66,30 @@ BitmapBuffer::BitmapBuffer(uint8_t format, uint16_t width, uint16_t height, BitmapBuffer::~BitmapBuffer() { - DMAWait(); if (dataAllocated) { -#if !defined(BOOT) - lv_obj_del(canvas); -#endif free(data); } } +#if !defined(BOOT) +lv_obj_t* BitmapBuffer::addCanvas(Window* parent, lv_img_cf_t fmt) +{ + removeCanvas(); + canvas = lv_canvas_create(parent ? parent->getLvObj() : nullptr); + lv_canvas_set_buffer(canvas, data, _width, _height, fmt); + lv_obj_center(canvas); + return canvas; +} + +void BitmapBuffer::removeCanvas() +{ + if (canvas) { + lv_obj_del(canvas); + canvas = nullptr; + } +} +#endif + void BitmapBuffer::setData(uint16_t *d) { if (!dataAllocated) { @@ -151,12 +161,6 @@ 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) @@ -460,7 +464,13 @@ coord_t BitmapBuffer::drawSizedText(coord_t x, coord_t y, const char *s, uint8_t len, LcdFlags flags) { if (!s) return x; - MOVE_OFFSET(); + + coord_t offsetX = this->offsetX; + x += offsetX; + this->offsetX = 0; + coord_t offsetY = this->offsetY; + y += offsetY; + this->offsetY = 0; // LVGL does not handle non-null terminated strings static char buffer[256]; @@ -522,8 +532,8 @@ coord_t BitmapBuffer::drawSizedText(coord_t x, coord_t y, const char *s, } #endif - RESTORE_OFFSET(); - + this->offsetX = offsetX; + this->offsetY = offsetY; pos += p.x; return ((flags & RIGHT) ? orig_pos : pos) - offsetX; diff --git a/radio/src/gui/colorlcd/libui/bitmapbuffer.h b/radio/src/gui/colorlcd/libui/bitmapbuffer.h index e6a9a69c6..29d4ee04d 100644 --- a/radio/src/gui/colorlcd/libui/bitmapbuffer.h +++ b/radio/src/gui/colorlcd/libui/bitmapbuffer.h @@ -26,31 +26,20 @@ struct MaskBitmap; class TelemetryItem; +class Window; 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) -#define USE_STB - enum BitmapFormats { BMP_INVALID = -1, BMP_RGB565 = 0, BMP_ARGB4444 }; class BitmapBuffer @@ -140,20 +129,18 @@ class BitmapBuffer void clearClippingRect(); - void setOffset(coord_t offsetX, coord_t offsetY); - - inline void clearOffset() { setOffset(0, 0); } + inline void setOffset(coord_t offsetX, coord_t offsetY) + { + this->offsetX = offsetX; + this->offsetY = offsetY; + } inline void reset() { - clearOffset(); + setOffset(0, 0); 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; } @@ -161,6 +148,11 @@ class BitmapBuffer uint32_t getDataSize() const { return _width * _height * sizeof(pixel_t); } +#if !defined(BOOT) + lv_obj_t* addCanvas(Window* parent, lv_img_cf_t fmt = LV_IMG_CF_TRUE_COLOR); + void removeCanvas(); +#endif + // Lua API functions void setClippingRect(coord_t xmin, coord_t xmax, coord_t ymin, coord_t ymax); void getClippingRect(coord_t& xmin, coord_t& xmax, coord_t& ymin, @@ -259,6 +251,8 @@ class BitmapBuffer #if defined(DEBUG) bool leakReported; #endif +#if !defined(BOOT) lv_obj_t* canvas = nullptr; +#endif lv_draw_ctx_t* draw_ctx = nullptr; }; diff --git a/radio/src/gui/colorlcd/libui/bitmapbuffer_fileio.cpp b/radio/src/gui/colorlcd/libui/bitmapbuffer_fileio.cpp index e02b458ed..542e72ff1 100644 --- a/radio/src/gui/colorlcd/libui/bitmapbuffer_fileio.cpp +++ b/radio/src/gui/colorlcd/libui/bitmapbuffer_fileio.cpp @@ -125,7 +125,9 @@ BitmapBuffer *BitmapBuffer::loadBitmap(const char *filename, BitmapFormats fmt) } BitmapBuffer *bmp = new BitmapBuffer(dst_fmt, w, h); - if (bmp == nullptr) { + if (bmp == nullptr || bmp->getData() == nullptr) { + if (bmp) delete bmp; + stbi_image_free(img); TRACE_ERROR("loadBitmap: malloc failed\n"); return nullptr; } diff --git a/radio/src/gui/colorlcd/libui/file_preview.cpp b/radio/src/gui/colorlcd/libui/file_preview.cpp index a907b9f24..8fde63e91 100644 --- a/radio/src/gui/colorlcd/libui/file_preview.cpp +++ b/radio/src/gui/colorlcd/libui/file_preview.cpp @@ -30,5 +30,16 @@ FilePreview::FilePreview(Window *parent, const rect_t &rect) : void FilePreview::setFile(const char *filename) { setSource(filename ? filename : ""); - show(hasImage()); + if (!hasImage() && filename) { + if (!errorIcon) { + errorIcon = new StaticIcon(this, 0, 0, ICON_ERROR, COLOR_THEME_PRIMARY1_INDEX); + lv_obj_center(errorIcon->getLvObj()); + } + errorIcon->show(); + show(); + } else { + if (errorIcon) + errorIcon->hide(); + show(hasImage()); + } } diff --git a/radio/src/gui/colorlcd/libui/file_preview.h b/radio/src/gui/colorlcd/libui/file_preview.h index b0e0073d6..a0d55e988 100644 --- a/radio/src/gui/colorlcd/libui/file_preview.h +++ b/radio/src/gui/colorlcd/libui/file_preview.h @@ -33,4 +33,7 @@ class FilePreview : public StaticBitmap #endif void setFile(const char *filename); + + protected: + StaticIcon* errorIcon = nullptr; }; diff --git a/radio/src/gui/colorlcd/libui/mainwindow.cpp b/radio/src/gui/colorlcd/libui/mainwindow.cpp index 127a00f35..b749aed39 100644 --- a/radio/src/gui/colorlcd/libui/mainwindow.cpp +++ b/radio/src/gui/colorlcd/libui/mainwindow.cpp @@ -44,9 +44,6 @@ MainWindow::MainWindow() : Window(nullptr, {0, 0, LCD_W, LCD_H}) setWindowFlag(OPAQUE); etx_solid_bg(lvobj); - - background = lv_canvas_create(lvobj); - lv_obj_center(background); } void MainWindow::emptyTrash() @@ -105,9 +102,7 @@ void MainWindow::shutdown() clear(); emptyTrash(); - // Re-add background canvas - background = lv_canvas_create(lvobj); - lv_obj_center(background); + backgroundBitmap = nullptr; } bool MainWindow::setBackgroundImage(std::string& fileName) @@ -115,14 +110,16 @@ bool MainWindow::setBackgroundImage(std::string& fileName) if (fileName.empty()) return false; // ensure you delete old bitmap - if (backgroundBitmap != nullptr) delete backgroundBitmap; + if (backgroundBitmap != nullptr) { + backgroundBitmap->removeCanvas(); + delete backgroundBitmap; + } // Try to load bitmap. backgroundBitmap = BitmapBuffer::loadBitmap(fileName.c_str(), BMP_RGB565); if (backgroundBitmap) { - lv_canvas_set_buffer(background, backgroundBitmap->getData(), backgroundBitmap->width(), - backgroundBitmap->height(), LV_IMG_CF_TRUE_COLOR); + lv_obj_move_background(backgroundBitmap->addCanvas(this)); return true; } diff --git a/radio/src/gui/colorlcd/libui/mainwindow.h b/radio/src/gui/colorlcd/libui/mainwindow.h index 06f6fcff9..0b4e0cab8 100644 --- a/radio/src/gui/colorlcd/libui/mainwindow.h +++ b/radio/src/gui/colorlcd/libui/mainwindow.h @@ -56,8 +56,7 @@ class MainWindow: public Window void blockUntilClose(bool checkPwr, std::function closeCondition, bool isError = false); protected: - lv_obj_t* background = nullptr; - const BitmapBuffer *backgroundBitmap = nullptr; + BitmapBuffer *backgroundBitmap = nullptr; bool widgetRefreshEnable = true; static MainWindow * _instance; diff --git a/radio/src/gui/colorlcd/libui/static.cpp b/radio/src/gui/colorlcd/libui/static.cpp index 26baeb0c8..9578e4aa5 100644 --- a/radio/src/gui/colorlcd/libui/static.cpp +++ b/radio/src/gui/colorlcd/libui/static.cpp @@ -284,25 +284,22 @@ StaticBitmap::StaticBitmap(Window* parent, const rect_t& rect, void StaticBitmap::setSource(const char *filename) { if (filename) { - if (img) delete img; + clearSource(); img = BitmapBuffer::loadBitmap(filename, BMP_ARGB4444); if (img) { img->resizeToLVGL(width(), height()); - if (canvas) lv_obj_del(canvas); - canvas = lv_canvas_create(lvobj); - lv_obj_center(canvas); - lv_canvas_set_buffer(canvas, img->getData(), img->width(), img->height(), - LV_IMG_CF_TRUE_COLOR_ALPHA); + img->addCanvas(this, LV_IMG_CF_TRUE_COLOR_ALPHA); } } } void StaticBitmap::clearSource() { - if (img) delete img; + if (img) { + img->removeCanvas(); + delete img; + } img = nullptr; - if (canvas) lv_obj_del(canvas); - canvas = nullptr; } StaticBitmap::~StaticBitmap() @@ -312,7 +309,7 @@ StaticBitmap::~StaticBitmap() bool StaticBitmap::hasImage() const { - return img && canvas; + return img; } //----------------------------------------------------------------------------- diff --git a/radio/src/gui/colorlcd/libui/static.h b/radio/src/gui/colorlcd/libui/static.h index 417af8212..9caf8859e 100644 --- a/radio/src/gui/colorlcd/libui/static.h +++ b/radio/src/gui/colorlcd/libui/static.h @@ -182,7 +182,6 @@ class StaticBitmap : public Window bool hasImage() const; protected: - lv_obj_t *canvas = nullptr; BitmapBuffer *img = nullptr; }; diff --git a/radio/src/gui/colorlcd/model/function_switches.h b/radio/src/gui/colorlcd/model/function_switches.h index 962c00bbc..c371f9f0e 100644 --- a/radio/src/gui/colorlcd/model/function_switches.h +++ b/radio/src/gui/colorlcd/model/function_switches.h @@ -126,7 +126,6 @@ class FunctionSwitchesBase : public Page void addQRCode(); protected: - BitmapBuffer* qrcode = nullptr; StaticText* startupHeader = nullptr; #if defined(FUNCTION_SWITCHES_RGB_LEDS) Messaging previewMsg; diff --git a/radio/src/gui/colorlcd/radio/radio_sdmanager.cpp b/radio/src/gui/colorlcd/radio/radio_sdmanager.cpp index 611008772..f3707de22 100644 --- a/radio/src/gui/colorlcd/radio/radio_sdmanager.cpp +++ b/radio/src/gui/colorlcd/radio/radio_sdmanager.cpp @@ -236,6 +236,7 @@ void RadioSdManagerPage::build(Window * window) }); browser->setFileSelected([=](const char* path, const char* name, const char* fullpath, bool isDir) { preview->setFile(nullptr); + loadPreview = 0; loading->hide(); if (fullpath && !isDir) { auto ext = getFileExtension(fullpath); diff --git a/radio/src/gui/colorlcd/standalone_lua.cpp b/radio/src/gui/colorlcd/standalone_lua.cpp index fe3598a04..7944cbcb9 100644 --- a/radio/src/gui/colorlcd/standalone_lua.cpp +++ b/radio/src/gui/colorlcd/standalone_lua.cpp @@ -152,17 +152,13 @@ StandaloneLuaWindow::StandaloneLuaWindow(bool useLvgl, int initFn, int runFn) : lv_label_set_text(lbl, STR_LOADING); } else { lcdBuffer = new BitmapBuffer(BMP_RGB565, LCD_W, LCD_H); + lcdBuffer->addCanvas(this); lcdBuffer->clear(); lcdBuffer->drawText(LCD_W / 2, LCD_H / 2 - EdgeTxStyles::STD_FONT_HEIGHT, STR_LOADING, FONT(L) | COLOR_THEME_PRIMARY2 | CENTERED); setWindowFlag(NO_FOCUS | NO_SCROLL); - auto canvas = lv_canvas_create(lvobj); - lv_obj_center(canvas); - lv_canvas_set_buffer(canvas, lcdBuffer->getData(), - lcdBuffer->width(), lcdBuffer->height(), LV_IMG_CF_TRUE_COLOR); - lv_group_add_obj(lv_group_get_default(), lvobj); lv_group_set_editing(lv_group_get_default(), true); } diff --git a/radio/src/gui/colorlcd/startup_shutdown.cpp b/radio/src/gui/colorlcd/startup_shutdown.cpp index c675b6b32..be4008dce 100644 --- a/radio/src/gui/colorlcd/startup_shutdown.cpp +++ b/radio/src/gui/colorlcd/startup_shutdown.cpp @@ -139,7 +139,6 @@ const int8_t bmp_shutdown_yo[] = {-SHUTDOWN_CIRCLE_RADIUS, 0, 0, static Window* shutdownWindow = nullptr; static StaticIcon* shutdownAnim[4] = {nullptr}; static BitmapBuffer* shutdownSplashImg = nullptr; -static lv_obj_t* shutdownCanvas = nullptr; void drawSleepBitmap() { @@ -164,7 +163,6 @@ void cancelShutdownAnimation() if (shutdownWindow) { shutdownWindow->deleteLater(); shutdownWindow = nullptr; - shutdownCanvas = nullptr; for (int i = 0; i < 4; i += 1) shutdownAnim[i] = nullptr; } } @@ -180,17 +178,13 @@ void drawShutdownAnimation(uint32_t duration, uint32_t totalDuration, shutdownWindow->setWindowFlag(OPAQUE); etx_solid_bg(shutdownWindow->getLvObj(), COLOR_THEME_PRIMARY1_INDEX); - if (sdMounted() && !shutdownSplashImg) + if (sdMounted() && !shutdownSplashImg) { shutdownSplashImg = BitmapBuffer::loadBitmap( BITMAPS_PATH "/" SHUTDOWN_SPLASH_FILE, BMP_RGB565); - - if (shutdownSplashImg) { - shutdownCanvas = lv_canvas_create(shutdownWindow->getLvObj()); - lv_obj_center(shutdownCanvas); - lv_canvas_set_buffer(shutdownCanvas, shutdownSplashImg->getData(), - shutdownSplashImg->width(), - shutdownSplashImg->height(), LV_IMG_CF_TRUE_COLOR); + if (shutdownSplashImg) + shutdownSplashImg->addCanvas(shutdownWindow); } + (new StaticIcon(shutdownWindow, 0, 0, ICON_SHUTDOWN, COLOR_THEME_PRIMARY2_INDEX)) ->center(LCD_W, LCD_H); diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index 5c85005bf..767f888be 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -79,8 +79,6 @@ const char YAMLFILE_CHECKSUM_TAG_NAME[] = "checksum"; #define LOGS_EXT ".csv" #define SOUNDS_EXT ".wav" #define BMP_EXT ".bmp" -#define PNG_EXT ".png" -#define JPG_EXT ".jpg" #define SCRIPT_EXT ".lua" #define SCRIPT_BIN_EXT ".luac" #define TEXT_EXT ".txt" @@ -96,8 +94,7 @@ const char YAMLFILE_CHECKSUM_TAG_NAME[] = "checksum"; #define YAML_EXT ".yml" #if defined(COLORLCD) -#define BITMAPS_EXT BMP_EXT JPG_EXT PNG_EXT -#define LEN_BITMAPS_EXT 4 +#define BITMAPS_EXT BMP_EXT ".png" ".jpg" ".jpeg" #else #define BITMAPS_EXT BMP_EXT #endif diff --git a/radio/src/tests/lcd_480x272.cpp b/radio/src/tests/lcd_480x272.cpp index 8cff1ed1b..dccda19bf 100644 --- a/radio/src/tests/lcd_480x272.cpp +++ b/radio/src/tests/lcd_480x272.cpp @@ -99,6 +99,7 @@ bool checkScreenshot_colorlcd(const BitmapBuffer* dc, const char* test) TEST(Lcd_colorlcd, lines) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + dc.addCanvas(nullptr); dc.clear(COLOR_THEME_SECONDARY3); dc.setClippingRect(50, 400, 50, 230); @@ -113,11 +114,13 @@ TEST(Lcd_colorlcd, lines) dc.clearClippingRect(); EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "lines")); + dc.removeCanvas(); } TEST(Lcd_colorlcd, vline) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + dc.addCanvas(nullptr); dc.clear(COLOR_THEME_SECONDARY3); @@ -125,11 +128,13 @@ TEST(Lcd_colorlcd, vline) dc.drawVerticalLine(x, x / 2, 12, SOLID, COLOR_THEME_SECONDARY1); } EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "vline")); + dc.removeCanvas(); } TEST(Lcd_colorlcd, primitives) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + dc.addCanvas(nullptr); dc.clear(COLOR_THEME_SECONDARY3); @@ -156,11 +161,13 @@ TEST(Lcd_colorlcd, primitives) dc.drawHorizontalLine(30, 85, 70, SOLID, COLOR_THEME_SECONDARY1); EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "primitives_" TRANSLATIONS)); + dc.removeCanvas(); } TEST(Lcd_colorlcd, transparency) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + dc.addCanvas(nullptr); dc.clear(COLOR_THEME_SECONDARY3); @@ -198,6 +205,7 @@ TEST(Lcd_colorlcd, transparency) } EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "transparency_" TRANSLATIONS)); + dc.removeCanvas(); } // @@ -210,7 +218,8 @@ TEST(Lcd_colorlcd, transparency) TEST(Lcd_colorlcd, fonts) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); - + dc.addCanvas(nullptr); + dc.clear(COLOR_THEME_SECONDARY3); dc.drawText(8, 8, "The quick brown fox jumps over the lazy dog", COLOR_THEME_SECONDARY1); @@ -226,12 +235,14 @@ TEST(Lcd_colorlcd, fonts) dc.drawText(5, 205, "The quick brown fox jumps over the lazy dog", COLOR_THEME_SECONDARY1); EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "fonts_" TRANSLATIONS)); + dc.removeCanvas(); } #endif TEST(Lcd_colorlcd, clipping) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + dc.addCanvas(nullptr); dc.clear(COLOR_THEME_SECONDARY3); @@ -259,11 +270,13 @@ TEST(Lcd_colorlcd, clipping) dc.clearClippingRect(); EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "clipping")); + dc.removeCanvas(); } TEST(Lcd_colorlcd, bitmap) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + dc.addCanvas(nullptr); dc.clear(COLOR_THEME_SECONDARY3); @@ -275,6 +288,7 @@ TEST(Lcd_colorlcd, bitmap) dc.clearClippingRect(); EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "bitmap")); + dc.removeCanvas(); } static const uint8_t mask_menu_radio[] = { @@ -286,6 +300,7 @@ extern MaskBitmap* _decompressed_mask(const uint8_t* lz4_compressed); TEST(Lcd_colorlcd, masks) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + dc.addCanvas(nullptr); dc.clear(COLOR_THEME_SECONDARY3); @@ -299,6 +314,7 @@ TEST(Lcd_colorlcd, masks) EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "masks")); free(mask); + dc.removeCanvas(); } #if 0 @@ -337,6 +353,7 @@ TEST(Lcd_colorlcd, masks) TEST(Lcd_colorlcd, extra_font) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + dc.addCanvas(nullptr); dc.clear(COLOR_THEME_SECONDARY3); dc.drawText(10, 25, EXTRA_FULL, COLOR_THEME_SECONDARY1 | FONT(XXS)); @@ -347,6 +364,7 @@ TEST(Lcd_colorlcd, extra_font) dc.drawText(10, 184, EXTRA_TEST2, COLOR_THEME_SECONDARY1 | FONT(XXL)); EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "extra")); + dc.removeCanvas(); } constexpr coord_t LBM_USB_PLUGGED_W = 211; @@ -359,6 +377,7 @@ const uint8_t LBM_USB_PLUGGED[] = { TEST(Lcd_colorlcd, darkmode) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + dc.addCanvas(nullptr); dc.clear(COLOR_BLACK); @@ -370,6 +389,7 @@ TEST(Lcd_colorlcd, darkmode) COLOR2FLAGS(RGB(0, 0, 0xFF))); EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "darkmode_" TRANSLATIONS)); + dc.removeCanvas(); } #endif