Merge "LayoutLib: Font variants" into lmp-preview-dev
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index 9ea4538..d73adab 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -21,6 +21,8 @@
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import android.content.res.AssetManager;
+
import java.awt.Font;
import java.io.File;
import java.util.ArrayList;
@@ -47,7 +49,6 @@
private static final String FONT_SUFFIX_BOLDITALIC = "BoldItalic.ttf";
private static final String FONT_SUFFIX_BOLD = "Bold.ttf";
private static final String FONT_SUFFIX_ITALIC = "Italic.ttf";
- private static final String FONT_SUBSTRING_COMPACT = "UI";
/**
* A class associating {@link Font} with its metadata.
@@ -56,11 +57,6 @@
Font mFont;
/** Regular, Bold, Italic, or BoldItalic. */
int mStyle;
- /**
- * The variant of the Font - compact or elegant.
- * @see Paint#setElegantTextHeight(boolean)
- */
- boolean mIsCompact;
}
// ---- delegate manager ----
@@ -75,6 +71,14 @@
// ---- delegate data ----
private List<FontInfo> mFonts = new ArrayList<FontInfo>();
+ /**
+ * The variant of the Font Family - compact or elegant.
+ * 0 is unspecified, 1 is compact and 2 is elegant. This needs to be kept in sync with values in
+ * android.graphics.FontFamily
+ *
+ * @see Paint#setElegantTextHeight(boolean)
+ */
+ private FontVariant mVariant;
// Path of fonts that haven't been created since sFontLoader hasn't been initialized.
private List<String> mPath = new ArrayList<String>();
@@ -93,37 +97,22 @@
sPostInitDelegate.clear();
}
- public Font getFont(int style, boolean isCompact) {
+ public Font getFont(int style) {
FontInfo plainFont = null;
- FontInfo styledFont = null; // Font matching the style but not isCompact
for (FontInfo font : mFonts) {
if (font.mStyle == style) {
- if (font.mIsCompact == isCompact) {
- return font.mFont;
- }
- styledFont = font;
+ return font.mFont;
}
- if (font.mStyle == Font.PLAIN) {
- if (plainFont == null) {
- plainFont = font;
- continue;
- }
- if (font.mIsCompact == isCompact) {
- // Override the previous selection of plain font since we've found a better one.
- plainFont = font;
- }
+ if (font.mStyle == Font.PLAIN && plainFont == null) {
+ plainFont = font;
}
}
- if (styledFont != null) {
- return styledFont.mFont;
- }
// No font with the mentioned style is found. Try to derive one.
if (plainFont != null && style > 0 && style < 4) {
- styledFont = new FontInfo();
+ FontInfo styledFont = new FontInfo();
styledFont.mFont = plainFont.mFont.deriveFont(style);
styledFont.mStyle = style;
- styledFont.mIsCompact = plainFont.mIsCompact;
// Add the font to the list of fonts so that we don't have to derive it the next time.
mFonts.add(styledFont);
return styledFont.mFont;
@@ -131,11 +120,20 @@
return null;
}
+ public FontVariant getVariant() {
+ return mVariant;
+ }
+
+
// ---- native methods ----
@LayoutlibDelegate
- /*package*/ static long nCreateFamily() {
+ /*package*/ static long nCreateFamily(String lang, int variant) {
+ // TODO: support lang. This is required for japanese locale.
FontFamily_Delegate delegate = new FontFamily_Delegate();
+ // variant can be 0, 1 or 2.
+ assert variant < 3;
+ delegate.mVariant = FontVariant.values()[variant];
if (sFontLocation != null) {
delegate.init();
} else {
@@ -164,6 +162,13 @@
return false;
}
+ @LayoutlibDelegate
+ /*package*/ static boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, String path) {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+ "FontFamily.addFontFromAsset is not supported.", null /*throwable*/, null /*data*/);
+ return false;
+ }
+
private void init() {
for (String path : mPath) {
addFont(path);
@@ -195,13 +200,6 @@
style = Font.ITALIC;
}
fontInfo.mStyle = style;
-
- // Names of compact fonts end with UI-<style>.ttf. For example, NotoNakshUI-Regular.ttf.
- // This should go away when this info is passed on by nAddFont().
- int hyphenIndex = fontName.lastIndexOf('-');
- fontInfo.mIsCompact = hyphenIndex > 0 &&
- fontName.substring(0, hyphenIndex).endsWith(FONT_SUBSTRING_COMPACT);
-
}
private static Font loadFont(String path) {
@@ -214,7 +212,7 @@
} catch (Exception e) {
Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
String.format("Unable to load font %1$s", relativePath),
- null /*throwable*/, null /*data*/);
+ e /*throwable*/, null /*data*/);
}
} else {
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
@@ -224,4 +222,12 @@
return null;
}
+
+
+ // ---- Public helper class ----
+
+ public enum FontVariant {
+ // The order needs to be kept in sync with android.graphics.FontFamily.
+ NONE, COMPACT, ELEGANT
+ }
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 911f4e7..d6e97f5 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -21,6 +21,7 @@
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import android.graphics.FontFamily_Delegate.FontVariant;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.FontMetricsInt;
import android.text.TextUtils;
@@ -30,7 +31,6 @@
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.Collections;
@@ -81,7 +81,8 @@
private float mTextScaleX;
private float mTextSkewX;
private int mHintingMode = Paint.HINTING_ON;
- private boolean mIsCompact = true;
+ // Variant of the font.
+ private FontVariant mFontVariant = FontVariant.NONE;
private Xfermode_Delegate mXfermode;
private ColorFilter_Delegate mColorFilter;
@@ -437,7 +438,7 @@
/*package*/ static boolean isElegantTextHeight(Paint thisPaint) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
- return delegate != null && !delegate.mIsCompact;
+ return delegate != null && delegate.mFontVariant == FontVariant.ELEGANT;
}
@LayoutlibDelegate
@@ -448,7 +449,7 @@
return;
}
- delegate.mIsCompact = !elegant;
+ delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
}
@LayoutlibDelegate
@@ -1022,31 +1023,31 @@
}
@LayoutlibDelegate
- /*package*/ static void native_getTextPath(long native_object, int bidiFlags,
- char[] text, int index, int count, float x, float y, long path) {
+ /*package*/ static void native_getTextPath(long native_object, long native_typeface,
+ int bidiFlags, char[] text, int index, int count, float x, float y, long path) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
"Paint.getTextPath is not supported.", null, null /*data*/);
}
@LayoutlibDelegate
- /*package*/ static void native_getTextPath(long native_object, int bidiFlags,
- String text, int start, int end, float x, float y, long path) {
+ /*package*/ static void native_getTextPath(long native_object, long native_typeface,
+ int bidiFlags, String text, int start, int end, float x, float y, long path) {
// FIXME
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
"Paint.getTextPath is not supported.", null, null /*data*/);
}
@LayoutlibDelegate
- /*package*/ static void nativeGetStringBounds(long nativePaint, String text, int start,
- int end, int bidiFlags, Rect bounds) {
- nativeGetCharArrayBounds(nativePaint, text.toCharArray(), start, end - start, bidiFlags,
- bounds);
+ /*package*/ static void nativeGetStringBounds(long nativePaint, long native_typeface,
+ String text, int start, int end, int bidiFlags, Rect bounds) {
+ nativeGetCharArrayBounds(nativePaint, native_typeface, text.toCharArray(), start,
+ end - start, bidiFlags, bounds);
}
@LayoutlibDelegate
- /*package*/ static void nativeGetCharArrayBounds(long nativePaint, char[] text, int index,
- int count, int bidiFlags, Rect bounds) {
+ /*package*/ static void nativeGetCharArrayBounds(long nativePaint, long native_typeface,
+ char[] text, int index, int count, int bidiFlags, Rect bounds) {
// get the delegate from the native int.
Paint_Delegate delegate = sManager.getDelegate(nativePaint);
@@ -1124,7 +1125,7 @@
private void updateFontObject() {
if (mTypeface != null) {
// Get the fonts from the TypeFace object.
- List<Font> fonts = mTypeface.getFonts(mIsCompact);
+ List<Font> fonts = mTypeface.getFonts(mFontVariant);
// create new font objects as well as FontMetrics, based on the current text size
// and skew info.
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 9746b48..908bb64 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -22,6 +22,7 @@
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.content.res.AssetManager;
+import android.graphics.FontFamily_Delegate.FontVariant;
import java.awt.Font;
import java.io.File;
@@ -69,17 +70,28 @@
return sManager.getDelegate(nativeTypeface);
}
- public List<Font> getFonts(boolean compact) {
+ public List<Font> getFonts(FontVariant variant) {
List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
+ // If we are unable to find fonts matching the variant, we return the fonts from the
+ // other variant since we always want to draw something, rather than nothing.
+ // TODO: check this behaviour with platform.
+ List<Font> otherVariantFonts = new ArrayList<Font>();
for (FontFamily_Delegate ffd : mFontFamilies) {
if (ffd != null) {
- Font font = ffd.getFont(mStyle, compact);
+ Font font = ffd.getFont(mStyle);
if (font != null) {
- fonts.add(font);
+ if (ffd.getVariant() == variant || ffd.getVariant() == FontVariant.NONE) {
+ fonts.add(font);
+ } else {
+ otherVariantFonts.add(font);
+ }
}
}
}
- return fonts;
+ if (fonts.size() > 0) {
+ return fonts;
+ }
+ return otherVariantFonts;
}
// ---- native methods ----