From 880b06dd3bdad22ea727a8b6fe7d94535ea6e3c0 Mon Sep 17 00:00:00 2001 From: arkon Date: Fri, 24 Mar 2023 22:48:59 -0400 Subject: [PATCH] Add "Rotate wide pages to fit" setting for paged reader Originally authored in #7983 Co-authored-by: timothyng-164 (cherry picked from commit 953720472fe64ef488ecae7ae7fea453b8c7c68b) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt # app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt # app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt # app/src/main/res/layout/reader_pager_settings.xml --- .../settings/screen/SettingsReaderScreen.kt | 19 ++++++++++++++++ .../ui/reader/setting/ReaderPreferences.kt | 4 ++++ .../setting/ReaderReadingModeSettings.kt | 19 ++++++++++++++-- .../ui/reader/viewer/ViewerConfig.kt | 6 +++++ .../ui/reader/viewer/pager/PagerConfig.kt | 12 ++++++++++ .../ui/reader/viewer/pager/PagerPageHolder.kt | 14 ++++++++++++ .../main/res/layout/reader_pager_settings.xml | 22 ++++++++++++++++++- .../tachiyomi/core/util/system/ImageUtil.kt | 18 +++++++++++++++ i18n/src/main/res/values/strings.xml | 2 ++ 9 files changed, 113 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt index 29de0047f..ab19bfccc 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt @@ -183,10 +183,12 @@ object SettingsReaderScreen : SearchableSettings { val navModePref = readerPreferences.navigationModePager() val imageScaleTypePref = readerPreferences.imageScaleType() val dualPageSplitPref = readerPreferences.dualPageSplitPaged() + val rotateToFitPref = readerPreferences.dualPageRotateToFit() val navMode by navModePref.collectAsState() val imageScaleType by imageScaleTypePref.collectAsState() val dualPageSplit by dualPageSplitPref.collectAsState() + val rotateToFit by rotateToFitPref.collectAsState() return Preference.PreferenceGroup( title = stringResource(R.string.pager_viewer), @@ -255,6 +257,10 @@ object SettingsReaderScreen : SearchableSettings { Preference.PreferenceItem.SwitchPreference( pref = dualPageSplitPref, title = stringResource(R.string.pref_dual_page_split), + onValueChanged = { + rotateToFitPref.set(false) + true + }, ), Preference.PreferenceItem.SwitchPreference( pref = readerPreferences.dualPageInvertPaged(), @@ -262,6 +268,19 @@ object SettingsReaderScreen : SearchableSettings { subtitle = stringResource(R.string.pref_dual_page_invert_summary), enabled = dualPageSplit, ), + Preference.PreferenceItem.SwitchPreference( + pref = rotateToFitPref, + title = stringResource(R.string.pref_page_rotate), + onValueChanged = { + dualPageSplitPref.set(false) + true + }, + ), + Preference.PreferenceItem.SwitchPreference( + pref = readerPreferences.dualPageRotateToFitInvert(), + title = stringResource(R.string.pref_page_rotate_invert), + enabled = rotateToFit, + ), ), ) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt index cab73f830..a1eece56f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt @@ -78,6 +78,10 @@ class ReaderPreferences( fun dualPageInvertWebtoon() = preferenceStore.getBoolean("pref_dual_page_invert_webtoon", false) + fun dualPageRotateToFit() = preferenceStore.getBoolean("pref_dual_page_rotate", false) + + fun dualPageRotateToFitInvert() = preferenceStore.getBoolean("pref_dual_page_rotate_invert", false) + // endregion // region Color filter diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt index 8ebf0f803..7b74947f5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderReadingModeSettings.kt @@ -92,12 +92,27 @@ class ReaderReadingModeSettings @JvmOverloads constructor(context: Context, attr binding.pagerPrefsGroup.cropBorders.bindToPreference(readerPreferences.cropBorders()) binding.pagerPrefsGroup.dualPageSplit.bindToPreference(readerPreferences.dualPageSplitPaged()) - // Makes it so that dual page invert gets hidden away when dual page split is turned off readerPreferences.dualPageSplitPaged() - .asHotFlow { binding.pagerPrefsGroup.dualPageInvert.isVisible = it } + .asHotFlow { + binding.pagerPrefsGroup.dualPageInvert.isVisible = it + if (it) { + binding.pagerPrefsGroup.dualPageRotateToFit.isChecked = false + } + } .launchIn((context as ReaderActivity).lifecycleScope) binding.pagerPrefsGroup.dualPageInvert.bindToPreference(readerPreferences.dualPageInvertPaged()) + binding.pagerPrefsGroup.dualPageRotateToFit.bindToPreference(readerPreferences.dualPageRotateToFit()) + readerPreferences.dualPageRotateToFit() + .asHotFlow { + binding.pagerPrefsGroup.dualPageRotateToFitInvert.isVisible = it + if (it) { + binding.pagerPrefsGroup.dualPageSplit.isChecked = false + } + } + .launchIn((context as ReaderActivity).lifecycleScope) + binding.pagerPrefsGroup.dualPageRotateToFitInvert.bindToPreference(readerPreferences.dualPageRotateToFitInvert()) + // SY --> binding.pagerPrefsGroup.pageTransitionsPager.bindToPreference(readerPreferences.pageTransitionsPager()) binding.pagerPrefsGroup.pageLayout.bindToPreference(readerPreferences.pageLayout()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt index 53c5144de..3356ac39b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt @@ -36,6 +36,12 @@ abstract class ViewerConfig(readerPreferences: ReaderPreferences, private val sc var dualPageInvert = false protected set + var dualPageRotateToFit = false + protected set + + var dualPageRotateToFitInvert = false + protected set + abstract var navigator: ViewerNavigation protected set diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt index 753c9d33d..480fa12ad 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerConfig.kt @@ -123,6 +123,18 @@ class PagerConfig( readerPreferences.dualPageInvertPaged() .register({ dualPageInvert = it }, { imagePropertyChangedListener?.invoke() }) + readerPreferences.dualPageRotateToFit() + .register( + { dualPageRotateToFit = it }, + { imagePropertyChangedListener?.invoke() }, + ) + + readerPreferences.dualPageRotateToFitInvert() + .register( + { dualPageRotateToFitInvert = it }, + { imagePropertyChangedListener?.invoke() }, + ) + // SY --> readerPreferences.pageTransitionsPager() .register({ usePageTransitions = it }, { imagePropertyChangedListener?.invoke() }) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index 49900cfe6..420589e3e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -210,6 +210,10 @@ class PagerPageHolder( } private fun process(page: ReaderPage, imageStream: BufferedInputStream): InputStream { + if (viewer.config.dualPageRotateToFit) { + return rotateDualPage(imageStream) + } + if (!viewer.config.dualPageSplit) { return imageStream } @@ -228,6 +232,16 @@ class PagerPageHolder( return splitInHalf(imageStream) } + private fun rotateDualPage(imageStream: BufferedInputStream): InputStream { + val isDoublePage = ImageUtil.isWideImage(imageStream) + return if (isDoublePage) { + val rotation = if (viewer.config.dualPageRotateToFitInvert) -90f else 90f + ImageUtil.rotateImage(imageStream, rotation) + } else { + imageStream + } + } + private fun mergePages(imageStream: InputStream, imageStream2: InputStream?): InputStream { // Handle adding a center margin to wide images if requested if (imageStream2 == null) { diff --git a/app/src/main/res/layout/reader_pager_settings.xml b/app/src/main/res/layout/reader_pager_settings.xml index f931fdf45..dde76ee2d 100644 --- a/app/src/main/res/layout/reader_pager_settings.xml +++ b/app/src/main/res/layout/reader_pager_settings.xml @@ -98,6 +98,26 @@ android:visibility="gone" tools:visibility="visible" /> + + + + + app:constraint_referenced_ids="pager_nav,tapping_inverted,dual_page_split,dual_page_invert,dual_page_rotate_to_fit,dual_page_rotate_to_fit_invert,page_transitions_pager" /> diff --git a/core/src/main/java/tachiyomi/core/util/system/ImageUtil.kt b/core/src/main/java/tachiyomi/core/util/system/ImageUtil.kt index 2734f820c..f5083cb9c 100644 --- a/core/src/main/java/tachiyomi/core/util/system/ImageUtil.kt +++ b/core/src/main/java/tachiyomi/core/util/system/ImageUtil.kt @@ -8,6 +8,7 @@ import android.graphics.BitmapFactory import android.graphics.BitmapRegionDecoder import android.graphics.Canvas import android.graphics.Color +import android.graphics.Matrix import android.graphics.Rect import android.graphics.drawable.ColorDrawable import android.graphics.drawable.Drawable @@ -152,6 +153,23 @@ object ImageUtil { return ByteArrayInputStream(output.toByteArray()) } + fun rotateImage(imageStream: InputStream, degrees: Float): InputStream { + val imageBytes = imageStream.readBytes() + + val imageBitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size) + val rotated = rotateBitMap(imageBitmap, degrees) + + val output = ByteArrayOutputStream() + rotated.compress(Bitmap.CompressFormat.JPEG, 100, output) + + return ByteArrayInputStream(output.toByteArray()) + } + + private fun rotateBitMap(bitmap: Bitmap, degrees: Float): Bitmap { + val matrix = Matrix().apply { postRotate(degrees) } + return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) + } + /** * Split the image into left and right parts, then merge them into a * new vertically-aligned image. diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index a32823e77..309998f88 100755 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -314,6 +314,8 @@ Split wide pages Invert split page placement If the placement of the split wide pages don\'t match reading direction + Rotate wide pages to fit + Flip orientation of rotated wide pages Split tall images (BETA) Show content in cutout area Animate page transitions