Epub reader themes (#97)
* Implemented a custom theme engine for the EPUB reader, allowing users to switch between built-in themes (System, Light, Dark, Sepia, Slate, and OLED). Key changes include: - Added `ReaderThemePanel` and theme selection logic to `EpubReaderScreen`. - Introduced a theme persistence layer using SharedPreferences. - Updated `ChapterWebView` and `epub_reader.js` to dynamically apply background and text colors via JavaScript, including improved contrast adjustment for inline styles. - Enhanced `CssParser` and `ContentStyler` in the paginated reader to adapt CSS colors based on the active theme's background and text luminance. - Integrated theme-specific background and text colors into `PaginatedReaderScreen` and its layout components. - Added a theme palette icon to the reader controls. * Added custom theme builder and texture support to EPUB reader * Refactored color picker(PDF) into shared components and enhanced EPUB theme editor * Updated theme customization UI and improved WebView theme application efficiency * Updated page flip animation to use paper color with a theme-based tint * Improved state restoration during paginated reader reconfiguration
This commit is contained in:
parent
eaf0d4af00
commit
c9dc3ce8c2
16 changed files with 1817 additions and 847 deletions
|
|
@ -50,6 +50,8 @@ class ContentStyler(
|
|||
private val fontFamilyMap: Map<String, FontFamily>,
|
||||
private val density: Density,
|
||||
private val isDarkTheme: Boolean,
|
||||
private val themeBackgroundColor: Color,
|
||||
private val themeTextColor: Color,
|
||||
private val chapterAbsPath: String,
|
||||
private val extractionBasePath: String,
|
||||
private val userTextAlign: TextAlign?
|
||||
|
|
@ -59,7 +61,6 @@ class ContentStyler(
|
|||
return groupFloatingBlocks(semanticBlocks.mapNotNull { styleBlock(it) })
|
||||
}
|
||||
|
||||
// ADD this function to group floating blocks, similar to the original parser
|
||||
private fun groupFloatingBlocks(blocks: List<ContentBlock>): List<ContentBlock> {
|
||||
if (blocks.isEmpty()) return emptyList()
|
||||
|
||||
|
|
@ -71,7 +72,6 @@ class ContentStyler(
|
|||
val floatDirection = (currentBlock as? ImageBlock)?.style?.float
|
||||
|
||||
if (currentBlock is ImageBlock && floatDirection in listOf("left", "right")) {
|
||||
val floatedImage = currentBlock
|
||||
val paragraphsToWrap = mutableListOf<ParagraphBlock>()
|
||||
|
||||
while (processingQueue.isNotEmpty()) {
|
||||
|
|
@ -86,11 +86,11 @@ class ContentStyler(
|
|||
}
|
||||
}
|
||||
val wrappingBlock = WrappingContentBlock(
|
||||
floatedImage,
|
||||
currentBlock,
|
||||
paragraphsToWrap,
|
||||
elementId = floatedImage.elementId,
|
||||
cfi = floatedImage.cfi,
|
||||
blockIndex = floatedImage.blockIndex
|
||||
elementId = currentBlock.elementId,
|
||||
cfi = currentBlock.cfi,
|
||||
blockIndex = currentBlock.blockIndex
|
||||
)
|
||||
result.add(wrappingBlock)
|
||||
} else {
|
||||
|
|
@ -208,7 +208,7 @@ class ContentStyler(
|
|||
private fun applyThemeToStyle(style: CssStyle): CssStyle {
|
||||
val newSpanStyle = style.spanStyle.let { original ->
|
||||
val newColor = if (original.color.isSpecified) {
|
||||
CssParser.adaptColorForTheme(original.color, isDarkTheme, isBackground = false)
|
||||
CssParser.adaptColorForTheme(original.color, isDarkTheme, isBackground = false, themeBackgroundColor, themeTextColor)
|
||||
} else {
|
||||
original.color
|
||||
}
|
||||
|
|
@ -217,14 +217,14 @@ class ContentStyler(
|
|||
|
||||
val newBlockStyle = style.blockStyle.let { original ->
|
||||
val newBgColor = if (original.backgroundColor.isSpecified) {
|
||||
CssParser.adaptColorForTheme(original.backgroundColor, isDarkTheme, isBackground = true)
|
||||
CssParser.adaptColorForTheme(original.backgroundColor, isDarkTheme, isBackground = true, themeBackgroundColor, themeTextColor)
|
||||
} else {
|
||||
original.backgroundColor
|
||||
}
|
||||
|
||||
fun themeBorder(b: BorderStyle?): BorderStyle? {
|
||||
if (b == null) return null
|
||||
val newColor = CssParser.adaptColorForTheme(b.color, isDarkTheme, isBackground = false)
|
||||
val newColor = CssParser.adaptColorForTheme(b.color, isDarkTheme, isBackground = false, themeBackgroundColor, themeTextColor)
|
||||
return b.copy(color = newColor)
|
||||
}
|
||||
|
||||
|
|
@ -474,7 +474,7 @@ class ContentStyler(
|
|||
}
|
||||
|
||||
private fun toRoman(number: Int): String {
|
||||
if (number < 1 || number > 3999) return number.toString()
|
||||
if (number !in 1..3999) return number.toString()
|
||||
val values = listOf(1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
|
||||
val symbols = listOf("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I")
|
||||
val result = StringBuilder()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue