fix(reader): make webview align with reading font family (#882)

* fix(reader): make webview align with reading font family

* feat(reader): external font support in webview
This commit is contained in:
junkfood 2024-11-20 16:17:40 +09:00 committed by GitHub
parent 47a911ae0d
commit 697e94eb88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 4 deletions

View File

@ -16,6 +16,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import me.ash.reader.infrastructure.preference.LocalOpenLink
import me.ash.reader.infrastructure.preference.LocalOpenLinkSpecificBrowser
import me.ash.reader.infrastructure.preference.LocalReadingBionicReading
import me.ash.reader.infrastructure.preference.LocalReadingFonts
import me.ash.reader.infrastructure.preference.LocalReadingImageHorizontalPadding
import me.ash.reader.infrastructure.preference.LocalReadingImageRoundedCorners
import me.ash.reader.infrastructure.preference.LocalReadingPageTonalElevation
@ -27,6 +28,8 @@ import me.ash.reader.infrastructure.preference.LocalReadingTextFontSize
import me.ash.reader.infrastructure.preference.LocalReadingTextHorizontalPadding
import me.ash.reader.infrastructure.preference.LocalReadingTextLetterSpacing
import me.ash.reader.infrastructure.preference.LocalReadingTextLineHeight
import me.ash.reader.infrastructure.preference.ReadingFontsPreference
import me.ash.reader.ui.ext.ExternalFonts
import me.ash.reader.ui.ext.openURL
import me.ash.reader.ui.ext.surfaceColorAtElevation
import me.ash.reader.ui.theme.palette.alwaysLight
@ -55,6 +58,7 @@ fun RYWebView(
val linkTextColor: Int = MaterialTheme.colorScheme.primary.toArgb()
val subheadBold: Boolean = LocalReadingSubheadBold.current.value
val subheadUpperCase: Boolean = LocalReadingSubheadUpperCase.current.value
val readingFonts = LocalReadingFonts.current
val fontSize: Int = LocalReadingTextFontSize.current
val letterSpacing: Float = LocalReadingTextLetterSpacing.current
val lineHeight: Float = LocalReadingTextLineHeight.current
@ -69,6 +73,7 @@ fun RYWebView(
mutableStateOf(
WebViewLayout.get(
context = context,
readingFontsPreference = readingFonts,
webViewClient = WebViewClient(
context = context,
refererDomain = refererDomain,
@ -81,6 +86,11 @@ fun RYWebView(
)
}
val fontPath =
if (readingFonts is ReadingFontsPreference.External) ExternalFonts.FontType.ReadingFont.toPath(
context
) else null
AndroidView(
modifier = modifier,
factory = { webView },
@ -95,6 +105,7 @@ fun RYWebView(
WebViewHtml.HTML.format(
WebViewStyle.get(
fontSize = fontSize,
fontPath = fontPath,
lineHeight = lineHeight,
letterSpacing = letterSpacing,
textMargin = textMargin,

View File

@ -5,12 +5,15 @@ import android.content.Context
import android.graphics.Color
import android.webkit.JavascriptInterface
import android.webkit.WebView
import me.ash.reader.infrastructure.preference.BasicFontsPreference
import me.ash.reader.infrastructure.preference.ReadingFontsPreference
object WebViewLayout {
@SuppressLint("SetJavaScriptEnabled")
fun get(
context: Context,
readingFontsPreference: ReadingFontsPreference,
webViewClient: WebViewClient,
onImageClick: ((imgUrl: String, altText: String) -> Unit)? = null,
) = WebView(context).apply {
@ -20,6 +23,20 @@ object WebViewLayout {
isVerticalScrollBarEnabled = true
setBackgroundColor(Color.TRANSPARENT)
with(this.settings) {
standardFontFamily = when (readingFontsPreference) {
ReadingFontsPreference.Cursive -> "cursive"
ReadingFontsPreference.Monospace -> "monospace"
ReadingFontsPreference.SansSerif -> "sans-serif"
ReadingFontsPreference.Serif -> "serif"
ReadingFontsPreference.External -> {
allowFileAccess = true
allowFileAccessFromFileURLs = true
"sans-serif"
}
else -> "sans-serif"
}
domStorageEnabled = true
javaScriptEnabled = true
addJavascriptInterface(object : JavaScriptInterface {

View File

@ -4,8 +4,24 @@ object WebViewStyle {
private fun argbToCssColor(argb: Int): String = String.format("#%06X", 0xFFFFFF and argb)
private fun applyFontFace(
fontPath: String? = null
): String = if (fontPath != null) """
@font-face {
font-family: external;
src: url("file://$fontPath")
}
""".trimIndent() else ""
private fun applyFontFamily(
fontPath: String? = null
): String = if (fontPath != null) """
--font-family: external;
""".trimIndent() else ""
fun get(
fontSize: Int,
fontPath: String? = null,
lineHeight: Float,
letterSpacing: Float,
textMargin: Int,
@ -24,21 +40,22 @@ object WebViewStyle {
selectionTextColor: Int,
selectionBgColor: Int,
): String = """
${applyFontFace(fontPath)}
:root {
/* --font-family: Inter; */
${applyFontFamily(fontPath)}
--font-size: ${fontSize}px;
--line-height: ${lineHeight * 1.5f};
--letter-spacing: ${letterSpacing}px;
--text-margin: ${textMargin}px;
--text-color: ${argbToCssColor(textColor)};
--text-bold: ${if(textBold) "600" else "normal"};
--text-bold: ${if (textBold) "600" else "normal"};
--text-align: ${textAlign};
--bold-text-color: ${argbToCssColor(boldTextColor)};
--link-text-color: ${argbToCssColor(linkTextColor)};
--selection-text-color: ${argbToCssColor(selectionTextColor)};
--selection-bg-color: ${argbToCssColor(selectionBgColor)};
--subhead-bold: ${if(subheadBold) "600" else "normal"};
--subhead-upper-case: ${if(subheadUpperCase) "uppercase" else "none"};
--subhead-bold: ${if (subheadBold) "600" else "normal"};
--subhead-upper-case: ${if (subheadUpperCase) "uppercase" else "none"};
--img-margin: ${imgMargin}px;
--img-border-radius: ${imgBorderRadius}px;
--content-padding;