Default covers + optimisations

This commit is contained in:
jpirnay
2026-05-19 12:34:54 +02:00
parent d2f660ea64
commit 5fec0e0210
10 changed files with 177 additions and 8 deletions
+26
View File
@@ -9,6 +9,7 @@
#include <JpegToBmpConverter.h>
#include <Logging.h>
#include <PngToBmpConverter.h>
#include <Txt.h>
#include <Utf8.h>
#include <Xtc.h>
@@ -239,6 +240,16 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
LOG_DBG("HOME", "Generated missing cover for %s", book.path.c_str());
}
}
} else if (FsHelpers::hasTxtExtension(book.path) || FsHelpers::hasMarkdownExtension(book.path)) {
Txt txt(book.path, "/.crosspoint");
const std::string thumbPath = txt.getThumbBmpPath();
bool success = thumbSizes.empty() ? txt.generateThumbBmp(coverHeight)
: txt.generateThumbBmp(thumbSizes[0].first, thumbSizes[0].second);
if (success) {
RECENT_BOOKS.updateBook(book.path, book.title, book.author, book.series, thumbPath);
book.coverBmpPath = thumbPath;
LOG_DBG("HOME", "Generated surrogate cover for %s", book.path.c_str());
}
}
onCoverGenerated();
return;
@@ -320,6 +331,12 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
if (!Storage.exists(path.c_str())) success = xtc.generateThumbBmp(sz.first, sz.second) && success;
}
}
} else if (FsHelpers::hasTxtExtension(book.path) || FsHelpers::hasMarkdownExtension(book.path)) {
Txt txt(book.path, "/.crosspoint");
for (const auto& sz : thumbSizes) {
const std::string path = UITheme::getCoverThumbPath(book.coverBmpPath, sz.first, sz.second);
if (!Storage.exists(path.c_str())) success = txt.generateThumbBmp(sz.first, sz.second) && success;
}
}
if (!success) {
RECENT_BOOKS.updateBook(book.path, book.title, book.author, book.series, "");
@@ -352,6 +369,15 @@ void HomeActivity::loadRecentCovers(int coverHeight) {
onCoverGenerated();
return;
}
} else if (FsHelpers::hasTxtExtension(book.path) || FsHelpers::hasMarkdownExtension(book.path)) {
Txt txt(book.path, "/.crosspoint");
bool success = txt.generateThumbBmp(coverHeight);
if (!success) {
RECENT_BOOKS.updateBook(book.path, book.title, book.author, book.series, "");
book.coverBmpPath = "";
}
onCoverGenerated();
return;
}
}
}
+3 -1
View File
@@ -54,7 +54,9 @@ void MdReaderActivity::onEnter() {
auto fileName = filePath.substr(filePath.rfind('/') + 1);
APP_STATE.openEpubPath = filePath;
APP_STATE.saveToFile();
RECENT_BOOKS.addBook(filePath, fileName, "", "", ReaderActivity::sidecarCoverPath(filePath));
const std::string txtSidecar = ReaderActivity::sidecarCoverPath(filePath);
const std::string txtCover = txtSidecar.empty() ? txt->getThumbBmpPath() : txtSidecar;
RECENT_BOOKS.addBook(filePath, fileName, "", "", txtCover);
requestUpdate();
}
+3 -1
View File
@@ -118,7 +118,9 @@ void TxtReaderActivity::onEnter() {
auto fileName = filePath.substr(filePath.rfind('/') + 1);
APP_STATE.openEpubPath = filePath;
APP_STATE.saveToFile();
RECENT_BOOKS.addBook(filePath, fileName, "", "", ReaderActivity::sidecarCoverPath(filePath));
const std::string txtSidecar = ReaderActivity::sidecarCoverPath(filePath);
const std::string txtCover = txtSidecar.empty() ? txt->getThumbBmpPath() : txtSidecar;
RECENT_BOOKS.addBook(filePath, fileName, "", "", txtCover);
// Trigger first update
requestUpdate();
+1 -1
View File
@@ -516,7 +516,7 @@ void BaseTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std:
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
LOG_DBG("THEME", "Rendering bmp");
// Draw the cover image (bookWidth and bookHeight already match image aspect ratio)
renderer.fillRect(bookX, bookY, bookWidth, bookHeight, false);
renderer.drawBitmap(bitmap, bookX, bookY, bookWidth, bookHeight);
// Draw border around the card
@@ -57,6 +57,10 @@ void Lyra3CoversTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, con
static_cast<float>(tileWidth - 2 * hPaddingInSelection) / static_cast<float>(coverHeight);
const float cropX = std::max(0.0f, 1.0f - (tileRatio / ratio));
// Clear tile to white before drawing: 1-bit BMPs only draw dark pixels,
// leaving white pixels transparent — any stale dark content shows through.
renderer.fillRect(tileX + hPaddingInSelection, tileY + hPaddingInSelection,
tileWidth - 2 * hPaddingInSelection, coverHeight, false);
renderer.drawBitmap(bitmap, tileX + hPaddingInSelection, tileY + hPaddingInSelection,
tileWidth - 2 * hPaddingInSelection, coverHeight, cropX);
} else {
@@ -338,6 +338,7 @@ void LyraCarouselTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect,
const float bmpRatio = static_cast<float>(bitmap.getWidth()) / static_cast<float>(bitmap.getHeight());
const float tileRatio = static_cast<float>(maxW) / static_cast<float>(maxH);
const float cropX = (bmpRatio > tileRatio) ? (1.0f - tileRatio / bmpRatio) : 0.0f;
renderer.fillRect(x, y, maxW, maxH, false);
renderer.drawBitmap(bitmap, x, y, maxW, maxH, cropX, 0.0f);
// Clear only the pixels outside the arc in each corner.
// The arc centre for the top-left corner is (x+r, y+r). A pixel at
+1
View File
@@ -568,6 +568,7 @@ void LyraTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std:
Bitmap bitmap(file);
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
coverWidth = bitmap.getWidth();
renderer.fillRect(tileX + hPaddingInSelection, tileY + hPaddingInSelection, coverWidth, coverHeight, false);
renderer.drawBitmap(bitmap, tileX + hPaddingInSelection, tileY + hPaddingInSelection, coverWidth,
coverHeight);
} else {