diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorText.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorText.kt deleted file mode 100644 index 0cfb8475c..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorText.kt +++ /dev/null @@ -1,42 +0,0 @@ -package eu.kanade.tachiyomi.ui.reader - -import androidx.compose.foundation.layout.Box -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.drawscope.Stroke -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp - -@Composable -fun PageIndicatorText( - currentPage: Int, - totalPages: Int, -) { - if (currentPage <= 0 || totalPages <= 0) return - - val text = "$currentPage / $totalPages" - - Box { - Text( - text = text, - color = Color(45, 45, 45), - fontSize = MaterialTheme.typography.bodySmall.fontSize, - fontWeight = FontWeight.Bold, - letterSpacing = 1.sp, - style = TextStyle.Default.copy( - drawStyle = Stroke(width = 4f), - ), - ) - - Text( - text = text, - color = Color(235, 235, 235), - fontSize = MaterialTheme.typography.bodySmall.fontSize, - fontWeight = FontWeight.Bold, - letterSpacing = 1.sp, - ) - } -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorTextView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorTextView.kt new file mode 100644 index 000000000..d0cd94f2a --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/PageIndicatorTextView.kt @@ -0,0 +1,52 @@ +package eu.kanade.tachiyomi.ui.reader + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.Color +import android.text.Spannable +import android.text.SpannableString +import android.text.style.ScaleXSpan +import android.util.AttributeSet +import androidx.appcompat.widget.AppCompatTextView +import eu.kanade.tachiyomi.widget.OutlineSpan + +/** + * Page indicator found at the bottom of the reader + */ +class PageIndicatorTextView( + context: Context, + attrs: AttributeSet? = null, +) : AppCompatTextView(context, attrs) { + + init { + setTextColor(fillColor) + } + + @SuppressLint("SetTextI18n") + override fun setText(text: CharSequence?, type: BufferType?) { + // Add spaces at the start & end of the text, otherwise the stroke is cut-off because it's + // not taken into account when measuring the text (view's padding doesn't help). + val currText = " $text " + + // Also add a bit of spacing between each character, as the stroke overlaps them + val finalText = SpannableString(currText.asIterable().joinToString("\u00A0")).apply { + // Apply text outline + setSpan(spanOutline, 1, length - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + + for (i in 1..lastIndex step 2) { + setSpan(ScaleXSpan(0.2f), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + } + } + + super.setText(finalText, BufferType.SPANNABLE) + } +} + +private val fillColor = Color.rgb(235, 235, 235) +private val strokeColor = Color.rgb(45, 45, 45) + +// A span object with text outlining properties +private val spanOutline = OutlineSpan( + strokeColor = strokeColor, + strokeWidth = 4f, +) 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 bf09741c6..742ffcb8a 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 @@ -46,10 +46,6 @@ import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts.CreateDocument import androidx.appcompat.app.AlertDialog -import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.LocalTextStyle -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf @@ -675,18 +671,6 @@ class ReaderActivity : EhActivity() { } } - binding.pageNumber.setMD3Content { - CompositionLocalProvider( - LocalTextStyle provides MaterialTheme.typography.bodySmall, - LocalContentColor provides MaterialTheme.colorScheme.onBackground, - ) { - PageIndicatorText( - currentPage = currentPage, - totalPages = totalPage, - ) - } - } - // Init listeners on bottom menu binding.readerNav.setMD3Content { ChapterNavigator( @@ -808,6 +792,7 @@ class ReaderActivity : EhActivity() { fun onPageSelected(page: ReaderPage) { // Set bottom page number currentPage = page.number + binding.pageNumber.text = "$currentPage/$totalPage" mCurrentIndex = page.index mGalleryProvider?.putStartPage(mCurrentIndex) diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/OutlineSpan.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/OutlineSpan.kt new file mode 100644 index 000000000..e5125a28c --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/OutlineSpan.kt @@ -0,0 +1,56 @@ +package eu.kanade.tachiyomi.widget + +import android.graphics.Canvas +import android.graphics.Paint +import android.text.style.ReplacementSpan +import androidx.annotation.ColorInt +import androidx.annotation.Dimension + +/** + * Source: https://github.com/santaevpavel + * + * A class that draws the outlines of a text when given a stroke color and stroke width. + */ +class OutlineSpan( + @ColorInt private val strokeColor: Int, + @Dimension private val strokeWidth: Float, +) : ReplacementSpan() { + + override fun getSize( + paint: Paint, + text: CharSequence, + start: Int, + end: Int, + fm: Paint.FontMetricsInt?, + ): Int { + return paint.measureText(text.toString().substring(start until end)).toInt() + } + + override fun draw( + canvas: Canvas, + text: CharSequence, + start: Int, + end: Int, + x: Float, + top: Int, + y: Int, + bottom: Int, + paint: Paint, + ) { + val originTextColor = paint.color + + paint.apply { + color = strokeColor + style = Paint.Style.STROKE + this.strokeWidth = this@OutlineSpan.strokeWidth + } + canvas.drawText(text, start, end, x, y.toFloat(), paint) + + paint.apply { + color = originTextColor + style = Paint.Style.FILL + } + + canvas.drawText(text, start, end, x, y.toFloat(), paint) + } +} diff --git a/app/src/main/res/layout/reader_activity.xml b/app/src/main/res/layout/reader_activity.xml index 009b34a27..da346ecd6 100644 --- a/app/src/main/res/layout/reader_activity.xml +++ b/app/src/main/res/layout/reader_activity.xml @@ -16,12 +16,15 @@ android:layout_height="match_parent" android:descendantFocusability="blocksDescendants" /> - + android:padding="4dp" + android:textAppearance="?attr/textAppearanceBodySmall" + android:textDirection="ltr" + android:textStyle="bold" />