aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2014-10-23 07:08:05 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-10-23 07:08:06 -0700
commitc20386e3937d3d398ac9b35f9c7d997e972ade98 (patch)
treea8c66e05bad1508b43b2689edf3773b2b9f34595 /src
parent7fdffe41494cbd78a8ee2a6ef0509e46ec77039f (diff)
Update fontMgr to take list of bcp47 language tags.
This will enable clients to pass more than one bcp47 tag to ensure that the most appropriate font is selected. BUG=chromium:422180 Review URL: https://codereview.chromium.org/670243002
Diffstat (limited to 'src')
-rw-r--r--src/core/SkFontHost.cpp24
-rw-r--r--src/fonts/SkFontMgr_indirect.cpp18
-rw-r--r--src/ports/SkFontMgr_android.cpp95
-rw-r--r--src/ports/SkFontMgr_fontconfig.cpp22
-rw-r--r--src/ports/SkRemotableFontMgr_win_dw.cpp29
5 files changed, 135 insertions, 53 deletions
diff --git a/src/core/SkFontHost.cpp b/src/core/SkFontHost.cpp
index 77b80e8821..14cca5a6a5 100644
--- a/src/core/SkFontHost.cpp
+++ b/src/core/SkFontHost.cpp
@@ -119,10 +119,18 @@ protected:
const SkFontStyle&) const SK_OVERRIDE {
return NULL;
}
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
const SkFontStyle& style,
- const char bpc47[],
- uint32_t character) const SK_OVERRIDE {
+ const char* bcp47[],
+ int bcp47Count,
+ SkUnichar character) const SK_OVERRIDE {
+#else
+ virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+ const SkFontStyle& style,
+ const char bcp47[],
+ SkUnichar character) const SK_OVERRIDE {
+#endif
return NULL;
}
virtual SkTypeface* onMatchFaceStyle(const SkTypeface*,
@@ -171,10 +179,18 @@ SkTypeface* SkFontMgr::matchFamilyStyle(const char familyName[],
return this->onMatchFamilyStyle(familyName, fs);
}
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
+SkTypeface* SkFontMgr::matchFamilyStyleCharacter(const char familyName[], const SkFontStyle& style,
+ const char* bcp47[], int bcp47Count,
+ SkUnichar character) const {
+ return this->onMatchFamilyStyleCharacter(familyName, style, bcp47, bcp47Count, character);
+}
+#else
SkTypeface* SkFontMgr::matchFamilyStyleCharacter(const char familyName[], const SkFontStyle& style,
- const char bpc47[], uint32_t character) const {
- return this->onMatchFamilyStyleCharacter(familyName, style, bpc47, character);
+ const char bcp47[], SkUnichar character) const {
+ return this->onMatchFamilyStyleCharacter(familyName, style, bcp47, character);
}
+#endif
SkTypeface* SkFontMgr::matchFaceStyle(const SkTypeface* face,
const SkFontStyle& fs) const {
diff --git a/src/fonts/SkFontMgr_indirect.cpp b/src/fonts/SkFontMgr_indirect.cpp
index 54f2de8290..c9d30259c5 100644
--- a/src/fonts/SkFontMgr_indirect.cpp
+++ b/src/fonts/SkFontMgr_indirect.cpp
@@ -245,13 +245,25 @@ SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyle(const char familyName[],
return this->createTypefaceFromFontId(id);
}
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[],
const SkFontStyle& style,
- const char bpc47[],
- uint32_t character) const {
- SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bpc47, character);
+ const char* bcp47[],
+ int bcp47Count,
+ SkUnichar character) const {
+ SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bcp47,
+ bcp47Count, character);
return this->createTypefaceFromFontId(id);
}
+#else
+SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[],
+ const SkFontStyle& style,
+ const char bcp47[],
+ SkUnichar character) const {
+ SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bcp47, character);
+ return this->createTypefaceFromFontId(id);
+}
+#endif
SkTypeface* SkFontMgr_Indirect::onMatchFaceStyle(const SkTypeface* familyMember,
const SkFontStyle& fontStyle) const {
diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp
index 15f1d3ed58..2865d800b7 100644
--- a/src/ports/SkFontMgr_android.cpp
+++ b/src/ports/SkFontMgr_android.cpp
@@ -344,50 +344,79 @@ protected:
return NULL;
}
+static SkTypeface_AndroidSystem* find_family_style_character(
+ const SkTDArray<NameToFamily>& fallbackNameToFamilyMap,
+ const SkFontStyle& style, bool elegant,
+ const SkString& langTag, SkUnichar character)
+{
+ for (int i = 0; i < fallbackNameToFamilyMap.count(); ++i) {
+ SkFontStyleSet_Android* family = fallbackNameToFamilyMap[i].styleSet;
+ SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(style));
+
+ if (!langTag.isEmpty() && langTag != face->fLang.getTag()) {
+ continue;
+ }
+
+ if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) {
+ continue;
+ }
+
+ SkPaint paint;
+ paint.setTypeface(face);
+ paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
+
+ uint16_t glyphID;
+ paint.textToGlyphs(&character, sizeof(character), &glyphID);
+ if (glyphID != 0) {
+ return face.detach();
+ }
+ }
+ return NULL;
+}
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
const SkFontStyle& style,
- const char bpc47[],
- uint32_t character) const SK_OVERRIDE
+ const char* bcp47[],
+ int bcp47Count,
+ SkUnichar character) const SK_OVERRIDE
{
+#else
+ virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+ const SkFontStyle& style,
+ const char bcp47_val[],
+ SkUnichar character) const SK_OVERRIDE
+ {
+ const char** bcp47 = &bcp47_val;
+ int bcp47Count = bcp47_val ? 1 : 0;
+#endif
// The variant 'elegant' is 'not squashed', 'compact' is 'stays in ascent/descent'.
// The variant 'default' means 'compact and elegant'.
// As a result, it is not possible to know the variant context from the font alone.
// TODO: add 'is_elegant' and 'is_compact' bits to 'style' request.
- // For compatibility, try 'elegant' fonts first in fallback.
- uint32_t variantMask = kElegant_FontVariant;
-
- // The first time match anything in the mask, second time anything not in the mask.
- for (bool maskMatches = true; maskMatches != false; maskMatches = false) {
- SkLanguage lang(bpc47);
- // Match against the language, removing a segment each time.
- // The last time through the loop, the language will be empty.
- // The empty language is special, and matches all languages.
- do {
- const SkString& langTag = lang.getTag();
- for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) {
- SkFontStyleSet_Android* family = fFallbackNameToFamilyMap[i].styleSet;
- SkAutoTUnref<SkTypeface_AndroidSystem> face(family->matchStyle(style));
-
- if (!langTag.isEmpty() && langTag != face->fLang.getTag()) {
- continue;
- }
-
- if (SkToBool(face->fVariantStyle & variantMask) != maskMatches) {
- continue;
+ // The first time match anything elegant, second time anything not elegant.
+ for (int elegant = 2; elegant --> 0;) {
+ for (int bcp47Index = bcp47Count; bcp47Index --> 0;) {
+ SkLanguage lang(bcp47[bcp47Index]);
+ while (!lang.getTag().isEmpty()) {
+ SkTypeface_AndroidSystem* matchingTypeface =
+ find_family_style_character(fFallbackNameToFamilyMap,
+ style, SkToBool(elegant),
+ lang.getTag(), character);
+ if (matchingTypeface) {
+ return matchingTypeface;
}
- SkPaint paint;
- paint.setTypeface(face);
- paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
-
- uint16_t glyphID;
- paint.textToGlyphs(&character, sizeof(character), &glyphID);
- if (glyphID != 0) {
- return face.detach();
- }
+ lang = lang.getParent();
}
- } while (!lang.getTag().isEmpty() && (lang = lang.getParent(), true));
+ }
+ SkTypeface_AndroidSystem* matchingTypeface =
+ find_family_style_character(fFallbackNameToFamilyMap,
+ style, SkToBool(elegant),
+ SkString(), character);
+ if (matchingTypeface) {
+ return matchingTypeface;
+ }
}
return NULL;
}
diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp
index dbc64b6e47..6ec5604af4 100644
--- a/src/ports/SkFontMgr_fontconfig.cpp
+++ b/src/ports/SkFontMgr_fontconfig.cpp
@@ -762,11 +762,22 @@ protected:
return createTypefaceFromFcPattern(font);
}
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
const SkFontStyle& style,
- const char bpc47[],
- uint32_t character) const SK_OVERRIDE
+ const char* bcp47[],
+ int bcp47Count,
+ SkUnichar character) const SK_OVERRIDE
{
+#else
+ virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+ const SkFontStyle& style,
+ const char bcp47_val[],
+ SkUnichar character) const SK_OVERRIDE
+ {
+ const char** bcp47 = &bcp47_val;
+ int bcp47Count = bcp47_val ? 1 : 0;
+#endif
FCLocker lock;
SkAutoFcPattern pattern;
@@ -777,9 +788,12 @@ protected:
FcCharSetAddChar(charSet, character);
FcPatternAddCharSet(pattern, FC_CHARSET, charSet);
- if (bpc47) {
+ if (bcp47Count > 0) {
+ SkASSERT(bcp47);
SkAutoFcLangSet langSet;
- FcLangSetAdd(langSet, (const FcChar8*)bpc47);
+ for (int i = bcp47Count; i --> 0;) {
+ FcLangSetAdd(langSet, (const FcChar8*)bcp47[i]);
+ }
FcPatternAddLangSet(pattern, FC_LANG, langSet);
}
diff --git a/src/ports/SkRemotableFontMgr_win_dw.cpp b/src/ports/SkRemotableFontMgr_win_dw.cpp
index d979683273..9fef440d83 100644
--- a/src/ports/SkRemotableFontMgr_win_dw.cpp
+++ b/src/ports/SkRemotableFontMgr_win_dw.cpp
@@ -408,11 +408,21 @@ public:
SkFontIdentity fIdentity;
};
+#ifdef SK_FM_NEW_MATCH_FAMILY_STYLE_CHARACTER
+ virtual SkFontIdentity matchNameStyleCharacter(const char familyName[],
+ const SkFontStyle&, pattern
+ const char* bcp47[], int bcp47Count,
+ SkUnichar character) const SK_OVERRIDE
+ {
+#else
virtual SkFontIdentity matchNameStyleCharacter(const char familyName[],
const SkFontStyle& pattern,
- const char bpc47[],
- SkUnichar character) const SK_OVERRIDE
+ const char bcp47_val[],
+ SkUnichar character) const SK_OVERRIDE
{
+ const char** bcp47 = &bcp47_val;
+ int bcp47Count = bcp47_val ? 1 : 0;
+#endif
SkFontIdentity identity = { SkFontIdentity::kInvalidDataId };
IDWriteFactory* dwFactory = sk_get_dwrite_factory();
@@ -431,13 +441,14 @@ public:
HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), NULL, identity);
}
- const SkSMallocWCHAR* dwBpc47;
- SkSMallocWCHAR dwBpc47Local;
- if (NULL == bpc47) {
- dwBpc47 = &fLocaleName;
+ const SkSMallocWCHAR* dwBcp47;
+ SkSMallocWCHAR dwBcp47Local;
+ if (bcp47Count < 1) {
+ dwBcp47 = &fLocaleName;
} else {
- HR_GENERAL(sk_cstring_to_wchar(bpc47, &dwBpc47Local), NULL, identity);
- dwBpc47 = &dwBpc47Local;
+ //TODO: support fallback stack.
+ HR_GENERAL(sk_cstring_to_wchar(bcp47[bcp47Count-1], &dwBcp47Local), NULL, identity);
+ dwBcp47 = &dwBcp47Local;
}
SkTScopedComPtr<IDWriteTextFormat> fallbackFormat;
@@ -447,7 +458,7 @@ public:
dwStyle.fSlant,
dwStyle.fWidth,
72.0f,
- *dwBpc47,
+ *dwBcp47,
&fallbackFormat),
"Could not create text format.",
identity);