Port three new upstream commits and align the existing #1002 port: - PR #1014: Strip unused CSS rules by filtering unsupported selector types (+, >, [, :, #, ~, *, descendants) in processRuleBlockWithStyle. Fix normalized() trailing whitespace to also strip newlines. - PR #1018: Add deleteCache() to CssParser, move CSS_CACHE_VERSION to static class member, remove stale cache on version mismatch, invalidate section caches (Storage.removeDir) when CSS is rebuilt. Refactor parseCssFiles() to early-return when cache exists. - PR #990: Adapt classic theme continue-reading card width to cover aspect ratio (clamped to 90% screen width), increase homeTopPadding 20->40, fix centering with rect.x offset for boxX/continueBoxX. - #1002 alignment: Add tryInterpretLength() to skip non-numeric CSS values (auto, inherit), add "both width and height set" image sizing branch in ChapterHtmlSlimParser. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -365,14 +365,52 @@ void BaseTheme::drawTabBar(const GfxRenderer& renderer, const Rect rect, const s
|
||||
void BaseTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std::vector<RecentBook>& recentBooks,
|
||||
const int selectorIndex, bool& coverRendered, bool& coverBufferStored,
|
||||
bool& bufferRestored, std::function<bool()> storeCoverBuffer) const {
|
||||
// --- Top "book" card for the current title (selectorIndex == 0) ---
|
||||
const int bookWidth = rect.width / 2;
|
||||
const int bookHeight = rect.height;
|
||||
const int bookX = (rect.width - bookWidth) / 2;
|
||||
const int bookY = rect.y;
|
||||
const bool hasContinueReading = !recentBooks.empty();
|
||||
const bool bookSelected = hasContinueReading && selectorIndex == 0;
|
||||
|
||||
// --- Top "book" card for the current title (selectorIndex == 0) ---
|
||||
// Adapt width to cover image aspect ratio; fall back to half screen when no cover
|
||||
const int baseHeight = rect.height;
|
||||
|
||||
int bookWidth;
|
||||
bool hasCoverImage = false;
|
||||
|
||||
if (hasContinueReading && !recentBooks[0].coverBmpPath.empty()) {
|
||||
const std::string coverBmpPath =
|
||||
UITheme::getCoverThumbPath(recentBooks[0].coverBmpPath, BaseMetrics::values.homeCoverHeight);
|
||||
|
||||
FsFile file;
|
||||
if (Storage.openFileForRead("HOME", coverBmpPath, file)) {
|
||||
Bitmap bitmap(file);
|
||||
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
|
||||
hasCoverImage = true;
|
||||
const int imgWidth = bitmap.getWidth();
|
||||
const int imgHeight = bitmap.getHeight();
|
||||
|
||||
if (imgWidth > 0 && imgHeight > 0) {
|
||||
const float aspectRatio = static_cast<float>(imgWidth) / static_cast<float>(imgHeight);
|
||||
bookWidth = static_cast<int>(baseHeight * aspectRatio);
|
||||
|
||||
const int maxWidth = static_cast<int>(rect.width * 0.9f);
|
||||
if (bookWidth > maxWidth) {
|
||||
bookWidth = maxWidth;
|
||||
}
|
||||
} else {
|
||||
bookWidth = rect.width / 2;
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasCoverImage) {
|
||||
bookWidth = rect.width / 2;
|
||||
}
|
||||
|
||||
const int bookX = rect.x + (rect.width - bookWidth) / 2;
|
||||
const int bookY = rect.y;
|
||||
const int bookHeight = baseHeight;
|
||||
|
||||
// Bookmark dimensions (used in multiple places)
|
||||
const int bookmarkWidth = bookWidth / 8;
|
||||
const int bookmarkHeight = bookHeight / 5;
|
||||
@@ -394,29 +432,9 @@ void BaseTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std:
|
||||
Bitmap bitmap(file);
|
||||
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
|
||||
LOG_DBG("THEME", "Rendering bmp");
|
||||
// Calculate position to center image within the book card
|
||||
int coverX, coverY;
|
||||
|
||||
if (bitmap.getWidth() > bookWidth || bitmap.getHeight() > bookHeight) {
|
||||
const float imgRatio = static_cast<float>(bitmap.getWidth()) / static_cast<float>(bitmap.getHeight());
|
||||
const float boxRatio = static_cast<float>(bookWidth) / static_cast<float>(bookHeight);
|
||||
renderer.drawBitmap(bitmap, bookX, bookY, bookWidth, bookHeight);
|
||||
|
||||
if (imgRatio > boxRatio) {
|
||||
coverX = bookX;
|
||||
coverY = bookY + (bookHeight - static_cast<int>(bookWidth / imgRatio)) / 2;
|
||||
} else {
|
||||
coverX = bookX + (bookWidth - static_cast<int>(bookHeight * imgRatio)) / 2;
|
||||
coverY = bookY;
|
||||
}
|
||||
} else {
|
||||
coverX = bookX + (bookWidth - bitmap.getWidth()) / 2;
|
||||
coverY = bookY + (bookHeight - bitmap.getHeight()) / 2;
|
||||
}
|
||||
|
||||
// Draw the cover image centered within the book card
|
||||
renderer.drawBitmap(bitmap, coverX, coverY, bookWidth, bookHeight);
|
||||
|
||||
// Draw border around the card
|
||||
renderer.drawRect(bookX, bookY, bookWidth, bookHeight);
|
||||
|
||||
// No bookmark ribbon when cover is shown - it would just cover the art
|
||||
@@ -597,7 +615,7 @@ void BaseTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std:
|
||||
|
||||
const int boxWidth = maxTextWidth + boxPadding * 2;
|
||||
const int boxHeight = totalTextHeight + boxPadding * 2;
|
||||
const int boxX = (rect.width - boxWidth) / 2;
|
||||
const int boxX = rect.x + (rect.width - boxWidth) / 2;
|
||||
const int boxY = titleYStart - boxPadding;
|
||||
|
||||
// Draw box (inverted when selected: black box instead of white)
|
||||
@@ -640,7 +658,7 @@ void BaseTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std:
|
||||
constexpr int continuePadding = 6;
|
||||
const int continueBoxWidth = continueTextWidth + continuePadding * 2;
|
||||
const int continueBoxHeight = renderer.getLineHeight(UI_10_FONT_ID) + continuePadding;
|
||||
const int continueBoxX = (rect.width - continueBoxWidth) / 2;
|
||||
const int continueBoxX = rect.x + (rect.width - continueBoxWidth) / 2;
|
||||
const int continueBoxY = continueY - continuePadding / 2;
|
||||
renderer.fillRect(continueBoxX, continueBoxY, continueBoxWidth, continueBoxHeight, bookSelected);
|
||||
renderer.drawRect(continueBoxX, continueBoxY, continueBoxWidth, continueBoxHeight, !bookSelected);
|
||||
|
||||
Reference in New Issue
Block a user