diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index e076002fe7..a7515c2934 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -53,6 +53,8 @@ object PreferenceKeys { const val grayscale = "pref_grayscale" + const val invertedColors = "pref_inverted_colors" + const val defaultReadingMode = "pref_default_reading_mode_key" const val defaultOrientationType = "pref_default_orientation_type_key" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 66442c7ba3..06c6e8dd1e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -129,6 +129,8 @@ class PreferencesHelper(val context: Context) { fun grayscale() = flowPrefs.getBoolean(Keys.grayscale, false) + fun invertedColors() = flowPrefs.getBoolean(Keys.invertedColors, false) + fun defaultReadingMode() = prefs.getInt(Keys.defaultReadingMode, ReadingModeType.RIGHT_TO_LEFT.flagValue) fun defaultOrientationType() = prefs.getInt(Keys.defaultOrientationType, OrientationType.FREE.flagValue) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index deedca7fa0..309600ae40 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -76,6 +76,7 @@ import eu.kanade.tachiyomi.widget.listener.SimpleAnimationListener import eu.kanade.tachiyomi.widget.listener.SimpleSeekBarListener import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.sample import nucleus.factory.RequiresPresenter @@ -879,11 +880,25 @@ class ReaderActivity : BaseRxActivity() */ private inner class ReaderConfig { - private val grayscalePaint by lazy { - Paint().apply { + private fun getCombinedPaint(grayscale: Boolean, invertedColors: Boolean): Paint { + return Paint().apply { colorFilter = ColorMatrixColorFilter( ColorMatrix().apply { - setSaturation(0f) + if (grayscale) { + setSaturation(0f) + } + if (invertedColors) { + postConcat( + ColorMatrix( + floatArrayOf( + -1f, 0f, 0f, 0f, 255f, + 0f, -1f, 0f, 0f, 255f, + 0f, 0f, -1f, 0f, 255f, + 0f, 0f, 0f, 1f, 0f + ) + ) + ) + } } ) } @@ -936,8 +951,8 @@ class ReaderActivity : BaseRxActivity() .onEach { setColorFilter(preferences.colorFilter().get()) } .launchIn(lifecycleScope) - preferences.grayscale().asFlow() - .onEach { setGrayscale(it) } + merge(preferences.grayscale().asFlow(), preferences.invertedColors().asFlow()) + .onEach { setLayerPaint(preferences.grayscale().get(), preferences.invertedColors().get()) } .launchIn(lifecycleScope) preferences.fullscreen().asFlow() @@ -1065,8 +1080,8 @@ class ReaderActivity : BaseRxActivity() binding.colorOverlay.setFilterColor(value, preferences.colorFilterMode().get()) } - private fun setGrayscale(enabled: Boolean) { - val paint = if (enabled) grayscalePaint else null + private fun setLayerPaint(grayscale: Boolean, invertedColors: Boolean) { + val paint = if (grayscale || invertedColors) getCombinedPaint(grayscale, invertedColors) else null binding.viewerContainer.setLayerType(LAYER_TYPE_HARDWARE, paint) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderColorFilterSettings.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderColorFilterSettings.kt index f491049d65..9f978cd9a0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderColorFilterSettings.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderColorFilterSettings.kt @@ -67,6 +67,7 @@ class ReaderColorFilterSettings @JvmOverloads constructor(context: Context, attr binding.customBrightness.bindToPreference(preferences.customBrightness()) binding.colorFilterMode.bindToPreference(preferences.colorFilterMode()) binding.grayscale.bindToPreference(preferences.grayscale()) + binding.invertedColors.bindToPreference(preferences.invertedColors()) binding.seekbarColorFilterAlpha.setOnSeekBarChangeListener( object : SimpleSeekBarListener() { diff --git a/app/src/main/res/layout/reader_color_filter_settings.xml b/app/src/main/res/layout/reader_color_filter_settings.xml index 804b5f1446..56ef8c084b 100644 --- a/app/src/main/res/layout/reader_color_filter_settings.xml +++ b/app/src/main/res/layout/reader_color_filter_settings.xml @@ -193,6 +193,16 @@ android:textColor="?android:attr/textColorSecondary" app:layout_constraintTop_toBottomOf="@id/color_filter_mode" /> + + + app:layout_constraintTop_toBottomOf="@id/inverted_colors" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f6b944824e..2c67a26984 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -275,6 +275,7 @@ Off Custom brightness Grayscale + Inverted Custom color filter Color filter blend mode Default