summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/text/FontConfig.java12
-rw-r--r--core/jni/android/graphics/FontFamily.cpp6
-rw-r--r--core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java55
-rw-r--r--data/fonts/fonts.xml8
-rw-r--r--graphics/java/android/graphics/FontFamily.java16
-rw-r--r--graphics/java/android/graphics/FontListParser.java13
-rw-r--r--graphics/java/android/graphics/Typeface.java15
7 files changed, 87 insertions, 38 deletions
diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java
index 029f66e1d670..4654e83c1af6 100644
--- a/core/java/android/text/FontConfig.java
+++ b/core/java/android/text/FontConfig.java
@@ -175,7 +175,7 @@ public final class FontConfig {
public static final class Family {
private final @NonNull String mName;
private final @NonNull Font[] mFonts;
- private final @NonNull String mLanguage;
+ private final @NonNull String[] mLanguages;
/** @hide */
@Retention(SOURCE)
@@ -209,11 +209,11 @@ public final class FontConfig {
// See frameworks/minikin/include/minikin/FontFamily.h
private final @Variant int mVariant;
- public Family(@NonNull String name, @NonNull Font[] fonts, @NonNull String language,
+ public Family(@NonNull String name, @NonNull Font[] fonts, @NonNull String[] languages,
@Variant int variant) {
mName = name;
mFonts = fonts;
- mLanguage = language;
+ mLanguages = languages;
mVariant = variant;
}
@@ -232,10 +232,10 @@ public final class FontConfig {
}
/**
- * Returns the language for this family. May be null.
+ * Returns the languages for this family. May be null.
*/
- public @Nullable String getLanguage() {
- return mLanguage;
+ public @Nullable String[] getLanguages() {
+ return mLanguages;
}
/**
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index 4cf2b562b9ee..0ba27f61d3a0 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -51,10 +51,10 @@ struct NativeFamilyBuilder {
std::vector<minikin::FontVariation> axes;
};
-static jlong FontFamily_initBuilder(JNIEnv* env, jobject clazz, jstring lang, jint variant) {
+static jlong FontFamily_initBuilder(JNIEnv* env, jobject clazz, jstring langs, jint variant) {
NativeFamilyBuilder* builder;
- if (lang != nullptr) {
- ScopedUtfChars str(env, lang);
+ if (langs != nullptr) {
+ ScopedUtfChars str(env, langs);
builder = new NativeFamilyBuilder(
minikin::FontStyle::registerLanguageList(str.c_str()), variant);
} else {
diff --git a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
index ca4f7d43caf4..417faf220d39 100644
--- a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
+++ b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
@@ -40,6 +40,7 @@ import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
+import java.util.Locale;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -128,7 +129,7 @@ public class TypefaceSystemFallbackTest {
@Test
public void testBuildSystemFallback_NonExistentFontShouldBeIgnored() {
final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
+ + "<familyset>"
+ " <family name='sans-serif'>"
+ " <font weight='400' style='normal'>a3em.ttf</font>"
+ " <font weight='400' style='normal'>NoSuchFont.ttf</font>"
@@ -154,7 +155,7 @@ public class TypefaceSystemFallbackTest {
@Test
public void testBuildSystemFallback_NamedFamily() {
final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
+ + "<familyset>"
+ " <family name='sans-serif'>"
+ " <font weight='400' style='normal'>a3em.ttf</font>"
+ " </family>"
@@ -200,7 +201,7 @@ public class TypefaceSystemFallbackTest {
@Test
public void testBuildSystemFallback_defaultFallback() {
final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
+ + "<familyset>"
+ " <family name='sans-serif'>"
+ " <font weight='400' style='normal'>no_coverage.ttf</font>"
+ " </family>"
@@ -239,7 +240,7 @@ public class TypefaceSystemFallbackTest {
@Test
public void testBuildSystemFallback_namedFallbackFamily() {
final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
+ + "<familyset>"
+ " <family name='sans-serif'>"
+ " <font weight='400' style='normal'>no_coverage.ttf</font>"
+ " </family>"
@@ -291,7 +292,7 @@ public class TypefaceSystemFallbackTest {
@Test
public void testBuildSystemFallback_namedFallbackFamily2() {
final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
+ + "<familyset>"
+ " <family name='sans-serif'>"
+ " <font weight='400' style='normal'>no_coverage.ttf</font>"
+ " </family>"
@@ -341,7 +342,7 @@ public class TypefaceSystemFallbackTest {
@Test
public void testBuildSystemFallback_ImplicitSansSerifFallback() {
final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
+ + "<familyset>"
+ " <family name='sans-serif'>"
+ " <font weight='400' style='normal'>a3em.ttf</font>"
+ " </family>"
@@ -380,7 +381,7 @@ public class TypefaceSystemFallbackTest {
@Test
public void testBuildSystemFallback_ElegantFallback() {
final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
+ + "<familyset>"
+ " <family name='sans-serif'>"
+ " <font weight='400' style='normal'>no_coverage.ttf</font>"
+ " </family>"
@@ -418,7 +419,7 @@ public class TypefaceSystemFallbackTest {
@Test
public void testBuildSystemFallback_ElegantFallback_customFallback() {
final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
+ + "<familyset>"
+ " <family name='sans-serif'>"
+ " <font weight='400' style='normal'>no_coverage.ttf</font>"
+ " </family>"
@@ -466,4 +467,42 @@ public class TypefaceSystemFallbackTest {
assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
}
+
+ @Test
+ public void testBuildSystemFallback_multiLingualFamilies() {
+ final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+ + "<familyset>"
+ + " <family name='sans-serif'>"
+ + " <font weight='400' style='normal'>no_coverage.ttf</font>"
+ + " </family>"
+ + " <family lang='de'>"
+ + " <font weight='400' style='normal'>a3em.ttf</font>"
+ + " </family>"
+ + " <family lang='it fr'>"
+ + " <font weight='400' style='normal'>b3em.ttf</font>"
+ + " </family>"
+ + "</familyset>";
+ final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+ final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+
+ buildSystemFallback(xml, fontMap, fallbackMap);
+
+ final Paint paint = new Paint();
+ paint.setTypeface(fontMap.get("sans-serif"));
+
+ paint.setTextLocale(Locale.GERMANY);
+ assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
+ assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
+ assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+
+ paint.setTextLocale(Locale.ITALY);
+ assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
+ assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
+ assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+
+ paint.setTextLocale(Locale.FRANCE);
+ assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
+ assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
+ assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
+ }
}
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index ae93608726a3..209f364e041b 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -19,7 +19,7 @@
effectively add 300 to the weight, this ensures that 900 is the bold
paired with the 500 weight, ensuring adequate contrast.
-->
-<familyset version="22">
+<familyset version="23">
<!-- first font is default -->
<family name="sans-serif">
<font weight="100" style="normal">Roboto-Thin.ttf</font>
@@ -128,8 +128,7 @@
<font weight="400" style="normal">NotoSansArmenian-Regular.ttf</font>
<font weight="700" style="normal">NotoSansArmenian-Bold.ttf</font>
</family>
- <!-- TODO: add Geok -->
- <family lang="und-Geor">
+ <family lang="und-Geor und-Geok">
<font weight="400" style="normal">NotoSansGeorgian-Regular.ttf</font>
<font weight="700" style="normal">NotoSansGeorgian-Bold.ttf</font>
</family>
@@ -474,8 +473,7 @@
<family lang="zh-Hans">
<font weight="400" style="normal" index="2">NotoSansCJK-Regular.ttc</font>
</family>
- <!-- TODO: Add Bopo -->
- <family lang="zh-Hant">
+ <family lang="zh-Hant zh-Bopo">
<font weight="400" style="normal" index="3">NotoSansCJK-Regular.ttc</font>
</family>
<family lang="ja">
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index d9a77e752823..d77e6012fb46 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -16,9 +16,11 @@
package android.graphics;
+import android.annotation.Nullable;
import android.content.res.AssetManager;
import android.graphics.fonts.FontVariationAxis;
import android.text.FontConfig;
+import android.text.TextUtils;
import android.util.Log;
import dalvik.annotation.optimization.CriticalNative;
@@ -48,8 +50,16 @@ public class FontFamily {
mBuilderPtr = nInitBuilder(null, 0);
}
- public FontFamily(String lang, int variant) {
- mBuilderPtr = nInitBuilder(lang, variant);
+ public FontFamily(@Nullable String[] langs, int variant) {
+ final String langsString;
+ if (langs == null || langs.length == 0) {
+ langsString = null;
+ } else if (langs.length == 1) {
+ langsString = langs[0];
+ } else {
+ langsString = TextUtils.join(",", langs);
+ }
+ mBuilderPtr = nInitBuilder(langsString, variant);
}
/**
@@ -174,7 +184,7 @@ public class FontFamily {
return nAddFont(builderPtr, font, ttcIndex, -1, -1);
}
- private static native long nInitBuilder(String lang, int variant);
+ private static native long nInitBuilder(String langs, int variant);
@CriticalNative
private static native long nCreateFamily(long mBuilderPtr);
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 80a9324d04f3..9f672e30e05b 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -74,13 +74,14 @@ public class FontListParser {
private static FontConfig.Family readFamily(XmlPullParser parser)
throws XmlPullParserException, IOException {
- String name = parser.getAttributeValue(null, "name");
- String lang = parser.getAttributeValue(null, "lang");
- String variant = parser.getAttributeValue(null, "variant");
- List<FontConfig.Font> fonts = new ArrayList<FontConfig.Font>();
+ final String name = parser.getAttributeValue(null, "name");
+ final String lang = parser.getAttributeValue(null, "lang");
+ final String[] langs = lang == null ? null : lang.split("\\s+");
+ final String variant = parser.getAttributeValue(null, "variant");
+ final List<FontConfig.Font> fonts = new ArrayList<FontConfig.Font>();
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
- String tag = parser.getName();
+ final String tag = parser.getName();
if (tag.equals("font")) {
fonts.add(readFont(parser));
} else {
@@ -95,7 +96,7 @@ public class FontListParser {
intVariant = FontConfig.Family.VARIANT_ELEGANT;
}
}
- return new FontConfig.Family(name, fonts.toArray(new FontConfig.Font[fonts.size()]), lang,
+ return new FontConfig.Family(name, fonts.toArray(new FontConfig.Font[fonts.size()]), langs,
intVariant);
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 3a8dfb014d5d..7496fa6abf47 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -929,9 +929,9 @@ public class Typeface {
}
private static @Nullable FontFamily createFontFamily(
- String familyName, List<FontConfig.Font> fonts, String languageTag, int variant,
+ String familyName, List<FontConfig.Font> fonts, String[] languageTags, int variant,
Map<String, ByteBuffer> cache, String fontDir) {
- final FontFamily family = new FontFamily(languageTag, variant);
+ final FontFamily family = new FontFamily(languageTags, variant);
for (int i = 0; i < fonts.size(); i++) {
final FontConfig.Font font = fonts.get(i);
final String fullPath = fontDir + font.getFontName();
@@ -952,7 +952,8 @@ public class Typeface {
}
}
if (!family.freeze()) {
- Log.e(TAG, "Unable to load Family: " + familyName + " : " + languageTag);
+ Log.e(TAG, "Unable to load Family: " + familyName + " : "
+ + Arrays.toString(languageTags));
return null;
}
return family;
@@ -963,7 +964,7 @@ public class Typeface {
Map<String, ByteBuffer> cache,
String fontDir) {
- final String languageTag = xmlFamily.getLanguage();
+ final String[] languageTags = xmlFamily.getLanguages();
final int variant = xmlFamily.getVariant();
final ArrayList<FontConfig.Font> defaultFonts = new ArrayList<>();
@@ -985,7 +986,7 @@ public class Typeface {
}
final FontFamily defaultFamily = defaultFonts.isEmpty() ? null : createFontFamily(
- xmlFamily.getName(), defaultFonts, languageTag, variant, cache, fontDir);
+ xmlFamily.getName(), defaultFonts, languageTags, variant, cache, fontDir);
// Insert family into fallback map.
for (int i = 0; i < fallbackMap.size(); i++) {
@@ -997,7 +998,7 @@ public class Typeface {
}
} else {
final FontFamily family = createFontFamily(
- xmlFamily.getName(), fallback, languageTag, variant, cache, fontDir);
+ xmlFamily.getName(), fallback, languageTags, variant, cache, fontDir);
if (family != null) {
fallbackMap.valueAt(i).add(family);
}
@@ -1034,7 +1035,7 @@ public class Typeface {
}
final FontFamily family = createFontFamily(
xmlFamily.getName(), Arrays.asList(xmlFamily.getFonts()),
- xmlFamily.getLanguage(), xmlFamily.getVariant(), bufferCache, fontDir);
+ xmlFamily.getLanguages(), xmlFamily.getVariant(), bufferCache, fontDir);
if (family == null) {
continue;
}