From 05a027e2bf0e59b0db8ac2bc8ac4d8518cced06e Mon Sep 17 00:00:00 2001 From: Dave Allie Date: Sat, 6 Dec 2025 00:34:16 +1100 Subject: [PATCH] Wrap up multiple font styles into EpdFontFamily --- lib/EpdFont/EpdFontFamily.cpp | 37 ++++++++++ lib/EpdFont/EpdFontFamily.h | 24 +++++++ lib/EpdFontRenderer/EpdFontRenderer.hpp | 41 +++++------ lib/EpdRenderer/EpdRenderer.cpp | 96 +++++++++++-------------- lib/EpdRenderer/EpdRenderer.h | 36 ++++------ lib/Epub/Epub/Section.cpp | 8 +-- lib/Epub/Epub/blocks/TextBlock.cpp | 25 ++++++- src/main.cpp | 4 +- src/screens/EpubReaderScreen.cpp | 20 +++--- src/screens/FileSelectionScreen.cpp | 6 +- src/screens/FileSelectionScreen.h | 2 +- src/screens/FullScreenMessageScreen.cpp | 4 +- src/screens/FullScreenMessageScreen.h | 10 +-- 13 files changed, 184 insertions(+), 129 deletions(-) create mode 100644 lib/EpdFont/EpdFontFamily.cpp create mode 100644 lib/EpdFont/EpdFontFamily.h diff --git a/lib/EpdFont/EpdFontFamily.cpp b/lib/EpdFont/EpdFontFamily.cpp new file mode 100644 index 0000000..e70f8a6 --- /dev/null +++ b/lib/EpdFont/EpdFontFamily.cpp @@ -0,0 +1,37 @@ +#include "EpdFontFamily.h" + +const EpdFont* EpdFontFamily::getFont(const EpdFontStyle style) const { + if (style == BOLD && bold) { + return bold; + } + if (style == ITALIC && italic) { + return italic; + } + if (style == BOLD_ITALIC) { + if (boldItalic) { + return boldItalic; + } + if (bold) { + return bold; + } + if (italic) { + return italic; + } + } + + return regular; +} + +void EpdFontFamily::getTextDimensions(const char* string, int* w, int* h, const EpdFontStyle style) const { + getFont(style)->getTextDimensions(string, w, h); +} + +bool EpdFontFamily::hasPrintableChars(const char* string, const EpdFontStyle style) const { + return getFont(style)->hasPrintableChars(string); +} + +const EpdFontData* EpdFontFamily::getData(const EpdFontStyle style) const { return getFont(style)->data; } + +const EpdGlyph* EpdFontFamily::getGlyph(const uint32_t cp, const EpdFontStyle style) const { + return getFont(style)->getGlyph(cp); +}; diff --git a/lib/EpdFont/EpdFontFamily.h b/lib/EpdFont/EpdFontFamily.h new file mode 100644 index 0000000..dbf8ccd --- /dev/null +++ b/lib/EpdFont/EpdFontFamily.h @@ -0,0 +1,24 @@ +#pragma once +#include "EpdFont.h" + +enum EpdFontStyle { REGULAR, BOLD, ITALIC, BOLD_ITALIC }; + +class EpdFontFamily { + const EpdFont* regular; + const EpdFont* bold; + const EpdFont* italic; + const EpdFont* boldItalic; + + const EpdFont* getFont(EpdFontStyle style) const; + + public: + explicit EpdFontFamily(const EpdFont* regular, const EpdFont* bold = nullptr, const EpdFont* italic = nullptr, + const EpdFont* boldItalic = nullptr) + : regular(regular), bold(bold), italic(italic), boldItalic(boldItalic) {} + ~EpdFontFamily() = default; + void getTextDimensions(const char* string, int* w, int* h, EpdFontStyle style = REGULAR) const; + bool hasPrintableChars(const char* string, EpdFontStyle style = REGULAR) const; + + const EpdFontData* getData(EpdFontStyle style = REGULAR) const; + const EpdGlyph* getGlyph(uint32_t cp, EpdFontStyle style = REGULAR) const; +}; diff --git a/lib/EpdFontRenderer/EpdFontRenderer.hpp b/lib/EpdFontRenderer/EpdFontRenderer.hpp index 647ab7c..127c728 100644 --- a/lib/EpdFontRenderer/EpdFontRenderer.hpp +++ b/lib/EpdFontRenderer/EpdFontRenderer.hpp @@ -1,5 +1,5 @@ #pragma once -#include +#include #include #include #include @@ -12,13 +12,14 @@ static tinfl_decompressor decomp; template class EpdFontRenderer { Renderable* renderer; - void renderChar(uint32_t cp, int* x, const int* y, uint16_t color); + void renderChar(uint32_t cp, int* x, const int* y, uint16_t color, EpdFontStyle style = REGULAR); public: - const EpdFont* font; - explicit EpdFontRenderer(const EpdFont* font, Renderable* renderer); + const EpdFontFamily* fontFamily; + explicit EpdFontRenderer(const EpdFontFamily* fontFamily, Renderable* renderer) + : fontFamily(fontFamily), renderer(renderer) {} ~EpdFontRenderer() = default; - void renderString(const char* string, int* x, int* y, uint16_t color); + void renderString(const char* string, int* x, int* y, uint16_t color, EpdFontStyle style = REGULAR); }; inline int uncompress(uint8_t* dest, size_t uncompressedSize, const uint8_t* source, size_t sourceSize) { @@ -38,37 +39,33 @@ inline int uncompress(uint8_t* dest, size_t uncompressedSize, const uint8_t* sou } template -EpdFontRenderer::EpdFontRenderer(const EpdFont* font, Renderable* renderer) { - this->font = font; - this->renderer = renderer; -} - -template -void EpdFontRenderer::renderString(const char* string, int* x, int* y, const uint16_t color) { +void EpdFontRenderer::renderString(const char* string, int* x, int* y, const uint16_t color, + const EpdFontStyle style) { // cannot draw a NULL / empty string if (string == nullptr || *string == '\0') { return; } // no printable characters - if (!font->hasPrintableChars(string)) { + if (!fontFamily->hasPrintableChars(string, style)) { return; } uint32_t cp; while ((cp = utf8NextCodepoint(reinterpret_cast(&string)))) { - renderChar(cp, x, y, color); + renderChar(cp, x, y, color, style); } - *y += font->data->advanceY; + *y += fontFamily->getData(style)->advanceY; } template -void EpdFontRenderer::renderChar(const uint32_t cp, int* x, const int* y, uint16_t color) { - const EpdGlyph* glyph = font->getGlyph(cp); +void EpdFontRenderer::renderChar(const uint32_t cp, int* x, const int* y, uint16_t color, + const EpdFontStyle style) { + const EpdGlyph* glyph = fontFamily->getGlyph(cp, style); if (!glyph) { // TODO: Replace with fallback glyph property? - glyph = font->getGlyph('?'); + glyph = fontFamily->getGlyph('?', style); } // no glyph? @@ -86,17 +83,17 @@ void EpdFontRenderer::renderChar(const uint32_t cp, int* x, const in const unsigned long bitmapSize = byteWidth * height; const uint8_t* bitmap = nullptr; - if (font->data->compressed) { + if (fontFamily->getData(style)->compressed) { auto* tmpBitmap = static_cast(malloc(bitmapSize)); if (tmpBitmap == nullptr && bitmapSize) { Serial.println("Failed to allocate memory for decompression buffer"); return; } - uncompress(tmpBitmap, bitmapSize, &font->data->bitmap[offset], glyph->compressedSize); + uncompress(tmpBitmap, bitmapSize, &fontFamily->getData(style)->bitmap[offset], glyph->compressedSize); bitmap = tmpBitmap; } else { - bitmap = &font->data->bitmap[offset]; + bitmap = &fontFamily->getData(style)->bitmap[offset]; } if (bitmap != nullptr) { @@ -123,7 +120,7 @@ void EpdFontRenderer::renderChar(const uint32_t cp, int* x, const in } } - if (font->data->compressed) { + if (fontFamily->getData(style)->compressed) { free(const_cast(bitmap)); } } diff --git a/lib/EpdRenderer/EpdRenderer.cpp b/lib/EpdRenderer/EpdRenderer.cpp index 455d367..5ff5ed1 100644 --- a/lib/EpdRenderer/EpdRenderer.cpp +++ b/lib/EpdRenderer/EpdRenderer.cpp @@ -7,12 +7,13 @@ #include "builtinFonts/bookerly_italic.h" EpdRenderer::EpdRenderer(XteinkDisplay* display) { + const auto bookerlyFontFamily = new EpdFontFamily(new EpdFont(&bookerly), new EpdFont(&bookerly_bold), + new EpdFont(&bookerly_italic), new EpdFont(&bookerly_bold_italic)); + const auto babyblueFontFamily = new EpdFontFamily(new EpdFont(&babyblue)); + this->display = display; - this->regularFont = new EpdFontRenderer(new EpdFont(&bookerly), display); - this->boldFont = new EpdFontRenderer(new EpdFont(&bookerly_bold), display); - this->italicFont = new EpdFontRenderer(new EpdFont(&bookerly_italic), display); - this->bold_italicFont = new EpdFontRenderer(new EpdFont(&bookerly_bold_italic), display); - this->smallFont = new EpdFontRenderer(new EpdFont(&babyblue), display); + this->regularFontRenderer = new EpdFontRenderer(bookerlyFontFamily, display); + this->smallFontRenderer = new EpdFontRenderer(babyblueFontFamily, display); this->marginTop = 11; this->marginBottom = 30; @@ -21,50 +22,38 @@ EpdRenderer::EpdRenderer(XteinkDisplay* display) { this->lineCompression = 0.95f; } -EpdFontRenderer* EpdRenderer::getFontRenderer(const bool bold, const bool italic) const { - if (bold && italic) { - return bold_italicFont; - } - if (bold) { - return boldFont; - } - if (italic) { - return italicFont; - } - return regularFont; -} - -int EpdRenderer::getTextWidth(const char* text, const bool bold, const bool italic) const { +int EpdRenderer::getTextWidth(const char* text, const EpdFontStyle style) const { int w = 0, h = 0; - getFontRenderer(bold, italic)->font->getTextDimensions(text, &w, &h); + regularFontRenderer->fontFamily->getTextDimensions(text, &w, &h, style); return w; } -int EpdRenderer::getSmallTextWidth(const char* text) const { +int EpdRenderer::getSmallTextWidth(const char* text, const EpdFontStyle style) const { int w = 0, h = 0; - smallFont->font->getTextDimensions(text, &w, &h); + smallFontRenderer->fontFamily->getTextDimensions(text, &w, &h, style); return w; } -void EpdRenderer::drawText(const int x, const int y, const char* text, const bool bold, const bool italic, - const uint16_t color) const { +void EpdRenderer::drawText(const int x, const int y, const char* text, const uint16_t color, + const EpdFontStyle style) const { int ypos = y + getLineHeight() + marginTop; int xpos = x + marginLeft; - getFontRenderer(bold, italic)->renderString(text, &xpos, &ypos, color > 0 ? GxEPD_BLACK : GxEPD_WHITE); + regularFontRenderer->renderString(text, &xpos, &ypos, color > 0 ? GxEPD_BLACK : GxEPD_WHITE, style); } -void EpdRenderer::drawSmallText(const int x, const int y, const char* text, const uint16_t color) const { - int ypos = y + smallFont->font->data->advanceY + marginTop; +void EpdRenderer::drawSmallText(const int x, const int y, const char* text, const uint16_t color, + const EpdFontStyle style) const { + int ypos = y + smallFontRenderer->fontFamily->getData(style)->advanceY + marginTop; int xpos = x + marginLeft; - smallFont->renderString(text, &xpos, &ypos, color > 0 ? GxEPD_BLACK : GxEPD_WHITE); + smallFontRenderer->renderString(text, &xpos, &ypos, color > 0 ? GxEPD_BLACK : GxEPD_WHITE); } void EpdRenderer::drawTextBox(const int x, const int y, const std::string& text, const int width, const int height, - const bool bold, const bool italic) const { + const EpdFontStyle style) const { const size_t length = text.length(); // fit the text into the box int start = 0; @@ -72,7 +61,7 @@ void EpdRenderer::drawTextBox(const int x, const int y, const std::string& text, int ypos = 0; while (true) { if (end >= length) { - drawText(x, y + ypos, text.substr(start, length - start).c_str(), bold, italic); + drawText(x, y + ypos, text.substr(start, length - start).c_str(), 1, style); break; } @@ -81,15 +70,15 @@ void EpdRenderer::drawTextBox(const int x, const int y, const std::string& text, } if (text[end - 1] == '\n') { - drawText(x, y + ypos, text.substr(start, end - start).c_str(), bold, italic); + drawText(x, y + ypos, text.substr(start, end - start).c_str(), 1, style); ypos += getLineHeight(); start = end; end = start + 1; continue; } - if (getTextWidth(text.substr(start, end - start).c_str(), bold, italic) > width) { - drawText(x, y + ypos, text.substr(start, end - start - 1).c_str(), bold, italic); + if (getTextWidth(text.substr(start, end - start).c_str(), style) > width) { + drawText(x, y + ypos, text.substr(start, end - start - 1).c_str(), 1, style); ypos += getLineHeight(); start = end - 1; continue; @@ -108,11 +97,23 @@ void EpdRenderer::drawRect(const int x, const int y, const int width, const int display->drawRect(x + marginLeft, y + marginTop, width, height, color > 0 ? GxEPD_BLACK : GxEPD_WHITE); } -void EpdRenderer::fillRect(const int x, const int y, const int width, const int height, - const uint16_t color = 0) const { +void EpdRenderer::fillRect(const int x, const int y, const int width, const int height, const uint16_t color) const { display->fillRect(x + marginLeft, y + marginTop, width, height, color > 0 ? GxEPD_BLACK : GxEPD_WHITE); } +void EpdRenderer::drawCircle(const int x, const int y, const int radius, const uint16_t color) const { + display->drawCircle(x + marginLeft, y + marginTop, radius, color > 0 ? GxEPD_BLACK : GxEPD_WHITE); +} + +void EpdRenderer::fillCircle(const int x, const int y, const int radius, const uint16_t color) const { + display->fillCircle(x + marginLeft, y + marginTop, radius, color > 0 ? GxEPD_BLACK : GxEPD_WHITE); +} + +void EpdRenderer::drawImage(const uint8_t bitmap[], const int x, const int y, const int width, const int height, + const bool invert) const { + display->drawImage(bitmap, x + marginLeft, y + marginTop, width, height, invert); +} + void EpdRenderer::clearScreen(const bool black) const { Serial.println("Clearing screen"); display->fillScreen(black ? GxEPD_BLACK : GxEPD_WHITE); @@ -121,30 +122,15 @@ void EpdRenderer::clearScreen(const bool black) const { void EpdRenderer::flushDisplay(const bool partialUpdate) const { display->display(partialUpdate); } void EpdRenderer::flushArea(const int x, const int y, const int width, const int height) const { - display->displayWindow(x, y, width, height); + display->displayWindow(x + marginLeft, y + marginTop, width, height); } int EpdRenderer::getPageWidth() const { return display->width() - marginLeft - marginRight; } int EpdRenderer::getPageHeight() const { return display->height() - marginTop - marginBottom; } -int EpdRenderer::getSpaceWidth() const { return regularFont->font->getGlyph(' ')->advanceX; } +int EpdRenderer::getSpaceWidth() const { return regularFontRenderer->fontFamily->getGlyph(' ', REGULAR)->advanceX; } -int EpdRenderer::getLineHeight() const { return regularFont->font->data->advanceY * lineCompression; } - -// deep sleep helper - persist any state to disk that may be needed on wake -bool EpdRenderer::dehydrate() { - // TODO: Implement - return false; -}; - -// deep sleep helper - retrieve any state from disk after wake -bool EpdRenderer::hydrate() { - // TODO: Implement - return false; -}; - -// really really clear the screen -void EpdRenderer::reset() { - // TODO: Implement -}; +int EpdRenderer::getLineHeight() const { + return regularFontRenderer->fontFamily->getData(REGULAR)->advanceY * lineCompression; +} diff --git a/lib/EpdRenderer/EpdRenderer.h b/lib/EpdRenderer/EpdRenderer.h index 72ee7c3..9c2c06f 100644 --- a/lib/EpdRenderer/EpdRenderer.h +++ b/lib/EpdRenderer/EpdRenderer.h @@ -8,30 +8,28 @@ class EpdRenderer { XteinkDisplay* display; - EpdFontRenderer* regularFont; - EpdFontRenderer* boldFont; - EpdFontRenderer* italicFont; - EpdFontRenderer* bold_italicFont; - EpdFontRenderer* smallFont; + EpdFontRenderer* regularFontRenderer; + EpdFontRenderer* smallFontRenderer; int marginTop; int marginBottom; int marginLeft; int marginRight; float lineCompression; - EpdFontRenderer* getFontRenderer(bool bold, bool italic) const; public: explicit EpdRenderer(XteinkDisplay* display); ~EpdRenderer() = default; - int getTextWidth(const char* text, bool bold = false, bool italic = false) const; - int getSmallTextWidth(const char* text) const; - void drawText(int x, int y, const char* text, bool bold = false, bool italic = false, uint16_t color = 1) const; - void drawSmallText(int x, int y, const char* text, uint16_t color = 1) const; - void drawTextBox(int x, int y, const std::string& text, int width, int height, bool bold = false, - bool italic = false) const; - void drawLine(int x1, int y1, int x2, int y2, uint16_t color) const; - void drawRect(int x, int y, int width, int height, uint16_t color) const; - void fillRect(int x, int y, int width, int height, uint16_t color) const; + int getTextWidth(const char* text, EpdFontStyle style = REGULAR) const; + int getSmallTextWidth(const char* text, EpdFontStyle style = REGULAR) const; + void drawText(int x, int y, const char* text, uint16_t color = 1, EpdFontStyle style = REGULAR) const; + void drawSmallText(int x, int y, const char* text, uint16_t color = 1, EpdFontStyle style = REGULAR) const; + void drawTextBox(int x, int y, const std::string& text, int width, int height, EpdFontStyle style = REGULAR) const; + void drawLine(int x1, int y1, int x2, int y2, uint16_t color = 1) const; + void drawRect(int x, int y, int width, int height, uint16_t color = 1) const; + void fillRect(int x, int y, int width, int height, uint16_t color = 1) const; + void drawCircle(int x, int y, int radius, uint16_t color = 1) const; + void fillCircle(int x, int y, int radius, uint16_t color = 1) const; + void drawImage(const uint8_t bitmap[], int x, int y, int width, int height, bool invert = false) const; void clearScreen(bool black = false) const; void flushDisplay(bool partialUpdate = true) const; void flushArea(int x, int y, int width, int height) const; @@ -45,12 +43,4 @@ class EpdRenderer { void setMarginBottom(const int newMarginBottom) { this->marginBottom = newMarginBottom; } void setMarginLeft(const int newMarginLeft) { this->marginLeft = newMarginLeft; } void setMarginRight(const int newMarginRight) { this->marginRight = newMarginRight; } - // deep sleep helper - persist any state to disk that may be needed on wake - bool dehydrate(); - // deep sleep helper - retrieve any state from disk after wake - bool hydrate(); - // really really clear the screen - void reset(); - - uint8_t temperature = 20; }; diff --git a/lib/Epub/Epub/Section.cpp b/lib/Epub/Epub/Section.cpp index 2c09a19..06f3a5d 100644 --- a/lib/Epub/Epub/Section.cpp +++ b/lib/Epub/Epub/Section.cpp @@ -107,11 +107,11 @@ void Section::renderPage() { delete p; } else if (pageCount == 0) { Serial.println("No pages to render"); - const int width = renderer->getTextWidth("Empty chapter", true); - renderer->drawText((renderer->getPageWidth() - width) / 2, 300, "Empty chapter", true); + const int width = renderer->getTextWidth("Empty chapter", BOLD); + renderer->drawText((renderer->getPageWidth() - width) / 2, 300, "Empty chapter", 1, BOLD); } else { Serial.printf("Page out of bounds: %d (max %d)\n", currentPage, pageCount); - const int width = renderer->getTextWidth("Out of bounds", true); - renderer->drawText((renderer->getPageWidth() - width) / 2, 300, "Out of bounds", true); + const int width = renderer->getTextWidth("Out of bounds", BOLD); + renderer->drawText((renderer->getPageWidth() - width) / 2, 300, "Out of bounds", 1, BOLD); } } diff --git a/lib/Epub/Epub/blocks/TextBlock.cpp b/lib/Epub/Epub/blocks/TextBlock.cpp index 70c9def..1178a92 100644 --- a/lib/Epub/Epub/blocks/TextBlock.cpp +++ b/lib/Epub/Epub/blocks/TextBlock.cpp @@ -56,7 +56,17 @@ std::list TextBlock::splitIntoLines(const EpdRenderer* renderer) { uint16_t wordWidths[totalWordCount]; for (int i = 0; i < words.size(); i++) { // measure the word - const int width = renderer->getTextWidth(words[i].c_str(), wordStyles[i] & BOLD_SPAN, wordStyles[i] & ITALIC_SPAN); + EpdFontStyle fontStyle = REGULAR; + if (wordStyles[i] & BOLD_SPAN) { + if (wordStyles[i] & ITALIC_SPAN) { + fontStyle = BOLD_ITALIC; + } else { + fontStyle = BOLD; + } + } else if (wordStyles[i] & ITALIC_SPAN) { + fontStyle = ITALIC; + } + const int width = renderer->getTextWidth(words[i].c_str(), fontStyle); wordWidths[i] = width; } @@ -182,7 +192,18 @@ void TextBlock::render(const EpdRenderer* renderer, const int x, const int y) co // get the style const uint8_t wordStyle = wordStyles[i]; // render the word - renderer->drawText(x + wordXpos[i], y, words[i].c_str(), wordStyle & BOLD_SPAN, wordStyle & ITALIC_SPAN); + EpdFontStyle fontStyle = REGULAR; + if (wordStyles[i] & BOLD_SPAN) { + if (wordStyles[i] & ITALIC_SPAN) { + fontStyle = BOLD_ITALIC; + } else { + fontStyle = BOLD; + } + + } else if (wordStyles[i] & ITALIC_SPAN) { + fontStyle = ITALIC; + } + renderer->drawText(x + wordXpos[i], y, words[i].c_str(), 1, fontStyle); } } diff --git a/src/main.cpp b/src/main.cpp index 1ad9a17..e9250f0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -89,7 +89,7 @@ void waitForNoButton() { // Enter deep sleep mode void enterDeepSleep() { - enterNewScreen(new FullScreenMessageScreen(renderer, "Sleeping", true, false, true)); + enterNewScreen(new FullScreenMessageScreen(renderer, "Sleeping", BOLD, true)); Serial.println("Power button released after a long press. Entering deep sleep."); delay(1000); // Allow Serial buffer to empty and display to update @@ -137,7 +137,7 @@ void setup() { display.setTextColor(GxEPD_BLACK); Serial.println("Display initialized"); - enterNewScreen(new FullScreenMessageScreen(renderer, "Booting...", true)); + enterNewScreen(new FullScreenMessageScreen(renderer, "Booting...", BOLD)); // SD Card Initialization SD.begin(SD_SPI_CS, SPI, SPI_FQ); diff --git a/src/screens/EpubReaderScreen.cpp b/src/screens/EpubReaderScreen.cpp index 1d818a6..f6969b9 100644 --- a/src/screens/EpubReaderScreen.cpp +++ b/src/screens/EpubReaderScreen.cpp @@ -134,8 +134,8 @@ void EpubReaderScreen::renderPage() { const int h = renderer->getLineHeight() + margin * 2; renderer->fillRect(x, y, w, h, 0); renderer->drawText(x + margin, y + margin, "Indexing..."); - renderer->drawRect(x + 5, y + 5, w - 10, h - 10, 1); - renderer->flushArea(x - 20, y - 20, w + 40, h + 40); + renderer->drawRect(x + 5, y + 5, w - 10, h - 10); + renderer->flushArea(x, y, w, h); } section->setupCacheDir(); @@ -199,23 +199,23 @@ void EpubReaderScreen::renderStatusBar() const { constexpr int y = 772; // Top line - renderer->drawLine(x, y, x + batteryWidth - 4, y, 1); + renderer->drawLine(x, y, x + batteryWidth - 4, y); // Bottom line - renderer->drawLine(x, y + batteryHeight - 1, x + batteryWidth - 4, y + batteryHeight - 1, 1); + renderer->drawLine(x, y + batteryHeight - 1, x + batteryWidth - 4, y + batteryHeight - 1); // Left line - renderer->drawLine(x, y, x, y + batteryHeight - 1, 1); + renderer->drawLine(x, y, x, y + batteryHeight - 1); // Battery end - renderer->drawLine(x + batteryWidth - 4, y, x + batteryWidth - 4, y + batteryHeight - 1, 1); - renderer->drawLine(x + batteryWidth - 3, y + 2, x + batteryWidth - 3, y + batteryHeight - 3, 1); - renderer->drawLine(x + batteryWidth - 2, y + 2, x + batteryWidth - 2, y + batteryHeight - 3, 1); - renderer->drawLine(x + batteryWidth - 1, y + 2, x + batteryWidth - 1, y + batteryHeight - 3, 1); + renderer->drawLine(x + batteryWidth - 4, y, x + batteryWidth - 4, y + batteryHeight - 1); + renderer->drawLine(x + batteryWidth - 3, y + 2, x + batteryWidth - 3, y + batteryHeight - 3); + renderer->drawLine(x + batteryWidth - 2, y + 2, x + batteryWidth - 2, y + batteryHeight - 3); + renderer->drawLine(x + batteryWidth - 1, y + 2, x + batteryWidth - 1, y + batteryHeight - 3); // The +1 is to round up, so that we always fill at least one pixel int filledWidth = percentage * (batteryWidth - 5) / 100 + 1; if (filledWidth > batteryWidth - 5) { filledWidth = batteryWidth - 5; // Ensure we don't overflow } - renderer->fillRect(x + 1, y + 1, filledWidth, batteryHeight - 2, 1); + renderer->fillRect(x + 1, y + 1, filledWidth, batteryHeight - 2); // Page width minus existing content with 30px padding on each side const int leftMargin = 20 + percentageTextWidth + 30; diff --git a/src/screens/FileSelectionScreen.cpp b/src/screens/FileSelectionScreen.cpp index 8a9fad3..2568b7d 100644 --- a/src/screens/FileSelectionScreen.cpp +++ b/src/screens/FileSelectionScreen.cpp @@ -91,14 +91,14 @@ void FileSelectionScreen::render() const { renderer->clearScreen(); const auto pageWidth = renderer->getPageWidth(); - const auto titleWidth = renderer->getTextWidth("CrossPoint Reader", true); - renderer->drawText((pageWidth - titleWidth) / 2, 0, "CrossPoint Reader", true); + const auto titleWidth = renderer->getTextWidth("CrossPoint Reader", BOLD); + renderer->drawText((pageWidth - titleWidth) / 2, 0, "CrossPoint Reader", 1, BOLD); if (files.empty()) { renderer->drawSmallText(50, 50, "No EPUBs found"); } else { // Draw selection - renderer->fillRect(0, 50 + selectorIndex * 20 + 2, pageWidth - 1, 20, 1); + renderer->fillRect(0, 50 + selectorIndex * 20 + 2, pageWidth - 1, 20); for (size_t i = 0; i < files.size(); i++) { const auto file = files[i]; diff --git a/src/screens/FileSelectionScreen.h b/src/screens/FileSelectionScreen.h index c64e423..84a3f80 100644 --- a/src/screens/FileSelectionScreen.h +++ b/src/screens/FileSelectionScreen.h @@ -21,7 +21,7 @@ class FileSelectionScreen final : public Screen { void render() const; void loadFiles(); -public: + public: explicit FileSelectionScreen(EpdRenderer* renderer, const std::function& onSelect) : Screen(renderer), onSelect(onSelect) {} void onEnter() override; diff --git a/src/screens/FullScreenMessageScreen.cpp b/src/screens/FullScreenMessageScreen.cpp index b2d8f90..e11c4a7 100644 --- a/src/screens/FullScreenMessageScreen.cpp +++ b/src/screens/FullScreenMessageScreen.cpp @@ -3,13 +3,13 @@ #include void FullScreenMessageScreen::onEnter() { - const auto width = renderer->getTextWidth(text.c_str(), bold, italic); + const auto width = renderer->getTextWidth(text.c_str(), style); const auto height = renderer->getLineHeight(); const auto left = (renderer->getPageWidth() - width) / 2; const auto top = (renderer->getPageHeight() - height) / 2; renderer->clearScreen(invert); - renderer->drawText(left, top, text.c_str(), bold, italic, invert ? 0 : 1); + renderer->drawText(left, top, text.c_str(), invert ? 0 : 1, style); // If inverted, do a full screen update to ensure no ghosting renderer->flushDisplay(!invert); } diff --git a/src/screens/FullScreenMessageScreen.h b/src/screens/FullScreenMessageScreen.h index a07ac67..fbf3791 100644 --- a/src/screens/FullScreenMessageScreen.h +++ b/src/screens/FullScreenMessageScreen.h @@ -2,17 +2,17 @@ #include #include +#include "EpdFontFamily.h" #include "Screen.h" class FullScreenMessageScreen final : public Screen { std::string text; - bool bold; - bool italic; + EpdFontStyle style; bool invert; public: - explicit FullScreenMessageScreen(EpdRenderer* renderer, std::string text, const bool bold = false, - const bool italic = false, const bool invert = false) - : Screen(renderer), text(std::move(text)), bold(bold), italic(italic), invert(invert) {} + explicit FullScreenMessageScreen(EpdRenderer* renderer, std::string text, const EpdFontStyle style = REGULAR, + const bool invert = false) + : Screen(renderer), text(std::move(text)), style(style), invert(invert) {} void onEnter() override; };