Linux support (#381)

* Add desktop release CI and support for Arch Linux packaging

* Make Gradle wrapper executable in desktop-release workflow

* Make Gradle wrapper executable in desktop-release workflow

* Make Gradle wrapper executable in desktop-release workflow

* Configure Gradle and update Java environment in desktop-release workflow

* Update Java setup and AUR packaging in desktop release workflow

* Update Java setup and AUR packaging in desktop release workflow

* Add MSIX packaging support for Windows desktop distribution

* Update AUR packaging metadata and validation

* Use spine toc attribute for NCX resolution

* crash fixes

* Implement automatic discovery and injection of EPUB font face siblings

* Enhance custom font support with family grouping and variable font handling

* Optimize metadata loading and improve TTS highlighting

* Add keyboard navigation support for EPUB reader

* Refine PDF spread page sizing to respect aspect ratios

* Implement responsive maximum height for reader popups and sheets

* Handle TTS generation failures by skipping problematic chunks

* Refactor PDF tile rendering logic and zoom indicator behavior

* Prefer block and offset locators over page index in native vertical flow

* Implement save and share actions for original book files

* Add Estonian language support

* Implement temporary viewing mode for external files

* Implement direct opening for temporary external files without library persistence

* fix failing tests

* Import SharedFileCapabilities in DesktopLibraryUi

* Improve native vertical reader progress, persistence, and image support

* Center target in viewport for native vertical reader and support animated scrolling
This commit is contained in:
Aryan 2026-06-14 13:43:49 +05:30 committed by GitHub
parent a13d6599d1
commit 625a4d5d2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
102 changed files with 6012 additions and 687 deletions

View file

@ -213,7 +213,7 @@ private class SemanticHtmlParser(
}
val body = document.body()
return parseContainer(body, getElementStyle(body))
return parseContainer(body, getElementStyle(body).withResolvedFontFamily())
}
private inline fun Element.anyChildElement(predicate: (Element) -> Boolean): Boolean {
@ -295,7 +295,7 @@ private class SemanticHtmlParser(
textEmphasis = elementOwnStyle.textEmphasis ?: inheritedStyle.textEmphasis,
whiteSpace = elementOwnStyle.whiteSpace ?: inheritedStyle.whiteSpace,
customProperties = inheritedStyle.customProperties + elementOwnStyle.customProperties
)
).withResolvedFontFamily()
if (finalStyle.display == "none") return emptyList()
@ -364,7 +364,19 @@ private class SemanticHtmlParser(
val pseudoStyle = rulesForElement(element, pseudoElement).fold(CssStyle()) { acc, rule ->
acc.merge(rule.style)
}
return inheritedStyle.merge(pseudoStyle)
return inheritedStyle.merge(pseudoStyle).withResolvedFontFamily()
}
private fun CssStyle.withResolvedFontFamily(): CssStyle {
if (spanStyle.fontFamily != null) return this
val resolvedFontFamily = fontFamilies.asSequence()
.mapNotNull { name ->
val normalized = name.trim().lowercase()
currentFontFamilyMap[normalized] ?: FontFamilyMapper.nameToFontFamily(normalized)
}
.firstOrNull()
?: return this
return copy(spanStyle = spanStyle.copy(fontFamily = resolvedFontFamily))
}
private fun firstCssUrl(value: String): String? {
@ -805,7 +817,7 @@ private class SemanticHtmlParser(
appendText("\n"); return
}
val currentElementStyle = getElementStyle(node, inheritedStyle.customProperties)
val newStyle = inheritedStyle.merge(currentElementStyle)
val newStyle = inheritedStyle.merge(currentElementStyle).withResolvedFontFamily()
if (newStyle.display == "none") return
val tag = node.tagName().lowercase()
val href = node.linkHrefOrNull()
@ -969,7 +981,10 @@ private class SemanticHtmlParser(
val isOrdered = listElement.tagName().lowercase() == "ol"
val items = listElement.children().mapNotNull { child ->
if (child.tagName().lowercase() != "li") return@mapNotNull null
val itemStyle = listStyle.merge(getElementStyle(child, listStyle.customProperties)).withResolvedBlockResources()
val itemStyle = listStyle
.merge(getElementStyle(child, listStyle.customProperties))
.withResolvedFontFamily()
.withResolvedBlockResources()
val (text, spans) = buildSemanticTextAndSpans(child, itemStyle, inheritedLinkHref)
val imageSrc = itemStyle.blockStyle.listStyleImage?.let { resolveImagePath(it) }
SemanticListItem(text, spans, itemStyle, child.id().ifBlank { null }, child.getCfiPath(), 0, imageSrc, blockIndex = nextBlockIndex++)
@ -990,7 +1005,9 @@ private class SemanticHtmlParser(
val tagName = cellElement.tagName().lowercase()
if (tagName !in listOf("td", "th")) return@mapNotNull null
var cellCssStyle = getElementStyle(cellElement, rowStyle.customProperties).withResolvedBlockResources()
var cellCssStyle = getElementStyle(cellElement, rowStyle.customProperties)
.withResolvedFontFamily()
.withResolvedBlockResources()
if (cellCssStyle.display == "none") return@mapNotNull null
if (!cellCssStyle.blockStyle.backgroundColor.isSpecified) {