Merge "LayoutLib: Font variants" into lmp-preview-dev

This commit is contained in:
Deepanshu Gupta
2014-06-05 22:37:08 +00:00
committed by Android (Google) Code Review
3 changed files with 73 additions and 54 deletions

View File

@@ -21,6 +21,8 @@ import com.android.layoutlib.bridge.Bridge;
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 @@ public class FontFamily_Delegate {
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 @@ public class FontFamily_Delegate {
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 @@ public class FontFamily_Delegate {
// ---- 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 @@ public class FontFamily_Delegate {
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 @@ public class FontFamily_Delegate {
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 @@ public class FontFamily_Delegate {
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 @@ public class FontFamily_Delegate {
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 @@ public class FontFamily_Delegate {
} 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 @@ public class FontFamily_Delegate {
return null;
}
// ---- Public helper class ----
public enum FontVariant {
// The order needs to be kept in sync with android.graphics.FontFamily.
NONE, COMPACT, ELEGANT
}
}

View File

@@ -21,6 +21,7 @@ import com.android.layoutlib.bridge.Bridge;
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.Font;
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 @@ public class Paint_Delegate {
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 @@ public class Paint_Delegate {
/*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 @@ public class Paint_Delegate {
return;
}
delegate.mIsCompact = !elegant;
delegate.mFontVariant = elegant ? FontVariant.ELEGANT : FontVariant.COMPACT;
}
@LayoutlibDelegate
@@ -1022,31 +1023,31 @@ public class Paint_Delegate {
}
@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 @@ public class Paint_Delegate {
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.

View File

@@ -22,6 +22,7 @@ import com.android.layoutlib.bridge.impl.DelegateManager;
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 @@ public final class Typeface_Delegate {
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 ----