Epub improvements (#162)

* Added a "Remove Edge Padding" option in "Visual Options"

* Added support for paragraph gap settings in the EPUB vertical reader.

* Added support for adjustable paragraph gaps in the paginated reader.

* fix(epub-pagination): ensure custom fonts override embedded epub fonts

* feat(epub): allow overlapping highlights and resolve gesture selection conflicts
This commit is contained in:
Aryan 2026-04-10 17:43:01 +05:30 committed by GitHub
parent 291504fd90
commit 49e08cc9f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 315 additions and 264 deletions

View file

@ -54,7 +54,8 @@ class ContentStyler(
private val themeTextColor: Color,
private val chapterAbsPath: String,
private val extractionBasePath: String,
private val userTextAlign: TextAlign?
private val userTextAlign: TextAlign?,
private val paragraphGapMultiplier: Float
) {
fun style(semanticBlocks: List<SemanticBlock>): List<ContentBlock> {
@ -102,6 +103,18 @@ class ContentStyler(
private fun styleBlock(block: SemanticBlock): ContentBlock? {
val themedStyle = applyThemeToStyle(block.style)
val finalBlockStyle = if (block is SemanticParagraph) {
val originalMargin = themedStyle.blockStyle.margin
val newMargin = originalMargin.copy(
top = originalMargin.top * paragraphGapMultiplier,
bottom = originalMargin.bottom * paragraphGapMultiplier
)
themedStyle.blockStyle.copy(margin = newMargin)
} else {
themedStyle.blockStyle
}
return when (block) {
is SemanticParagraph -> {
val computedTextAlign = userTextAlign ?: themedStyle.paragraphStyle.textAlign
@ -109,7 +122,7 @@ class ContentStyler(
ParagraphBlock(
content = buildAnnotatedString(block, themedStyle),
textAlign = computedTextAlign,
style = themedStyle.blockStyle,
style = finalBlockStyle,
elementId = block.elementId,
cfi = block.cfi,
startCharOffsetInSource = block.startCharOffsetInSource,
@ -353,14 +366,20 @@ class ContentStyler(
textMotion = mergedParagraphStyle.textMotion
)
var initialSpanStyle = baseTextStyle.toSpanStyle()
.merge(blockStyle.spanStyle)
.copy(fontFamily = baseTextStyle.fontFamily)
val isCustomFont = baseTextStyle.fontFamily != null && baseTextStyle.fontFamily != FontFamily.Default
if (rootFontFamily == FontFamily.Monospace) {
initialSpanStyle = initialSpanStyle.copy(fontFamily = rootFontFamily)
val effectiveBlockFontFamily = if (rootFontFamily == FontFamily.Monospace) {
FontFamily.Monospace
} else if (isCustomFont) {
baseTextStyle.fontFamily
} else {
rootFontFamily ?: baseTextStyle.fontFamily
}
val initialSpanStyle = baseTextStyle.toSpanStyle()
.merge(blockStyle.spanStyle)
.copy(fontFamily = effectiveBlockFontFamily)
Timber.d("ContentStyler: InitialSpanStyle. BaseFontSize=${baseTextStyle.fontSize}, BlockFontSize=${blockStyle.spanStyle.fontSize} -> Merged=${initialSpanStyle.fontSize}")
withStyle(finalParagraphStyle) {
@ -368,14 +387,23 @@ class ContentStyler(
append(block.text)
block.spans.sortedBy { it.start }.forEach { span ->
val themedSpanStyle = applyThemeToStyle(span.style)
val fontFamily = findFirstAvailableFontFamily(themedSpanStyle.fontFamilies, fontFamilyMap)
val spanFontFamily = findFirstAvailableFontFamily(themedSpanStyle.fontFamilies, fontFamilyMap)
val effectiveSpanFontFamily = if (spanFontFamily == FontFamily.Monospace) {
FontFamily.Monospace
} else if (isCustomFont) {
baseTextStyle.fontFamily
} else {
spanFontFamily
}
val baselineShift = when (span.tag) {
"sub" -> BaselineShift.Subscript
"sup" -> BaselineShift.Superscript
else -> null
}
val finalSpanStyle = themedSpanStyle.spanStyle.copy(
fontFamily = fontFamily,
fontFamily = effectiveSpanFontFamily,
baselineShift = baselineShift
)
addStyle(initialSpanStyle.merge(finalSpanStyle), span.start, span.end)