mod: Phase 3 — Re-port unmerged upstream PRs

Re-applied upstream PRs not yet merged to upstream/master:

- #1055: Byte-level framebuffer writes (fillPhysicalHSpan*,
  optimized fillRect/drawLine/fillRectDither/fillPolygon)
- #1027: Word-width cache (FNV-1a, 128-entry) and hyphenation
  early exit in ParsedText for 7-9% layout speedup
- #1068: Already present in upstream — URL hyphenation fix
- #1019: Already present in upstream — file extensions in browser
- #1090/#1185/#1217: KOReader sync improvements — binary credential
  store, document hash caching, ChapterXPathIndexer integration
- #1209: OPDS multi-server — OpdsBookBrowserActivity accepts
  OpdsServer, directory picker for downloads, download-complete
  prompt with open/back options
- #857: Dictionary activities already ported in Phase 1/2
- #1003: Placeholder cover already integrated in Phase 2

Also fixed: STR_OFF i18n string, include paths, replaced
Epub::isValidThumbnailBmp with Storage.exists, replaced
StringUtils::checkFileExtension with FsHelpers equivalents.

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-07 16:15:42 -05:00
parent 30473c27d3
commit 60a3e21c0e
25 changed files with 811 additions and 295 deletions

View File

@@ -24,7 +24,7 @@
#include "components/UITheme.h"
#include "fontIds.h"
#include "util/BookManager.h"
#include "util/StringUtils.h"
int HomeActivity::getMenuItemCount() const {
int count = 4; // File Browser, Recents, File transfer, Settings
@@ -66,7 +66,7 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
for (RecentBook& book : recentBooks) {
if (!book.coverBmpPath.empty()) {
std::string coverPath = UITheme::getCoverThumbPath(book.coverBmpPath, coverHeight);
if (!Epub::isValidThumbnailBmp(coverPath)) {
if (!Storage.exists(coverPath.c_str())) {
if (!showingLoading) {
showingLoading = true;
popupRect = GUI.drawPopup(renderer, tr(STR_LOADING));
@@ -75,7 +75,7 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
bool success = false;
if (StringUtils::checkFileExtension(book.path, ".epub")) {
if (FsHelpers::hasEpubExtension(book.path)) {
Epub epub(book.path, "/.crosspoint");
if (!epub.load(false, true)) {
epub.load(true, true);
@@ -87,13 +87,9 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
book.coverBmpPath = thumbPath;
} else {
const int thumbWidth = static_cast<int>(coverHeight * 0.6);
success = PlaceholderCoverGenerator::generate(coverPath, book.title, book.author, thumbWidth, coverHeight);
if (!success) {
epub.generateInvalidFormatThumbBmp(coverHeight);
}
PlaceholderCoverGenerator::generate(coverPath, book.title, book.author, thumbWidth, coverHeight);
}
} else if (StringUtils::checkFileExtension(book.path, ".xtch") ||
StringUtils::checkFileExtension(book.path, ".xtc")) {
} else if (FsHelpers::hasXtcExtension(book.path)) {
Xtc xtc(book.path, "/.crosspoint");
if (xtc.load()) {
success = xtc.generateThumbBmp(coverHeight);