diff --git a/lib/GfxRenderer/GfxRenderer.cpp b/lib/GfxRenderer/GfxRenderer.cpp index 1989658..e94ea46 100644 --- a/lib/GfxRenderer/GfxRenderer.cpp +++ b/lib/GfxRenderer/GfxRenderer.cpp @@ -234,8 +234,11 @@ void GfxRenderer::drawBitmap(const Bitmap& bitmap, const int x, const int y, con // draw extended pixels /// amount of pixels taken from bitmap and repeated to extend int extendY = 20; + int extendX = 20; // The width of the strip to be mirrored int drawExtY = 0; if (extend) { + int imgHeight = std::floor(scale * (bitmap.getHeight() - cropPixY)); + int imgWidth = std::floor(scale * (bitmap.getWidth() - cropPixX)); // 1. TOP EXTENSION // Check if the current pixel is within the strip to be mirrored if (screenY >= y && screenY < y + extendY) { @@ -256,7 +259,6 @@ void GfxRenderer::drawBitmap(const Bitmap& bitmap, const int x, const int y, con } // 2. BOTTOM EXTENSION - int imgHeight = std::floor(scale * (bitmap.getHeight() - cropPixY)); int imgBottom = y + imgHeight; int gapBottom = getScreenHeight() - imgBottom; @@ -273,6 +275,38 @@ void GfxRenderer::drawBitmap(const Bitmap& bitmap, const int x, const int y, con if (t2 >= imgBottom && t2 < getScreenHeight()) drawVal(screenX, t2, val); } } + + // --- 2. LEFT EXTENSION --- + int imgRight = x + imgWidth; // x is the left margin/offset + // If the current pixel is within the leftmost 'extendX' pixels of the image + if (screenX >= x && screenX < x + extendX) { + int numIterations = (x / extendX) + 1; + for (int nx = 0; nx < numIterations; nx++) { + // Mirror Fold (pixel at 'x' maps to 'x-1') + int t1 = x - 1 - (2 * nx * extendX + (screenX - x)); + // Reverse Fold + int t2 = x - 1 - (2 * nx * extendX + (2 * extendX - 1 - (screenX - x))); + + if (t1 >= 0 && t1 < x) drawVal(t1, screenY, val); + if (t2 >= 0 && t2 < x) drawVal(t2, screenY, val); + } + } + + // --- 3. RIGHT EXTENSION --- + int gapRight = getScreenWidth() - imgRight; + // If the current pixel is within the rightmost 'extendX' pixels of the image + if (screenX >= imgRight - extendX && screenX < imgRight) { + int numIterations = (gapRight / extendX) + 1; + for (int nx = 0; nx < numIterations; nx++) { + // Mirror Fold (pixel at 'imgRight-1' maps to 'imgRight') + int t1 = imgRight + (2 * nx * extendX + (imgRight - 1 - screenX)); + // Reverse Fold + int t2 = imgRight + (2 * nx * extendX + (2 * extendX - 1 - (imgRight - 1 - screenX))); + + if (t1 >= imgRight && t1 < getScreenWidth()) drawVal(t1, screenY, val); + if (t2 >= imgRight && t2 < getScreenWidth()) drawVal(t2, screenY, val); + } + } } } } diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index d5f9103..4a03786 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -17,7 +17,7 @@ class CrossPointSettings { // Should match with SettingsActivity text enum SLEEP_SCREEN_MODE { DARK = 0, LIGHT = 1, CUSTOM = 2, COVER = 3, BLANK = 4 }; - enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1 }; + enum SLEEP_SCREEN_COVER_MODE { FIT = 0, CROP = 1, EXTEND = 2 }; // Status bar display type enum enum STATUS_BAR_MODE { NONE = 0, NO_PROGRESS = 1, FULL = 2 }; diff --git a/src/activities/boot_sleep/SleepActivity.cpp b/src/activities/boot_sleep/SleepActivity.cpp index a9de529..6003d47 100644 --- a/src/activities/boot_sleep/SleepActivity.cpp +++ b/src/activities/boot_sleep/SleepActivity.cpp @@ -170,22 +170,23 @@ void SleepActivity::renderBitmapSleepScreen(const Bitmap& bitmap) const { y = (pageHeight - bitmap.getHeight()) / 2; } + bool extended = SETTINGS.sleepScreenCoverMode == CrossPointSettings::SLEEP_SCREEN_COVER_MODE::EXTEND; Serial.printf("[%lu] [SLP] drawing to %d x %d\n", millis(), x, y); renderer.clearScreen(); - renderer.drawBitmap(bitmap, x, y, pageWidth, pageHeight, cropX, cropY, true); + renderer.drawBitmap(bitmap, x, y, pageWidth, pageHeight, cropX, cropY, extended); renderer.displayBuffer(EInkDisplay::HALF_REFRESH); if (bitmap.hasGreyscale()) { bitmap.rewindToData(); renderer.clearScreen(0x00); renderer.setRenderMode(GfxRenderer::GRAYSCALE_LSB); - renderer.drawBitmap(bitmap, x, y, pageWidth, pageHeight, cropX, cropY, true); + renderer.drawBitmap(bitmap, x, y, pageWidth, pageHeight, cropX, cropY, extended); renderer.copyGrayscaleLsbBuffers(); bitmap.rewindToData(); renderer.clearScreen(0x00); renderer.setRenderMode(GfxRenderer::GRAYSCALE_MSB); - renderer.drawBitmap(bitmap, x, y, pageWidth, pageHeight, cropX, cropY, true); + renderer.drawBitmap(bitmap, x, y, pageWidth, pageHeight, cropX, cropY, extended); renderer.copyGrayscaleMsbBuffers(); renderer.displayGrayBuffer(); diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index f22850a..9a9e459 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -17,7 +17,7 @@ constexpr int settingsCount = 19; const SettingInfo settingsList[settingsCount] = { // Should match with SLEEP_SCREEN_MODE SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}), - SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop"}), + SettingInfo::Enum("Sleep Screen Cover Mode", &CrossPointSettings::sleepScreenCoverMode, {"Fit", "Crop", "Extend"}), SettingInfo::Enum("Status Bar", &CrossPointSettings::statusBar, {"None", "No Progress", "Full"}), SettingInfo::Enum("Hide Battery %", &CrossPointSettings::hideBatteryPercentage, {"Never", "In Reader", "Always"}), SettingInfo::Toggle("Extra Paragraph Spacing", &CrossPointSettings::extraParagraphSpacing),