Automatic background color for PagerViewer (#4996)

* Add J2K implementation of automatic background

Co-authored-by: Jays2Kings <8617760+Jays2Kings@users.noreply.github.com>

* Tweak the monstrosity called automatic background

* Add ability to choose Automatic as a background

* More tweaks

Co-authored-by: Jays2Kings <8617760+Jays2Kings@users.noreply.github.com>
(cherry picked from commit 122cdae5bcbb0421c98e271521d32fadc7c95beb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt
#	app/src/main/res/values/arrays.xml
This commit is contained in:
Andreas 2021-05-05 04:46:42 +02:00 committed by Jobobby04
parent 7e612e63b4
commit 6238f06d39
13 changed files with 145 additions and 198 deletions

View File

@ -34,7 +34,7 @@ android {
minSdkVersion(AndroidConfig.minSdk)
targetSdkVersion(AndroidConfig.targetSdk)
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
versionCode = 17
versionCode = 18
versionName = "1.6.2"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")

View File

@ -1,15 +1,12 @@
package eu.kanade.tachiyomi.ui.reader.loader
import android.graphics.BitmapFactory
import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerPageHolder
import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.system.ImageUtil
import exh.source.isEhBasedSource
import rx.Completable
import rx.Observable
@ -258,20 +255,6 @@ class HttpPageLoader(
}
}
.doOnNext {
// SY -->
val readerTheme = preferences.readerTheme().get()
if (readerTheme >= 3) {
val stream = chapterCache.getImageFile(imageUrl).inputStream()
val image = BitmapFactory.decodeStream(stream)
page.bg = ImageUtil.autoSetBackground(
image,
readerTheme == 3,
preferences.context
)
page.bgType = PagerPageHolder.getBGType(readerTheme, preferences.context)
stream.close()
}
// SY <--
page.stream = { chapterCache.getImageFile(imageUrl).inputStream() }
page.status = Page.READY
}

View File

@ -23,6 +23,9 @@ class PagerConfig(
preferences: PreferencesHelper = Injekt.get()
) : ViewerConfig(preferences, scope) {
var automaticBackground = false
private set
var dualPageSplitChangedListener: ((Boolean) -> Unit)? = null
var imageScaleType = 1
@ -39,6 +42,9 @@ class PagerConfig(
// SY <--
init {
preferences.readerTheme()
.register({ automaticBackground = it == 3 }, { imagePropertyChangedListener?.invoke() })
preferences.imageScaleType()
.register({ imageScaleType = it }, { imagePropertyChangedListener?.invoke() })

View File

@ -1,11 +1,8 @@
package eu.kanade.tachiyomi.ui.reader.viewer.pager
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.PointF
import android.graphics.drawable.Animatable
import android.graphics.drawable.Drawable
import android.view.GestureDetector
import android.view.Gravity
import android.view.MotionEvent
@ -24,26 +21,19 @@ import com.davemorrissey.labs.subscaleview.ImageSource
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.github.chrisbanes.photoview.PhotoView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.ui.reader.model.InsertPage
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.viewer.ReaderProgressBar
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig.ZoomType
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.widget.ViewPagerAdapter
import exh.util.isInNightMode
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import rx.Observable
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.InputStream
import java.nio.ByteBuffer
import java.util.concurrent.TimeUnit
@ -104,12 +94,6 @@ class PagerPageHolder(
*/
private var readImageHeaderSubscription: Subscription? = null
// SY -->
private val readerTheme by lazy {
Injekt.get<PreferencesHelper>().readerTheme().get()
}
// SY <--
init {
addView(progressBar)
observeStatus()
@ -254,30 +238,12 @@ class PagerPageHolder(
.observeOn(AndroidSchedulers.mainThread())
.doOnNext { isAnimated ->
if (!isAnimated) {
// SY -->
if (readerTheme >= 3) {
val imageView = initSubsamplingImageView()
if (page.bg != null && page.bgType == getBGType(readerTheme, context)) {
imageView.setImage(ImageSource.inputStream(openStream!!))
imageView.background = page.bg
initSubsamplingImageView().apply {
if (viewer.config.automaticBackground) {
background = ImageUtil.chooseBackground(context, openStream!!)
}
// if the user switches to automatic when pages are already cached, the bg needs to be loaded
else {
val bytesArray = openStream!!.readBytes()
val bytesStream = bytesArray.inputStream()
imageView.setImage(ImageSource.inputStream(bytesStream))
bytesStream.close()
launchUI {
imageView.background = setBG(bytesArray)
page.bg = imageView.background
page.bgType = getBGType(readerTheme, context)
}
}
} else {
initSubsamplingImageView().setImage(ImageSource.inputStream(openStream!!))
setImage(ImageSource.inputStream(openStream!!))
}
// SY <--
} else {
initImageView().setImage(openStream!!)
}
@ -331,22 +297,6 @@ class PagerPageHolder(
viewer.onPageSplit(page, newPage)
}
// SY -->
private suspend fun setBG(bytesArray: ByteArray): Drawable {
return withContext(Dispatchers.Default) {
ImageUtil.autoSetBackground(
BitmapFactory.decodeByteArray(
bytesArray,
0,
bytesArray.size
),
readerTheme == 3,
context
)
}
}
// SY <--
/**
* Called when the page has an error.
*/
@ -550,14 +500,4 @@ class PagerPageHolder(
.build()
context.imageLoader.enqueue(request)
}
// SY -->
companion object {
fun getBGType(readerTheme: Int, context: Context): Int {
return if (readerTheme == 4) {
if (context.isInNightMode) 2 else 1
} else 0
}
}
// SY <--
}

View File

@ -120,8 +120,8 @@ class SettingsReaderController : SettingsController() {
intListPreference {
key = Keys.readerTheme
titleRes = R.string.pref_reader_theme
entriesRes = arrayOf(R.string.black_background, R.string.gray_background, R.string.white_background, R.string.smart_based_on_page, R.string.smart_based_on_page_and_theme)
entryValues = arrayOf("1", "2", "0", "3", "4")
entriesRes = arrayOf(R.string.black_background, R.string.gray_background, R.string.white_background, R.string.automatic_background)
entryValues = arrayOf("1", "2", "0", "3")
defaultValue = "3"
summary = "%s"
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.util.system
import android.content.Context
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
@ -9,8 +10,11 @@ import android.graphics.Rect
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import androidx.core.graphics.alpha
import androidx.core.graphics.blue
import androidx.core.graphics.createBitmap
import eu.kanade.tachiyomi.R
import androidx.core.graphics.green
import androidx.core.graphics.red
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.InputStream
@ -161,16 +165,22 @@ object ImageUtil {
RIGHT, LEFT
}
// SY -->
@Suppress("UNUSED_VARIABLE")
fun autoSetBackground(image: Bitmap?, alwaysUseWhite: Boolean, context: Context): Drawable {
val backgroundColor = if (alwaysUseWhite) Color.WHITE else {
context.getResourceColor(R.attr.colorPrimary)
}
if (image == null) return ColorDrawable(backgroundColor)
/**
* Algorithm for determining what background to accompany a comic/manga page
*/
fun chooseBackground(context: Context, imageStream: InputStream): Drawable {
imageStream.mark(imageStream.available() + 1)
val image = BitmapFactory.decodeStream(imageStream)
imageStream.reset()
val whiteColor = Color.WHITE
if (image == null) return ColorDrawable(whiteColor)
if (image.width < 50 || image.height < 50) {
return ColorDrawable(backgroundColor)
return ColorDrawable(whiteColor)
}
val top = 5
val bot = image.height - 5
val left = (image.width * 0.0275).toInt()
@ -178,42 +188,52 @@ object ImageUtil {
val midX = image.width / 2
val midY = image.height / 2
val offsetX = (image.width * 0.01).toInt()
val offsetY = (image.height * 0.01).toInt()
val topLeftIsDark = isDark(image.getPixel(left, top))
val topRightIsDark = isDark(image.getPixel(right, top))
val midLeftIsDark = isDark(image.getPixel(left, midY))
val midRightIsDark = isDark(image.getPixel(right, midY))
val topMidIsDark = isDark(image.getPixel(midX, top))
val botLeftIsDark = isDark(image.getPixel(left, bot))
val botRightIsDark = isDark(image.getPixel(right, bot))
val leftOffsetX = left - offsetX
val rightOffsetX = right + offsetX
val topLeftPixel = image.getPixel(left, top)
val topRightPixel = image.getPixel(right, top)
val midLeftPixel = image.getPixel(left, midY)
val midRightPixel = image.getPixel(right, midY)
val topCenterPixel = image.getPixel(midX, top)
val botLeftPixel = image.getPixel(left, bot)
val bottomCenterPixel = image.getPixel(midX, bot)
val botRightPixel = image.getPixel(right, bot)
val topLeftIsDark = topLeftPixel.isDark()
val topRightIsDark = topRightPixel.isDark()
val midLeftIsDark = midLeftPixel.isDark()
val midRightIsDark = midRightPixel.isDark()
val topMidIsDark = topCenterPixel.isDark()
val botLeftIsDark = botLeftPixel.isDark()
val botRightIsDark = botRightPixel.isDark()
var darkBG = (topLeftIsDark && (botLeftIsDark || botRightIsDark || topRightIsDark || midLeftIsDark || topMidIsDark)) ||
(topRightIsDark && (botRightIsDark || botLeftIsDark || midRightIsDark || topMidIsDark))
if (!isWhite(image.getPixel(left, top)) && pixelIsClose(image.getPixel(left, top), image.getPixel(midX, top)) &&
!isWhite(image.getPixel(midX, top)) && pixelIsClose(image.getPixel(midX, top), image.getPixel(right, top)) &&
!isWhite(image.getPixel(right, top)) && pixelIsClose(image.getPixel(right, top), image.getPixel(right, bot)) &&
!isWhite(image.getPixel(right, bot)) && pixelIsClose(image.getPixel(right, bot), image.getPixel(midX, bot)) &&
!isWhite(image.getPixel(midX, bot)) && pixelIsClose(image.getPixel(midX, bot), image.getPixel(left, bot)) &&
!isWhite(image.getPixel(left, bot)) && pixelIsClose(image.getPixel(left, bot), image.getPixel(left, top))
) {
return ColorDrawable(image.getPixel(left, top))
val topAndBotPixels = listOf(topLeftPixel, topCenterPixel, topRightPixel, botRightPixel, bottomCenterPixel, botLeftPixel)
val isNotWhiteAndCloseTo = topAndBotPixels.mapIndexed { index, color ->
val other = topAndBotPixels[(index + 1) % topAndBotPixels.size]
!color.isWhite() && color.isCloseTo(other)
}
if (isNotWhiteAndCloseTo.all { it }) {
return ColorDrawable(topLeftPixel)
}
if (isWhite(image.getPixel(left, top)).toInt() +
isWhite(image.getPixel(right, top)).toInt() +
isWhite(image.getPixel(left, bot)).toInt() +
isWhite(image.getPixel(right, bot)).toInt() > 2
) {
val cornerPixels = listOf(topLeftPixel, topRightPixel, botLeftPixel, botRightPixel)
val numberOfWhiteCorners = cornerPixels.map { cornerPixel -> cornerPixel.isWhite() }
.filter { it }
.size
if (numberOfWhiteCorners > 2) {
darkBG = false
}
var blackPixel = when {
topLeftIsDark -> image.getPixel(left, top)
topRightIsDark -> image.getPixel(right, top)
botLeftIsDark -> image.getPixel(left, bot)
botRightIsDark -> image.getPixel(right, bot)
else -> backgroundColor
var blackColor = when {
topLeftIsDark -> topLeftPixel
topRightIsDark -> topRightPixel
botLeftIsDark -> botLeftPixel
botRightIsDark -> botRightPixel
else -> whiteColor
}
var overallWhitePixels = 0
@ -222,32 +242,32 @@ object ImageUtil {
var topWhiteStreak = 0
var botBlackStreak = 0
var botWhiteStreak = 0
outer@ for (x in intArrayOf(left, right, left - offsetX, right + offsetX)) {
outer@ for (x in intArrayOf(left, right, leftOffsetX, rightOffsetX)) {
var whitePixelsStreak = 0
var whitePixels = 0
var blackPixelsStreak = 0
var blackPixels = 0
var blackStreak = false
var whiteStrak = false
var whiteStreak = false
val notOffset = x == left || x == right
for ((index, y) in (0 until image.height step image.height / 25).withIndex()) {
inner@ for ((index, y) in (0 until image.height step image.height / 25).withIndex()) {
val pixel = image.getPixel(x, y)
val pixelOff = image.getPixel(x + (if (x < image.width / 2) -offsetX else offsetX), y)
if (isWhite(pixel)) {
if (pixel.isWhite()) {
whitePixelsStreak++
whitePixels++
if (notOffset) {
overallWhitePixels++
}
if (whitePixelsStreak > 14) {
whiteStrak = true
whiteStreak = true
}
if (whitePixelsStreak > 6 && whitePixelsStreak >= index - 1) {
topWhiteStreak = whitePixelsStreak
}
} else {
whitePixelsStreak = 0
if (isDark(pixel) && isDark(pixelOff)) {
if (pixel.isDark() && pixelOff.isDark()) {
blackPixels++
if (notOffset) {
overallBlackPixels++
@ -256,7 +276,7 @@ object ImageUtil {
if (blackPixelsStreak >= 14) {
blackStreak = true
}
continue
continue@inner
}
}
if (blackPixelsStreak > 6 && blackPixelsStreak >= index - 1) {
@ -271,11 +291,11 @@ object ImageUtil {
}
when {
blackPixels > 22 -> {
if (x == right || x == right + offsetX) {
blackPixel = when {
topRightIsDark -> image.getPixel(right, top)
botRightIsDark -> image.getPixel(right, bot)
else -> blackPixel
if (x == right || x == rightOffsetX) {
blackColor = when {
topRightIsDark -> topRightPixel
botRightIsDark -> botRightPixel
else -> blackColor
}
}
darkBG = true
@ -284,11 +304,11 @@ object ImageUtil {
}
blackStreak -> {
darkBG = true
if (x == right || x == right + offsetX) {
blackPixel = when {
topRightIsDark -> image.getPixel(right, top)
botRightIsDark -> image.getPixel(right, bot)
else -> blackPixel
if (x == right || x == rightOffsetX) {
blackColor = when {
topRightIsDark -> topRightPixel
botRightIsDark -> botRightPixel
else -> blackColor
}
}
if (blackPixels > 18) {
@ -296,7 +316,7 @@ object ImageUtil {
break@outer
}
}
whiteStrak || whitePixels > 22 -> darkBG = false
whiteStreak || whitePixels > 22 -> darkBG = false
}
}
@ -308,58 +328,57 @@ object ImageUtil {
if (topIsBlackStreak && bottomIsBlackStreak) {
darkBG = true
}
if (darkBG) {
return if (isWhite(image.getPixel(left, bot)) && isWhite(image.getPixel(right, bot))) {
GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
intArrayOf(blackPixel, blackPixel, backgroundColor, backgroundColor)
)
} else if (isWhite(image.getPixel(left, top)) && isWhite(image.getPixel(right, top))) {
GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
intArrayOf(backgroundColor, backgroundColor, blackPixel, blackPixel)
)
} else ColorDrawable(blackPixel)
val isLandscape = context.resources.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE
if (isLandscape) {
return when {
darkBG -> ColorDrawable(blackColor)
else -> ColorDrawable(whiteColor)
}
}
if (topIsBlackStreak || (
topLeftIsDark && topRightIsDark &&
isDark(image.getPixel(left - offsetX, top)) && isDark(image.getPixel(right + offsetX, top)) &&
(topMidIsDark || overallBlackPixels > 9)
)
) {
return GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
intArrayOf(blackPixel, blackPixel, backgroundColor, backgroundColor)
)
} else if (bottomIsBlackStreak || (
botLeftIsDark && botRightIsDark &&
isDark(image.getPixel(left - offsetX, bot)) && isDark(image.getPixel(right + offsetX, bot)) &&
(isDark(image.getPixel(midX, bot)) || overallBlackPixels > 9)
)
) {
return GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
intArrayOf(backgroundColor, backgroundColor, blackPixel, blackPixel)
)
val botCornersIsWhite = botLeftPixel.isWhite() && botRightPixel.isWhite()
val topCornersIsWhite = topLeftPixel.isWhite() && topRightPixel.isWhite()
val topCornersIsDark = topLeftIsDark && topRightIsDark
val botCornersIsDark = botLeftIsDark && botRightIsDark
val topOffsetCornersIsDark = image.getPixel(leftOffsetX, top).isDark() && image.getPixel(rightOffsetX, top).isDark()
val botOffsetCornersIsDark = image.getPixel(leftOffsetX, bot).isDark() && image.getPixel(rightOffsetX, bot).isDark()
val gradient = when {
darkBG && botCornersIsWhite -> {
intArrayOf(blackColor, blackColor, whiteColor, whiteColor)
}
darkBG && topCornersIsWhite -> {
intArrayOf(whiteColor, whiteColor, blackColor, blackColor)
}
darkBG -> {
return ColorDrawable(blackColor)
}
topIsBlackStreak || (topCornersIsDark && topOffsetCornersIsDark && (topMidIsDark || overallBlackPixels > 9)) -> {
intArrayOf(blackColor, blackColor, whiteColor, whiteColor)
}
bottomIsBlackStreak || (botCornersIsDark && botOffsetCornersIsDark && (bottomCenterPixel.isDark() || overallBlackPixels > 9)) -> {
intArrayOf(whiteColor, whiteColor, blackColor, blackColor)
}
else -> {
return ColorDrawable(whiteColor)
}
}
return ColorDrawable(backgroundColor)
return GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
gradient
)
}
private fun isDark(color: Int): Boolean {
return Color.red(color) < 40 && Color.blue(color) < 40 && Color.green(color) < 40 &&
Color.alpha(color) > 200
}
private fun Int.isDark(): Boolean =
red < 40 && blue < 40 && green < 40 && alpha > 200
private fun isWhite(color: Int): Boolean {
return Color.red(color) + Color.blue(color) + Color.green(color) > 740
}
private fun Int.isCloseTo(other: Int): Boolean =
abs(red - other.red) < 30 && abs(green - other.green) < 30 && abs(blue - other.blue) < 30
private fun Boolean.toInt() = if (this) 1 else 0
private fun pixelIsClose(color1: Int, color2: Int): Boolean {
return abs(Color.red(color1) - Color.red(color2)) < 30 &&
abs(Color.green(color1) - Color.green(color2)) < 30 &&
abs(Color.blue(color1) - Color.blue(color2)) < 30
}
// SY <--
private fun Int.isWhite(): Boolean =
red + blue + green > 740
}

View File

@ -275,6 +275,15 @@ object EXHMigrations {
.build()
)
}
if (oldVersion under 18) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val readerTheme = prefs.getInt("pref_reader_theme_key", 3)
if (readerTheme == 4) {
prefs.edit {
putInt("pref_reader_theme_key", 3)
}
}
}
// if (oldVersion under 1) { } (1 is current release version)
// do stuff here when releasing changed crap

View File

@ -180,7 +180,6 @@
<string name="library_group_updates_all">Lancer des mises à jour de catégorie tout le temps</string>
<!-- Browse settings -->
<string name="pref_latest_tab_language_code">Afficher le code de langue à côté du nom</string>
<string name="pref_latest_position">Dernière position de l\'onglet</string>
<string name="pref_latest_position_summery">Voulez-vous que le dernier onglet soit le premier onglet de la navigation? Cela en fera l\'onglet par défaut lors de l\'ouverture de la navigation, non recommandé si vous êtes sur des données ou un réseau mesuré</string>
<string name="pref_source_navigation">Remplacer le dernier bouton</string>
@ -232,8 +231,6 @@
<string name="auto_webtoon_mode">Mode Webtoon automatique</string>
<string name="auto_webtoon_mode_summary">Utilisez le mode Webtoon automatique pour les mangas détectés comme susceptibles d\'utiliser le format de bande longue</string>
<string name="enable_zoom_out">Activer le zoom arrière</string>
<string name="smart_based_on_page">Intelligent(basé sur la page)</string>
<string name="smart_based_on_page_and_theme">Intelligent(basé sur la page et le thème)</string>
<string name="tap_scroll_page">Appuyez sur faire défiler par page</string>
<!-- <string name="tap_scroll_page_summary">Tapping will scroll by page instead of screen size when this option is enabled</string>-->

View File

@ -209,8 +209,6 @@
<string name="auto_webtoon_mode">Modo Auto Webtoon</string>
<string name="auto_webtoon_mode_summary">Use o modo webtoon automático para mangás que são detectados provavelmente no formato longstrip</string>
<string name="enable_zoom_out">Enable zoom out</string>
<string name="smart_based_on_page">Inteligente (Baseado na página)</string>
<string name="smart_based_on_page_and_theme">Inteligente (baseado na página e no tema)</string>
<string name="tap_scroll_page">Tap scroll by page</string>
<string name="tap_scroll_page_summary">Tapping will scroll by page instead of screen size when this option is enabled</string>

View File

@ -240,8 +240,6 @@
<string name="auto_webtoon_mode">Автоматический веб-комикс</string>
<string name="auto_webtoon_mode_summary">Использовать автоматический режим для веб-комикса, в которых выявлены вероятно, использовать длинные полосы формате</string>
<string name="enable_zoom_out">Включить зум</string>
<string name="smart_based_on_page">Умный (по странице)</string>
<string name="smart_based_on_page_and_theme">Умный (по странице и теме)</string>
<string name="tap_scroll_page">Нажмите прокрутить по странице</string>
<string name="tap_scroll_page_summary">Нажатие будет прокручиваться по странице, а не по размеру экрана, если эта опция включена</string>

View File

@ -13,8 +13,7 @@
<item>@string/black_background</item>
<item>@string/gray_background</item>
<item>@string/white_background</item>
<item>@string/smart_based_on_page</item>
<item>@string/smart_based_on_page_and_theme</item>
<item>@string/automatic_background</item>
</string-array>
<string-array name="reader_themes_values">
@ -22,7 +21,6 @@
<item>2</item>
<item>0</item>
<item>3</item>
<item>4</item>
</string-array>
<string-array name="image_scale_type">

View File

@ -303,6 +303,7 @@
<string name="white_background">White</string>
<string name="gray_background">Gray</string>
<string name="black_background">Black</string>
<string name="automatic_background">Automatic</string>
<string name="pref_viewer_type">Default reading mode</string>
<string name="default_viewer">Default</string>
<string name="default_nav">Default</string>

View File

@ -249,8 +249,6 @@
<string name="auto_webtoon_mode">Auto Webtoon Mode</string>
<string name="auto_webtoon_mode_summary">Use auto webtoon mode for manga that are detected to likely use the long strip format</string>
<string name="enable_zoom_out">Enable zoom out</string>
<string name="smart_based_on_page">Smart (based on page)</string>
<string name="smart_based_on_page_and_theme">Smart (based on page and theme)</string>
<string name="tap_scroll_page">Tap scroll by page</string>
<string name="tap_scroll_page_summary">Tapping will scroll by page instead of screen size when this option is enabled</string>
<string name="reader_bottom_buttons">Reader Bottom Buttons</string>