Add "Rotate wide pages to fit" setting for paged reader

Originally authored in #7983

Co-authored-by: timothyng-164 <timothyng-164@users.noreply.github.com>
(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
This commit is contained in:
arkon 2023-03-24 22:48:59 -04:00 committed by Jobobby04
parent be17682e3c
commit 880b06dd3b
9 changed files with 113 additions and 3 deletions

View File

@ -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,
),
),
)
}

View File

@ -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

View File

@ -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())

View File

@ -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

View File

@ -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() })

View File

@ -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) {

View File

@ -98,6 +98,26 @@
android:visibility="gone"
tools:visibility="visible" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/dual_page_rotate_to_fit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_page_rotate"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/dual_page_rotate_to_fit_invert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/pref_page_rotate_invert"
android:textColor="?android:attr/textColorSecondary"
android:visibility="gone"
tools:visibility="visible" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/page_transitions_pager"
android:layout_width="match_parent"
@ -127,6 +147,6 @@
android:id="@+id/tapping_prefs_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="pager_nav,tapping_inverted,dual_page_split,dual_page_invert,page_transitions_pager" />
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" />
</LinearLayout>

View File

@ -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.

View File

@ -314,6 +314,8 @@
<string name="pref_dual_page_split">Split wide pages</string>
<string name="pref_dual_page_invert">Invert split page placement</string>
<string name="pref_dual_page_invert_summary">If the placement of the split wide pages don\'t match reading direction</string>
<string name="pref_page_rotate">Rotate wide pages to fit</string>
<string name="pref_page_rotate_invert">Flip orientation of rotated wide pages</string>
<string name="pref_long_strip_split">Split tall images (BETA)</string>
<string name="pref_cutout_short">Show content in cutout area</string>
<string name="pref_page_transitions">Animate page transitions</string>