字体阴影与斜体 #141
This commit is contained in:
@@ -32,6 +32,8 @@ import io.legato.kazusa.utils.putPrefInt
|
||||
import io.legato.kazusa.utils.resizeAndRecycle
|
||||
import splitties.init.appCtx
|
||||
import java.io.File
|
||||
import kotlin.String
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
|
||||
/**
|
||||
* 阅读界面配置
|
||||
@@ -58,6 +60,7 @@ object ReadBookConfig {
|
||||
var bg: Drawable? = null
|
||||
var bgMeanColor: Int = 0
|
||||
val textColor: Int get() = durConfig.curTextColor()
|
||||
val textShadowColor: Int get() = durConfig.curTextShadowColor()
|
||||
|
||||
init {
|
||||
initConfigs()
|
||||
@@ -246,6 +249,36 @@ object ReadBookConfig {
|
||||
config.textBold = value
|
||||
}
|
||||
|
||||
var textItalic: Boolean
|
||||
get() = config.textItalic
|
||||
set(value) {
|
||||
config.textItalic = value
|
||||
}
|
||||
|
||||
var textShadow: Boolean
|
||||
get() = config.textShadow
|
||||
set(value) {
|
||||
config.textShadow = value
|
||||
}
|
||||
|
||||
var shadowRadius: Float
|
||||
get() = config.shadowRadius
|
||||
set(value) {
|
||||
config.shadowRadius = value
|
||||
}
|
||||
|
||||
var shadowDx: Float
|
||||
get() = config.shadowDx
|
||||
set(value) {
|
||||
config.shadowDx = value
|
||||
}
|
||||
|
||||
var shadowDy: Float
|
||||
get() = config.shadowDy
|
||||
set(value) {
|
||||
config.shadowDy = value
|
||||
}
|
||||
|
||||
var textSize: Int
|
||||
get() = config.textSize
|
||||
set(value) {
|
||||
@@ -509,6 +542,13 @@ object ReadBookConfig {
|
||||
var textFont: String = "",//字体
|
||||
var textBold: Int = 500,//是否粗体字 0:正常, 1:粗体, 2:细体
|
||||
var textSize: Int = 20,//文字大小
|
||||
var textItalic: Boolean = false,// 是否启用斜体
|
||||
var textShadow: Boolean = false,// 是否启用阴影
|
||||
var shadowRadius: Float = 16f,// 阴影模糊半径
|
||||
var shadowDx: Float = 1f,// 阴影x偏移
|
||||
var shadowDy: Float = 1f,// 阴影y偏移
|
||||
private var shadowColor: String = "#3E3D3B",
|
||||
private var shadowColorN: String = "#3E3D3B",
|
||||
var letterSpacing: Float = 0.1f,//字间距
|
||||
var lineSpacingExtra: Int = 12,//行间距
|
||||
var paragraphSpacing: Int = 2,//段距
|
||||
@@ -553,16 +593,37 @@ object ReadBookConfig {
|
||||
@Transient
|
||||
private var textColorInt = -1
|
||||
|
||||
@Transient
|
||||
private var textColorSIntNight = -1
|
||||
|
||||
@Transient
|
||||
private var textColorSInt = -1
|
||||
|
||||
@Transient
|
||||
private var initColorInt = false
|
||||
|
||||
private fun initColorInt() {
|
||||
textColorIntEInk = Color.parseColor(textColorEInk)
|
||||
textColorIntNight = Color.parseColor(textColorNight)
|
||||
textColorInt = Color.parseColor(textColor)
|
||||
textColorIntEInk = textColorEInk.toColorInt()
|
||||
textColorIntNight = textColorNight.toColorInt()
|
||||
textColorInt = textColor.toColorInt()
|
||||
textColorSIntNight = shadowColorN.toColorInt()
|
||||
textColorSInt = shadowColor.toColorInt()
|
||||
initColorInt = true
|
||||
}
|
||||
|
||||
fun setCurShadColor(color: Int){
|
||||
when {
|
||||
AppConfig.isNightTheme -> {
|
||||
shadowColorN = "#${color.hexString}"
|
||||
textColorSIntNight = color
|
||||
}
|
||||
else -> {
|
||||
shadowColor = "#${color.hexString}"
|
||||
textColorSInt = color
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setCurTextColor(color: Int) {
|
||||
when {
|
||||
AppConfig.isEInkMode -> {
|
||||
@@ -593,6 +654,16 @@ object ReadBookConfig {
|
||||
}
|
||||
}
|
||||
|
||||
fun curTextShadowColor(): Int {
|
||||
if (!initColorInt) {
|
||||
initColorInt()
|
||||
}
|
||||
return when {
|
||||
AppConfig.isNightTheme -> textColorSIntNight
|
||||
else -> textColorSInt
|
||||
}
|
||||
}
|
||||
|
||||
fun setCurStatusIconDark(isDark: Boolean) {
|
||||
when {
|
||||
AppConfig.isEInkMode -> darkStatusIconEInk = isDark
|
||||
@@ -661,18 +732,18 @@ object ReadBookConfig {
|
||||
fun curBgDrawable(width: Int, height: Int): Drawable {
|
||||
if (width == 0 || height == 0) {
|
||||
val backgroundColor = MaterialColors.getColor(appCtx, com.google.android.material.R.attr.colorSurface, Color.WHITE)
|
||||
return ColorDrawable(backgroundColor)
|
||||
return backgroundColor.toDrawable()
|
||||
}
|
||||
|
||||
var bgDrawable: Drawable? = null
|
||||
val resources = appCtx.resources
|
||||
try {
|
||||
bgDrawable = when (curBgType()) {
|
||||
0 -> ColorDrawable(Color.parseColor(curBgStr()))
|
||||
0 -> curBgStr().toColorInt().toDrawable()
|
||||
1 -> {
|
||||
val path = "bg" + File.separator + curBgStr()
|
||||
val bitmap = BitmapUtils.decodeAssetsBitmap(appCtx, path, width, height)
|
||||
BitmapDrawable(resources, bitmap?.resizeAndRecycle(width, height))
|
||||
bitmap?.resizeAndRecycle(width, height)?.toDrawable(resources)
|
||||
}
|
||||
else -> {
|
||||
val path = curBgStr().let {
|
||||
@@ -680,7 +751,7 @@ object ReadBookConfig {
|
||||
else FileUtils.getPath(appCtx.externalFiles, "bg", curBgStr())
|
||||
}
|
||||
val bitmap = BitmapUtils.decodeBitmap(path, width, height)
|
||||
BitmapDrawable(resources, bitmap?.resizeAndRecycle(width, height))
|
||||
bitmap?.resizeAndRecycle(width, height)?.toDrawable(resources)
|
||||
}
|
||||
}
|
||||
} catch (e: OutOfMemoryError) {
|
||||
@@ -691,7 +762,7 @@ object ReadBookConfig {
|
||||
|
||||
// fallback 使用 MD3 的 colorSurface 作为背景色
|
||||
val fallbackColor = MaterialColors.getColor(appCtx, com.google.android.material.R.attr.colorSurface, Color.WHITE)
|
||||
return bgDrawable ?: ColorDrawable(fallbackColor)
|
||||
return bgDrawable ?: fallbackColor.toDrawable()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,7 @@ import io.legato.kazusa.ui.book.info.BookInfoActivity
|
||||
import io.legato.kazusa.ui.book.read.config.AutoReadDialog
|
||||
import io.legato.kazusa.ui.book.read.config.BgTextConfigDialog.Companion.BG_COLOR
|
||||
import io.legato.kazusa.ui.book.read.config.BgTextConfigDialog.Companion.TEXT_COLOR
|
||||
import io.legato.kazusa.ui.book.read.config.FontSelectDialog.Companion.S_COLOR
|
||||
import io.legato.kazusa.ui.book.read.config.ReadAloudDialog
|
||||
import io.legato.kazusa.ui.book.read.config.ReadStyleDialog
|
||||
import io.legato.kazusa.ui.book.read.config.TipConfigDialog.Companion.TIP_COLOR
|
||||
@@ -1504,6 +1505,10 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
*/
|
||||
override fun onColorSelected(dialogId: Int, color: Int) = ReadBookConfig.durConfig.run {
|
||||
when (dialogId) {
|
||||
S_COLOR -> {
|
||||
setCurShadColor(color)
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(2, 6, 9, 11))
|
||||
}
|
||||
TEXT_COLOR -> {
|
||||
setCurTextColor(color)
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(2, 6, 9, 11))
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package io.legato.kazusa.ui.book.read.config
|
||||
|
||||
//import io.legado.app.lib.theme.primaryColor
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import io.legato.kazusa.help.config.ReadBookConfig
|
||||
import androidx.core.net.toUri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.jaredrummler.android.colorpicker.ColorPickerDialog
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.base.BaseBottomSheetDialogFragment
|
||||
import io.legato.kazusa.base.adapter.ItemViewHolder
|
||||
@@ -22,7 +24,6 @@ import io.legato.kazusa.constant.PreferKey
|
||||
import io.legato.kazusa.databinding.DialogFontSelectBinding
|
||||
import io.legato.kazusa.databinding.ItemFontBinding
|
||||
import io.legato.kazusa.help.config.AppConfig
|
||||
import io.legato.kazusa.help.config.ReadBookConfig
|
||||
import io.legato.kazusa.lib.dialogs.SelectItem
|
||||
import io.legato.kazusa.lib.dialogs.alert
|
||||
import io.legato.kazusa.lib.permission.Permissions
|
||||
@@ -54,6 +55,10 @@ import java.net.URLDecoder
|
||||
*/
|
||||
class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_select),
|
||||
Toolbar.OnMenuItemClickListener {
|
||||
|
||||
companion object {
|
||||
const val S_COLOR = 123
|
||||
}
|
||||
private val fontRegex = Regex("(?i).*\\.[ot]tf")
|
||||
private val binding by viewBinding(DialogFontSelectBinding::bind)
|
||||
private val adapter by lazy {
|
||||
@@ -118,21 +123,19 @@ class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_sele
|
||||
((it - 50) / 100f).toString()
|
||||
}
|
||||
dsbLineSize.valueFormat = { ((it - 10) / 10f).toString() }
|
||||
binding.dsbShadowRadius.valueFormat = { "${it.toInt()} px" }
|
||||
binding.dsbShadowDx.valueFormat = { "${it.toInt()} px" }
|
||||
binding.dsbShadowDy.valueFormat = { "${it.toInt()} px" }
|
||||
|
||||
binding.bgTextIndent.apply {
|
||||
val currentIndex = ReadBookConfig.paragraphIndent.length.coerceAtMost(childCount - 1)
|
||||
val defaultButtonId = getChildAt(currentIndex).id
|
||||
check(defaultButtonId)
|
||||
|
||||
addOnButtonCheckedListener { group, checkedId, isChecked ->
|
||||
if (isChecked) {
|
||||
val checkedIndex = (0 until group.childCount)
|
||||
.firstOrNull { group.getChildAt(it).id == checkedId }
|
||||
?: return@addOnButtonCheckedListener
|
||||
|
||||
ReadBookConfig.paragraphIndent = " ".repeat(checkedIndex)
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
binding.textIndentDropdown.apply {
|
||||
val items = listOf("0", "1", "2", "3", "4")
|
||||
val adapter = ArrayAdapter(context, android.R.layout.simple_list_item_1, items)
|
||||
setAdapter(adapter)
|
||||
val currentIndex = ReadBookConfig.paragraphIndent.length.coerceIn(0, items.lastIndex)
|
||||
setText(items[currentIndex], false)
|
||||
setOnItemClickListener { _, _, position, _ ->
|
||||
ReadBookConfig.paragraphIndent = " ".repeat(position)
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,6 +169,9 @@ class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_sele
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 9, 6))
|
||||
}
|
||||
}
|
||||
|
||||
binding.btnTextItalic.isChecked = ReadBookConfig.textItalic
|
||||
binding.btnTextShadow.isChecked = ReadBookConfig.textShadow
|
||||
}
|
||||
|
||||
private fun initViewEvent() = binding.run {
|
||||
@@ -192,6 +198,35 @@ class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_sele
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.btnTextItalic.addOnCheckedChangeListener { _, isChecked ->
|
||||
ReadBookConfig.textItalic = isChecked
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
binding.btnTextShadow.addOnCheckedChangeListener { _, isChecked ->
|
||||
ReadBookConfig.textShadow = isChecked
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
binding.dsbShadowRadius.onChanged = {
|
||||
ReadBookConfig.shadowRadius = it.toFloat()
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
binding.dsbShadowDx.onChanged = {
|
||||
ReadBookConfig.shadowDx = it.toFloat()
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
binding.dsbShadowDy.onChanged = {
|
||||
ReadBookConfig.shadowDy = it.toFloat()
|
||||
postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
binding.btnShadowColor.setOnClickListener {
|
||||
ColorPickerDialog.newBuilder()
|
||||
.setColor(ReadBookConfig.config.curTextShadowColor())
|
||||
.setShowAlphaSlider(false)
|
||||
.setDialogType(ColorPickerDialog.TYPE_CUSTOM)
|
||||
.setDialogId(S_COLOR)
|
||||
.show(requireActivity())
|
||||
//postEvent(EventBus.UP_CONFIG, arrayListOf(8, 5))
|
||||
}
|
||||
}
|
||||
|
||||
private fun upView() = binding.run {
|
||||
@@ -199,6 +234,9 @@ class FontSelectDialog : BaseBottomSheetDialogFragment(R.layout.dialog_font_sele
|
||||
dsbTextLetterSpacing.progress = (it.letterSpacing * 100).toInt() + 50
|
||||
dsbLineSize.progress = it.lineSpacingExtra
|
||||
dsbParagraphSpacing.value = it.paragraphSpacing.toFloat()
|
||||
binding.dsbShadowRadius.progress = it.shadowRadius.toInt()
|
||||
binding.dsbShadowDx.progress = it.shadowDx.toInt()
|
||||
binding.dsbShadowDy.progress = it.shadowDy.toInt()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.legato.kazusa.ui.book.read.page.provider
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint.FontMetrics
|
||||
import android.graphics.RectF
|
||||
import android.graphics.Typeface
|
||||
@@ -38,6 +40,7 @@ import splitties.init.appCtx
|
||||
import java.io.File
|
||||
import java.util.LinkedList
|
||||
import java.util.Locale
|
||||
import androidx.core.graphics.toColorInt
|
||||
|
||||
/**
|
||||
* 解析内容生成章节和页面
|
||||
@@ -910,6 +913,7 @@ object ChapterProvider {
|
||||
} ?: Typeface.DEFAULT
|
||||
}
|
||||
|
||||
@SuppressLint("UseKtx")
|
||||
private fun getPaints(typeface: Typeface?): Pair<TextPaint, TextPaint> {
|
||||
val bold = Typeface.create(typeface, Typeface.BOLD)
|
||||
val normal = Typeface.create(typeface, Typeface.NORMAL)
|
||||
@@ -952,6 +956,17 @@ object ChapterProvider {
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q && AppConfig.optimizeRender) {
|
||||
tPaint.isLinearText = true
|
||||
}
|
||||
if (ReadBookConfig.textItalic) {
|
||||
tPaint.textSkewX = -0.25f
|
||||
}
|
||||
if (ReadBookConfig.textShadow) {
|
||||
tPaint.setShadowLayer(
|
||||
ReadBookConfig.shadowRadius,
|
||||
ReadBookConfig.shadowDx,
|
||||
ReadBookConfig.shadowDy,
|
||||
ReadBookConfig.textShadowColor
|
||||
)
|
||||
}
|
||||
//正文
|
||||
val cPaint = TextPaint()
|
||||
cPaint.color = ReadBookConfig.textColor
|
||||
@@ -964,7 +979,17 @@ object ChapterProvider {
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q && AppConfig.optimizeRender) {
|
||||
cPaint.isLinearText = true
|
||||
}
|
||||
|
||||
if (ReadBookConfig.textItalic) {
|
||||
cPaint.textSkewX = -0.25f
|
||||
}
|
||||
if (ReadBookConfig.textShadow) {
|
||||
cPaint.setShadowLayer(
|
||||
ReadBookConfig.shadowRadius,
|
||||
ReadBookConfig.shadowDx,
|
||||
ReadBookConfig.shadowDy,
|
||||
ReadBookConfig.textShadowColor
|
||||
)
|
||||
}
|
||||
return Pair(tPaint, cPaint)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user