am 242dded6: Merge "LayoutLib: Font variants" into lmp-preview-dev
* commit '242dded6e8b7e5851ad7b80a0c05e4883d2a9f42': LayoutLib: Font variants
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 ----
|
||||
|
||||
Reference in New Issue
Block a user