[修复] 书籍封面作者显示不足

[新增] 书籍封面字体颜色自定义、描边选择开关、阴影颜色自定义与开关
This commit is contained in:
HapeLee
2025-12-11 00:47:30 +08:00
parent 32fe45319b
commit e146bfcd97
9 changed files with 163 additions and 31 deletions
+1 -1
View File
@@ -124,7 +124,7 @@ android {
} }
manifestPlaceholders.put("app_name", "@string/app_name") manifestPlaceholders.put("app_name", "@string/app_name")
//applicationIdSuffix '.debug' applicationIdSuffix '.debug'
versionNameSuffix "_debug+${getGitCommitHash()}" versionNameSuffix "_debug+${getGitCommitHash()}"
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'cronet-proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'cronet-proguard-rules.pro'
@@ -13,6 +13,13 @@ object PreferKey {
const val loadCoverOnlyWifi = "loadCoverOnlyWifi" const val loadCoverOnlyWifi = "loadCoverOnlyWifi"
const val coverShowName = "coverShowName" const val coverShowName = "coverShowName"
const val coverShowAuthor = "coverShowAuthor" const val coverShowAuthor = "coverShowAuthor"
const val coverShowShadow = "coverShowShadow"
const val coverShowStroke = "coverShowStroke"
const val coverTextColor = "coverTextColor"
const val coverTextColorN = "coverTextColorN"
const val coverShadowColor = "coverShadowColor"
const val coverShadowColorN = "coverShadowColorN"
const val coverDefaultColor = "coverDefaultColor"
const val coverShowNameN = "coverShowNameN" const val coverShowNameN = "coverShowNameN"
const val coverShowAuthorN = "coverShowAuthorN" const val coverShowAuthorN = "coverShowAuthorN"
const val remoteServerId = "remoteServerId" const val remoteServerId = "remoteServerId"
@@ -3,6 +3,7 @@ package io.legado.app.model
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import androidx.annotation.Keep import androidx.annotation.Keep
import androidx.core.graphics.drawable.toDrawable import androidx.core.graphics.drawable.toDrawable
@@ -35,10 +36,11 @@ import io.legado.app.utils.BitmapUtils
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonObject import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.getPrefInt
import io.legado.app.utils.getPrefString import io.legado.app.utils.getPrefString
import kotlinx.coroutines.currentCoroutineContext
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import kotlin.coroutines.coroutineContext
@Keep @Keep
object BookCover { object BookCover {
@@ -48,6 +50,20 @@ object BookCover {
private set private set
var drawBookAuthor = true var drawBookAuthor = true
private set private set
var drawBookShadow = true
private set
var drawBookStroke = true
private set
var coverTextColor: Int = Color.WHITE
private set
var coverShadowColor: Int = Color.WHITE
private set
var coverTextColorN: Int = Color.WHITE
private set
var coverShadowColorN: Int = Color.WHITE
private set
var coverDefaultColor = true
private set
lateinit var defaultDrawable: Drawable lateinit var defaultDrawable: Drawable
private set private set
@@ -69,6 +85,21 @@ object BookCover {
} else { } else {
appCtx.getPrefBoolean(PreferKey.coverShowAuthor, true) appCtx.getPrefBoolean(PreferKey.coverShowAuthor, true)
} }
drawBookShadow =
appCtx.getPrefBoolean(PreferKey.coverShowShadow, false)
drawBookStroke =
appCtx.getPrefBoolean(PreferKey.coverShowStroke, true)
coverDefaultColor =
appCtx.getPrefBoolean(PreferKey.coverDefaultColor, true)
coverTextColor =
appCtx.getPrefInt(PreferKey.coverTextColor, Color.WHITE)
coverTextColorN =
appCtx.getPrefInt(PreferKey.coverTextColorN, Color.BLACK)
coverShadowColor =
appCtx.getPrefInt(PreferKey.coverShadowColor, Color.WHITE)
coverShadowColorN =
appCtx.getPrefInt(PreferKey.coverShadowColorN, Color.BLACK)
val key = if (isNightTheme) PreferKey.defaultCoverDark else PreferKey.defaultCover val key = if (isNightTheme) PreferKey.defaultCoverDark else PreferKey.defaultCover
val path = appCtx.getPrefString(key) val path = appCtx.getPrefString(key)
if (path.isNullOrBlank()) { if (path.isNullOrBlank()) {
@@ -222,12 +253,12 @@ object BookCover {
config.searchUrl, config.searchUrl,
book.name, book.name,
source = config, source = config,
coroutineContext = coroutineContext, coroutineContext = currentCoroutineContext(),
hasLoginHeader = false hasLoginHeader = false
) )
val res = analyzeUrl.getStrResponseAwait() val res = analyzeUrl.getStrResponseAwait()
val analyzeRule = AnalyzeRule(book) val analyzeRule = AnalyzeRule(book)
analyzeRule.setCoroutineContext(coroutineContext) analyzeRule.setCoroutineContext(currentCoroutineContext())
analyzeRule.setContent(res.body) analyzeRule.setContent(res.body)
analyzeRule.setRedirectUrl(res.url) analyzeRule.setRedirectUrl(res.url)
return analyzeRule.getString(config.coverRule, isUrl = true) return analyzeRule.getString(config.coverRule, isUrl = true)
@@ -74,6 +74,13 @@ class CoverConfigFragment : PreferenceFragment(),
?.isEnabled = getPrefBoolean(key) ?.isEnabled = getPrefBoolean(key)
BookCover.upDefaultCover() BookCover.upDefaultCover()
} }
PreferKey.coverTextColor,
PreferKey.coverTextColorN,
PreferKey.coverShadowColor,
PreferKey.coverShadowColorN,
PreferKey.coverDefaultColor,
PreferKey.coverShowShadow,
PreferKey.coverShowStroke,
PreferKey.coverShowAuthor, PreferKey.coverShowAuthor,
PreferKey.coverShowAuthorN -> { PreferKey.coverShowAuthorN -> {
BookCover.upDefaultCover() BookCover.upDefaultCover()
@@ -22,7 +22,6 @@ import io.legado.app.constant.AppPattern
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.glide.ImageLoader import io.legado.app.help.glide.ImageLoader
import io.legado.app.help.glide.OkHttpModelLoader import io.legado.app.help.glide.OkHttpModelLoader
//import io.legado.app.lib.theme.accentColor
import io.legado.app.model.BookCover import io.legado.app.model.BookCover
import io.legado.app.utils.spToPx import io.legado.app.utils.spToPx
import io.legado.app.utils.textHeight import io.legado.app.utils.textHeight
@@ -47,6 +46,9 @@ class CoverImageView @JvmOverloads constructor(
private var author: String? = null private var author: String? = null
private var nameHeight = 0f private var nameHeight = 0f
private var authorHeight = 0f private var authorHeight = 0f
private val isNightTheme = AppConfig.isNightTheme
val colorKey = if (isNightTheme) BookCover.coverTextColorN else BookCover.coverTextColor
val shadowKey = if (isNightTheme) BookCover.coverShadowColorN else BookCover.coverShadowColor
private val namePaint by lazy { private val namePaint by lazy {
val textPaint = TextPaint() val textPaint = TextPaint()
textPaint.typeface = Typeface.DEFAULT_BOLD textPaint.typeface = Typeface.DEFAULT_BOLD
@@ -119,21 +121,35 @@ class CoverImageView @JvmOverloads constructor(
} }
private fun drawNameAuthor(canvas: Canvas) { private fun drawNameAuthor(canvas: Canvas) {
var startX = width * 0.2f
var startY = viewHeight * 0.2f
if (BookCover.drawBookName) { if (BookCover.drawBookName) {
var startX = width * 0.2f
var startY = viewHeight * 0.2f
name?.toStringArray()?.let { nameChars -> name?.toStringArray()?.let { nameChars ->
val textSize = viewWidth / 8 val textSize = viewWidth / 8
namePaint.textSize = textSize namePaint.textSize = textSize
namePaint.strokeWidth = textSize / 8 namePaint.strokeWidth = textSize / 8
nameChars.forEach { char -> if (BookCover.drawBookShadow) {
namePaint.color = Color.WHITE namePaint.setShadowLayer(
namePaint.style = Paint.Style.STROKE 4f,
canvas.drawText(char, startX, startY, namePaint) 0f,
0f,
shadowKey
)
} else {
namePaint.clearShadowLayer()
}
namePaint.color = context.themeColor(androidx.appcompat.R.attr.colorPrimary) nameChars.forEach { char ->
if (BookCover.drawBookStroke) {
namePaint.color = Color.WHITE
namePaint.style = Paint.Style.STROKE
canvas.drawText(char, startX, startY, namePaint)
}
if (BookCover.coverDefaultColor)
namePaint.color = context.themeColor(com.google.android.material.R.attr.colorSecondary)
else
namePaint.color = colorKey
namePaint.style = Paint.Style.FILL namePaint.style = Paint.Style.FILL
canvas.drawText(char, startX, startY, namePaint) canvas.drawText(char, startX, startY, namePaint)
@@ -144,33 +160,48 @@ class CoverImageView @JvmOverloads constructor(
startY = viewHeight * 0.2f startY = viewHeight * 0.2f
} }
} }
namePaint.clearShadowLayer()
} }
} }
if (BookCover.drawBookAuthor) { if (BookCover.drawBookAuthor) {
author?.toStringArray()?.let { authorChars -> author?.toStringArray()?.let { author ->
val textSize = viewWidth / 10 authorPaint.textSize = viewWidth / 10
authorPaint.textSize = textSize authorPaint.strokeWidth = authorPaint.textSize / 5
authorPaint.strokeWidth = textSize / 5 startX = width * 0.8f
startY = viewHeight * 0.95f - author.size * authorPaint.textHeight
startY = maxOf(startY, viewHeight * 0.2f)
if (BookCover.drawBookShadow) {
authorPaint.setShadowLayer(
4f,
0f,
0f,
shadowKey
)
} else {
authorPaint.clearShadowLayer()
}
var startX = width * 0.8f author.forEach {
var startY = viewHeight * 0.8f if (BookCover.drawBookStroke) {
authorPaint.color = Color.WHITE
authorChars.forEach { char -> authorPaint.style = Paint.Style.STROKE
canvas.drawText(it, startX, startY, authorPaint)
authorPaint.color = Color.WHITE }
authorPaint.style = Paint.Style.STROKE if (BookCover.coverDefaultColor)
canvas.drawText(char, startX, startY, authorPaint) authorPaint.color = context.themeColor(com.google.android.material.R.attr.colorSecondary)
else
authorPaint.color = authorPaint.color = colorKey
context.themeColor(com.google.android.material.R.attr.colorSecondary)
authorPaint.style = Paint.Style.FILL authorPaint.style = Paint.Style.FILL
canvas.drawText(char, startX, startY, authorPaint) canvas.drawText(it, startX, startY, authorPaint)
startY += authorPaint.textHeight startY += authorPaint.textHeight
if (startY > viewHeight * 0.95f) return@let if (startY > viewHeight * 0.95) {
return@let
}
} }
authorPaint.clearShadowLayer()
} }
} }
} }
+3
View File
@@ -1356,4 +1356,7 @@
<string name="is_read_finished">已读</string> <string name="is_read_finished">已读</string>
<string name="manga">漫画</string> <string name="manga">漫画</string>
<string name="noval">小说</string> <string name="noval">小说</string>
<string name="cover_show_shadow">显示字体阴影</string>
<string name="cover_show_stroke">显示字体描边</string>
<string name="default_color">使用默认字体颜色</string>
</resources> </resources>
-1
View File
@@ -589,7 +589,6 @@
<color name="disabled">@color/md_light_disabled</color> <color name="disabled">@color/md_light_disabled</color>
<color name="divider">#66666666</color> <color name="divider">#66666666</color>
<color name="lightBlue_color">#FF578FCC</color> <color name="lightBlue_color">#FF578FCC</color>
<color name="error">#eb4333</color> <color name="error">#eb4333</color>
+3
View File
@@ -1359,4 +1359,7 @@
<string name="is_read_finished">已读</string> <string name="is_read_finished">已读</string>
<string name="manga">漫画</string> <string name="manga">漫画</string>
<string name="noval">小说</string> <string name="noval">小说</string>
<string name="cover_show_shadow">显示字体阴影</string>
<string name="cover_show_stroke">显示字体描边</string>
<string name="default_color">使用默认字体颜色</string>
</resources> </resources>
@@ -25,6 +25,29 @@
app:allowDividerBelow="false" app:allowDividerBelow="false"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.SwitchPreference
android:key="coverShowShadow"
android:title="@string/cover_show_shadow"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.SwitchPreference
android:key="coverShowStroke"
android:title="@string/cover_show_stroke"
android:defaultValue="true"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.SwitchPreference
android:key="coverDefaultColor"
android:title="@string/default_color"
android:defaultValue="true"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.PreferenceCategory <io.legado.app.lib.prefs.PreferenceCategory
android:key="dayThemeCategory" android:key="dayThemeCategory"
android:title="@string/day" android:title="@string/day"
@@ -40,6 +63,20 @@
app:allowDividerBelow="false" app:allowDividerBelow="false"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.ColorPreference
android:defaultValue="@color/md_green_500"
android:key="coverTextColor"
android:title="@string/text_color"
app:cpv_dialogType="preset"
app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.ColorPreference
android:defaultValue="@color/md_green_500"
android:key="coverShadowColor"
android:title="@string/text_shadow_color"
app:cpv_dialogType="preset"
app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.SwitchPreference <io.legado.app.lib.prefs.SwitchPreference
android:defaultValue="true" android:defaultValue="true"
android:key="coverShowName" android:key="coverShowName"
@@ -75,6 +112,20 @@
app:allowDividerBelow="false" app:allowDividerBelow="false"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.ColorPreference
android:defaultValue="@color/md_green_500"
android:key="coverTextColorN"
android:title="@string/text_color"
app:cpv_dialogType="preset"
app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.ColorPreference
android:defaultValue="@color/md_green_500"
android:key="coverShadowColorN"
android:title="@string/text_shadow_color"
app:cpv_dialogType="preset"
app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.SwitchPreference <io.legado.app.lib.prefs.SwitchPreference
android:defaultValue="true" android:defaultValue="true"
android:key="coverShowNameN" android:key="coverShowNameN"