summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hawkwood Glazier <jglazier@google.com> 2025-02-13 17:21:17 +0000
committer Hawkwood Glazier <jglazier@google.com> 2025-02-14 16:59:24 +0000
commita1e84d0888dd976082e46129832ebdb2a234e83a (patch)
treef1378bea688ce45ae4c8836272e32bc54958e8b8
parentc26379f212e327cbf9ee93b3f72fb08be07a1b82 (diff)
Limit interpolated axis values to set of valid values
Rouding the axis values to the nearest valid step value should keep the var cache from missing repeatedly due to functionally identical axis values. Formerly this was not a problem because the progress float was rounded to the nearest animation frame. However that is no longer occuring as it caused issues w/ non-linear interpolation. Since different axes have different min and max values, we manually adjust the step size to roughly target the same number of valid values within that range. This gives us a good target, but also allows us to make specific adjustments to keep hit-rate high depending on which axes are more important visually. Bug: 394840414 Test: Ran animation on device Flag: NONE TextAnimator Memory Fix Change-Id: I1800b71601ef10e1c2b9fd083134f312c8dd6711
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt93
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/FontVariationUtils.kt32
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/GSFAxes.kt98
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt30
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt2
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt43
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt31
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/animation/FontVariationUtilsTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt6
9 files changed, 223 insertions, 117 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 f8bcb81dc073..bc75b1dad40c 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
@@ -22,19 +22,8 @@ import android.util.Log
import android.util.LruCache
import android.util.MathUtils
import androidx.annotation.VisibleForTesting
-import java.lang.Float.max
-import java.lang.Float.min
import kotlin.math.roundToInt
-private const val TAG_WGHT = "wght"
-private const val TAG_ITAL = "ital"
-
-private const val FONT_WEIGHT_DEFAULT_VALUE = 400f
-private const val FONT_ITALIC_MAX = 1f
-private const val FONT_ITALIC_MIN = 0f
-private const val FONT_ITALIC_ANIMATION_STEP = 0.1f
-private const val FONT_ITALIC_DEFAULT_VALUE = 0f
-
/** Caches for font interpolation */
interface FontCache {
val animationFrameCount: Int
@@ -91,11 +80,8 @@ class FontCacheImpl(override val animationFrameCount: Int = DEFAULT_FONT_CACHE_M
class FontInterpolator(val fontCache: FontCache = FontCacheImpl()) {
/** Linear interpolate the font variation settings. */
fun lerp(start: Font, end: Font, progress: Float, linearProgress: Float): Font {
- if (progress == 0f) {
- return start
- } else if (progress == 1f) {
- return end
- }
+ if (progress <= 0f) return start
+ if (progress >= 1f) return end
val startAxes = start.axes ?: EMPTY_AXES
val endAxes = end.axes ?: EMPTY_AXES
@@ -110,7 +96,7 @@ class FontInterpolator(val fontCache: FontCache = FontCacheImpl()) {
InterpKey(start, end, (linearProgress * fontCache.animationFrameCount).roundToInt())
fontCache.get(iKey)?.let {
if (DEBUG) {
- Log.d(LOG_TAG, "[$progress] Interp. cache hit for $iKey")
+ Log.d(LOG_TAG, "[$progress, $linearProgress] Interp. cache hit for $iKey")
}
return it
}
@@ -121,37 +107,16 @@ class FontInterpolator(val fontCache: FontCache = FontCacheImpl()) {
// and also pre-fill the missing axes value with default value from 'fvar' table.
val newAxes =
lerp(startAxes, endAxes) { tag, startValue, endValue ->
- when (tag) {
- TAG_WGHT ->
- MathUtils.lerp(
- startValue ?: FONT_WEIGHT_DEFAULT_VALUE,
- endValue ?: FONT_WEIGHT_DEFAULT_VALUE,
- 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)
- }
- }
+ MathUtils.lerp(startValue, endValue, progress)
}
// Check if we already make font for this axes. This is typically happens if the animation
- // happens backward.
+ // happens backward and is being linearly interpolated.
val vKey = VarFontKey(start, newAxes)
fontCache.get(vKey)?.let {
fontCache.put(iKey, it)
if (DEBUG) {
- Log.d(LOG_TAG, "[$progress] Axis cache hit for $vKey")
+ Log.d(LOG_TAG, "[$progress, $linearProgress] Axis cache hit for $vKey")
}
return it
}
@@ -164,14 +129,14 @@ class FontInterpolator(val fontCache: FontCache = FontCacheImpl()) {
fontCache.put(vKey, newFont)
// Cache misses are likely to create memory leaks, so this is logged at error level.
- Log.e(LOG_TAG, "[$progress] Cache MISS for $iKey / $vKey")
+ Log.e(LOG_TAG, "[$progress, $linearProgress] Cache MISS for $iKey / $vKey")
return newFont
}
private fun lerp(
start: Array<FontVariationAxis>,
end: Array<FontVariationAxis>,
- filter: (tag: String, left: Float?, right: Float?) -> Float,
+ filter: (tag: String, left: Float, right: Float) -> Float,
): List<FontVariationAxis> {
// Safe to modify result of Font#getAxes since it returns cloned object.
start.sortBy { axis -> axis.tag }
@@ -191,39 +156,37 @@ class FontInterpolator(val fontCache: FontCache = FontCacheImpl()) {
else -> tagA.compareTo(tagB)
}
- val axis =
+ val tag =
+ when {
+ comp == 0 -> tagA!!
+ comp < 0 -> tagA!!
+ else -> tagB!!
+ }
+
+ val axisDefinition = GSFAxes.getAxis(tag)
+ require(comp == 0 || axisDefinition != null) {
+ "Unable to interpolate due to unknown default axes value: $tag"
+ }
+
+ val axisValue =
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)
- }
+ comp == 0 -> filter(tag, start[i++].styleValue, end[j++].styleValue)
+ comp < 0 -> filter(tag, start[i++].styleValue, axisDefinition!!.defaultValue)
+ else -> filter(tag, axisDefinition!!.defaultValue, end[j++].styleValue)
}
- result.add(axis)
+ // Round axis value to valid intermediate steps. This improves the cache hit rate.
+ val step = axisDefinition?.animationStep ?: DEFAULT_ANIMATION_STEP
+ result.add(FontVariationAxis(tag, (axisValue / step).roundToInt() * step))
}
return result
}
- // 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)
-
- private fun coerceInWithStep(v: Float, min: Float, max: Float, step: Float) =
- (v.coerceIn(min, max) / step).toInt() * step
-
companion object {
private const val LOG_TAG = "FontInterpolator"
private val DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG)
private val EMPTY_AXES = arrayOf<FontVariationAxis>()
+ private const val DEFAULT_ANIMATION_STEP = 1f
// Returns true if given two font instance can be interpolated.
fun canInterpolate(start: Font, end: Font) =
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontVariationUtils.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/FontVariationUtils.kt
index 9545bda80b2d..9a746870c6ff 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/FontVariationUtils.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/FontVariationUtils.kt
@@ -1,12 +1,20 @@
-package com.android.systemui.animation
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-object GSFAxes {
- const val WEIGHT = "wght"
- const val WIDTH = "wdth"
- const val SLANT = "slnt"
- const val ROUND = "ROND"
- const val OPTICAL_SIZE = "opsz"
-}
+package com.android.systemui.animation
class FontVariationUtils {
private var mWeight = -1
@@ -46,20 +54,20 @@ class FontVariationUtils {
}
var resultString = ""
if (mWeight >= 0) {
- resultString += "'${GSFAxes.WEIGHT}' $mWeight"
+ resultString += "'${GSFAxes.WEIGHT.tag}' $mWeight"
}
if (mWidth >= 0) {
resultString +=
- (if (resultString.isBlank()) "" else ", ") + "'${GSFAxes.WIDTH}' $mWidth"
+ (if (resultString.isBlank()) "" else ", ") + "'${GSFAxes.WIDTH.tag}' $mWidth"
}
if (mOpticalSize >= 0) {
resultString +=
(if (resultString.isBlank()) "" else ", ") +
- "'${GSFAxes.OPTICAL_SIZE}' $mOpticalSize"
+ "'${GSFAxes.OPTICAL_SIZE.tag}' $mOpticalSize"
}
if (mRoundness >= 0) {
resultString +=
- (if (resultString.isBlank()) "" else ", ") + "'${GSFAxes.ROUND}' $mRoundness"
+ (if (resultString.isBlank()) "" else ", ") + "'${GSFAxes.ROUND.tag}' $mRoundness"
}
return if (isUpdated) resultString else ""
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GSFAxes.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GSFAxes.kt
new file mode 100644
index 000000000000..f4e03613169a
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GSFAxes.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.animation
+
+data class AxisDefinition(
+ val tag: String,
+ val minValue: Float,
+ val defaultValue: Float,
+ val maxValue: Float,
+ val animationStep: Float,
+)
+
+object GSFAxes {
+ val WEIGHT =
+ AxisDefinition(
+ tag = "wght",
+ minValue = 1f,
+ defaultValue = 400f,
+ maxValue = 1000f,
+ animationStep = 10f,
+ )
+
+ val WIDTH =
+ AxisDefinition(
+ tag = "wdth",
+ minValue = 25f,
+ defaultValue = 100f,
+ maxValue = 151f,
+ animationStep = 1f,
+ )
+
+ val SLANT =
+ AxisDefinition(
+ tag = "slnt",
+ minValue = 0f,
+ defaultValue = 0f,
+ maxValue = -10f,
+ animationStep = 0.1f,
+ )
+
+ val ROUND =
+ AxisDefinition(
+ tag = "ROND",
+ minValue = 0f,
+ defaultValue = 0f,
+ maxValue = 100f,
+ animationStep = 1f,
+ )
+
+ val GRADE =
+ AxisDefinition(
+ tag = "GRAD",
+ minValue = 0f,
+ defaultValue = 0f,
+ maxValue = 100f,
+ animationStep = 1f,
+ )
+
+ val OPTICAL_SIZE =
+ AxisDefinition(
+ tag = "opsz",
+ minValue = 6f,
+ defaultValue = 18f,
+ maxValue = 144f,
+ animationStep = 1f,
+ )
+
+ // Not a GSF Axis, but present for FontInterpolator compatibility
+ val ITALIC =
+ AxisDefinition(
+ tag = "ITAL",
+ minValue = 0f,
+ defaultValue = 0f,
+ maxValue = 1f,
+ animationStep = 0.1f,
+ )
+
+ private val AXIS_MAP =
+ listOf(WEIGHT, WIDTH, SLANT, ROUND, GRADE, OPTICAL_SIZE, ITALIC)
+ .map { def -> def.tag.toLowerCase() to def }
+ .toMap()
+
+ fun getAxis(axis: String): AxisDefinition? = AXIS_MAP[axis.toLowerCase()]
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
index 004d1aa1fe93..ac1c5a8dfaf3 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
@@ -130,39 +130,25 @@ class FlexClockController(private val clockCtx: ClockContext) : ClockController
private val FONT_AXES =
listOf(
- ClockFontAxis(
- key = GSFAxes.WEIGHT,
+ GSFAxes.WEIGHT.toClockAxis(
type = AxisType.Float,
- minValue = 25f,
currentValue = 400f,
- maxValue = 1000f,
name = "Weight",
description = "Glyph Weight",
),
- ClockFontAxis(
- key = GSFAxes.WIDTH,
+ GSFAxes.WIDTH.toClockAxis(
type = AxisType.Float,
- minValue = 25f,
currentValue = 85f,
- maxValue = 151f,
name = "Width",
description = "Glyph Width",
),
- ClockFontAxis(
- key = GSFAxes.ROUND,
+ GSFAxes.ROUND.toClockAxis(
type = AxisType.Boolean,
- minValue = 0f,
- currentValue = 0f,
- maxValue = 100f,
name = "Round",
description = "Glyph Roundness",
),
- ClockFontAxis(
- key = GSFAxes.SLANT,
+ GSFAxes.SLANT.toClockAxis(
type = AxisType.Boolean,
- minValue = 0f,
- currentValue = 0f,
- maxValue = -10f,
name = "Slant",
description = "Glyph Slant",
),
@@ -170,10 +156,10 @@ class FlexClockController(private val clockCtx: ClockContext) : ClockController
private val LEGACY_FLEX_SETTINGS =
listOf(
- ClockFontAxisSetting(GSFAxes.WEIGHT, 600f),
- ClockFontAxisSetting(GSFAxes.WIDTH, 100f),
- ClockFontAxisSetting(GSFAxes.ROUND, 100f),
- ClockFontAxisSetting(GSFAxes.SLANT, 0f),
+ GSFAxes.WEIGHT.toClockAxisSetting(600f),
+ GSFAxes.WIDTH.toClockAxisSetting(100f),
+ GSFAxes.ROUND.toClockAxisSetting(100f),
+ GSFAxes.SLANT.toClockAxisSetting(0f),
)
}
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt
index b2dbd6552955..b4c2f5de290f 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt
@@ -132,7 +132,7 @@ class FlexClockFaceController(clockCtx: ClockContext, private val isLargeClock:
if (!isLargeClock) {
axes =
axes.map { axis ->
- if (axis.key == GSFAxes.WIDTH && axis.value > SMALL_CLOCK_MAX_WDTH) {
+ if (axis.key == GSFAxes.WIDTH.tag && axis.value > SMALL_CLOCK_MAX_WDTH) {
axis.copy(value = SMALL_CLOCK_MAX_WDTH)
} else {
axis
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt
new file mode 100644
index 000000000000..212b1e29d1b8
--- /dev/null
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shared.clocks
+
+import com.android.systemui.animation.AxisDefinition
+import com.android.systemui.plugins.clocks.AxisType
+import com.android.systemui.plugins.clocks.ClockFontAxis
+import com.android.systemui.plugins.clocks.ClockFontAxisSetting
+
+fun AxisDefinition.toClockAxis(
+ type: AxisType,
+ currentValue: Float? = null,
+ name: String,
+ description: String,
+): ClockFontAxis {
+ return ClockFontAxis(
+ key = this.tag,
+ type = type,
+ maxValue = this.maxValue,
+ minValue = this.minValue,
+ currentValue = currentValue ?: this.defaultValue,
+ name = name,
+ description = description,
+ )
+}
+
+fun AxisDefinition.toClockAxisSetting(value: Float? = null): ClockFontAxisSetting {
+ return ClockFontAxisSetting(this.tag, value ?: this.defaultValue)
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
index 8317aa39ef2b..5b0db225f9cd 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
@@ -49,6 +49,7 @@ import com.android.systemui.shared.clocks.DigitTranslateAnimator
import com.android.systemui.shared.clocks.DimensionParser
import com.android.systemui.shared.clocks.FLEX_CLOCK_ID
import com.android.systemui.shared.clocks.FontTextStyle
+import com.android.systemui.shared.clocks.toClockAxisSetting
import java.lang.Thread
import kotlin.math.max
import kotlin.math.min
@@ -594,25 +595,25 @@ open class SimpleDigitalClockTextView(
val FIDGET_INTERPOLATOR = PathInterpolator(0.26873f, 0f, 0.45042f, 1f)
val FIDGET_DISTS =
mapOf(
- GSFAxes.WEIGHT to Pair(200f, 500f),
- GSFAxes.WIDTH to Pair(30f, 75f),
- GSFAxes.ROUND to Pair(0f, 50f),
- GSFAxes.SLANT to Pair(0f, -5f),
+ GSFAxes.WEIGHT.tag to Pair(200f, 500f),
+ GSFAxes.WIDTH.tag to Pair(30f, 75f),
+ GSFAxes.ROUND.tag to Pair(0f, 50f),
+ GSFAxes.SLANT.tag to Pair(0f, -5f),
)
val AOD_COLOR = Color.WHITE
- val LS_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 400f)
- val AOD_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 200f)
- val WIDTH_AXIS = ClockFontAxisSetting(GSFAxes.WIDTH, 85f)
- val ROUND_AXIS = ClockFontAxisSetting(GSFAxes.ROUND, 0f)
- val SLANT_AXIS = ClockFontAxisSetting(GSFAxes.SLANT, 0f)
+ val LS_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(400f)
+ val AOD_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(200f)
+ val WIDTH_AXIS = GSFAxes.WIDTH.toClockAxisSetting(85f)
+ val ROUND_AXIS = GSFAxes.ROUND.toClockAxisSetting(0f)
+ val SLANT_AXIS = GSFAxes.SLANT.toClockAxisSetting(0f)
// Axes for Legacy version of the Flex Clock
- val FLEX_LS_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 600f)
- val FLEX_AOD_LARGE_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 74f)
- val FLEX_AOD_SMALL_WEIGHT_AXIS = ClockFontAxisSetting(GSFAxes.WEIGHT, 133f)
- val FLEX_LS_WIDTH_AXIS = ClockFontAxisSetting(GSFAxes.WIDTH, 100f)
- val FLEX_AOD_WIDTH_AXIS = ClockFontAxisSetting(GSFAxes.WIDTH, 43f)
- val FLEX_ROUND_AXIS = ClockFontAxisSetting(GSFAxes.ROUND, 100f)
+ val FLEX_LS_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(600f)
+ val FLEX_AOD_LARGE_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(74f)
+ val FLEX_AOD_SMALL_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(133f)
+ val FLEX_LS_WIDTH_AXIS = GSFAxes.WIDTH.toClockAxisSetting(100f)
+ val FLEX_AOD_WIDTH_AXIS = GSFAxes.WIDTH.toClockAxisSetting(43f)
+ val FLEX_ROUND_AXIS = GSFAxes.ROUND.toClockAxisSetting(100f)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/FontVariationUtilsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/FontVariationUtilsTest.kt
index f44769d522eb..8d3640d8d809 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/FontVariationUtilsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/animation/FontVariationUtilsTest.kt
@@ -21,7 +21,7 @@ class FontVariationUtilsTest : SysuiTestCase() {
roundness = 100,
)
Assert.assertEquals(
- "'${GSFAxes.WEIGHT}' 100, '${GSFAxes.WIDTH}' 100, '${GSFAxes.ROUND}' 100",
+ "'${GSFAxes.WEIGHT.tag}' 100, '${GSFAxes.WIDTH.tag}' 100, '${GSFAxes.ROUND.tag}' 100",
initFvar,
)
val updatedFvar =
@@ -32,7 +32,8 @@ class FontVariationUtilsTest : SysuiTestCase() {
roundness = 100,
)
Assert.assertEquals(
- "'${GSFAxes.WEIGHT}' 200, '${GSFAxes.WIDTH}' 100, '${GSFAxes.OPTICAL_SIZE}' 0, '${GSFAxes.ROUND}' 100",
+ "'${GSFAxes.WEIGHT.tag}' 200, '${GSFAxes.WIDTH.tag}' 100," +
+ " '${GSFAxes.OPTICAL_SIZE.tag}' 0, '${GSFAxes.ROUND.tag}' 100",
updatedFvar,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
index 2e634390679a..c2a495d13c02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
@@ -64,6 +64,12 @@ class FontInterpolatorTest : SysuiTestCase() {
"'wght' 500, 'ital' 0.5, 'GRAD' 450",
interp.lerp(startFont, endFont, 0.5f, 0.5f),
)
+
+ // Ensure axes rounded correctly to nearest step
+ assertSameAxes(
+ "'wght' 490, 'ital' 0.5, 'GRAD' 446",
+ interp.lerp(startFont, endFont, 0.492f, 0.492f),
+ )
}
@Test