diff --git a/lib/Epub/Epub/blocks/BlockStyle.h b/lib/Epub/Epub/blocks/BlockStyle.h index a5a616bf9..4166fceb6 100644 --- a/lib/Epub/Epub/blocks/BlockStyle.h +++ b/lib/Epub/Epub/blocks/BlockStyle.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include "Epub/css/CssStyle.h" @@ -8,6 +9,12 @@ * BlockStyle - Block-level styling properties */ struct BlockStyle { + // Upper bound (in em) for any single side's horizontal margin or padding. + // Some EPUBs apply huge em-based insets to chapter-opener classes; without a + // cap, effectiveWidth collapses to 1-2 words per line and justification dumps + // the remaining space into a single gap. + static constexpr float MAX_HORIZONTAL_INSET_EM = 2.0f; + CssTextAlign alignment = CssTextAlign::Justify; // Spacing (in pixels) @@ -68,16 +75,17 @@ struct BlockStyle { const uint16_t viewportWidth = 0) { BlockStyle blockStyle; const float vw = viewportWidth; + const auto maxHorizontalInsetPx = static_cast(emSize * MAX_HORIZONTAL_INSET_EM); // Resolve all CssLength values to pixels using the current font's em size and viewport width blockStyle.marginTop = cssStyle.marginTop.toPixelsInt16(emSize, vw); blockStyle.marginBottom = cssStyle.marginBottom.toPixelsInt16(emSize, vw); - blockStyle.marginLeft = cssStyle.marginLeft.toPixelsInt16(emSize, vw); - blockStyle.marginRight = cssStyle.marginRight.toPixelsInt16(emSize, vw); + blockStyle.marginLeft = std::min(cssStyle.marginLeft.toPixelsInt16(emSize, vw), maxHorizontalInsetPx); + blockStyle.marginRight = std::min(cssStyle.marginRight.toPixelsInt16(emSize, vw), maxHorizontalInsetPx); blockStyle.paddingTop = cssStyle.paddingTop.toPixelsInt16(emSize, vw); blockStyle.paddingBottom = cssStyle.paddingBottom.toPixelsInt16(emSize, vw); - blockStyle.paddingLeft = cssStyle.paddingLeft.toPixelsInt16(emSize, vw); - blockStyle.paddingRight = cssStyle.paddingRight.toPixelsInt16(emSize, vw); + blockStyle.paddingLeft = std::min(cssStyle.paddingLeft.toPixelsInt16(emSize, vw), maxHorizontalInsetPx); + blockStyle.paddingRight = std::min(cssStyle.paddingRight.toPixelsInt16(emSize, vw), maxHorizontalInsetPx); // For textIndent: if it's a percentage we can't resolve (no viewport width), // leave textIndentDefined=false so the EmSpace fallback in applyParagraphIndent() is used