diff options
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/java/android/graphics/FontFamily.java | 56 | ||||
-rw-r--r-- | graphics/java/android/graphics/FontListParser.java | 117 | ||||
-rw-r--r-- | graphics/java/android/graphics/ImageFormat.java | 1 | ||||
-rw-r--r-- | graphics/java/android/graphics/Paint.java | 24 | ||||
-rw-r--r-- | graphics/java/android/graphics/Rect.java | 16 | ||||
-rw-r--r-- | graphics/java/android/graphics/Typeface.java | 134 |
6 files changed, 328 insertions, 20 deletions
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java new file mode 100644 index 0000000..a759a79 --- /dev/null +++ b/graphics/java/android/graphics/FontFamily.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + +import java.io.File; + +/** + * A family of typefaces with different styles. + * + * @hide + */ +public class FontFamily { + /** + * @hide + */ + public long mNativePtr; + + public FontFamily() { + mNativePtr = nCreateFamily(); + mNativePtr = nCreateFamily(); + if (mNativePtr == 0) { + throw new RuntimeException(); + } + } + + @Override + protected void finalize() throws Throwable { + try { + nUnrefFamily(mNativePtr); + } finally { + super.finalize(); + } + } + + public boolean addFont(File path) { + return nAddFont(mNativePtr, path.getAbsolutePath()); + } + + static native long nCreateFamily(); + static native void nUnrefFamily(long nativePtr); + static native boolean nAddFont(long nativeFamily, String path); +} diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java new file mode 100644 index 0000000..f304f4e --- /dev/null +++ b/graphics/java/android/graphics/FontListParser.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics; + +import android.util.Xml; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * Parser for font config files. + * + * @hide + */ +public class FontListParser { + + public static class Family { + public Family(List<String> names, List<String> fontFiles) { + this.names = names; + this.fontFiles = fontFiles; + } + + public List<String> names; + // todo: need attributes for font files + public List<String> fontFiles; + } + + /* Parse fallback list (no names) */ + public static List<Family> parse(InputStream in) throws XmlPullParserException, IOException { + try { + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(in, null); + parser.nextTag(); + return readFamilies(parser); + } finally { + in.close(); + } + } + + private static List<Family> readFamilies(XmlPullParser parser) + throws XmlPullParserException, IOException { + List<Family> families = new ArrayList<Family>(); + parser.require(XmlPullParser.START_TAG, null, "familyset"); + while (parser.next() != XmlPullParser.END_TAG) { + if (parser.getEventType() != XmlPullParser.START_TAG) continue; + if (parser.getName().equals("family")) { + families.add(readFamily(parser)); + } else { + skip(parser); + } + } + return families; + } + + private static Family readFamily(XmlPullParser parser) + throws XmlPullParserException, IOException { + List<String> names = null; + List<String> fontFiles = new ArrayList<String>(); + while (parser.next() != XmlPullParser.END_TAG) { + if (parser.getEventType() != XmlPullParser.START_TAG) continue; + String tag = parser.getName(); + if (tag.equals("fileset")) { + while (parser.next() != XmlPullParser.END_TAG) { + if (parser.getEventType() != XmlPullParser.START_TAG) continue; + if (parser.getName().equals("file")) { + String filename = parser.nextText(); + String fullFilename = "/system/fonts/" + filename; + fontFiles.add(fullFilename); + } + } + } else if (tag.equals("nameset")) { + names = new ArrayList<String>(); + while (parser.next() != XmlPullParser.END_TAG) { + if (parser.getEventType() != XmlPullParser.START_TAG) continue; + if (parser.getName().equals("name")) { + String name = parser.nextText(); + names.add(name); + } + } + } + } + return new Family(names, fontFiles); + } + + private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException { + int depth = 1; + while (depth > 0) { + switch (parser.next()) { + case XmlPullParser.START_TAG: + depth++; + break; + case XmlPullParser.END_TAG: + depth--; + break; + } + } + } +} diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java index 062acaf..fe53a17 100644 --- a/graphics/java/android/graphics/ImageFormat.java +++ b/graphics/java/android/graphics/ImageFormat.java @@ -272,6 +272,7 @@ public class ImageFormat { case NV16: case YUY2: case YV12: + case JPEG: case NV21: case YUV_420_888: case RAW_SENSOR: diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 457b3ea..bdef404 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -1655,12 +1655,12 @@ public class Paint { return 0; } if (!mHasCompatScaling) { - return native_getTextWidths(mNativePaint, text, index, count, mBidiFlags, widths); + return native_getTextWidths(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, widths); } final float oldSize = getTextSize(); setTextSize(oldSize*mCompatScaling); - int res = native_getTextWidths(mNativePaint, text, index, count, mBidiFlags, widths); + int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, widths); setTextSize(oldSize); for (int i=0; i<res; i++) { widths[i] *= mInvCompatScaling; @@ -1737,12 +1737,12 @@ public class Paint { return 0; } if (!mHasCompatScaling) { - return native_getTextWidths(mNativePaint, text, start, end, mBidiFlags, widths); + return native_getTextWidths(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, widths); } final float oldSize = getTextSize(); setTextSize(oldSize*mCompatScaling); - int res = native_getTextWidths(mNativePaint, text, start, end, mBidiFlags, widths); + int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, widths); setTextSize(oldSize); for (int i=0; i<res; i++) { widths[i] *= mInvCompatScaling; @@ -1832,13 +1832,13 @@ public class Paint { return 0f; } if (!mHasCompatScaling) { - return native_getTextRunAdvances(mNativePaint, chars, index, count, + return native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count, contextIndex, contextCount, flags, advances, advancesIndex); } final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); - float res = native_getTextRunAdvances(mNativePaint, chars, index, count, + float res = native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count, contextIndex, contextCount, flags, advances, advancesIndex); setTextSize(oldSize); @@ -1963,13 +1963,13 @@ public class Paint { } if (!mHasCompatScaling) { - return native_getTextRunAdvances(mNativePaint, text, start, end, + return native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end, contextStart, contextEnd, flags, advances, advancesIndex); } final float oldSize = getTextSize(); setTextSize(oldSize * mCompatScaling); - float totalAdvance = native_getTextRunAdvances(mNativePaint, text, start, end, + float totalAdvance = native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end, contextStart, contextEnd, flags, advances, advancesIndex); setTextSize(oldSize); @@ -2234,19 +2234,19 @@ public class Paint { private static native void native_setTextLocale(long native_object, String locale); - private static native int native_getTextWidths(long native_object, + private static native int native_getTextWidths(long native_object, long native_typeface, char[] text, int index, int count, int bidiFlags, float[] widths); - private static native int native_getTextWidths(long native_object, + private static native int native_getTextWidths(long native_object, long native_typeface, String text, int start, int end, int bidiFlags, float[] widths); private static native int native_getTextGlyphs(long native_object, String text, int start, int end, int contextStart, int contextEnd, int flags, char[] glyphs); - private static native float native_getTextRunAdvances(long native_object, + private static native float native_getTextRunAdvances(long native_object, long native_typeface, char[] text, int index, int count, int contextIndex, int contextCount, int flags, float[] advances, int advancesIndex); - private static native float native_getTextRunAdvances(long native_object, + private static native float native_getTextRunAdvances(long native_object, long native_typeface, String text, int start, int end, int contextStart, int contextEnd, int flags, float[] advances, int advancesIndex); diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index 8b5609f..437d2f4 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -36,9 +36,21 @@ public final class Rect implements Parcelable { public int right; public int bottom; - private static final Pattern FLATTENED_PATTERN = Pattern.compile( + /** + * A helper class for flattened rectange pattern recognition. A separate + * class to avoid an initialization dependency on a regular expression + * causing Rect to not be initializable with an ahead-of-time compilation + * scheme. + */ + private static final class UnflattenHelper { + private static final Pattern FLATTENED_PATTERN = Pattern.compile( "(-?\\d+) (-?\\d+) (-?\\d+) (-?\\d+)"); + static Matcher getMatcher(String str) { + return FLATTENED_PATTERN.matcher(str); + } + } + /** * Create a new empty Rect. All coordinates are initialized to 0. */ @@ -152,7 +164,7 @@ public final class Rect implements Parcelable { * or null if the string is not of that form. */ public static Rect unflattenFromString(String str) { - Matcher matcher = FLATTENED_PATTERN.matcher(str); + Matcher matcher = UnflattenHelper.getMatcher(str); if (!matcher.matches()) { return null; } diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 73e0e8d..64451c4 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -17,10 +17,21 @@ package android.graphics; import android.content.res.AssetManager; -import android.util.SparseArray; +import android.graphics.FontListParser.Family; +import android.util.Log; import android.util.LongSparseArray; +import android.util.SparseArray; + +import org.xmlpull.v1.XmlPullParserException; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * The Typeface class specifies the typeface and intrinsic style of a font. @@ -30,6 +41,8 @@ import java.io.File; */ public class Typeface { + private static String TAG = "Typeface"; + /** The default NORMAL typeface object */ public static final Typeface DEFAULT; /** @@ -49,6 +62,10 @@ public class Typeface { private static final LongSparseArray<SparseArray<Typeface>> sTypefaceCache = new LongSparseArray<SparseArray<Typeface>>(3); + static Typeface sDefaultTypeface; + static Map<String, Typeface> sSystemFontMap; + static FontFamily[] sFallbackFonts; + /** * @hide */ @@ -62,6 +79,11 @@ public class Typeface { private int mStyle = 0; + private static void setDefault(Typeface t) { + sDefaultTypeface = t; + nativeSetDefault(t.native_instance); + } + /** Returns the typeface's intrinsic style attributes */ public int getStyle() { return mStyle; @@ -89,6 +111,9 @@ public class Typeface { * @return The best matching typeface. */ public static Typeface create(String familyName, int style) { + if (sSystemFontMap != null) { + return create(sSystemFontMap.get(familyName), style); + } return new Typeface(nativeCreate(familyName, style)); } @@ -142,7 +167,7 @@ public class Typeface { public static Typeface defaultFromStyle(int style) { return sDefaults[style]; } - + /** * Create a new typeface from the specified font data. * @param mgr The application's asset manager @@ -156,7 +181,7 @@ public class Typeface { /** * Create a new typeface from the specified font file. * - * @param path The path to the font data. + * @param path The path to the font data. * @return The new typeface. */ public static Typeface createFromFile(File path) { @@ -166,13 +191,45 @@ public class Typeface { /** * Create a new typeface from the specified font file. * - * @param path The full path to the font data. + * @param path The full path to the font data. * @return The new typeface. */ public static Typeface createFromFile(String path) { return new Typeface(nativeCreateFromFile(path)); } + /** + * Create a new typeface from an array of font families. + * + * @param families array of font families + * @hide + */ + public static Typeface createFromFamilies(FontFamily[] families) { + long[] ptrArray = new long[families.length]; + for (int i = 0; i < families.length; i++) { + ptrArray[i] = families[i].mNativePtr; + } + return new Typeface(nativeCreateFromArray(ptrArray)); + } + + /** + * Create a new typeface from an array of font families, including + * also the font families in the fallback list. + * + * @param families array of font families + * @hide + */ + public static Typeface createFromFamiliesWithDefault(FontFamily[] families) { + long[] ptrArray = new long[families.length + sFallbackFonts.length]; + for (int i = 0; i < families.length; i++) { + ptrArray[i] = families[i].mNativePtr; + } + for (int i = 0; i < sFallbackFonts.length; i++) { + ptrArray[i + families.length] = sFallbackFonts[i].mNativePtr; + } + return new Typeface(nativeCreateFromArray(ptrArray)); + } + // don't allow clients to call this directly private Typeface(long ni) { if (ni == 0) { @@ -182,14 +239,76 @@ public class Typeface { native_instance = ni; mStyle = nativeGetStyle(ni); } - + + private static FontFamily makeFamilyFromParsed(FontListParser.Family family) { + // TODO: expand to handle attributes like lang and variant + FontFamily fontFamily = new FontFamily(); + for (String fontFile : family.fontFiles) { + fontFamily.addFont(new File(fontFile)); + } + return fontFamily; + } + static { + // Load font config and initialize Minikin state + String systemConfigFilename = "/system/etc/system_fonts.xml"; + String configFilename = "/system/etc/fallback_fonts.xml"; + try { + // TODO: throws an exception non-Minikin builds, to fail early; + // remove when Minikin-only + new FontFamily(); + + FileInputStream systemIn = new FileInputStream(systemConfigFilename); + List<FontListParser.Family> systemFontConfig = FontListParser.parse(systemIn); + + FileInputStream fallbackIn = new FileInputStream(configFilename); + List<FontFamily> familyList = new ArrayList<FontFamily>(); + // Note that the default typeface is always present in the fallback list; + // this is an enhancement from pre-Minikin behavior. + familyList.add(makeFamilyFromParsed(systemFontConfig.get(0))); + for (Family f : FontListParser.parse(fallbackIn)) { + familyList.add(makeFamilyFromParsed(f)); + } + sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]); + setDefault(Typeface.createFromFamilies(sFallbackFonts)); + + Map<String, Typeface> systemFonts = new HashMap<String, Typeface>(); + for (int i = 0; i < systemFontConfig.size(); i++) { + Typeface typeface; + Family f = systemFontConfig.get(i); + if (i == 0) { + // The first entry is the default typeface; no sense in duplicating + // the corresponding FontFamily. + typeface = sDefaultTypeface; + } else { + FontFamily fontFamily = makeFamilyFromParsed(f); + FontFamily[] families = { fontFamily }; + typeface = Typeface.createFromFamiliesWithDefault(families); + } + for (String name : f.names) { + systemFonts.put(name, typeface); + } + } + sSystemFontMap = systemFonts; + + } catch (RuntimeException e) { + Log.w(TAG, "Didn't create default family (most likely, non-Minikin build)"); + // TODO: normal in non-Minikin case, remove or make error when Minikin-only + } catch (FileNotFoundException e) { + Log.e(TAG, "Error opening " + configFilename); + } catch (IOException e) { + Log.e(TAG, "Error reading " + configFilename); + } catch (XmlPullParserException e) { + Log.e(TAG, "XML parse exception for " + configFilename); + } + + // Set up defaults and typefaces exposed in public API DEFAULT = create((String) null, 0); DEFAULT_BOLD = create((String) null, Typeface.BOLD); SANS_SERIF = create("sans-serif", 0); SERIF = create("serif", 0); MONOSPACE = create("monospace", 0); - + sDefaults = new Typeface[] { DEFAULT, DEFAULT_BOLD, @@ -198,6 +317,7 @@ public class Typeface { }; } + @Override protected void finalize() throws Throwable { try { nativeUnref(native_instance); @@ -234,4 +354,6 @@ public class Typeface { private static native int nativeGetStyle(long native_instance); private static native long nativeCreateFromAsset(AssetManager mgr, String path); private static native long nativeCreateFromFile(String path); + private static native long nativeCreateFromArray(long[] familyArray); + private static native void nativeSetDefault(long native_instance); } |