mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 06:17:57 +01:00 
			
		
		
		
	Use OutlineSpan approach from CarlosEsco/Neko to avoid infinite redraws
Based on work by @arsonistAnt: 1876f850f6
			
			
This commit is contained in:
		| @@ -2,15 +2,14 @@ package eu.kanade.tachiyomi.ui.reader | ||||
|  | ||||
| import android.annotation.SuppressLint | ||||
| import android.content.Context | ||||
| import android.graphics.Canvas | ||||
| import android.graphics.Color | ||||
| import android.graphics.Paint | ||||
| import androidx.appcompat.widget.AppCompatTextView | ||||
| import android.text.Spannable | ||||
| import android.text.SpannableString | ||||
| import android.text.style.ScaleXSpan | ||||
| import android.util.AttributeSet | ||||
| import android.widget.TextView | ||||
| import androidx.appcompat.widget.AppCompatTextView | ||||
| import eu.kanade.tachiyomi.widget.OutlineSpan | ||||
|  | ||||
| /** | ||||
|  * Page indicator found at the bottom of the reader | ||||
| @@ -20,19 +19,8 @@ class PageIndicatorTextView( | ||||
|         attrs: AttributeSet? = null | ||||
| ) : AppCompatTextView(context, attrs) { | ||||
|  | ||||
|     private val fillColor = Color.rgb(235, 235, 235) | ||||
|     private val strokeColor = Color.rgb(45, 45, 45) | ||||
|  | ||||
|     override fun onDraw(canvas: Canvas) { | ||||
|         textColorField.set(this, strokeColor) | ||||
|         paint.strokeWidth = 4f | ||||
|         paint.style = Paint.Style.STROKE | ||||
|         super.onDraw(canvas) | ||||
|  | ||||
|         textColorField.set(this, fillColor) | ||||
|         paint.strokeWidth = 0f | ||||
|         paint.style = Paint.Style.FILL | ||||
|         super.onDraw(canvas) | ||||
|     init { | ||||
|         setTextColor(fillColor) | ||||
|     } | ||||
|  | ||||
|     @SuppressLint("SetTextI18n") | ||||
| @@ -42,20 +30,26 @@ class PageIndicatorTextView( | ||||
|         val currText = " $text " | ||||
|  | ||||
|         // Also add a bit of spacing between each character, as the stroke overlaps them | ||||
|         val finalText = SpannableString(currText.asIterable().joinToString("\u00A0")) | ||||
|         val finalText = SpannableString(currText.asIterable().joinToString("\u00A0")).apply { | ||||
|             // Apply text outline | ||||
|             setSpan(spanOutline, 1, length-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) | ||||
|  | ||||
|         for (i in 1..finalText.lastIndex step 2) { | ||||
|             finalText.setSpan(ScaleXSpan(0.1f), i, i + 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, TextView.BufferType.SPANNABLE) | ||||
|     } | ||||
|  | ||||
|     private companion object { | ||||
|         // We need to use reflection to set the text color instead of using [setTextColor], | ||||
|         // otherwise the view is invalidated inside [onDraw] and there's an infinite loop | ||||
|         val textColorField = TextView::class.java.getDeclaredField("mCurTextColor").apply { | ||||
|             isAccessible = true | ||||
|         }!! | ||||
|         private val fillColor = Color.rgb(235, 235, 235) | ||||
|         private val strokeColor = Color.rgb(45, 45, 45) | ||||
|  | ||||
|         // A span object with text outlining properties | ||||
|         val spanOutline = OutlineSpan( | ||||
|                 strokeColor = strokeColor, | ||||
|                 strokeWidth = 4f | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										57
									
								
								app/src/main/java/eu/kanade/tachiyomi/widget/OutlineSpan.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/src/main/java/eu/kanade/tachiyomi/widget/OutlineSpan.kt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| 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) | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user