From c5533ab0eff0981d4fbf236684c4ab6780d23e74 Mon Sep 17 00:00:00 2001 From: Norbert Walter Date: Wed, 4 Mar 2026 09:02:29 +0000 Subject: [PATCH] Add frame buffer for scaled picture --- lib/obp60task/OBP60Extensions.cpp | 28 ++++++++++++++ lib/obp60task/OBP60Extensions.h | 62 ++++++++++++++++--------------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/lib/obp60task/OBP60Extensions.cpp b/lib/obp60task/OBP60Extensions.cpp index eaec447..6566a62 100644 --- a/lib/obp60task/OBP60Extensions.cpp +++ b/lib/obp60task/OBP60Extensions.cpp @@ -60,10 +60,15 @@ GxEPD2_BW & getdisplay(){r // panel device + offscreen shadow framebuffer static LGFX panelDisplay; static LGFXCanvas shadowDisplay(&panelDisplay); +static LGFXCanvas scaleDisplay(&panelDisplay); static bool shadowDisplayInitialized = false; +static bool scaleDisplayInitialized = false; +static uint16_t scaleDisplayWidth = 0; +static uint16_t scaleDisplayHeight = 0; LGFXCanvas & getdisplay(){return shadowDisplay;} LGFX & getpaneldisplay(){return panelDisplay;} +LGFXCanvas & getscaleddisplay(){return scaleDisplay;} bool initDisplayShadowBuffer(){ if (shadowDisplayInitialized) return true; @@ -81,6 +86,29 @@ bool initDisplayShadowBuffer(){ shadowDisplayInitialized = true; return true; } + +bool initDisplayScaleBuffer(uint16_t width, uint16_t height){ + if (scaleDisplayInitialized && scaleDisplayWidth == width && scaleDisplayHeight == height) { + return true; + } + + scaleDisplay.deleteSprite(); + scaleDisplay.setPsram(true); + scaleDisplay.setColorDepth(16); + scaleDisplay.setTextDatum(textdatum_t::baseline_left); + + if (scaleDisplay.createSprite(width, height) == nullptr) { + scaleDisplayInitialized = false; + scaleDisplayWidth = 0; + scaleDisplayHeight = 0; + return false; + } + + scaleDisplayWidth = width; + scaleDisplayHeight = height; + scaleDisplayInitialized = true; + return true; +} #endif // Horter I2C moduls diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index 662b2c0..62c7c2a 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -423,7 +423,9 @@ private: LGFXCanvas & getdisplay(); LGFX & getpaneldisplay(); +LGFXCanvas & getscaleddisplay(); bool initDisplayShadowBuffer(); +bool initDisplayScaleBuffer(uint16_t width, uint16_t height); #endif // Page display return values @@ -568,42 +570,44 @@ inline void displayNextPage() { const uint16_t drawX = static_cast((dstW - targetW) / 2U); const uint16_t drawY = static_cast((dstH - targetH) / 2U); - dst.startWrite(); const uint16_t borderColor = src.readPixel(0, 0); - if (drawX > 0) { - dst.fillRect(0, drawY, drawX, targetH, borderColor); - dst.fillRect(drawX + targetW, drawY, dstW - (drawX + targetW), targetH, borderColor); - } + if (initDisplayScaleBuffer(dstW, dstH)) { + LGFXCanvas &scaled = getscaleddisplay(); + scaled.fillScreen(borderColor); - for (uint16_t y = 0; y < targetH; ++y) { - const uint32_t syfp = (targetH > 1) - ? (static_cast(y) * (srcH - 1) * 256U) / (targetH - 1) - : 0; - const uint16_t sy0 = static_cast(syfp >> 8); - const uint16_t sy1 = (sy0 + 1 < srcH) ? static_cast(sy0 + 1) : sy0; - const uint16_t wy = static_cast(syfp & 0xFFU); - - for (uint16_t x = 0; x < targetW; ++x) { - const uint32_t sxfp = (targetW > 1) - ? (static_cast(x) * (srcW - 1) * 256U) / (targetW - 1) + for (uint16_t y = 0; y < targetH; ++y) { + const uint32_t syfp = (targetH > 1) + ? (static_cast(y) * (srcH - 1) * 256U) / (targetH - 1) : 0; - const uint16_t sx0 = static_cast(sxfp >> 8); - const uint16_t sx1 = (sx0 + 1 < srcW) ? static_cast(sx0 + 1) : sx0; + const uint16_t sy0 = static_cast(syfp >> 8); + const uint16_t sy1 = (sy0 + 1 < srcH) ? static_cast(sy0 + 1) : sy0; + const uint16_t wy = static_cast(syfp & 0xFFU); - #if OBP_TFT_SCALE_ANTIALIAS - const uint16_t wx = static_cast(sxfp & 0xFFU); - const uint16_t color = sampleBilinearRgb565(src, sx0, sy0, sx1, sy1, wx, wy); - #else - const uint16_t color = src.readPixel(sx0, sy0); - #endif + for (uint16_t x = 0; x < targetW; ++x) { + const uint32_t sxfp = (targetW > 1) + ? (static_cast(x) * (srcW - 1) * 256U) / (targetW - 1) + : 0; + const uint16_t sx0 = static_cast(sxfp >> 8); + const uint16_t sx1 = (sx0 + 1 < srcW) ? static_cast(sx0 + 1) : sx0; - dst.drawPixel(drawX + x, drawY + y, color); - } - if ((y & 0x0F) == 0) { - yield(); + #if OBP_TFT_SCALE_ANTIALIAS + const uint16_t wx = static_cast(sxfp & 0xFFU); + const uint16_t color = sampleBilinearRgb565(src, sx0, sy0, sx1, sy1, wx, wy); + #else + const uint16_t color = src.readPixel(sx0, sy0); + #endif + + scaled.drawPixel(drawX + x, drawY + y, color); + } + if ((y & 0x0F) == 0) { + yield(); + } } + + scaled.pushSprite(0, 0); + } else { + src.pushSprite(drawX, drawY); } - dst.endWrite(); #endif } #else