diff options
author | bungeman <bungeman@google.com> | 2014-10-23 07:08:05 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-23 07:08:06 -0700 |
commit | c20386e3937d3d398ac9b35f9c7d997e972ade98 (patch) | |
tree | a8c66e05bad1508b43b2689edf3773b2b9f34595 /src | |
parent | 7fdffe41494cbd78a8ee2a6ef0509e46ec77039f (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.cpp | 24 | ||||
-rw-r--r-- | src/fonts/SkFontMgr_indirect.cpp | 18 | ||||
-rw-r--r-- | src/ports/SkFontMgr_android.cpp | 95 | ||||
-rw-r--r-- | src/ports/SkFontMgr_fontconfig.cpp | 22 | ||||
-rw-r--r-- | src/ports/SkRemotableFontMgr_win_dw.cpp | 29 |
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); |