From ae36b313588ea1471f6f67421d660ff166ed5ef2 Mon Sep 17 00:00:00 2001 From: Hawkwood Glazier Date: Wed, 11 Jan 2023 20:54:48 +0000 Subject: [PATCH] Copy unformatted files from tm-qpr-dev to master These files differ between master and tm-qpr-dev which cuases headaches. This effectively undoes I6c22d0079bad774058f34ebb349e105e4e4b99a2 but also catches any changes that were only submitted to tm-qpr-dev. Bug: 264262853 Test: Manually checked clock on device Change-Id: I7bde225a41ab41e8c419a9784eb0307691550f3f --- .../systemui/animation/FontInterpolator.kt | 106 ++++---- .../systemui/animation/TextAnimator.kt | 155 ++++++------ .../systemui/animation/TextInterpolator.kt | 230 +++++++++--------- 3 files changed, 252 insertions(+), 239 deletions(-) diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt index 290328894439b..3d341af3b3970 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt @@ -33,7 +33,9 @@ private const val FONT_ITALIC_MIN = 0f private const val FONT_ITALIC_ANIMATION_STEP = 0.1f private const val FONT_ITALIC_DEFAULT_VALUE = 0f -/** Provide interpolation of two fonts by adjusting font variation settings. */ +/** + * Provide interpolation of two fonts by adjusting font variation settings. + */ class FontInterpolator { /** @@ -59,14 +61,11 @@ class FontInterpolator { var index: Int, val sortedAxes: MutableList ) { - constructor( - font: Font, - axes: List - ) : this( - font.sourceIdentifier, - font.ttcIndex, - axes.toMutableList().apply { sortBy { it.tag } } - ) + constructor(font: Font, axes: List) : + this(font.sourceIdentifier, + font.ttcIndex, + axes.toMutableList().apply { sortBy { it.tag } } + ) fun set(font: Font, axes: List) { sourceId = font.sourceIdentifier @@ -87,7 +86,9 @@ class FontInterpolator { private val tmpInterpKey = InterpKey(null, null, 0f) private val tmpVarFontKey = VarFontKey(0, 0, mutableListOf()) - /** Linear interpolate the font variation settings. */ + /** + * Linear interpolate the font variation settings. + */ fun lerp(start: Font, end: Font, progress: Float): Font { if (progress == 0f) { return start @@ -114,34 +115,27 @@ class FontInterpolator { // this doesn't take much time since the variation axes is usually up to 5. If we need to // support more number of axes, we may want to preprocess the font and store the sorted axes // and also pre-fill the missing axes value with default value from 'fvar' table. - val newAxes = - lerp(startAxes, endAxes) { tag, startValue, endValue -> - when (tag) { - // TODO: Good to parse 'fvar' table for retrieving default value. - TAG_WGHT -> - adjustWeight( - MathUtils.lerp( + val newAxes = lerp(startAxes, endAxes) { tag, startValue, endValue -> + when (tag) { + // TODO: Good to parse 'fvar' table for retrieving default value. + TAG_WGHT -> adjustWeight( + MathUtils.lerp( startValue ?: FONT_WEIGHT_DEFAULT_VALUE, endValue ?: FONT_WEIGHT_DEFAULT_VALUE, - progress - ) - ) - TAG_ITAL -> - adjustItalic( - MathUtils.lerp( + progress)) + TAG_ITAL -> adjustItalic( + MathUtils.lerp( startValue ?: FONT_ITALIC_DEFAULT_VALUE, endValue ?: FONT_ITALIC_DEFAULT_VALUE, - progress - ) - ) - else -> { - require(startValue != null && endValue != null) { - "Unable to interpolate due to unknown default axes value : $tag" - } - MathUtils.lerp(startValue, endValue, progress) + progress)) + else -> { + require(startValue != null && endValue != null) { + "Unable to interpolate due to unknown default axes value : $tag" } + MathUtils.lerp(startValue, endValue, progress) } } + } // Check if we already make font for this axes. This is typically happens if the animation // happens backward. @@ -155,7 +149,9 @@ class FontInterpolator { // This is the first time to make the font for the axes. Build and store it to the cache. // Font.Builder#build won't throw IOException since creating fonts from existing fonts will // not do any IO work. - val newFont = Font.Builder(start).setFontVariationSettings(newAxes.toTypedArray()).build() + val newFont = Font.Builder(start) + .setFontVariationSettings(newAxes.toTypedArray()) + .build() interpCache[InterpKey(start, end, progress)] = newFont verFontCache[VarFontKey(start, newAxes)] = newFont return newFont @@ -177,28 +173,26 @@ class FontInterpolator { val tagA = if (i < start.size) start[i].tag else null val tagB = if (j < end.size) end[j].tag else null - val comp = - when { - tagA == null -> 1 - tagB == null -> -1 - else -> tagA.compareTo(tagB) - } + val comp = when { + tagA == null -> 1 + tagB == null -> -1 + else -> tagA.compareTo(tagB) + } - val axis = - when { - comp == 0 -> { - val v = filter(tagA!!, start[i++].styleValue, end[j++].styleValue) - FontVariationAxis(tagA, v) - } - comp < 0 -> { - val v = filter(tagA!!, start[i++].styleValue, null) - FontVariationAxis(tagA, v) - } - else -> { // comp > 0 - val v = filter(tagB!!, null, end[j++].styleValue) - FontVariationAxis(tagB, v) - } + val axis = when { + comp == 0 -> { + val v = filter(tagA!!, start[i++].styleValue, end[j++].styleValue) + FontVariationAxis(tagA, v) } + comp < 0 -> { + val v = filter(tagA!!, start[i++].styleValue, null) + FontVariationAxis(tagA, v) + } + else -> { // comp > 0 + val v = filter(tagB!!, null, end[j++].styleValue) + FontVariationAxis(tagB, v) + } + } result.add(axis) } @@ -208,21 +202,21 @@ class FontInterpolator { // For the performance reasons, we animate weight with FONT_WEIGHT_ANIMATION_STEP. This helps // Cache hit ratio in the Skia glyph cache. private fun adjustWeight(value: Float) = - coerceInWithStep(value, FONT_WEIGHT_MIN, FONT_WEIGHT_MAX, FONT_WEIGHT_ANIMATION_STEP) + coerceInWithStep(value, FONT_WEIGHT_MIN, FONT_WEIGHT_MAX, FONT_WEIGHT_ANIMATION_STEP) // For the performance reasons, we animate italic with FONT_ITALIC_ANIMATION_STEP. This helps // Cache hit ratio in the Skia glyph cache. private fun adjustItalic(value: Float) = - coerceInWithStep(value, FONT_ITALIC_MIN, FONT_ITALIC_MAX, FONT_ITALIC_ANIMATION_STEP) + coerceInWithStep(value, FONT_ITALIC_MIN, FONT_ITALIC_MAX, FONT_ITALIC_ANIMATION_STEP) private fun coerceInWithStep(v: Float, min: Float, max: Float, step: Float) = - (v.coerceIn(min, max) / step).toInt() * step + (v.coerceIn(min, max) / step).toInt() * step companion object { private val EMPTY_AXES = arrayOf() // Returns true if given two font instance can be interpolated. fun canInterpolate(start: Font, end: Font) = - start.ttcIndex == end.ttcIndex && start.sourceIdentifier == end.sourceIdentifier + start.ttcIndex == end.ttcIndex && start.sourceIdentifier == end.sourceIdentifier } } diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt index 65d6c83d74a8f..5f1bb83715c2f 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt @@ -36,7 +36,8 @@ typealias GlyphCallback = (TextAnimator.PositionedGlyph, Float) -> Unit * Currently this class can provide text style animation for text weight and text size. For example * the simple view that draws text with animating text size is like as follows: * - * ``` + *
+ * 
  *     class SimpleTextAnimation : View {
  *         @JvmOverloads constructor(...)
  *
@@ -52,34 +53,39 @@ typealias GlyphCallback = (TextAnimator.PositionedGlyph, Float) -> Unit
  *             animator.setTextStyle(-1 /* unchanged weight */, sizePx, animate)
  *         }
  *     }
- * ```
+ * 
+ * 
*/ -class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) { +class TextAnimator( + layout: Layout, + private val invalidateCallback: () -> Unit +) { // Following two members are for mutable for testing purposes. public var textInterpolator: TextInterpolator = TextInterpolator(layout) - public var animator: ValueAnimator = - ValueAnimator.ofFloat(1f).apply { - duration = DEFAULT_ANIMATION_DURATION - addUpdateListener { - textInterpolator.progress = it.animatedValue as Float - invalidateCallback() - } - addListener( - object : AnimatorListenerAdapter() { - override fun onAnimationEnd(animation: Animator?) { - textInterpolator.rebase() - } - override fun onAnimationCancel(animation: Animator?) = textInterpolator.rebase() - } - ) + public var animator: ValueAnimator = ValueAnimator.ofFloat(1f).apply { + duration = DEFAULT_ANIMATION_DURATION + addUpdateListener { + textInterpolator.progress = it.animatedValue as Float + invalidateCallback() } + addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator?) { + textInterpolator.rebase() + } + override fun onAnimationCancel(animation: Animator?) = textInterpolator.rebase() + }) + } sealed class PositionedGlyph { - /** Mutable X coordinate of the glyph position relative from drawing offset. */ + /** + * Mutable X coordinate of the glyph position relative from drawing offset. + */ var x: Float = 0f - /** Mutable Y coordinate of the glyph position relative from the baseline. */ + /** + * Mutable Y coordinate of the glyph position relative from the baseline. + */ var y: Float = 0f /** @@ -90,29 +96,40 @@ class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) { /** * Mutable text size of the glyph in pixels. */ - /** Mutable text size of the glyph in pixels. */ var textSize: Float = 0f - /** Mutable color of the glyph. */ + /** + * Mutable color of the glyph. + */ var color: Int = 0 - /** Immutable character offset in the text that the current font run start. */ + /** + * Immutable character offset in the text that the current font run start. + */ abstract var runStart: Int protected set - /** Immutable run length of the font run. */ + /** + * Immutable run length of the font run. + */ abstract var runLength: Int protected set - /** Immutable glyph index of the font run. */ + /** + * Immutable glyph index of the font run. + */ abstract var glyphIndex: Int protected set - /** Immutable font instance for this font run. */ + /** + * Immutable font instance for this font run. + */ abstract var font: Font protected set - /** Immutable glyph ID for this glyph. */ + /** + * Immutable glyph ID for this glyph. + */ abstract var glyphId: Int protected set } @@ -130,30 +147,30 @@ class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) { /** * GlyphFilter applied just before drawing to canvas for tweaking positions and text size. * - * This callback is called for each glyphs just before drawing the glyphs. This function will be - * called with the intrinsic position, size, color, glyph ID and font instance. You can mutate - * the position, size and color for tweaking animations. Do not keep the reference of passed - * glyph object. The interpolator reuses that object for avoiding object allocations. + * This callback is called for each glyphs just before drawing the glyphs. This function will + * be called with the intrinsic position, size, color, glyph ID and font instance. You can + * mutate the position, size and color for tweaking animations. + * Do not keep the reference of passed glyph object. The interpolator reuses that object for + * avoiding object allocations. * - * Details: The text is drawn with font run units. The font run is a text segment that draws - * with the same font. The {@code runStart} and {@code runLimit} is a range of the font run in - * the text that current glyph is in. Once the font run is determined, the system will convert - * characters into glyph IDs. The {@code glyphId} is the glyph identifier in the font and {@code - * glyphIndex} is the offset of the converted glyph array. Please note that the {@code - * glyphIndex} is not a character index, because the character will not be converted to glyph - * one-by-one. If there are ligatures including emoji sequence, etc, the glyph ID may be + * Details: + * The text is drawn with font run units. The font run is a text segment that draws with the + * same font. The {@code runStart} and {@code runLimit} is a range of the font run in the text + * that current glyph is in. Once the font run is determined, the system will convert characters + * into glyph IDs. The {@code glyphId} is the glyph identifier in the font and + * {@code glyphIndex} is the offset of the converted glyph array. Please note that the + * {@code glyphIndex} is not a character index, because the character will not be converted to + * glyph one-by-one. If there are ligatures including emoji sequence, etc, the glyph ID may be * composed from multiple characters. * * Here is an example of font runs: "fin. 終わり" * - * ``` * Characters : f i n . _ 終 わ り * Code Points: \u0066 \u0069 \u006E \u002E \u0020 \u7D42 \u308F \u308A * Font Runs : <-- Roboto-Regular.ttf --><-- NotoSans-CJK.otf --> * runStart = 0, runLength = 5 runStart = 5, runLength = 3 * Glyph IDs : 194 48 7 8 4367 1039 1002 * Glyph Index: 0 1 2 3 0 1 2 - * ``` * * In this example, the "fi" is converted into ligature form, thus the single glyph ID is * assigned for two characters, f and i. @@ -176,29 +193,28 @@ class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) { */ var glyphFilter: GlyphCallback? get() = textInterpolator.glyphFilter - set(value) { - textInterpolator.glyphFilter = value - } + set(value) { textInterpolator.glyphFilter = value } fun draw(c: Canvas) = textInterpolator.draw(c) /** * Set text style with animation. * - * By passing -1 to weight, the view preserve the current weight. By passing -1 to textSize, the - * view preserve the current text size. Bu passing -1 to duration, the default text animation, - * 1000ms, is used. By passing false to animate, the text will be updated without animation. + * By passing -1 to weight, the view preserve the current weight. + * By passing -1 to textSize, the view preserve the current text size. + * Bu passing -1 to duration, the default text animation, 1000ms, is used. + * By passing false to animate, the text will be updated without animation. * * @param weight an optional text weight. * @param textSize an optional font size. - * @param colors an optional colors array that must be the same size as numLines passed to the - * TextInterpolator + * @param colors an optional colors array that must be the same size as numLines passed to + * the TextInterpolator * @param animate an optional boolean indicating true for showing style transition as animation, - * false for immediate style transition. True by default. + * false for immediate style transition. True by default. * @param duration an optional animation duration in milliseconds. This is ignored if animate is - * false. + * false. * @param interpolator an optional time interpolator. If null is passed, last set interpolator - * will be used. This is ignored if animate is false. + * will be used. This is ignored if animate is false. */ fun setTextStyle( weight: Int = -1, @@ -221,11 +237,10 @@ class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) { if (weight >= 0) { // Paint#setFontVariationSettings creates Typeface instance from scratch. To reduce the // memory impact, cache the typeface result. - textInterpolator.targetPaint.typeface = - typefaceCache.getOrElse(weight) { - textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight" - textInterpolator.targetPaint.typeface - } + textInterpolator.targetPaint.typeface = typefaceCache.getOrElse(weight) { + textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight" + textInterpolator.targetPaint.typeface + } } if (color != null) { textInterpolator.targetPaint.color = color @@ -234,24 +249,22 @@ class TextAnimator(layout: Layout, private val invalidateCallback: () -> Unit) { if (animate) { animator.startDelay = delay - animator.duration = - if (duration == -1L) { - DEFAULT_ANIMATION_DURATION - } else { - duration - } + animator.duration = if (duration == -1L) { + DEFAULT_ANIMATION_DURATION + } else { + duration + } interpolator?.let { animator.interpolator = it } if (onAnimationEnd != null) { - val listener = - object : AnimatorListenerAdapter() { - override fun onAnimationEnd(animation: Animator?) { - onAnimationEnd.run() - animator.removeListener(this) - } - override fun onAnimationCancel(animation: Animator?) { - animator.removeListener(this) - } + val listener = object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator?) { + onAnimationEnd.run() + animator.removeListener(this) } + override fun onAnimationCancel(animation: Animator?) { + animator.removeListener(this) + } + } animator.addListener(listener) } animator.start() diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt index f9fb42cd1670a..0448c818f7655 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt @@ -26,8 +26,12 @@ import android.util.MathUtils import com.android.internal.graphics.ColorUtils import java.lang.Math.max -/** Provide text style linear interpolation for plain text. */ -class TextInterpolator(layout: Layout) { +/** + * Provide text style linear interpolation for plain text. + */ +class TextInterpolator( + layout: Layout +) { /** * Returns base paint used for interpolation. @@ -60,11 +64,12 @@ class TextInterpolator(layout: Layout) { var baseFont: Font, var targetFont: Font ) { - val length: Int - get() = end - start + val length: Int get() = end - start } - /** A class represents text layout of a single run. */ + /** + * A class represents text layout of a single run. + */ private class Run( val glyphIds: IntArray, val baseX: FloatArray, // same length as glyphIds @@ -74,8 +79,12 @@ class TextInterpolator(layout: Layout) { val fontRuns: List ) - /** A class represents text layout of a single line. */ - private class Line(val runs: List) + /** + * A class represents text layout of a single line. + */ + private class Line( + val runs: List + ) private var lines = listOf() private val fontInterpolator = FontInterpolator() @@ -97,8 +106,8 @@ class TextInterpolator(layout: Layout) { /** * The layout used for drawing text. * - * Only non-styled text is supported. Even if the given layout is created from Spanned, the span - * information is not used. + * Only non-styled text is supported. Even if the given layout is created from Spanned, the + * span information is not used. * * The paint objects used for interpolation are not changed by this method call. * @@ -121,8 +130,8 @@ class TextInterpolator(layout: Layout) { /** * Recalculate internal text layout for interpolation. * - * Whenever the target paint is modified, call this method to recalculate internal text layout - * used for interpolation. + * Whenever the target paint is modified, call this method to recalculate internal + * text layout used for interpolation. */ fun onTargetPaintModified() { updatePositionsAndFonts(shapeText(layout, targetPaint), updateBase = false) @@ -131,8 +140,8 @@ class TextInterpolator(layout: Layout) { /** * Recalculate internal text layout for interpolation. * - * Whenever the base paint is modified, call this method to recalculate internal text layout - * used for interpolation. + * Whenever the base paint is modified, call this method to recalculate internal + * text layout used for interpolation. */ fun onBasePaintModified() { updatePositionsAndFonts(shapeText(layout, basePaint), updateBase = true) @@ -143,11 +152,11 @@ class TextInterpolator(layout: Layout) { * * The text interpolator does not calculate all the text position by text shaper due to * performance reasons. Instead, the text interpolator shape the start and end state and - * calculate text position of the middle state by linear interpolation. Due to this trick, the - * text positions of the middle state is likely different from the text shaper result. So, if - * you want to start animation from the middle state, you will see the glyph jumps due to this - * trick, i.e. the progress 0.5 of interpolation between weight 400 and 700 is different from - * text shape result of weight 550. + * calculate text position of the middle state by linear interpolation. Due to this trick, + * the text positions of the middle state is likely different from the text shaper result. + * So, if you want to start animation from the middle state, you will see the glyph jumps due to + * this trick, i.e. the progress 0.5 of interpolation between weight 400 and 700 is different + * from text shape result of weight 550. * * After calling this method, do not call onBasePaintModified() since it reshape the text and * update the base state. As in above notice, the text shaping result at current progress is @@ -159,7 +168,8 @@ class TextInterpolator(layout: Layout) { * animate weight from 200 to 400, then if you want to move back to 200 at the half of the * animation, it will look like * - * ``` + *
+     * 
      *     val interp = TextInterpolator(layout)
      *
      *     // Interpolate between weight 200 to 400.
@@ -189,7 +199,9 @@ class TextInterpolator(layout: Layout) {
      *         // progress is 0.5
      *         animator.start()
      *     }
-     * ```
+     * 
+     * 
+ * */ fun rebase() { if (progress == 0f) { @@ -251,75 +263,69 @@ class TextInterpolator(layout: Layout) { } var maxRunLength = 0 - lines = - baseLayout.zip(targetLayout) { baseLine, targetLine -> - val runs = - baseLine.zip(targetLine) { base, target -> - require(base.glyphCount() == target.glyphCount()) { - "Inconsistent glyph count at line ${lines.size}" + lines = baseLayout.zip(targetLayout) { baseLine, targetLine -> + val runs = baseLine.zip(targetLine) { base, target -> + + require(base.glyphCount() == target.glyphCount()) { + "Inconsistent glyph count at line ${lines.size}" + } + + val glyphCount = base.glyphCount() + + // Good to recycle the array if the existing array can hold the new layout result. + val glyphIds = IntArray(glyphCount) { + base.getGlyphId(it).also { baseGlyphId -> + require(baseGlyphId == target.getGlyphId(it)) { + "Inconsistent glyph ID at $it in line ${lines.size}" } + } + } - val glyphCount = base.glyphCount() + val baseX = FloatArray(glyphCount) { base.getGlyphX(it) } + val baseY = FloatArray(glyphCount) { base.getGlyphY(it) } + val targetX = FloatArray(glyphCount) { target.getGlyphX(it) } + val targetY = FloatArray(glyphCount) { target.getGlyphY(it) } - // Good to recycle the array if the existing array can hold the new layout - // result. - val glyphIds = - IntArray(glyphCount) { - base.getGlyphId(it).also { baseGlyphId -> - require(baseGlyphId == target.getGlyphId(it)) { - "Inconsistent glyph ID at $it in line ${lines.size}" - } - } + // Calculate font runs + val fontRun = mutableListOf() + if (glyphCount != 0) { + var start = 0 + var baseFont = base.getFont(start) + var targetFont = target.getFont(start) + require(FontInterpolator.canInterpolate(baseFont, targetFont)) { + "Cannot interpolate font at $start ($baseFont vs $targetFont)" + } + + for (i in 1 until glyphCount) { + val nextBaseFont = base.getFont(i) + val nextTargetFont = target.getFont(i) + + if (baseFont !== nextBaseFont) { + require(targetFont !== nextTargetFont) { + "Base font has changed at $i but target font has not changed." } - - val baseX = FloatArray(glyphCount) { base.getGlyphX(it) } - val baseY = FloatArray(glyphCount) { base.getGlyphY(it) } - val targetX = FloatArray(glyphCount) { target.getGlyphX(it) } - val targetY = FloatArray(glyphCount) { target.getGlyphY(it) } - - // Calculate font runs - val fontRun = mutableListOf() - if (glyphCount != 0) { - var start = 0 - var baseFont = base.getFont(start) - var targetFont = target.getFont(start) + // Font transition point. push run and reset context. + fontRun.add(FontRun(start, i, baseFont, targetFont)) + maxRunLength = max(maxRunLength, i - start) + baseFont = nextBaseFont + targetFont = nextTargetFont + start = i require(FontInterpolator.canInterpolate(baseFont, targetFont)) { "Cannot interpolate font at $start ($baseFont vs $targetFont)" } - - for (i in 1 until glyphCount) { - val nextBaseFont = base.getFont(i) - val nextTargetFont = target.getFont(i) - - if (baseFont !== nextBaseFont) { - require(targetFont !== nextTargetFont) { - "Base font has changed at $i but target font has not " + - "changed." - } - // Font transition point. push run and reset context. - fontRun.add(FontRun(start, i, baseFont, targetFont)) - maxRunLength = max(maxRunLength, i - start) - baseFont = nextBaseFont - targetFont = nextTargetFont - start = i - require(FontInterpolator.canInterpolate(baseFont, targetFont)) { - "Cannot interpolate font at $start ($baseFont vs " + - "$targetFont)" - } - } else { // baseFont === nextBaseFont - require(targetFont === nextTargetFont) { - "Base font has not changed at $i but target font has " + - "changed." - } - } + } else { // baseFont === nextBaseFont + require(targetFont === nextTargetFont) { + "Base font has not changed at $i but target font has changed." } - fontRun.add(FontRun(start, glyphCount, baseFont, targetFont)) - maxRunLength = max(maxRunLength, glyphCount - start) } - Run(glyphIds, baseX, baseY, targetX, targetY, fontRun) } - Line(runs) + fontRun.add(FontRun(start, glyphCount, baseFont, targetFont)) + maxRunLength = max(maxRunLength, glyphCount - start) + } + Run(glyphIds, baseX, baseY, targetX, targetY, fontRun) } + Line(runs) + } // Update float array used for drawing. if (tmpPositionArray.size < maxRunLength * 2) { @@ -351,9 +357,9 @@ class TextInterpolator(layout: Layout) { if (glyphFilter == null) { for (i in run.start until run.end) { tmpPositionArray[arrayIndex++] = - MathUtils.lerp(line.baseX[i], line.targetX[i], progress) + MathUtils.lerp(line.baseX[i], line.targetX[i], progress) tmpPositionArray[arrayIndex++] = - MathUtils.lerp(line.baseY[i], line.targetY[i], progress) + MathUtils.lerp(line.baseY[i], line.targetY[i], progress) } c.drawGlyphs(line.glyphIds, run.start, tmpPositionArray, 0, run.length, font, paint) return @@ -382,14 +388,13 @@ class TextInterpolator(layout: Layout) { tmpPaintForGlyph.color = tmpGlyph.color c.drawGlyphs( - line.glyphIds, - prevStart, - tmpPositionArray, - 0, - i - prevStart, - font, - tmpPaintForGlyph - ) + line.glyphIds, + prevStart, + tmpPositionArray, + 0, + i - prevStart, + font, + tmpPaintForGlyph) prevStart = i arrayIndex = 0 } @@ -399,14 +404,13 @@ class TextInterpolator(layout: Layout) { } c.drawGlyphs( - line.glyphIds, - prevStart, - tmpPositionArray, - 0, - run.end - prevStart, - font, - tmpPaintForGlyph - ) + line.glyphIds, + prevStart, + tmpPositionArray, + 0, + run.end - prevStart, + font, + tmpPaintForGlyph) } private fun updatePositionsAndFonts( @@ -414,7 +418,9 @@ class TextInterpolator(layout: Layout) { updateBase: Boolean ) { // Update target positions with newly calculated text layout. - check(layoutResult.size == lines.size) { "The new layout result has different line count." } + check(layoutResult.size == lines.size) { + "The new layout result has different line count." + } lines.zip(layoutResult) { line, runs -> line.runs.zip(runs) { lineRun, newGlyphs -> @@ -430,7 +436,7 @@ class TextInterpolator(layout: Layout) { } require(newFont === newGlyphs.getFont(i)) { "The new layout has different font run." + - " $newFont vs ${newGlyphs.getFont(i)} at $i" + " $newFont vs ${newGlyphs.getFont(i)} at $i" } } @@ -438,7 +444,7 @@ class TextInterpolator(layout: Layout) { // check new font can be interpolatable with base font. require(FontInterpolator.canInterpolate(newFont, run.baseFont)) { "New font cannot be interpolated with existing font. $newFont," + - " ${run.baseFont}" + " ${run.baseFont}" } if (updateBase) { @@ -474,7 +480,10 @@ class TextInterpolator(layout: Layout) { } // Shape the text and stores the result to out argument. - private fun shapeText(layout: Layout, paint: TextPaint): List> { + private fun shapeText( + layout: Layout, + paint: TextPaint + ): List> { val out = mutableListOf>() for (lineNo in 0 until layout.lineCount) { // Shape all lines. val lineStart = layout.getLineStart(lineNo) @@ -486,13 +495,10 @@ class TextInterpolator(layout: Layout) { } val runs = mutableListOf() - TextShaper.shapeText( - layout.text, - lineStart, - count, - layout.textDirectionHeuristic, - paint - ) { _, _, glyphs, _ -> runs.add(glyphs) } + TextShaper.shapeText(layout.text, lineStart, count, layout.textDirectionHeuristic, + paint) { _, _, glyphs, _ -> + runs.add(glyphs) + } out.add(runs) } return out @@ -500,8 +506,8 @@ class TextInterpolator(layout: Layout) { } private fun Layout.getDrawOrigin(lineNo: Int) = - if (getParagraphDirection(lineNo) == Layout.DIR_LEFT_TO_RIGHT) { - getLineLeft(lineNo) - } else { - getLineRight(lineNo) - } + if (getParagraphDirection(lineNo) == Layout.DIR_LEFT_TO_RIGHT) { + getLineLeft(lineNo) + } else { + getLineRight(lineNo) + }