Compare commits

...
Author SHA1 Message Date
Dave Allie 77a964e83a Style fixes 2026-04-06 15:35:36 +10:00
Dave Allie e20f4550ce Render image inside existing block style margins 2026-04-06 15:18:38 +10:00
+25 -14
View File
@@ -339,18 +339,29 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
const bool hasCssHeight = imgStyle.hasImageHeight(); const bool hasCssHeight = imgStyle.hasImageHeight();
const bool hasCssWidth = imgStyle.hasImageWidth(); const bool hasCssWidth = imgStyle.hasImageWidth();
// Compute effective container width for percentage-based image sizes.
// If the image is inside a block with horizontal margins/padding (e.g.
// <div style="margin: 1em 40%">), percentage widths like width:100%
// should resolve against the container width, not the full viewport.
int containerWidth = self->viewportWidth;
if (self->currentTextBlock) {
const int inset = self->currentTextBlock->getBlockStyle().totalHorizontalInset();
if (inset > 0 && inset < self->viewportWidth) {
containerWidth = self->viewportWidth - inset;
}
}
if (hasCssHeight && hasCssWidth && dims.width > 0 && dims.height > 0) { if (hasCssHeight && hasCssWidth && dims.width > 0 && dims.height > 0) {
// Both CSS height and width set: resolve both, then clamp to viewport preserving requested ratio // Both CSS height and width set: resolve both, then clamp to viewport preserving requested ratio
displayHeight = static_cast<int>( displayHeight = static_cast<int>(
imgStyle.imageHeight.toPixels(emSize, static_cast<float>(self->viewportHeight)) + 0.5f); imgStyle.imageHeight.toPixels(emSize, static_cast<float>(self->viewportHeight)) + 0.5f);
displayWidth = static_cast<int>( displayWidth =
imgStyle.imageWidth.toPixels(emSize, static_cast<float>(self->viewportWidth)) + 0.5f); static_cast<int>(imgStyle.imageWidth.toPixels(emSize, static_cast<float>(containerWidth)) + 0.5f);
if (displayHeight < 1) displayHeight = 1; if (displayHeight < 1) displayHeight = 1;
if (displayWidth < 1) displayWidth = 1; if (displayWidth < 1) displayWidth = 1;
if (displayWidth > self->viewportWidth || displayHeight > self->viewportHeight) { if (displayWidth > containerWidth || displayHeight > self->viewportHeight) {
float scaleX = (displayWidth > self->viewportWidth) float scaleX =
? static_cast<float>(self->viewportWidth) / displayWidth (displayWidth > containerWidth) ? static_cast<float>(containerWidth) / displayWidth : 1.0f;
: 1.0f;
float scaleY = (displayHeight > self->viewportHeight) float scaleY = (displayHeight > self->viewportHeight)
? static_cast<float>(self->viewportHeight) / displayHeight ? static_cast<float>(self->viewportHeight) / displayHeight
: 1.0f; : 1.0f;
@@ -375,8 +386,8 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
static_cast<int>(displayHeight * (static_cast<float>(dims.width) / dims.height) + 0.5f); static_cast<int>(displayHeight * (static_cast<float>(dims.width) / dims.height) + 0.5f);
if (displayWidth < 1) displayWidth = 1; if (displayWidth < 1) displayWidth = 1;
} }
if (displayWidth > self->viewportWidth) { if (displayWidth > containerWidth) {
displayWidth = self->viewportWidth; displayWidth = containerWidth;
// Rescale height to preserve aspect ratio when width is clamped // Rescale height to preserve aspect ratio when width is clamped
displayHeight = displayHeight =
static_cast<int>(displayWidth * (static_cast<float>(dims.height) / dims.width) + 0.5f); static_cast<int>(displayWidth * (static_cast<float>(dims.height) / dims.width) + 0.5f);
@@ -385,10 +396,10 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
if (displayWidth < 1) displayWidth = 1; if (displayWidth < 1) displayWidth = 1;
LOG_DBG("EHP", "Display size from CSS height: %dx%d", displayWidth, displayHeight); LOG_DBG("EHP", "Display size from CSS height: %dx%d", displayWidth, displayHeight);
} else if (hasCssWidth && !hasCssHeight && dims.width > 0 && dims.height > 0) { } else if (hasCssWidth && !hasCssHeight && dims.width > 0 && dims.height > 0) {
// Use CSS width (resolve % against viewport width) and derive height from aspect ratio // Use CSS width (resolve % against container width) and derive height from aspect ratio
displayWidth = static_cast<int>( displayWidth =
imgStyle.imageWidth.toPixels(emSize, static_cast<float>(self->viewportWidth)) + 0.5f); static_cast<int>(imgStyle.imageWidth.toPixels(emSize, static_cast<float>(containerWidth)) + 0.5f);
if (displayWidth > self->viewportWidth) displayWidth = self->viewportWidth; if (displayWidth > containerWidth) displayWidth = containerWidth;
if (displayWidth < 1) displayWidth = 1; if (displayWidth < 1) displayWidth = 1;
displayHeight = displayHeight =
static_cast<int>(displayWidth * (static_cast<float>(dims.height) / dims.width) + 0.5f); static_cast<int>(displayWidth * (static_cast<float>(dims.height) / dims.width) + 0.5f);
@@ -402,8 +413,8 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
if (displayHeight < 1) displayHeight = 1; if (displayHeight < 1) displayHeight = 1;
LOG_DBG("EHP", "Display size from CSS width: %dx%d", displayWidth, displayHeight); LOG_DBG("EHP", "Display size from CSS width: %dx%d", displayWidth, displayHeight);
} else { } else {
// Scale to fit viewport while maintaining aspect ratio // Scale to fit container while maintaining aspect ratio
int maxWidth = self->viewportWidth; int maxWidth = containerWidth;
int maxHeight = self->viewportHeight; int maxHeight = self->viewportHeight;
float scaleX = (dims.width > maxWidth) ? (float)maxWidth / dims.width : 1.0f; float scaleX = (dims.width > maxWidth) ? (float)maxWidth / dims.width : 1.0f;
float scaleY = (dims.height > maxHeight) ? (float)maxHeight / dims.height : 1.0f; float scaleY = (dims.height > maxHeight) ? (float)maxHeight / dims.height : 1.0f;