Merge "Do not use Paint.setFontVariationSettings as basis for variant Typefaces" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ac3795b8aa
@@ -23,8 +23,8 @@ import android.animation.ValueAnimator
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Typeface
|
||||
import android.graphics.fonts.Font
|
||||
import android.graphics.fonts.FontVariationAxis
|
||||
import android.text.Layout
|
||||
import android.text.TextPaint
|
||||
import android.util.LruCache
|
||||
|
||||
private const val DEFAULT_ANIMATION_DURATION: Long = 300
|
||||
@@ -33,18 +33,39 @@ private const val TYPEFACE_CACHE_MAX_ENTRIES = 5
|
||||
typealias GlyphCallback = (TextAnimator.PositionedGlyph, Float) -> Unit
|
||||
|
||||
interface TypefaceVariantCache {
|
||||
fun getTypefaceForVariant(fvar: String, targetPaint: TextPaint): Typeface?
|
||||
fun getTypefaceForVariant(fvar: String?): Typeface?
|
||||
|
||||
companion object {
|
||||
fun createVariantTypeface(baseTypeface: Typeface, fVar: String?): Typeface {
|
||||
if (fVar.isNullOrEmpty()) {
|
||||
return baseTypeface
|
||||
}
|
||||
|
||||
val axes = FontVariationAxis.fromFontVariationSettings(fVar).toMutableList()
|
||||
axes.removeIf { !baseTypeface.isSupportedAxes(it.getOpenTypeTagValue()) }
|
||||
if (axes.isEmpty()) {
|
||||
return baseTypeface
|
||||
}
|
||||
return Typeface.createFromTypefaceWithVariation(baseTypeface, axes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TypefaceVariantCacheImpl() : TypefaceVariantCache {
|
||||
class TypefaceVariantCacheImpl(
|
||||
var baseTypeface: Typeface,
|
||||
) : TypefaceVariantCache {
|
||||
private val cache = LruCache<String, Typeface>(TYPEFACE_CACHE_MAX_ENTRIES)
|
||||
override fun getTypefaceForVariant(fvar: String, targetPaint: TextPaint): Typeface? {
|
||||
override fun getTypefaceForVariant(fvar: String?): Typeface? {
|
||||
if (fvar == null) {
|
||||
return baseTypeface
|
||||
}
|
||||
cache.get(fvar)?.let {
|
||||
return it
|
||||
}
|
||||
|
||||
targetPaint.fontVariationSettings = fvar
|
||||
return targetPaint.typeface?.also { cache.put(fvar, it) }
|
||||
return TypefaceVariantCache
|
||||
.createVariantTypeface(baseTypeface, fvar)
|
||||
.also { cache.put(fvar, it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +99,7 @@ class TextAnimator(
|
||||
layout: Layout,
|
||||
private val invalidateCallback: () -> Unit,
|
||||
) {
|
||||
var typefaceCache: TypefaceVariantCache = TypefaceVariantCacheImpl()
|
||||
var typefaceCache: TypefaceVariantCache = TypefaceVariantCacheImpl(layout.paint.typeface)
|
||||
get() = field
|
||||
set(value) {
|
||||
field = value
|
||||
@@ -244,8 +265,7 @@ class TextAnimator(
|
||||
}
|
||||
|
||||
if (!fvar.isNullOrBlank()) {
|
||||
textInterpolator.targetPaint.typeface =
|
||||
typefaceCache.getTypefaceForVariant(fvar, textInterpolator.targetPaint)
|
||||
textInterpolator.targetPaint.typeface = typefaceCache.getTypefaceForVariant(fvar)
|
||||
}
|
||||
|
||||
if (color != null) {
|
||||
@@ -339,4 +359,3 @@ class TextAnimator(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ class TextInterpolator(
|
||||
* Once you modified the style parameters, you have to call reshapeText to recalculate base text
|
||||
* layout.
|
||||
*
|
||||
* Do not bypass the cache and update the typeface or font variation directly.
|
||||
*
|
||||
* @return a paint object
|
||||
*/
|
||||
val basePaint = TextPaint(layout.paint)
|
||||
@@ -48,6 +50,8 @@ class TextInterpolator(
|
||||
* Once you modified the style parameters, you have to call reshapeText to recalculate target
|
||||
* text layout.
|
||||
*
|
||||
* Do not bypass the cache and update the typeface or font variation directly.
|
||||
*
|
||||
* @return a paint object
|
||||
*/
|
||||
val targetPaint = TextPaint(layout.paint)
|
||||
@@ -217,14 +221,8 @@ class TextInterpolator(
|
||||
run.fontRuns.forEach { fontRun ->
|
||||
fontRun.baseFont =
|
||||
fontInterpolator.lerp(fontRun.baseFont, fontRun.targetFont, progress)
|
||||
val fvar = run {
|
||||
val tmpFontVariationsArray = mutableListOf<FontVariationAxis>()
|
||||
fontRun.baseFont.axes.forEach {
|
||||
tmpFontVariationsArray.add(FontVariationAxis(it.tag, it.styleValue))
|
||||
}
|
||||
FontVariationAxis.toFontVariationSettings(tmpFontVariationsArray)
|
||||
}
|
||||
basePaint.typeface = typefaceCache.getTypefaceForVariant(fvar, basePaint)
|
||||
val fvar = FontVariationAxis.toFontVariationSettings(fontRun.baseFont.axes)
|
||||
basePaint.typeface = typefaceCache.getTypefaceForVariant(fvar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,6 @@ import org.mockito.Mockito.verify
|
||||
|
||||
import kotlin.math.ceil
|
||||
|
||||
private val PAINT = TextPaint().apply {
|
||||
textSize = 32f
|
||||
}
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
class TextAnimatorTest : SysuiTestCase() {
|
||||
|
||||
@@ -49,7 +49,7 @@ private val VF_FONT = Font.Builder(File("/system/fonts/Roboto-Regular.ttf")).bui
|
||||
private fun Font.toTypeface() =
|
||||
Typeface.CustomFallbackBuilder(FontFamily.Builder(this).build()).build()
|
||||
|
||||
private val PAINT = TextPaint().apply {
|
||||
internal val PAINT = TextPaint().apply {
|
||||
typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 400").build().toTypeface()
|
||||
textSize = 32f
|
||||
}
|
||||
@@ -79,7 +79,7 @@ class TextInterpolatorTest : SysuiTestCase() {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
typefaceCache = TypefaceVariantCacheImpl()
|
||||
typefaceCache = TypefaceVariantCacheImpl(PAINT.typeface)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user