diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp
index 368a4c60d..8b60d9f1e 100644
--- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp
+++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp
@@ -339,17 +339,29 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
const bool hasCssHeight = imgStyle.hasImageHeight();
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.
+ //
), 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) {
// Both CSS height and width set: resolve both, then clamp to viewport preserving requested ratio
displayHeight = static_cast(
imgStyle.imageHeight.toPixels(emSize, static_cast(self->viewportHeight)) + 0.5f);
displayWidth = static_cast(
- imgStyle.imageWidth.toPixels(emSize, static_cast(self->viewportWidth)) + 0.5f);
+ imgStyle.imageWidth.toPixels(emSize, static_cast(containerWidth)) + 0.5f);
if (displayHeight < 1) displayHeight = 1;
if (displayWidth < 1) displayWidth = 1;
- if (displayWidth > self->viewportWidth || displayHeight > self->viewportHeight) {
- float scaleX = (displayWidth > self->viewportWidth)
- ? static_cast(self->viewportWidth) / displayWidth
+ if (displayWidth > containerWidth || displayHeight > self->viewportHeight) {
+ float scaleX = (displayWidth > containerWidth)
+ ? static_cast(containerWidth) / displayWidth
: 1.0f;
float scaleY = (displayHeight > self->viewportHeight)
? static_cast(self->viewportHeight) / displayHeight
@@ -375,8 +387,8 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
static_cast(displayHeight * (static_cast(dims.width) / dims.height) + 0.5f);
if (displayWidth < 1) displayWidth = 1;
}
- if (displayWidth > self->viewportWidth) {
- displayWidth = self->viewportWidth;
+ if (displayWidth > containerWidth) {
+ displayWidth = containerWidth;
// Rescale height to preserve aspect ratio when width is clamped
displayHeight =
static_cast(displayWidth * (static_cast(dims.height) / dims.width) + 0.5f);
@@ -385,10 +397,10 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
if (displayWidth < 1) displayWidth = 1;
LOG_DBG("EHP", "Display size from CSS height: %dx%d", displayWidth, displayHeight);
} 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(
- imgStyle.imageWidth.toPixels(emSize, static_cast(self->viewportWidth)) + 0.5f);
- if (displayWidth > self->viewportWidth) displayWidth = self->viewportWidth;
+ imgStyle.imageWidth.toPixels(emSize, static_cast(containerWidth)) + 0.5f);
+ if (displayWidth > containerWidth) displayWidth = containerWidth;
if (displayWidth < 1) displayWidth = 1;
displayHeight =
static_cast(displayWidth * (static_cast(dims.height) / dims.width) + 0.5f);
@@ -402,8 +414,8 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
if (displayHeight < 1) displayHeight = 1;
LOG_DBG("EHP", "Display size from CSS width: %dx%d", displayWidth, displayHeight);
} else {
- // Scale to fit viewport while maintaining aspect ratio
- int maxWidth = self->viewportWidth;
+ // Scale to fit container while maintaining aspect ratio
+ int maxWidth = containerWidth;
int maxHeight = self->viewportHeight;
float scaleX = (dims.width > maxWidth) ? (float)maxWidth / dims.width : 1.0f;
float scaleY = (dims.height > maxHeight) ? (float)maxHeight / dims.height : 1.0f;