From 1a2cf776af55d3f8279ee2f14814bd94100f9739 Mon Sep 17 00:00:00 2001 From: Ahmed El-Helw Date: Fri, 11 Dec 2015 11:36:20 -0800 Subject: [PATCH] Support custom fonts for flat React rendering. Summary: Custom fonts weren't supported before, now they are when using flat rendering in React. Differential Revision: D2740489 --- .../react/flat/FlatUIImplementation.java | 9 ++-- .../facebook/react/flat/TypefaceCache.java | 44 +++++++++++++++++-- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java index c17de9be7..ffe105c27 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java @@ -9,20 +9,16 @@ package com.facebook.react.flat; +import javax.annotation.Nullable; + import java.util.ArrayList; import java.util.List; -import javax.annotation.Nullable; - -import com.facebook.csslayout.CSSNode; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.uimanager.CatalystStylesDiffMap; -import com.facebook.react.uimanager.NativeViewHierarchyManager; import com.facebook.react.uimanager.ReactShadowNode; -import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIImplementation; -import com.facebook.react.uimanager.UIViewOperationQueue; import com.facebook.react.uimanager.ViewManager; import com.facebook.react.uimanager.ViewManagerRegistry; import com.facebook.react.uimanager.events.EventDispatcher; @@ -45,6 +41,7 @@ public class FlatUIImplementation extends UIImplementation { viewManagers.add(new RCTTextManager()); viewManagers.add(new RCTRawTextManager()); viewManagers.add(new RCTVirtualTextManager()); + TypefaceCache.setAssetManager(reactContext.getAssets()); ViewManagerRegistry viewManagerRegistry = new ViewManagerRegistry(viewManagers); FlatNativeViewHierarchyManager nativeViewHierarchyManager = new FlatNativeViewHierarchyManager( diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/TypefaceCache.java b/ReactAndroid/src/main/java/com/facebook/react/flat/TypefaceCache.java index 9c023782e..b5e2d63b8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/TypefaceCache.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/TypefaceCache.java @@ -9,10 +9,15 @@ package com.facebook.react.flat; +import javax.annotation.Nullable; + import java.util.HashMap; +import android.content.res.AssetManager; import android.graphics.Typeface; +import com.facebook.infer.annotation.Assertions; + /** * TypefaceCache provides methods to resolve typeface from font family, or existing typeface * with a different style. @@ -24,9 +29,20 @@ import android.graphics.Typeface; private static final HashMap FONTFAMILY_CACHE = new HashMap<>(); private static final HashMap TYPEFACE_CACHE = new HashMap<>(); - /** - * Returns a Typeface for a given a FontFamily and style. - */ + private static final String[] EXTENSIONS = { + "", + "_bold", + "_italic", + "_bold_italic"}; + private static final String[] FILE_EXTENSIONS = {".ttf", ".otf"}; + private static final String FONTS_ASSET_PATH = "fonts/"; + + @Nullable private static AssetManager sAssetManager = null; + + public static void setAssetManager(AssetManager assetManager) { + sAssetManager = assetManager; + } + public static Typeface getTypeface(String fontFamily, int style) { Typeface[] cache = FONTFAMILY_CACHE.get(fontFamily); if (cache == null) { @@ -38,12 +54,32 @@ import android.graphics.Typeface; return cache[style]; } - Typeface typeface = Typeface.create(fontFamily, style); + Typeface typeface = createTypeface(fontFamily, style); cache[style] = typeface; TYPEFACE_CACHE.put(typeface, cache); return typeface; } + private static Typeface createTypeface(String fontFamilyName, int style) { + String extension = EXTENSIONS[style]; + StringBuilder fileNameBuffer = new StringBuilder(32) + .append(FONTS_ASSET_PATH) + .append(fontFamilyName) + .append(extension); + int length = fileNameBuffer.length(); + for (String fileExtension : FILE_EXTENSIONS) { + String fileName = fileNameBuffer.append(fileExtension).toString(); + try { + return Typeface.createFromAsset(sAssetManager, fileName); + } catch (RuntimeException e) { + // unfortunately Typeface.createFromAsset throws an exception instead of returning null + // if the typeface doesn't exist + fileNameBuffer.setLength(length); + } + } + return Assertions.assumeNotNull(Typeface.create(fontFamilyName, style)); + } + /** * Returns a derivative of a given Typeface with a different style. */