aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--resources/android_fonts/v22/fonts.xml14
-rw-r--r--src/ports/SkFontMgr_android.cpp14
-rw-r--r--src/ports/SkFontMgr_android_parser.cpp28
-rw-r--r--src/ports/SkFontMgr_android_parser.h2
-rw-r--r--tests/FontMgrAndroidParserTest.cpp20
5 files changed, 52 insertions, 26 deletions
diff --git a/resources/android_fonts/v22/fonts.xml b/resources/android_fonts/v22/fonts.xml
index f310ac4dfd..100c1a18b0 100644
--- a/resources/android_fonts/v22/fonts.xml
+++ b/resources/android_fonts/v22/fonts.xml
@@ -220,16 +220,16 @@
<font weight="400" style="normal">NotoSansYi-Regular.ttf</font>
</family>
<family lang="zh-Hans">
- <font weight="400" style="normal">NotoSansHans-Regular.otf</font>
+ <font weight="400" style="normal" index="2">NotoSansCJK-Regular.ttc</font>
</family>
- <family lang="zh-Hant">
- <font weight="400" style="normal">NotoSansHant-Regular.otf</font>
+ <family lang="zh-Hant zh-Bopo">
+ <font weight="400" style="normal" index="3">NotoSansCJK-Regular.ttc</font>
</family>
- <family lang="ja">
- <font weight="400" style="normal">NotoSansJP-Regular.otf</font>
+ <family lang=" ja ja-Latn">
+ <font weight="400" style="normal" index="0">NotoSansCJK-Regular.ttc</font>
</family>
- <family lang="ko">
- <font weight="400" style="normal">NotoSansKR-Regular.otf</font>
+ <family lang="ko ko-Latn ">
+ <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
</family>
<family>
<font weight="400" style="normal">NanumGothic.ttf</font>
diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp
index a180215e88..2dd3221466 100644
--- a/src/ports/SkFontMgr_android.cpp
+++ b/src/ports/SkFontMgr_android.cpp
@@ -27,6 +27,7 @@
#include "SkTemplates.h"
#include "SkTypefaceCache.h"
+#include <algorithm>
#include <limits>
class SkData;
@@ -60,7 +61,7 @@ public:
const SkFontStyle& style,
bool isFixedPitch,
const SkString& familyName,
- const SkLanguage& lang,
+ const SkTArray<SkLanguage, true>& lang,
FontVariant variantStyle)
: INHERITED(style, isFixedPitch, familyName)
, fPathName(pathName)
@@ -101,7 +102,7 @@ public:
const SkString fPathName;
int fIndex;
const SkSTArray<4, SkFixed, true> fAxes;
- const SkLanguage fLang;
+ const SkSTArray<4, SkLanguage, true> fLang;
const FontVariant fVariantStyle;
SkAutoTCallVProc<FILE, sk_fclose> fFile;
@@ -187,7 +188,6 @@ public:
}
style = SkFontStyle(weight, style.width(), slant);
- const SkLanguage& lang = family.fLanguage;
uint32_t variant = family.fVariant;
if (kDefault_FontVariant == variant) {
variant = kCompact_FontVariant | kElegant_FontVariant;
@@ -210,7 +210,7 @@ public:
fStyles.push_back().reset(new SkTypeface_AndroidSystem(
pathName, cacheFontFiles, ttcIndex, axisValues.get(), axisDefinitions.count(),
- style, isFixedWidth, familyName, lang, variant));
+ style, isFixedWidth, familyName, family.fLanguages, variant));
}
}
@@ -351,7 +351,11 @@ protected:
SkFontStyleSet_Android* family = fallbackNameToFamilyMap[i].styleSet;
sk_sp<SkTypeface_AndroidSystem> face(family->matchStyle(style));
- if (!langTag.isEmpty() && !face->fLang.getTag().startsWith(langTag.c_str())) {
+ if (!langTag.isEmpty() &&
+ std::none_of(face->fLang.begin(), face->fLang.end(), [&](SkLanguage lang){
+ return lang.getTag().startsWith(langTag.c_str());
+ }))
+ {
continue;
}
diff --git a/src/ports/SkFontMgr_android_parser.cpp b/src/ports/SkFontMgr_android_parser.cpp
index a68f791387..1269523062 100644
--- a/src/ports/SkFontMgr_android_parser.cpp
+++ b/src/ports/SkFontMgr_android_parser.cpp
@@ -249,7 +249,7 @@ static const TagHandler fontHandler = {
static const TagHandler familyHandler = {
/*start*/[](FamilyData* self, const char* tag, const char** attributes) {
// 'name' (string) [optional]
- // 'lang' (string) [default ""]
+ // 'lang' (space separated string) [default ""]
// 'variant' ("elegant", "compact") [default "default"]
// If there is no name, this is a fallback only font.
FontFamily* family = new FontFamily(self->fBasePath, true);
@@ -264,7 +264,16 @@ static const TagHandler familyHandler = {
family->fNames.push_back().set(tolc.lc());
family->fIsFallbackFont = false;
} else if (MEMEQ("lang", name, nameLen)) {
- family->fLanguage = SkLanguage(value, valueLen);
+ size_t i = 0;
+ while (true) {
+ for (; i < valueLen && is_whitespace(value[i]); ++i) { }
+ if (i == valueLen) { break; }
+ size_t j;
+ for (j = i + 1; j < valueLen && !is_whitespace(value[j]); ++j) { }
+ family->fLanguages.emplace_back(value + i, j - i);
+ i = j;
+ if (i == valueLen) { break; }
+ }
} else if (MEMEQ("variant", name, nameLen)) {
if (MEMEQ("elegant", value, valueLen)) {
family->fVariant = kElegant_FontVariant;
@@ -400,9 +409,16 @@ static const TagHandler fileHandler = {
}
} else if (MEMEQ("lang", name, nameLen)) {
- SkLanguage prevLang = currentFamily.fLanguage;
- currentFamily.fLanguage = SkLanguage(value, valueLen);
- if (currentFamily.fFonts.count() > 1 && currentFamily.fLanguage != prevLang) {
+ SkLanguage currentLanguage = SkLanguage(value, valueLen);
+ bool showWarning = false;
+ if (currentFamily.fLanguages.empty()) {
+ showWarning = (currentFamily.fFonts.count() > 1);
+ currentFamily.fLanguages.push_back(std::move(currentLanguage));
+ } else if (currentFamily.fLanguages[0] != currentLanguage) {
+ showWarning = true;
+ currentFamily.fLanguages[0] = std::move(currentLanguage);
+ }
+ if (showWarning) {
SK_FONTCONFIGPARSER_WARNING("'%s' unexpected language found\n"
"Note: Every font file within a family must have identical languages.",
value);
@@ -705,7 +721,7 @@ static void append_fallback_font_families_for_locale(SkTDArray<FontFamily*>& fal
for (int i = 0; i < langSpecificFonts.count(); ++i) {
FontFamily* family = langSpecificFonts[i];
- family->fLanguage = SkLanguage(locale);
+ family->fLanguages.emplace_back(locale);
*fallbackFonts.append() = family;
}
}
diff --git a/src/ports/SkFontMgr_android_parser.h b/src/ports/SkFontMgr_android_parser.h
index 75b31c300e..d8de6ab1fd 100644
--- a/src/ports/SkFontMgr_android_parser.h
+++ b/src/ports/SkFontMgr_android_parser.h
@@ -93,7 +93,7 @@ struct FontFamily {
SkTArray<SkString, true> fNames;
SkTArray<FontFileInfo, true> fFonts;
- SkLanguage fLanguage;
+ SkTArray<SkLanguage, true> fLanguages;
FontVariant fVariant;
int fOrder; // internal to the parser, not useful to users.
bool fIsFallbackFont;
diff --git a/tests/FontMgrAndroidParserTest.cpp b/tests/FontMgrAndroidParserTest.cpp
index cbcfb3be2a..b5346ef5b6 100644
--- a/tests/FontMgrAndroidParserTest.cpp
+++ b/tests/FontMgrAndroidParserTest.cpp
@@ -45,11 +45,13 @@ void ValidateLoadedFonts(SkTDArray<FontFamily*> fontFamilies, const char* firstE
REPORTER_ASSERT(reporter, !fontFamilies[0]->fIsFallbackFont);
// Check that the languages are all sane.
- for (int i = 0; i < fontFamilies.count(); ++i) {
- const SkString& lang = fontFamilies[i]->fLanguage.getTag();
- for (size_t j = 0; j < lang.size(); ++j) {
- int c = lang[j];
- REPORTER_ASSERT(reporter, isALPHA(c) || isDIGIT(c) || '-' == c);
+ for (const auto& fontFamily : fontFamilies) {
+ for (const auto& lang : fontFamily->fLanguages) {
+ const SkString& langString = lang.getTag();
+ for (size_t i = 0; i < langString.size(); ++i) {
+ int c = langString[i];
+ REPORTER_ASSERT(reporter, isALPHA(c) || isDIGIT(c) || '-' == c);
+ }
}
}
@@ -81,8 +83,12 @@ void DumpLoadedFonts(SkTDArray<FontFamily*> fontFamilies, const char* label) {
default: break;
}
SkDebugf(" basePath %s\n", fontFamilies[i]->fBasePath.c_str());
- if (!fontFamilies[i]->fLanguage.getTag().isEmpty()) {
- SkDebugf(" language %s\n", fontFamilies[i]->fLanguage.getTag().c_str());
+ if (!fontFamilies[i]->fLanguages.empty()) {
+ SkDebugf(" language");
+ for (const auto& lang : fontFamilies[i]->fLanguages) {
+ SkDebugf(" %s", lang.getTag().c_str());
+ }
+ SkDebugf("\n");
}
for (int j = 0; j < fontFamilies[i]->fNames.count(); ++j) {
SkDebugf(" name %s\n", fontFamilies[i]->fNames[j].c_str());