From 1f59f288afbf4d5667640e1e64a518fac8500e51 Mon Sep 17 00:00:00 2001 From: Dave Allie Date: Sun, 28 Dec 2025 21:16:28 +1100 Subject: [PATCH] Standardize screen offsets in all orientations --- lib/GfxRenderer/GfxRenderer.cpp | 29 ++++++++++ lib/GfxRenderer/GfxRenderer.h | 6 +++ src/activities/reader/EpubReaderActivity.cpp | 56 +++++++++++--------- src/activities/reader/EpubReaderActivity.h | 5 +- 4 files changed, 70 insertions(+), 26 deletions(-) diff --git a/lib/GfxRenderer/GfxRenderer.cpp b/lib/GfxRenderer/GfxRenderer.cpp index 725c435..c9a2554 100644 --- a/lib/GfxRenderer/GfxRenderer.cpp +++ b/lib/GfxRenderer/GfxRenderer.cpp @@ -476,3 +476,32 @@ void GfxRenderer::renderChar(const EpdFontFamily& fontFamily, const uint32_t cp, *x += glyph->advanceX; } + +void GfxRenderer::getOrientedViewableTRBL(int* outTop, int* outRight, int* outBottom, int* outLeft) const { + switch (orientation) { + case Portrait: + *outTop = VIEWABLE_MARGIN_TOP; + *outRight = VIEWABLE_MARGIN_RIGHT; + *outBottom = VIEWABLE_MARGIN_BOTTOM; + *outLeft = VIEWABLE_MARGIN_LEFT; + break; + case LandscapeClockwise: + *outTop = VIEWABLE_MARGIN_LEFT; + *outRight = VIEWABLE_MARGIN_TOP; + *outBottom = VIEWABLE_MARGIN_RIGHT; + *outLeft = VIEWABLE_MARGIN_BOTTOM; + break; + case PortraitInverted: + *outTop = VIEWABLE_MARGIN_BOTTOM; + *outRight = VIEWABLE_MARGIN_LEFT; + *outBottom = VIEWABLE_MARGIN_TOP; + *outLeft = VIEWABLE_MARGIN_RIGHT; + break; + case LandscapeCounterClockwise: + *outTop = VIEWABLE_MARGIN_RIGHT; + *outRight = VIEWABLE_MARGIN_BOTTOM; + *outBottom = VIEWABLE_MARGIN_LEFT; + *outLeft = VIEWABLE_MARGIN_TOP; + break; + } +} diff --git a/lib/GfxRenderer/GfxRenderer.h b/lib/GfxRenderer/GfxRenderer.h index 8199fbf..3ba69e8 100644 --- a/lib/GfxRenderer/GfxRenderer.h +++ b/lib/GfxRenderer/GfxRenderer.h @@ -42,6 +42,11 @@ class GfxRenderer { explicit GfxRenderer(EInkDisplay& einkDisplay) : einkDisplay(einkDisplay), renderMode(BW) {} ~GfxRenderer() = default; + static constexpr int VIEWABLE_MARGIN_TOP = 9; + static constexpr int VIEWABLE_MARGIN_RIGHT = 3; + static constexpr int VIEWABLE_MARGIN_BOTTOM = 3; + static constexpr int VIEWABLE_MARGIN_LEFT = 3; + // Setup void insertFont(int fontId, EpdFontFamily font); @@ -88,4 +93,5 @@ class GfxRenderer { uint8_t* getFrameBuffer() const; static size_t getBufferSize(); void grayscaleRevert() const; + void getOrientedViewableTRBL(int* outTop, int* outRight, int* outBottom, int* outLeft) const; }; diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index efc18e0..f0eed25 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -16,10 +16,8 @@ constexpr int pagesPerRefresh = 15; constexpr unsigned long skipChapterMs = 700; constexpr unsigned long goHomeMs = 1000; constexpr float lineCompression = 0.95f; -constexpr int marginTop = 8; -constexpr int marginRight = 10; -constexpr int marginBottom = 22; -constexpr int marginLeft = 10; +constexpr int horizontalPadding = 5; +constexpr int statusBarMargin = 19; } // namespace void EpubReaderActivity::taskTrampoline(void* param) { @@ -240,13 +238,21 @@ void EpubReaderActivity::renderScreen() { return; } + // Apply screen viewable areas and additional padding + int orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft; + renderer.getOrientedViewableTRBL(&orientedMarginTop, &orientedMarginRight, &orientedMarginBottom, + &orientedMarginLeft); + orientedMarginLeft += horizontalPadding; + orientedMarginRight += horizontalPadding; + orientedMarginBottom += statusBarMargin; + if (!section) { const auto filepath = epub->getSpineItem(currentSpineIndex).href; Serial.printf("[%lu] [ERS] Loading file: %s, index: %d\n", millis(), filepath.c_str(), currentSpineIndex); section = std::unique_ptr
(new Section(epub, currentSpineIndex, renderer)); - const auto viewportWidth = renderer.getScreenWidth() - marginLeft - marginRight; - const auto viewportHeight = renderer.getScreenHeight() - marginTop - marginBottom; + const auto viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight; + const auto viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom; if (!section->loadCacheMetadata(READER_FONT_ID, lineCompression, SETTINGS.extraParagraphSpacing, viewportWidth, viewportHeight)) { @@ -279,8 +285,7 @@ void EpubReaderActivity::renderScreen() { section->setupCacheDir(); // Setup callback - only called for chapters >= 50KB, redraws with progress bar - auto progressSetup = [this, boxXWithBar, boxWidthWithBar, boxHeightWithBar, boxMargin, barX, barY, barWidth, - barHeight]() { + auto progressSetup = [this, boxXWithBar, boxWidthWithBar, boxHeightWithBar, barX, barY] { renderer.fillRect(boxXWithBar, boxY, boxWidthWithBar, boxHeightWithBar, false); renderer.drawText(READER_FONT_ID, boxXWithBar + boxMargin, boxY + boxMargin, "Indexing..."); renderer.drawRect(boxXWithBar + 5, boxY + 5, boxWidthWithBar - 10, boxHeightWithBar - 10); @@ -317,7 +322,7 @@ void EpubReaderActivity::renderScreen() { if (section->pageCount == 0) { Serial.printf("[%lu] [ERS] No pages to render\n", millis()); renderer.drawCenteredText(READER_FONT_ID, 300, "Empty chapter", true, BOLD); - renderStatusBar(); + renderStatusBar(orientedMarginRight, orientedMarginBottom, orientedMarginLeft); renderer.displayBuffer(); return; } @@ -325,7 +330,7 @@ void EpubReaderActivity::renderScreen() { if (section->currentPage < 0 || section->currentPage >= section->pageCount) { Serial.printf("[%lu] [ERS] Page out of bounds: %d (max %d)\n", millis(), section->currentPage, section->pageCount); renderer.drawCenteredText(READER_FONT_ID, 300, "Out of bounds", true, BOLD); - renderStatusBar(); + renderStatusBar(orientedMarginRight, orientedMarginBottom, orientedMarginLeft); renderer.displayBuffer(); return; } @@ -339,7 +344,7 @@ void EpubReaderActivity::renderScreen() { return renderScreen(); } const auto start = millis(); - renderContents(std::move(p)); + renderContents(std::move(p), orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft); Serial.printf("[%lu] [ERS] Rendered page in %dms\n", millis(), millis() - start); } @@ -355,9 +360,11 @@ void EpubReaderActivity::renderScreen() { } } -void EpubReaderActivity::renderContents(std::unique_ptr page) { - page->render(renderer, READER_FONT_ID, marginLeft, marginTop); - renderStatusBar(); +void EpubReaderActivity::renderContents(std::unique_ptr page, const int orientedMarginTop, + const int orientedMarginRight, const int orientedMarginBottom, + const int orientedMarginLeft) { + page->render(renderer, READER_FONT_ID, orientedMarginLeft, orientedMarginTop); + renderStatusBar(orientedMarginRight, orientedMarginBottom, orientedMarginLeft); if (pagesUntilFullRefresh <= 1) { renderer.displayBuffer(EInkDisplay::HALF_REFRESH); pagesUntilFullRefresh = pagesPerRefresh; @@ -374,13 +381,13 @@ void EpubReaderActivity::renderContents(std::unique_ptr page) { { renderer.clearScreen(0x00); renderer.setRenderMode(GfxRenderer::GRAYSCALE_LSB); - page->render(renderer, READER_FONT_ID, marginLeft, marginTop); + page->render(renderer, READER_FONT_ID, orientedMarginLeft, orientedMarginTop); renderer.copyGrayscaleLsbBuffers(); // Render and copy to MSB buffer renderer.clearScreen(0x00); renderer.setRenderMode(GfxRenderer::GRAYSCALE_MSB); - page->render(renderer, READER_FONT_ID, marginLeft, marginTop); + page->render(renderer, READER_FONT_ID, orientedMarginLeft, orientedMarginTop); renderer.copyGrayscaleMsbBuffers(); // display grayscale part @@ -392,7 +399,8 @@ void EpubReaderActivity::renderContents(std::unique_ptr page) { renderer.restoreBwBuffer(); } -void EpubReaderActivity::renderStatusBar() const { +void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const int orientedMarginBottom, + const int orientedMarginLeft) const { // determine visible status bar elements const bool showProgress = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::FULL; const bool showBattery = SETTINGS.statusBar == CrossPointSettings::STATUS_BAR_MODE::NO_PROGRESS || @@ -402,7 +410,7 @@ void EpubReaderActivity::renderStatusBar() const { // Position status bar near the bottom of the logical screen, regardless of orientation const auto screenHeight = renderer.getScreenHeight(); - const auto textY = screenHeight - 24; + const auto textY = screenHeight - orientedMarginBottom - 2; int percentageTextWidth = 0; int progressTextWidth = 0; @@ -415,7 +423,7 @@ void EpubReaderActivity::renderStatusBar() const { const std::string progress = std::to_string(section->currentPage + 1) + "/" + std::to_string(section->pageCount) + " " + std::to_string(bookProgress) + "%"; progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str()); - renderer.drawText(SMALL_FONT_ID, renderer.getScreenWidth() - marginRight - progressTextWidth, textY, + renderer.drawText(SMALL_FONT_ID, renderer.getScreenWidth() - orientedMarginRight - progressTextWidth, textY, progress.c_str()); } @@ -424,13 +432,13 @@ void EpubReaderActivity::renderStatusBar() const { const uint16_t percentage = battery.readPercentage(); const auto percentageText = std::to_string(percentage) + "%"; percentageTextWidth = renderer.getTextWidth(SMALL_FONT_ID, percentageText.c_str()); - renderer.drawText(SMALL_FONT_ID, 20 + marginLeft, textY, percentageText.c_str()); + renderer.drawText(SMALL_FONT_ID, 20 + orientedMarginLeft, textY, percentageText.c_str()); // 1 column on left, 2 columns on right, 5 columns of battery body constexpr int batteryWidth = 15; constexpr int batteryHeight = 10; - constexpr int x = marginLeft; - const int y = screenHeight - 17; + const int x = orientedMarginLeft; + const int y = screenHeight - orientedMarginBottom + 5; // Top line renderer.drawLine(x, y, x + batteryWidth - 4, y); @@ -455,8 +463,8 @@ void EpubReaderActivity::renderStatusBar() const { if (showChapterTitle) { // Centered chatper title text // Page width minus existing content with 30px padding on each side - const int titleMarginLeft = 20 + percentageTextWidth + 30 + marginLeft; - const int titleMarginRight = progressTextWidth + 30 + marginRight; + const int titleMarginLeft = 20 + percentageTextWidth + 30 + orientedMarginLeft; + const int titleMarginRight = progressTextWidth + 30 + orientedMarginRight; const int availableTextWidth = renderer.getScreenWidth() - titleMarginLeft - titleMarginRight; const int tocIndex = epub->getTocIndexForSpineIndex(currentSpineIndex); diff --git a/src/activities/reader/EpubReaderActivity.h b/src/activities/reader/EpubReaderActivity.h index 143f56b..f1abc92 100644 --- a/src/activities/reader/EpubReaderActivity.h +++ b/src/activities/reader/EpubReaderActivity.h @@ -22,8 +22,9 @@ class EpubReaderActivity final : public ActivityWithSubactivity { static void taskTrampoline(void* param); [[noreturn]] void displayTaskLoop(); void renderScreen(); - void renderContents(std::unique_ptr p); - void renderStatusBar() const; + void renderContents(std::unique_ptr page, int orientedMarginTop, int orientedMarginRight, + int orientedMarginBottom, int orientedMarginLeft); + void renderStatusBar(int orientedMarginRight, int orientedMarginBottom, int orientedMarginLeft) const; public: explicit EpubReaderActivity(GfxRenderer& renderer, InputManager& inputManager, std::unique_ptr epub,