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
This commit is contained in:
Ahmed El-Helw 2015-12-11 11:36:20 -08:00
parent 5b182fa0ca
commit 1a2cf776af
2 changed files with 43 additions and 10 deletions

View File

@ -9,20 +9,16 @@
package com.facebook.react.flat; package com.facebook.react.flat;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.annotation.Nullable;
import com.facebook.csslayout.CSSNode;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.CatalystStylesDiffMap; import com.facebook.react.uimanager.CatalystStylesDiffMap;
import com.facebook.react.uimanager.NativeViewHierarchyManager;
import com.facebook.react.uimanager.ReactShadowNode; import com.facebook.react.uimanager.ReactShadowNode;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIImplementation; import com.facebook.react.uimanager.UIImplementation;
import com.facebook.react.uimanager.UIViewOperationQueue;
import com.facebook.react.uimanager.ViewManager; import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.ViewManagerRegistry; import com.facebook.react.uimanager.ViewManagerRegistry;
import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.EventDispatcher;
@ -45,6 +41,7 @@ public class FlatUIImplementation extends UIImplementation {
viewManagers.add(new RCTTextManager()); viewManagers.add(new RCTTextManager());
viewManagers.add(new RCTRawTextManager()); viewManagers.add(new RCTRawTextManager());
viewManagers.add(new RCTVirtualTextManager()); viewManagers.add(new RCTVirtualTextManager());
TypefaceCache.setAssetManager(reactContext.getAssets());
ViewManagerRegistry viewManagerRegistry = new ViewManagerRegistry(viewManagers); ViewManagerRegistry viewManagerRegistry = new ViewManagerRegistry(viewManagers);
FlatNativeViewHierarchyManager nativeViewHierarchyManager = new FlatNativeViewHierarchyManager( FlatNativeViewHierarchyManager nativeViewHierarchyManager = new FlatNativeViewHierarchyManager(

View File

@ -9,10 +9,15 @@
package com.facebook.react.flat; package com.facebook.react.flat;
import javax.annotation.Nullable;
import java.util.HashMap; import java.util.HashMap;
import android.content.res.AssetManager;
import android.graphics.Typeface; import android.graphics.Typeface;
import com.facebook.infer.annotation.Assertions;
/** /**
* TypefaceCache provides methods to resolve typeface from font family, or existing typeface * TypefaceCache provides methods to resolve typeface from font family, or existing typeface
* with a different style. * with a different style.
@ -24,9 +29,20 @@ import android.graphics.Typeface;
private static final HashMap<String, Typeface[]> FONTFAMILY_CACHE = new HashMap<>(); private static final HashMap<String, Typeface[]> FONTFAMILY_CACHE = new HashMap<>();
private static final HashMap<Typeface, Typeface[]> TYPEFACE_CACHE = new HashMap<>(); private static final HashMap<Typeface, Typeface[]> TYPEFACE_CACHE = new HashMap<>();
/** private static final String[] EXTENSIONS = {
* Returns a Typeface for a given a FontFamily and style. "",
*/ "_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) { public static Typeface getTypeface(String fontFamily, int style) {
Typeface[] cache = FONTFAMILY_CACHE.get(fontFamily); Typeface[] cache = FONTFAMILY_CACHE.get(fontFamily);
if (cache == null) { if (cache == null) {
@ -38,12 +54,32 @@ import android.graphics.Typeface;
return cache[style]; return cache[style];
} }
Typeface typeface = Typeface.create(fontFamily, style); Typeface typeface = createTypeface(fontFamily, style);
cache[style] = typeface; cache[style] = typeface;
TYPEFACE_CACHE.put(typeface, cache); TYPEFACE_CACHE.put(typeface, cache);
return typeface; 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. * Returns a derivative of a given Typeface with a different style.
*/ */