Compare commits

..

1 Commits

Author SHA1 Message Date
Maeve Andrews
4547dacdd9
Merge 4de27a164e into 3ce11f14ce 2026-01-26 21:25:09 +00:00
11 changed files with 14 additions and 45 deletions

1
.gitignore vendored
View File

@ -4,6 +4,5 @@
.vscode
lib/EpdFont/fontsrc
*.generated.h
.vs
build
**/__pycache__/

View File

@ -116,7 +116,6 @@ The Settings screen allows you to configure the device's behavior. There are a f
- Back, Confirm, Left, Right (default)
- Left, Right, Back, Confirm
- Left, Back, Confirm, Right
- Back, Confirm, Right, Left
- **Side Button Layout (reader)**: Swap the order of the up and down volume buttons from Previous/Next to Next/Previous. This change is only in effect when reading.
- **Long-press Chapter Skip**: Set whether long-pressing page turn buttons skip to the next/previous chapter.
- "Chapter Skip" (default) - Long-pressing skips to next/previous chapter

View File

@ -359,7 +359,7 @@ const std::string& Epub::getLanguage() const {
}
std::string Epub::getCoverBmpPath(bool cropped) const {
const auto coverFileName = std::string("cover") + (cropped ? "_crop" : "");
const auto coverFileName = "cover" + cropped ? "_crop" : "";
return cachePath + "/" + coverFileName + ".bmp";
}
@ -382,7 +382,7 @@ bool Epub::generateCoverBmp(bool cropped) const {
if (coverImageHref.substr(coverImageHref.length() - 4) == ".jpg" ||
coverImageHref.substr(coverImageHref.length() - 5) == ".jpeg") {
Serial.printf("[%lu] [EBP] Generating BMP from JPG cover image (%s mode)\n", millis(), cropped ? "cropped" : "fit");
Serial.printf("[%lu] [EBP] Generating BMP from JPG cover image\n", millis());
const auto coverJpgTempPath = getCachePath() + "/.cover.jpg";
FsFile coverJpg;
@ -401,7 +401,7 @@ bool Epub::generateCoverBmp(bool cropped) const {
coverJpg.close();
return false;
}
const bool success = JpegToBmpConverter::jpegFileToBmpStream(coverJpg, coverBmp, cropped);
const bool success = JpegToBmpConverter::jpegFileToBmpStream(coverJpg, coverBmp);
coverJpg.close();
coverBmp.close();
SdMan.remove(coverJpgTempPath.c_str());

View File

@ -125,8 +125,6 @@ bool isExplicitHyphen(const uint32_t cp) {
case 0xFE58: // small em dash
case 0xFE63: // small hyphen-minus
case 0xFF0D: // fullwidth hyphen-minus
case 0x005F: // Underscore
case 0x2026: // Ellipsis
return true;
default:
return false;

View File

@ -200,7 +200,7 @@ unsigned char JpegToBmpConverter::jpegReadCallback(unsigned char* pBuf, const un
// Internal implementation with configurable target size and bit depth
bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bmpOut, int targetWidth, int targetHeight,
bool oneBit, bool crop) {
bool oneBit) {
Serial.printf("[%lu] [JPG] Converting JPEG to %s BMP (target: %dx%d)\n", millis(), oneBit ? "1-bit" : "2-bit",
targetWidth, targetHeight);
@ -242,12 +242,8 @@ bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bm
const float scaleToFitWidth = static_cast<float>(targetWidth) / imageInfo.m_width;
const float scaleToFitHeight = static_cast<float>(targetHeight) / imageInfo.m_height;
// We scale to the smaller dimension, so we can potentially crop later.
float scale = 1.0;
if (crop) { // if we will crop, scale to the smaller dimension
scale = (scaleToFitWidth > scaleToFitHeight) ? scaleToFitWidth : scaleToFitHeight;
} else { // else, scale to the larger dimension to fit
scale = (scaleToFitWidth < scaleToFitHeight) ? scaleToFitWidth : scaleToFitHeight;
}
// TODO: ideally, we already crop here.
const float scale = (scaleToFitWidth > scaleToFitHeight) ? scaleToFitWidth : scaleToFitHeight;
outWidth = static_cast<int>(imageInfo.m_width * scale);
outHeight = static_cast<int>(imageInfo.m_height * scale);
@ -554,8 +550,8 @@ bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bm
}
// Core function: Convert JPEG file to 2-bit BMP (uses default target size)
bool JpegToBmpConverter::jpegFileToBmpStream(FsFile& jpegFile, Print& bmpOut, bool crop) {
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, TARGET_MAX_WIDTH, TARGET_MAX_HEIGHT, false, crop);
bool JpegToBmpConverter::jpegFileToBmpStream(FsFile& jpegFile, Print& bmpOut) {
return jpegFileToBmpStreamInternal(jpegFile, bmpOut, TARGET_MAX_WIDTH, TARGET_MAX_HEIGHT, false);
}
// Convert with custom target size (for thumbnails, 2-bit)

View File

@ -8,10 +8,10 @@ class JpegToBmpConverter {
static unsigned char jpegReadCallback(unsigned char* pBuf, unsigned char buf_size,
unsigned char* pBytes_actually_read, void* pCallback_data);
static bool jpegFileToBmpStreamInternal(class FsFile& jpegFile, Print& bmpOut, int targetWidth, int targetHeight,
bool oneBit, bool crop = true);
bool oneBit);
public:
static bool jpegFileToBmpStream(FsFile& jpegFile, Print& bmpOut, bool crop = true);
static bool jpegFileToBmpStream(FsFile& jpegFile, Print& bmpOut);
// Convert with custom target size (for thumbnails)
static bool jpegFileToBmpStreamWithSize(FsFile& jpegFile, Print& bmpOut, int targetMaxWidth, int targetMaxHeight);
// Convert to 1-bit BMP (black and white only, no grays) for fast home screen rendering

View File

@ -32,12 +32,7 @@ class CrossPointSettings {
// Front button layout options
// Default: Back, Confirm, Left, Right
// Swapped: Left, Right, Back, Confirm
enum FRONT_BUTTON_LAYOUT {
BACK_CONFIRM_LEFT_RIGHT = 0,
LEFT_RIGHT_BACK_CONFIRM = 1,
LEFT_BACK_CONFIRM_RIGHT = 2,
BACK_CONFIRM_RIGHT_LEFT = 3
};
enum FRONT_BUTTON_LAYOUT { BACK_CONFIRM_LEFT_RIGHT = 0, LEFT_RIGHT_BACK_CONFIRM = 1, LEFT_BACK_CONFIRM_RIGHT = 2 };
// Side button layout options
// Default: Previous, Next

View File

@ -14,9 +14,6 @@ decltype(InputManager::BTN_BACK) MappedInputManager::mapButton(const Button butt
case CrossPointSettings::LEFT_BACK_CONFIRM_RIGHT:
return InputManager::BTN_CONFIRM;
case CrossPointSettings::BACK_CONFIRM_LEFT_RIGHT:
/* fall through */
case CrossPointSettings::BACK_CONFIRM_RIGHT_LEFT:
/* fall through */
default:
return InputManager::BTN_BACK;
}
@ -27,22 +24,15 @@ decltype(InputManager::BTN_BACK) MappedInputManager::mapButton(const Button butt
case CrossPointSettings::LEFT_BACK_CONFIRM_RIGHT:
return InputManager::BTN_LEFT;
case CrossPointSettings::BACK_CONFIRM_LEFT_RIGHT:
/* fall through */
case CrossPointSettings::BACK_CONFIRM_RIGHT_LEFT:
/* fall through */
default:
return InputManager::BTN_CONFIRM;
}
case Button::Left:
switch (frontLayout) {
case CrossPointSettings::LEFT_RIGHT_BACK_CONFIRM:
/* fall through */
case CrossPointSettings::LEFT_BACK_CONFIRM_RIGHT:
return InputManager::BTN_BACK;
case CrossPointSettings::BACK_CONFIRM_RIGHT_LEFT:
return InputManager::BTN_RIGHT;
case CrossPointSettings::BACK_CONFIRM_LEFT_RIGHT:
/* fall through */
default:
return InputManager::BTN_LEFT;
}
@ -50,12 +40,8 @@ decltype(InputManager::BTN_BACK) MappedInputManager::mapButton(const Button butt
switch (frontLayout) {
case CrossPointSettings::LEFT_RIGHT_BACK_CONFIRM:
return InputManager::BTN_CONFIRM;
case CrossPointSettings::BACK_CONFIRM_RIGHT_LEFT:
return InputManager::BTN_LEFT;
case CrossPointSettings::BACK_CONFIRM_LEFT_RIGHT:
/* fall through */
case CrossPointSettings::LEFT_BACK_CONFIRM_RIGHT:
/* fall through */
default:
return InputManager::BTN_RIGHT;
}
@ -70,7 +56,6 @@ decltype(InputManager::BTN_BACK) MappedInputManager::mapButton(const Button butt
case CrossPointSettings::NEXT_PREV:
return InputManager::BTN_DOWN;
case CrossPointSettings::PREV_NEXT:
/* fall through */
default:
return InputManager::BTN_UP;
}
@ -79,7 +64,6 @@ decltype(InputManager::BTN_BACK) MappedInputManager::mapButton(const Button butt
case CrossPointSettings::NEXT_PREV:
return InputManager::BTN_UP;
case CrossPointSettings::PREV_NEXT:
/* fall through */
default:
return InputManager::BTN_DOWN;
}

View File

@ -261,7 +261,6 @@ void SleepActivity::renderCoverSleepScreen() const {
if (SdMan.openFileForRead("SLP", coverBmpPath, file)) {
Bitmap bitmap(file);
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
Serial.printf("[SLP] Rendering sleep cover: %s\n", coverBmpPath);
renderBitmapSleepScreen(bitmap);
return;
}

View File

@ -427,7 +427,7 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in
// Right aligned text for progress counter
char progressStr[32];
snprintf(progressStr, sizeof(progressStr), "%d/%d %.0f%%", section->currentPage + 1, section->pageCount,
snprintf(progressStr, sizeof(progressStr), "%d/%d %.1f%%", section->currentPage + 1, section->pageCount,
bookProgress);
const std::string progress = progressStr;
progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str());

View File

@ -37,9 +37,8 @@ const SettingInfo readerSettings[readerSettingsCount] = {
constexpr int controlsSettingsCount = 4;
const SettingInfo controlsSettings[controlsSettingsCount] = {
SettingInfo::Enum(
"Front Button Layout", &CrossPointSettings::frontButtonLayout,
{"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght", "Bck, Cnfrm, Rght, Lft"}),
SettingInfo::Enum("Front Button Layout", &CrossPointSettings::frontButtonLayout,
{"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght"}),
SettingInfo::Enum("Side Button Layout (reader)", &CrossPointSettings::sideButtonLayout,
{"Prev, Next", "Next, Prev"}),
SettingInfo::Toggle("Long-press Chapter Skip", &CrossPointSettings::longPressChapterSkip),