Index: src/ports/SkFontMgr_android.cpp |
diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp |
index 15f1d3ed58ba0da153aad7a64504c6908aeedd71..2865d800b7c34c0d40d7bdb09cbe52aadf375702 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; |
} |