mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2025-12-18 15:17:42 +03:00
Add UI font
This commit is contained in:
parent
248af4b8fb
commit
7198d943b0
1934
lib/EpdFont/builtinFonts/ubuntu_10.h
Normal file
1934
lib/EpdFont/builtinFonts/ubuntu_10.h
Normal file
File diff suppressed because it is too large
Load Diff
2120
lib/EpdFont/builtinFonts/ubuntu_bold_10.h
Normal file
2120
lib/EpdFont/builtinFonts/ubuntu_bold_10.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,15 +5,18 @@
|
|||||||
#include "builtinFonts/bookerly_bold.h"
|
#include "builtinFonts/bookerly_bold.h"
|
||||||
#include "builtinFonts/bookerly_bold_italic.h"
|
#include "builtinFonts/bookerly_bold_italic.h"
|
||||||
#include "builtinFonts/bookerly_italic.h"
|
#include "builtinFonts/bookerly_italic.h"
|
||||||
|
#include "builtinFonts/ubuntu_10.h"
|
||||||
|
#include "builtinFonts/ubuntu_bold_10.h"
|
||||||
|
|
||||||
EpdRenderer::EpdRenderer(XteinkDisplay* display) {
|
EpdRenderer::EpdRenderer(XteinkDisplay* display) {
|
||||||
const auto bookerlyFontFamily = new EpdFontFamily(new EpdFont(&bookerly), new EpdFont(&bookerly_bold),
|
const auto bookerlyFontFamily = new EpdFontFamily(new EpdFont(&bookerly), new EpdFont(&bookerly_bold),
|
||||||
new EpdFont(&bookerly_italic), new EpdFont(&bookerly_bold_italic));
|
new EpdFont(&bookerly_italic), new EpdFont(&bookerly_bold_italic));
|
||||||
const auto babyblueFontFamily = new EpdFontFamily(new EpdFont(&babyblue));
|
const auto ubuntuFontFamily = new EpdFontFamily(new EpdFont(&ubuntu_10), new EpdFont(&ubuntu_bold_10));
|
||||||
|
|
||||||
this->display = display;
|
this->display = display;
|
||||||
this->regularFontRenderer = new EpdFontRenderer<XteinkDisplay>(bookerlyFontFamily, display);
|
this->regularFontRenderer = new EpdFontRenderer<XteinkDisplay>(bookerlyFontFamily, display);
|
||||||
this->smallFontRenderer = new EpdFontRenderer<XteinkDisplay>(babyblueFontFamily, display);
|
this->smallFontRenderer = new EpdFontRenderer<XteinkDisplay>(new EpdFontFamily(new EpdFont(&babyblue)), display);
|
||||||
|
this->uiFontRenderer = new EpdFontRenderer<XteinkDisplay>(ubuntuFontFamily, display);
|
||||||
|
|
||||||
this->marginTop = 11;
|
this->marginTop = 11;
|
||||||
this->marginBottom = 30;
|
this->marginBottom = 30;
|
||||||
@ -30,6 +33,14 @@ int EpdRenderer::getTextWidth(const char* text, const EpdFontStyle style) const
|
|||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EpdRenderer::getUiTextWidth(const char* text, const EpdFontStyle style) const {
|
||||||
|
int w = 0, h = 0;
|
||||||
|
|
||||||
|
uiFontRenderer->fontFamily->getTextDimensions(text, &w, &h, style);
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
int EpdRenderer::getSmallTextWidth(const char* text, const EpdFontStyle style) const {
|
int EpdRenderer::getSmallTextWidth(const char* text, const EpdFontStyle style) const {
|
||||||
int w = 0, h = 0;
|
int w = 0, h = 0;
|
||||||
|
|
||||||
@ -45,11 +56,18 @@ void EpdRenderer::drawText(const int x, const int y, const char* text, const uin
|
|||||||
regularFontRenderer->renderString(text, &xpos, &ypos, color > 0 ? GxEPD_BLACK : GxEPD_WHITE, style);
|
regularFontRenderer->renderString(text, &xpos, &ypos, color > 0 ? GxEPD_BLACK : GxEPD_WHITE, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EpdRenderer::drawUiText(const int x, const int y, const char* text, const uint16_t color,
|
||||||
|
const EpdFontStyle style) const {
|
||||||
|
int ypos = y + uiFontRenderer->fontFamily->getData(style)->advanceY + marginTop;
|
||||||
|
int xpos = x + marginLeft;
|
||||||
|
uiFontRenderer->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,
|
void EpdRenderer::drawSmallText(const int x, const int y, const char* text, const uint16_t color,
|
||||||
const EpdFontStyle style) const {
|
const EpdFontStyle style) const {
|
||||||
int ypos = y + smallFontRenderer->fontFamily->getData(style)->advanceY + marginTop;
|
int ypos = y + smallFontRenderer->fontFamily->getData(style)->advanceY + marginTop;
|
||||||
int xpos = x + marginLeft;
|
int xpos = x + marginLeft;
|
||||||
smallFontRenderer->renderString(text, &xpos, &ypos, color > 0 ? GxEPD_BLACK : GxEPD_WHITE);
|
smallFontRenderer->renderString(text, &xpos, &ypos, color > 0 ? GxEPD_BLACK : GxEPD_WHITE, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EpdRenderer::drawTextBox(const int x, const int y, const std::string& text, const int width, const int height,
|
void EpdRenderer::drawTextBox(const int x, const int y, const std::string& text, const int width, const int height,
|
||||||
|
|||||||
@ -10,6 +10,7 @@ class EpdRenderer {
|
|||||||
XteinkDisplay* display;
|
XteinkDisplay* display;
|
||||||
EpdFontRenderer<XteinkDisplay>* regularFontRenderer;
|
EpdFontRenderer<XteinkDisplay>* regularFontRenderer;
|
||||||
EpdFontRenderer<XteinkDisplay>* smallFontRenderer;
|
EpdFontRenderer<XteinkDisplay>* smallFontRenderer;
|
||||||
|
EpdFontRenderer<XteinkDisplay>* uiFontRenderer;
|
||||||
int marginTop;
|
int marginTop;
|
||||||
int marginBottom;
|
int marginBottom;
|
||||||
int marginLeft;
|
int marginLeft;
|
||||||
@ -20,8 +21,10 @@ class EpdRenderer {
|
|||||||
explicit EpdRenderer(XteinkDisplay* display);
|
explicit EpdRenderer(XteinkDisplay* display);
|
||||||
~EpdRenderer() = default;
|
~EpdRenderer() = default;
|
||||||
int getTextWidth(const char* text, EpdFontStyle style = REGULAR) const;
|
int getTextWidth(const char* text, EpdFontStyle style = REGULAR) const;
|
||||||
|
int getUiTextWidth(const char* text, EpdFontStyle style = REGULAR) const;
|
||||||
int getSmallTextWidth(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 drawText(int x, int y, const char* text, uint16_t color = 1, EpdFontStyle style = REGULAR) const;
|
||||||
|
void drawUiText(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 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 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 drawLine(int x1, int y1, int x2, int y2, uint16_t color = 1) const;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
22
src/main.cpp
22
src/main.cpp
@ -55,11 +55,14 @@ Epub* loadEpub(const std::string& path) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void enterNewScreen(Screen* screen) {
|
void exitScreen() {
|
||||||
if (currentScreen) {
|
if (currentScreen) {
|
||||||
currentScreen->onExit();
|
currentScreen->onExit();
|
||||||
delete currentScreen;
|
delete currentScreen;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void enterNewScreen(Screen* screen) {
|
||||||
currentScreen = screen;
|
currentScreen = screen;
|
||||||
currentScreen->onEnter();
|
currentScreen->onEnter();
|
||||||
}
|
}
|
||||||
@ -90,7 +93,8 @@ void waitForNoButton() {
|
|||||||
|
|
||||||
// Enter deep sleep mode
|
// Enter deep sleep mode
|
||||||
void enterDeepSleep() {
|
void enterDeepSleep() {
|
||||||
enterNewScreen(new FullScreenMessageScreen(renderer, "Sleeping", BOLD, true));
|
exitScreen();
|
||||||
|
enterNewScreen(new FullScreenMessageScreen(renderer, "Sleeping", BOLD, true, false));
|
||||||
|
|
||||||
Serial.println("Power button released after a long press. Entering deep sleep.");
|
Serial.println("Power button released after a long press. Entering deep sleep.");
|
||||||
delay(1000); // Allow Serial buffer to empty and display to update
|
delay(1000); // Allow Serial buffer to empty and display to update
|
||||||
@ -106,18 +110,25 @@ void enterDeepSleep() {
|
|||||||
|
|
||||||
void onGoHome();
|
void onGoHome();
|
||||||
void onSelectEpubFile(const std::string& path) {
|
void onSelectEpubFile(const std::string& path) {
|
||||||
|
exitScreen();
|
||||||
enterNewScreen(new FullScreenMessageScreen(renderer, "Loading..."));
|
enterNewScreen(new FullScreenMessageScreen(renderer, "Loading..."));
|
||||||
|
|
||||||
Epub* epub = loadEpub(path);
|
Epub* epub = loadEpub(path);
|
||||||
if (epub) {
|
if (epub) {
|
||||||
appState->openEpubPath = path;
|
appState->openEpubPath = path;
|
||||||
appState->saveToFile();
|
appState->saveToFile();
|
||||||
|
exitScreen();
|
||||||
enterNewScreen(new EpubReaderScreen(renderer, epub, onGoHome));
|
enterNewScreen(new EpubReaderScreen(renderer, epub, onGoHome));
|
||||||
} else {
|
} else {
|
||||||
enterNewScreen(new FullScreenMessageScreen(renderer, "Failed to load epub"));
|
exitScreen();
|
||||||
|
enterNewScreen(new FullScreenMessageScreen(renderer, "Failed to load epub", REGULAR, false, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void onGoHome() { enterNewScreen(new FileSelectionScreen(renderer, onSelectEpubFile)); }
|
|
||||||
|
void onGoHome() {
|
||||||
|
exitScreen();
|
||||||
|
enterNewScreen(new FileSelectionScreen(renderer, onSelectEpubFile));
|
||||||
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
setupInputPinModes();
|
setupInputPinModes();
|
||||||
@ -138,6 +149,7 @@ void setup() {
|
|||||||
display.setTextColor(GxEPD_BLACK);
|
display.setTextColor(GxEPD_BLACK);
|
||||||
Serial.println("Display initialized");
|
Serial.println("Display initialized");
|
||||||
|
|
||||||
|
exitScreen();
|
||||||
enterNewScreen(new BootLogoScreen(renderer));
|
enterNewScreen(new BootLogoScreen(renderer));
|
||||||
|
|
||||||
// SD Card Initialization
|
// SD Card Initialization
|
||||||
@ -147,6 +159,7 @@ void setup() {
|
|||||||
if (!appState->openEpubPath.empty()) {
|
if (!appState->openEpubPath.empty()) {
|
||||||
Epub* epub = loadEpub(appState->openEpubPath);
|
Epub* epub = loadEpub(appState->openEpubPath);
|
||||||
if (epub) {
|
if (epub) {
|
||||||
|
exitScreen();
|
||||||
enterNewScreen(new EpubReaderScreen(renderer, epub, onGoHome));
|
enterNewScreen(new EpubReaderScreen(renderer, epub, onGoHome));
|
||||||
// Ensure we're not still holding the power button before leaving setup
|
// Ensure we're not still holding the power button before leaving setup
|
||||||
waitForNoButton();
|
waitForNoButton();
|
||||||
@ -154,6 +167,7 @@ void setup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exitScreen();
|
||||||
enterNewScreen(new FileSelectionScreen(renderer, onSelectEpubFile));
|
enterNewScreen(new FileSelectionScreen(renderer, onSelectEpubFile));
|
||||||
|
|
||||||
// Ensure we're not still holding the power button before leaving setup
|
// Ensure we're not still holding the power button before leaving setup
|
||||||
|
|||||||
@ -10,5 +10,5 @@ void BootLogoScreen::onEnter() {
|
|||||||
|
|
||||||
renderer->clearScreen();
|
renderer->clearScreen();
|
||||||
// Location for images is from top right in landscape orientation
|
// Location for images is from top right in landscape orientation
|
||||||
renderer->drawImage(CrossLarge, (pageHeight - 128) /2, (pageWidth - 128) / 2, 128, 128);
|
renderer->drawImage(CrossLarge, (pageHeight - 128) / 2, (pageWidth - 128) / 2, 128, 128);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
|
|
||||||
|
|
||||||
class BootLogoScreen final : public Screen {
|
class BootLogoScreen final : public Screen {
|
||||||
public:
|
public:
|
||||||
explicit BootLogoScreen(EpdRenderer* renderer): Screen(renderer) {}
|
explicit BootLogoScreen(EpdRenderer* renderer) : Screen(renderer) {}
|
||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -41,10 +41,10 @@ void EpubReaderScreen::onEnter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EpubReaderScreen::onExit() {
|
void EpubReaderScreen::onExit() {
|
||||||
vTaskDelete(displayTaskHandle);
|
|
||||||
displayTaskHandle = nullptr;
|
|
||||||
xSemaphoreTake(sectionMutex, portMAX_DELAY);
|
xSemaphoreTake(sectionMutex, portMAX_DELAY);
|
||||||
|
vTaskDelete(displayTaskHandle);
|
||||||
vSemaphoreDelete(sectionMutex);
|
vSemaphoreDelete(sectionMutex);
|
||||||
|
displayTaskHandle = nullptr;
|
||||||
sectionMutex = nullptr;
|
sectionMutex = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,10 @@ class EpubReaderScreen final : public Screen {
|
|||||||
public:
|
public:
|
||||||
explicit EpubReaderScreen(EpdRenderer* renderer, Epub* epub, const std::function<void()>& onGoHome)
|
explicit EpubReaderScreen(EpdRenderer* renderer, Epub* epub, const std::function<void()>& onGoHome)
|
||||||
: Screen(renderer), epub(epub), onGoHome(onGoHome) {}
|
: Screen(renderer), epub(epub), onGoHome(onGoHome) {}
|
||||||
~EpubReaderScreen() override { free(section); }
|
~EpubReaderScreen() override {
|
||||||
|
free(section);
|
||||||
|
free(epub);
|
||||||
|
}
|
||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
void onExit() override;
|
void onExit() override;
|
||||||
void handleInput(Input input) override;
|
void handleInput(Input input) override;
|
||||||
|
|||||||
@ -95,14 +95,14 @@ void FileSelectionScreen::render() const {
|
|||||||
renderer->drawText((pageWidth - titleWidth) / 2, 0, "CrossPoint Reader", 1, BOLD);
|
renderer->drawText((pageWidth - titleWidth) / 2, 0, "CrossPoint Reader", 1, BOLD);
|
||||||
|
|
||||||
if (files.empty()) {
|
if (files.empty()) {
|
||||||
renderer->drawSmallText(50, 50, "No EPUBs found");
|
renderer->drawUiText(10, 50, "No EPUBs found");
|
||||||
} else {
|
} else {
|
||||||
// Draw selection
|
// Draw selection
|
||||||
renderer->fillRect(0, 50 + selectorIndex * 20 + 2, pageWidth - 1, 20);
|
renderer->fillRect(0, 50 + selectorIndex * 30 + 2, pageWidth - 1, 30);
|
||||||
|
|
||||||
for (size_t i = 0; i < files.size(); i++) {
|
for (size_t i = 0; i < files.size(); i++) {
|
||||||
const auto file = files[i];
|
const auto file = files[i];
|
||||||
renderer->drawSmallText(50, 50 + i * 20, file.c_str(), i == selectorIndex ? 0 : 1);
|
renderer->drawUiText(10, 50 + i * 30, file.c_str(), i == selectorIndex ? 0 : 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,13 +3,12 @@
|
|||||||
#include <EpdRenderer.h>
|
#include <EpdRenderer.h>
|
||||||
|
|
||||||
void FullScreenMessageScreen::onEnter() {
|
void FullScreenMessageScreen::onEnter() {
|
||||||
const auto width = renderer->getTextWidth(text.c_str(), style);
|
const auto width = renderer->getUiTextWidth(text.c_str(), style);
|
||||||
const auto height = renderer->getLineHeight();
|
const auto height = renderer->getLineHeight();
|
||||||
const auto left = (renderer->getPageWidth() - width) / 2;
|
const auto left = (renderer->getPageWidth() - width) / 2;
|
||||||
const auto top = (renderer->getPageHeight() - height) / 2;
|
const auto top = (renderer->getPageHeight() - height) / 2;
|
||||||
|
|
||||||
renderer->clearScreen(invert);
|
renderer->clearScreen(invert);
|
||||||
renderer->drawText(left, top, text.c_str(), invert ? 0 : 1, style);
|
renderer->drawUiText(left, top, text.c_str(), invert ? 0 : 1, style);
|
||||||
// If inverted, do a full screen update to ensure no ghosting
|
renderer->flushDisplay(partialUpdate);
|
||||||
renderer->flushDisplay(!invert);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,10 +9,11 @@ class FullScreenMessageScreen final : public Screen {
|
|||||||
std::string text;
|
std::string text;
|
||||||
EpdFontStyle style;
|
EpdFontStyle style;
|
||||||
bool invert;
|
bool invert;
|
||||||
|
bool partialUpdate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FullScreenMessageScreen(EpdRenderer* renderer, std::string text, const EpdFontStyle style = REGULAR,
|
explicit FullScreenMessageScreen(EpdRenderer* renderer, std::string text, const EpdFontStyle style = REGULAR,
|
||||||
const bool invert = false)
|
const bool invert = false, const bool partialUpdate = true)
|
||||||
: Screen(renderer), text(std::move(text)), style(style), invert(invert) {}
|
: Screen(renderer), text(std::move(text)), style(style), invert(invert), partialUpdate(partialUpdate) {}
|
||||||
void onEnter() override;
|
void onEnter() override;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user