Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41f92097 authored by Hawkwood Glazier's avatar Hawkwood Glazier Committed by Android (Google) Code Review
Browse files

Merge "Normalize TextInterpolator rebase operations" into main

parents 601a5e0f 0a737d07
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -82,6 +82,10 @@ class TypefaceVariantCacheImpl(var baseTypeface: Typeface, override val animatio
    }
}

interface TextAnimatorListener : TextInterpolatorListener {
    fun onInvalidate() {}
}

/**
 * This class provides text animation between two styles.
 *
@@ -110,13 +114,19 @@ class TypefaceVariantCacheImpl(var baseTypeface: Typeface, override val animatio
class TextAnimator(
    layout: Layout,
    private val typefaceCache: TypefaceVariantCache,
    private val invalidateCallback: () -> Unit = {},
    private val listener: TextAnimatorListener? = null,
) {
    @VisibleForTesting var textInterpolator = TextInterpolator(layout, typefaceCache)
    var textInterpolator = TextInterpolator(layout, typefaceCache, listener)
    @VisibleForTesting var createAnimator: () -> ValueAnimator = { ValueAnimator.ofFloat(1f) }

    var animator: ValueAnimator? = null

    val progress: Float
        get() = textInterpolator.progress

    val linearProgress: Float
        get() = textInterpolator.linearProgress

    val fontVariationUtils = FontVariationUtils()

    sealed class PositionedGlyph {
@@ -288,8 +298,9 @@ class TextAnimator(
            animator = buildAnimator(animation).apply { start() }
        } else {
            textInterpolator.progress = 1f
            textInterpolator.linearProgress = 1f
            textInterpolator.rebase()
            invalidateCallback()
            listener?.onInvalidate()
        }
    }

@@ -302,7 +313,7 @@ class TextAnimator(
            addUpdateListener {
                textInterpolator.progress = it.animatedValue as Float
                textInterpolator.linearProgress = it.currentPlayTime / it.duration.toFloat()
                invalidateCallback()
                listener?.onInvalidate()
            }

            addListener(
+17 −1
Original line number Diff line number Diff line
@@ -27,8 +27,19 @@ import android.util.MathUtils
import com.android.internal.graphics.ColorUtils
import java.lang.Math.max

interface TextInterpolatorListener {
    fun onPaintModified() {}

    fun onRebased() {}
}

/** Provide text style linear interpolation for plain text. */
class TextInterpolator(layout: Layout, var typefaceCache: TypefaceVariantCache) {
class TextInterpolator(
    layout: Layout,
    var typefaceCache: TypefaceVariantCache,
    private val listener: TextInterpolatorListener? = null,
) {

    /**
     * Returns base paint used for interpolation.
     *
@@ -136,6 +147,7 @@ class TextInterpolator(layout: Layout, var typefaceCache: TypefaceVariantCache)
     */
    fun onTargetPaintModified() {
        updatePositionsAndFonts(shapeText(layout, targetPaint), updateBase = false)
        listener?.onPaintModified()
    }

    /**
@@ -146,6 +158,7 @@ class TextInterpolator(layout: Layout, var typefaceCache: TypefaceVariantCache)
     */
    fun onBasePaintModified() {
        updatePositionsAndFonts(shapeText(layout, basePaint), updateBase = true)
        listener?.onPaintModified()
    }

    /**
@@ -204,6 +217,7 @@ class TextInterpolator(layout: Layout, var typefaceCache: TypefaceVariantCache)
     */
    fun rebase() {
        if (progress == 0f) {
            listener?.onRebased()
            return
        } else if (progress == 1f) {
            basePaint.set(targetPaint)
@@ -233,6 +247,8 @@ class TextInterpolator(layout: Layout, var typefaceCache: TypefaceVariantCache)
        }

        progress = 0f
        linearProgress = 0f
        listener?.onRebased()
    }

    /**
+8 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import com.android.app.animation.Interpolators
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.animation.GlyphCallback
import com.android.systemui.animation.TextAnimator
import com.android.systemui.animation.TextAnimatorListener
import com.android.systemui.animation.TypefaceVariantCacheImpl
import com.android.systemui.customization.R
import com.android.systemui.log.core.LogLevel
@@ -100,7 +101,13 @@ constructor(
    @VisibleForTesting
    var textAnimatorFactory: (Layout, () -> Unit) -> TextAnimator = { layout, invalidateCb ->
        val cache = TypefaceVariantCacheImpl(layout.paint.typeface, NUM_CLOCK_FONT_ANIMATION_STEPS)
        TextAnimator(layout, cache, invalidateCb)
        TextAnimator(
            layout,
            cache,
            object : TextAnimatorListener {
                override fun onInvalidate() = invalidateCb()
            },
        )
    }

    // Used by screenshot tests to provide stability
+29 −19
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.os.VibrationEffect
import android.text.Layout
import android.text.TextPaint
import android.util.AttributeSet
import android.util.Log
@@ -39,6 +38,7 @@ import com.android.app.animation.Interpolators
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.animation.GSFAxes
import com.android.systemui.animation.TextAnimator
import com.android.systemui.animation.TextAnimatorListener
import com.android.systemui.customization.R
import com.android.systemui.plugins.clocks.ClockFontAxisSetting
import com.android.systemui.plugins.clocks.ClockFontAxisSetting.Companion.replace
@@ -175,11 +175,6 @@ open class SimpleDigitalClockTextView(

    private val typefaceCache = clockCtx.typefaceCache.getVariantCache("")

    @VisibleForTesting
    var textAnimatorFactory: (Layout, () -> Unit) -> TextAnimator = { layout, invalidateCb ->
        TextAnimator(layout, typefaceCache, invalidateCb)
    }

    var verticalAlignment: VerticalAlignment = VerticalAlignment.BASELINE
    var horizontalAlignment: HorizontalAlignment = HorizontalAlignment.CENTER

@@ -247,7 +242,18 @@ open class SimpleDigitalClockTextView(
        val layout = this.layout
        if (layout != null) {
            if (!this::textAnimator.isInitialized) {
                textAnimator = textAnimatorFactory(layout, ::invalidate)
                textAnimator =
                    TextAnimator(
                        layout,
                        typefaceCache,
                        object : TextAnimatorListener {
                            override fun onInvalidate() = invalidate()

                            override fun onRebased() = updateTextBounds()

                            override fun onPaintModified() = updateTextBounds()
                        },
                    )
                setInterpolatorPaint()
            } else {
                textAnimator.updateLayout(layout)
@@ -272,7 +278,7 @@ open class SimpleDigitalClockTextView(
    override fun onDraw(canvas: Canvas) {
        logger.onDraw(textAnimator.textInterpolator.shapedText)

        val interpProgress = getInterpolatedProgress()
        val interpProgress = textAnimator.progress
        val interpBounds = getInterpolatedTextBounds(interpProgress)
        if (interpProgress != drawnProgress) {
            drawnProgress = interpProgress
@@ -336,7 +342,6 @@ open class SimpleDigitalClockTextView(
                interpolator = aodDozingInterpolator,
            ),
        )
        updateTextBoundsForTextAnimator()

        if (!isAnimated) {
            requestLayout()
@@ -367,11 +372,9 @@ open class SimpleDigitalClockTextView(
                            duration = CHARGE_ANIMATION_DURATION,
                        ),
                    )
                    updateTextBoundsForTextAnimator()
                },
            ),
        )
        updateTextBoundsForTextAnimator()
    }

    fun animateFidget(x: Float, y: Float) = animateFidget(0L)
@@ -401,11 +404,9 @@ open class SimpleDigitalClockTextView(
                            interpolator = FIDGET_INTERPOLATOR,
                        ),
                    )
                    updateTextBoundsForTextAnimator()
                },
            ),
        )
        updateTextBoundsForTextAnimator()
    }

    fun refreshText() {
@@ -428,12 +429,8 @@ open class SimpleDigitalClockTextView(
            id == R.id.MINUTE_SECOND_DIGIT
    }

    private fun getInterpolatedProgress(): Float {
        return textAnimator.animator?.let { it.animatedValue as Float } ?: 1f
    }

    /** Returns the interpolated text bounding rect based on interpolation progress */
    private fun getInterpolatedTextBounds(progress: Float = getInterpolatedProgress()): VRectF {
    private fun getInterpolatedTextBounds(progress: Float = textAnimator.progress): VRectF {
        if (progress <= 0f) {
            return prevTextBounds
        } else if (!textAnimator.isRunning || progress >= 1f) {
@@ -487,6 +484,15 @@ open class SimpleDigitalClockTextView(
            MeasureSpec.makeMeasureSpec(measureBounds.x.roundToInt(), mode.x),
            MeasureSpec.makeMeasureSpec(measureBounds.y.roundToInt(), mode.y),
        )

        logger.d({
            val size = VPointF.fromLong(long1)
            val mode = VPoint.fromLong(long2)
            "setInterpolatedSize(size=$size, mode=$mode)"
        }) {
            long1 = measureBounds.toLong()
            long2 = mode.toLong()
        }
    }

    /** Set the location of the view to match the interpolated text bounds */
@@ -514,6 +520,9 @@ open class SimpleDigitalClockTextView(
            targetRect.bottom.roundToInt(),
        )
        onViewBoundsChanged?.let { it(targetRect) }
        logger.d({ "setInterpolatedLocation(${VRectF.fromLong(long1)})" }) {
            long1 = targetRect.toLong()
        }
        return targetRect
    }

@@ -616,7 +625,8 @@ open class SimpleDigitalClockTextView(
     * rebase if previous animator is canceled so basePaint will store the state we transition from
     * and targetPaint will store the state we transition to
     */
    private fun updateTextBoundsForTextAnimator() {
    private fun updateTextBounds() {
        drawnProgress = null
        prevTextBounds = textAnimator.textInterpolator.basePaint.getTextBounds(text)
        targetTextBounds = textAnimator.textInterpolator.targetPaint.getTextBounds(text)
    }
+3 −3
Original line number Diff line number Diff line
@@ -55,9 +55,9 @@ class ClockLogger(private val view: View?, buffer: MessageBuffer, tag: String) :
    }

    fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        d({ "onLayout($bool1, ${VRect(long1.toULong())})" }) {
        d({ "onLayout($bool1, ${VRect.fromLong(long1)})" }) {
            bool1 = changed
            long1 = VRect(left, top, right, bottom).data.toLong()
            long1 = VRect(left, top, right, bottom).toLong()
        }
    }

@@ -116,7 +116,7 @@ class ClockLogger(private val view: View?, buffer: MessageBuffer, tag: String) :
    }

    fun animateFidget(x: Float, y: Float) {
        d({ "animateFidget(${VPointF(long1.toULong())})" }) { long1 = VPointF(x, y).data.toLong() }
        d({ "animateFidget(${VPointF.fromLong(long1)})" }) { long1 = VPointF(x, y).toLong() }
    }

    companion object {
Loading