* 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
128 lines
4.7 KiB
Kotlin
128 lines
4.7 KiB
Kotlin
package com.aryan.reader.paginatedreader
|
|
|
|
import androidx.compose.ui.text.font.FontStyle
|
|
import androidx.compose.ui.text.font.FontWeight
|
|
import org.junit.Assert.assertEquals
|
|
import org.junit.Assert.assertTrue
|
|
import org.junit.Test
|
|
import java.io.File
|
|
|
|
class EpubFontFaceSiblingsTest {
|
|
|
|
@Test
|
|
fun expandFontFacesWithSiblings_addsItalicAndBoldItalicVariants() {
|
|
val root = createTempRoot()
|
|
val fontsDir = File(root, "OEBPS/fonts").apply { mkdirs() }
|
|
File(fontsDir, "Literata-Regular.ttf").writeText("regular")
|
|
File(fontsDir, "Literata-Italic.ttf").writeText("italic")
|
|
File(fontsDir, "Literata-BoldItalic.ttf").writeText("bold italic")
|
|
File(fontsDir, "Other-Italic.ttf").writeText("other")
|
|
|
|
val expanded = expandFontFacesWithSiblings(
|
|
fontFaces = listOf(
|
|
FontFaceInfo(
|
|
fontFamily = "literata",
|
|
src = "OEBPS/fonts/Literata-Regular.ttf",
|
|
fontWeight = FontWeight.Normal,
|
|
fontStyle = FontStyle.Normal
|
|
)
|
|
),
|
|
extractionPath = root.absolutePath
|
|
)
|
|
|
|
assertEquals(3, expanded.size)
|
|
assertTrue(expanded.any { it.src == "OEBPS/fonts/Literata-Italic.ttf" && it.fontStyle == FontStyle.Italic })
|
|
assertTrue(
|
|
expanded.any {
|
|
it.src == "OEBPS/fonts/Literata-BoldItalic.ttf" &&
|
|
it.fontStyle == FontStyle.Italic &&
|
|
it.fontWeight == FontWeight.Bold
|
|
}
|
|
)
|
|
assertTrue(expanded.none { it.src.contains("Other") })
|
|
}
|
|
|
|
@Test
|
|
fun buildEpubFontFaceCss_emitsVariantDescriptorsForSiblings() {
|
|
val root = createTempRoot()
|
|
val fontsDir = File(root, "fonts").apply { mkdirs() }
|
|
File(fontsDir, "LoraRegular.ttf").writeText("regular")
|
|
File(fontsDir, "LoraBoldItalic.ttf").writeText("bold italic")
|
|
|
|
val css = buildEpubFontFaceCss(
|
|
fontFaces = listOf(
|
|
FontFaceInfo(
|
|
fontFamily = "lora",
|
|
src = "fonts/LoraRegular.ttf",
|
|
fontWeight = FontWeight.Normal,
|
|
fontStyle = FontStyle.Normal
|
|
)
|
|
),
|
|
extractionPath = root.absolutePath
|
|
)
|
|
|
|
assertTrue(css.contains("font-family: 'lora'"))
|
|
assertTrue(css.contains("font-weight: 700"))
|
|
assertTrue(css.contains("font-style: italic"))
|
|
assertTrue(css.contains("LoraBoldItalic.ttf"))
|
|
}
|
|
|
|
@Test
|
|
fun expandFontFacesWithSiblings_groupsVariableRegularAndItalicFiles() {
|
|
val root = createTempRoot()
|
|
val fontsDir = File(root, "fonts").apply { mkdirs() }
|
|
File(fontsDir, "Pliant-VariableFont_wdth,wght.ttf").writeText("regular variable")
|
|
File(fontsDir, "Pliant-Italic-VariableFont_wdth,wght.ttf").writeText("italic variable")
|
|
|
|
val expanded = expandFontFacesWithSiblings(
|
|
fontFaces = listOf(
|
|
FontFaceInfo(
|
|
fontFamily = "pliant",
|
|
src = "fonts/Pliant-VariableFont_wdth,wght.ttf",
|
|
fontWeight = FontWeight.Normal,
|
|
fontStyle = FontStyle.Normal
|
|
)
|
|
),
|
|
extractionPath = root.absolutePath
|
|
)
|
|
|
|
assertEquals(2, expanded.size)
|
|
assertTrue(
|
|
expanded.any {
|
|
it.src == "fonts/Pliant-Italic-VariableFont_wdth,wght.ttf" &&
|
|
it.fontStyle == FontStyle.Italic &&
|
|
it.fontWeight == FontWeight.Normal
|
|
}
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun buildEpubFontFaceCss_usesWeightRangeForVariableWeightFonts() {
|
|
val root = createTempRoot()
|
|
val fontsDir = File(root, "fonts").apply { mkdirs() }
|
|
File(fontsDir, "Pliant-VariableFont_wdth,wght.ttf").writeText("regular variable")
|
|
File(fontsDir, "Pliant-Italic-VariableFont_wdth,wght.ttf").writeText("italic variable")
|
|
|
|
val css = buildEpubFontFaceCss(
|
|
fontFaces = listOf(
|
|
FontFaceInfo(
|
|
fontFamily = "pliant",
|
|
src = "fonts/Pliant-VariableFont_wdth,wght.ttf",
|
|
fontWeight = FontWeight.Normal,
|
|
fontStyle = FontStyle.Normal
|
|
)
|
|
),
|
|
extractionPath = root.absolutePath
|
|
)
|
|
|
|
assertTrue(css.contains("font-weight: 100 900"))
|
|
assertTrue(css.contains("font-style: italic"))
|
|
assertTrue(css.contains("Pliant-Italic-VariableFont_wdth,wght.ttf"))
|
|
}
|
|
|
|
private fun createTempRoot(): File {
|
|
return kotlin.io.path.createTempDirectory("epub-font-siblings").toFile().also {
|
|
it.deleteOnExit()
|
|
}
|
|
}
|
|
}
|