Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting a map of typefaces instead of a callback #2180

Merged
merged 2 commits into from
Nov 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.airbnb.lottie.compose

import android.graphics.Matrix
import android.graphics.Typeface
import androidx.annotation.FloatRange
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
Expand All @@ -19,6 +20,7 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.ScaleFactor
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import com.airbnb.lottie.FontAssetDelegate
import com.airbnb.lottie.LottieComposition
import com.airbnb.lottie.LottieDrawable
import com.airbnb.lottie.RenderMode
Expand Down Expand Up @@ -65,6 +67,7 @@ import kotlin.math.roundToInt
* size than this composable.
* @param contentScale Define how the animation should be scaled if it has a different size than this Composable.
* @param clipToCompositionBounds Determines whether or not Lottie will clip the animation to the original animation composition bounds.
* @param fontMap A map of keys to Typefaces. The key can be: "fName", "fFamily", or "fFamily-fStyle" as specified in your Lottie file.
*/
@Composable
fun LottieAnimation(
Expand All @@ -80,6 +83,7 @@ fun LottieAnimation(
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
clipToCompositionBounds: Boolean = true,
fontMap: Map<String, Typeface>? = null,
) {
val drawable = remember { LottieDrawable() }
val matrix = remember { Matrix() }
Expand All @@ -105,6 +109,7 @@ fun LottieAnimation(
drawable.enableMergePathsForKitKatAndAbove(enableMergePaths)
drawable.renderMode = renderMode
drawable.composition = composition
drawable.setFontMap(fontMap)
if (dynamicProperties !== setDynamicProperties) {
setDynamicProperties?.removeFrom(drawable)
dynamicProperties?.addTo(drawable)
Expand Down Expand Up @@ -184,6 +189,7 @@ fun LottieAnimation(
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
clipToCompositionBounds: Boolean = true,
fontMap: Map<String, Typeface>? = null,
) {
val progress by animateLottieCompositionAsState(
composition,
Expand All @@ -207,6 +213,7 @@ fun LottieAnimation(
alignment = alignment,
contentScale = contentScale,
clipToCompositionBounds = clipToCompositionBounds,
fontMap = fontMap,
)
}

Expand Down
29 changes: 23 additions & 6 deletions lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.ColorFilter;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Parcel;
Expand Down Expand Up @@ -37,6 +38,7 @@
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
Expand Down Expand Up @@ -351,9 +353,9 @@ public boolean isMergePathsEnabledForKitKatAndAbove() {

/**
* Sets whether or not Lottie should clip to the original animation composition bounds.
*
* <p>
* When set to true, the parent view may need to disable clipChildren so Lottie can render outside of the LottieAnimationView bounds.
*
* <p>
* Defaults to true.
*/
public void setClipToCompositionBounds(boolean clipToCompositionBounds) {
Expand All @@ -362,7 +364,7 @@ public void setClipToCompositionBounds(boolean clipToCompositionBounds) {

/**
* Gets whether or not Lottie should clip to the original animation composition bounds.
*
* <p>
* Defaults to true.
*/
public boolean getClipToCompositionBounds() {
Expand Down Expand Up @@ -861,7 +863,7 @@ public String getImageAssetsFolder() {
/**
* When true, dynamically set bitmaps will be drawn with the exact bounds of the original animation, regardless of the bitmap size.
* When false, dynamically set bitmaps will be drawn at the top left of the original image but with its own bounds.
*
* <p>
* Defaults to false.
*/
public void setMaintainOriginalImageBounds(boolean maintainOriginalImageBounds) {
Expand All @@ -871,7 +873,7 @@ public void setMaintainOriginalImageBounds(boolean maintainOriginalImageBounds)
/**
* When true, dynamically set bitmaps will be drawn with the exact bounds of the original animation, regardless of the bitmap size.
* When false, dynamically set bitmaps will be drawn at the top left of the original image but with its own bounds.
*
* <p>
* Defaults to false.
*/
public boolean getMaintainOriginalImageBounds() {
Expand Down Expand Up @@ -909,7 +911,7 @@ public void setImageAssetDelegate(ImageAssetDelegate assetDelegate) {
* where FONT_NAME is the fFamily specified in your Lottie file.
* If your fonts have a different extension, you can override the
* default here.
*
* <p>
* Alternatively, you can use {@link #setFontAssetDelegate(FontAssetDelegate)}
* for more control.
*
Expand All @@ -926,6 +928,21 @@ public void setFontAssetDelegate(FontAssetDelegate assetDelegate) {
lottieDrawable.setFontAssetDelegate(assetDelegate);
}

/**
* Set a map from font name keys to Typefaces.
* The keys can be in the form:
* * fontFamily
* * fontFamily-fontStyle
* * fontName
* All 3 are defined as fName, fFamily, and fStyle in the Lottie file.
* <p>
* If you change a value in fontMap, create a new map or call
* {@link #invalidate()}. Setting the same map again will noop.
*/
public void setFontMap(@Nullable Map<String, Typeface> fontMap) {
lottieDrawable.setFontMap(fontMap);
}

/**
* Set this to replace animation text with custom text at runtime
*/
Expand Down
48 changes: 43 additions & 5 deletions lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* This can be used to show an lottie animation in any place that would normally take a drawable.
Expand Down Expand Up @@ -106,6 +107,8 @@ public void onAnimationUpdate(ValueAnimator animation) {
private ImageAssetDelegate imageAssetDelegate;
@Nullable
private FontAssetManager fontAssetManager;
@Nullable
private Map<String, Typeface> fontMap;
/**
* Will be set if manually overridden by {@link #setDefaultFontFileExtension(String)}.
* This must be stored as a field in case it is set before the font asset delegate
Expand Down Expand Up @@ -222,7 +225,7 @@ public boolean isMergePathsEnabledForKitKatAndAbove() {

/**
* Sets whether or not Lottie should clip to the original animation composition bounds.
*
* <p>
* Defaults to true.
*/
public void setClipToCompositionBounds(boolean clipToCompositionBounds) {
Expand All @@ -238,7 +241,7 @@ public void setClipToCompositionBounds(boolean clipToCompositionBounds) {

/**
* Gets whether or not Lottie should clip to the original animation composition bounds.
*
* <p>
* Defaults to true.
*/
public boolean getClipToCompositionBounds() {
Expand Down Expand Up @@ -1034,6 +1037,25 @@ public void setFontAssetDelegate(FontAssetDelegate assetDelegate) {
}
}

/**
* Set a map from font name keys to Typefaces.
* The keys can be in the form:
* * fontFamily
* * fontFamily-fontStyle
* * fontName
* All 3 are defined as fName, fFamily, and fStyle in the Lottie file.
* <p>
* If you change a value in fontMap, create a new map or call
* {@link #invalidateSelf()}. Setting the same map again will noop.
*/
public void setFontMap(@Nullable Map<String, Typeface> fontMap) {
if (fontMap == this.fontMap) {
return;
}
this.fontMap = fontMap;
invalidateSelf();
}

public void setTextDelegate(@SuppressWarnings("NullableProblems") TextDelegate textDelegate) {
this.textDelegate = textDelegate;
}
Expand All @@ -1044,7 +1066,7 @@ public TextDelegate getTextDelegate() {
}

public boolean useTextGlyphs() {
return textDelegate == null && composition.getCharacters().size() > 0;
return fontMap == null && textDelegate == null && composition.getCharacters().size() > 0;
}

public LottieComposition getComposition() {
Expand Down Expand Up @@ -1253,6 +1275,22 @@ private ImageAssetManager getImageAssetManager() {
@Nullable
@RestrictTo(RestrictTo.Scope.LIBRARY)
public Typeface getTypeface(Font font) {
Map<String, Typeface> fontMap = this.fontMap;
if (fontMap != null) {
String key = font.getFamily();
if (fontMap.containsKey(key)) {
return fontMap.get(key);
}
key = font.getName();
if (fontMap.containsKey(key)) {
return fontMap.get(key);
}
key = font.getFamily() + "-" + font.getStyle();
if (fontMap.containsKey(key)) {
return fontMap.get(key);
}
}

FontAssetManager assetManager = getFontAssetManager();
if (assetManager != null) {
return assetManager.getTypeface(font);
Expand Down Expand Up @@ -1282,7 +1320,7 @@ private FontAssetManager getFontAssetManager() {
* where FONT_NAME is the fFamily specified in your Lottie file.
* If your fonts have a different extension, you can override the
* default here.
*
* <p>
* Alternatively, you can use {@link #setFontAssetDelegate(FontAssetDelegate)}
* for more control.
*
Expand Down Expand Up @@ -1387,7 +1425,7 @@ private void drawDirectlyToCanvas(Canvas canvas) {

/**
* Software accelerated render path.
*
* <p>
* This draws the animation to an internally managed bitmap and then draws the bitmap to the original canvas.
*
* @see LottieAnimationView#setRenderMode(RenderMode)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.airbnb.lottie.snapshots.tests

import android.graphics.Typeface
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import com.airbnb.lottie.LottieProperty
Expand Down Expand Up @@ -137,6 +138,15 @@ class TextTestCase : SnapshotTestCase {
textDelegate.setText("NAME", "\uD83D\uDC91")
}

snapshotComposable("Compose FontMap", "Text") {
val composition by rememberLottieComposition(LottieCompositionSpec.Asset("Tests/Text.json"))
val snapshotReady = LocalSnapshotReady.current
LaunchedEffect(snapshotReady, composition != null) {
snapshotReady.value = composition != null
}
LottieAnimation(composition, { 0f }, fontMap = mapOf("Helvetica" to Typeface.SERIF))
}

snapshotComposable("Compose Dynamic Text", "Emoji") {
val composition by rememberLottieComposition(LottieCompositionSpec.Asset("Tests/DynamicText.json"))
val snapshotReady = LocalSnapshotReady.current
Expand Down