diff --git a/RNTester/android/app/src/main/res/font/srisakdi.xml b/RNTester/android/app/src/main/res/font/srisakdi.xml new file mode 100644 index 00000000000..c38d8f34a0e --- /dev/null +++ b/RNTester/android/app/src/main/res/font/srisakdi.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/RNTester/android/app/src/main/res/font/srisakdi_bold.ttf b/RNTester/android/app/src/main/res/font/srisakdi_bold.ttf new file mode 100755 index 00000000000..01a5bcb5d30 Binary files /dev/null and b/RNTester/android/app/src/main/res/font/srisakdi_bold.ttf differ diff --git a/RNTester/android/app/src/main/res/font/srisakdi_regular.ttf b/RNTester/android/app/src/main/res/font/srisakdi_regular.ttf new file mode 100755 index 00000000000..4db47aaad38 Binary files /dev/null and b/RNTester/android/app/src/main/res/font/srisakdi_regular.ttf differ diff --git a/RNTester/js/TextExample.android.js b/RNTester/js/TextExample.android.js index a29fc01cb88..3101fabf7a1 100644 --- a/RNTester/js/TextExample.android.js +++ b/RNTester/js/TextExample.android.js @@ -182,6 +182,14 @@ class TextExample extends React.Component<{}> { NotoSerif Italic (Missing Font file) + Srisakdi Regular + + Srisakdi Bold + diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java index 7b5f33cc32b..f24fb72a36d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomStyleSpan.java @@ -7,8 +7,10 @@ package com.facebook.react.views.text; +import javax.annotation.Nonnull; import javax.annotation.Nullable; +import android.content.Context; import android.content.res.AssetManager; import android.graphics.Paint; import android.graphics.Typeface; @@ -29,31 +31,30 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan { * Fonts are retrieved and cached using the {@link ReactFontManager} */ - private final AssetManager mAssetManager; - private final int mStyle; private final int mWeight; private final @Nullable String mFontFamily; + private final Context mContext; public CustomStyleSpan( int fontStyle, int fontWeight, @Nullable String fontFamily, - AssetManager assetManager) { + @Nonnull Context context) { mStyle = fontStyle; mWeight = fontWeight; mFontFamily = fontFamily; - mAssetManager = assetManager; + mContext = context; } @Override public void updateDrawState(TextPaint ds) { - apply(ds, mStyle, mWeight, mFontFamily, mAssetManager); + apply(ds, mStyle, mWeight, mFontFamily, mContext); } @Override - public void updateMeasureState(TextPaint paint) { - apply(paint, mStyle, mWeight, mFontFamily, mAssetManager); + public void updateMeasureState(@Nonnull TextPaint paint) { + apply(paint, mStyle, mWeight, mFontFamily, mContext); } /** @@ -82,7 +83,7 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan { int style, int weight, @Nullable String family, - AssetManager assetManager) { + Context context) { int oldStyle; Typeface typeface = paint.getTypeface(); if (typeface == null) { @@ -103,7 +104,7 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan { } if (family != null) { - typeface = ReactFontManager.getInstance().getTypeface(family, want, assetManager); + typeface = ReactFontManager.getInstance().getTypeface(family, want, context); } else if (typeface != null) { // TODO(t9055065): Fix custom fonts getting applied to text children with different style typeface = Typeface.create(typeface, want); @@ -116,5 +117,4 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan { } paint.setSubpixelText(true); } - } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java index 5a420bbb977..04d4977ea06 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java @@ -188,7 +188,7 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode { textShadowNode.mFontStyle, textShadowNode.mFontWeight, textShadowNode.mFontFamily, - textShadowNode.getThemedContext().getAssets()))); + textShadowNode.getThemedContext()))); } if (textShadowNode.mIsUnderlineTextDecorationSet) { ops.add(new SetSpanOperation(start, end, new ReactUnderlineSpan())); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java index 41faa061a91..ae680e0d882 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java @@ -12,10 +12,14 @@ import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; +import android.content.Context; import android.content.res.AssetManager; import android.graphics.Typeface; import android.util.SparseArray; +import androidx.core.content.res.ResourcesCompat; + + /** * Class responsible to load and cache Typeface objects. It will first try to load typefaces inside * the assets/fonts folder and if it doesn't find the right Typeface in that folder will fall back @@ -37,9 +41,11 @@ public class ReactFontManager { private static ReactFontManager sReactFontManagerInstance; private Map mFontCache; + private Map mTypeCache; private ReactFontManager() { mFontCache = new HashMap<>(); + mTypeCache = new HashMap<>(); } public static ReactFontManager getInstance() { @@ -49,8 +55,7 @@ public class ReactFontManager { return sReactFontManagerInstance; } - public - @Nullable Typeface getTypeface( + private @Nullable Typeface getTypeface( String fontFamilyName, int style, AssetManager assetManager) { @@ -71,6 +76,33 @@ public class ReactFontManager { return typeface; } + public @Nullable Typeface getTypeface( + String fontFamilyName, + int style, + Context context) { + Typeface font = mTypeCache.get(fontFamilyName); + + if (font != null) { + return Typeface.create( + font, + style + ); + } + + int fontId = context.getResources().getIdentifier(fontFamilyName, "font", context.getPackageName()); + if (fontId != 0) { + font = ResourcesCompat.getFont(context, fontId); + if (font != null) { + mTypeCache.put(fontFamilyName, font); + return Typeface.create( + font, + style + ); + } + } + return getTypeface(fontFamilyName, style, context.getAssets()); + } + /** * Add additional font family, or replace the exist one in the font memory cache. * @param style diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java index 13c50424778..3f02d2f32b4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java @@ -97,7 +97,7 @@ public class TextLayoutManager { textAttributes.mFontStyle, textAttributes.mFontWeight, textAttributes.mFontFamily, - context.getAssets()))); + context))); } if (textAttributes.mIsUnderlineTextDecorationSet) { ops.add(new SetSpanOperation(start, end, new ReactUnderlineSpan())); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 84b63495473..7f917c0858d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -221,7 +221,7 @@ public class ReactTextInputManager extends BaseViewManager