Chromium Code Reviews| Index: src/ports/SkFontMgr_android.cpp |
| diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp |
| index 2bae9ca0e51a62409f61c51839ddccc3c0368316..713cb6af10d33fed6c9b9dcfd3b2c3ba2bece8ca 100644 |
| --- a/src/ports/SkFontMgr_android.cpp |
| +++ b/src/ports/SkFontMgr_android.cpp |
| @@ -33,6 +33,10 @@ |
| # define DEBUG_FONT(args) |
| #endif |
| +//SkTypeface* SkAndroidNextLogicalTypeface(SkFontID, SkFontID, SkPaintOptionsAndroid const&) { |
|
djsollen
2014/07/31 14:51:37
drop this
bungeman-skia
2014/07/31 22:15:53
As soon as https://codereview.chromium.org/4346230
|
| +// return NULL; |
| +//} |
| + |
| class SkTypeface_Android : public SkTypeface_FreeType { |
| public: |
| SkTypeface_Android(int index, |
| @@ -59,9 +63,11 @@ public: |
| int index, |
| Style style, |
| bool isFixedPitch, |
| - const SkString familyName) |
| + const SkString familyName, |
| + const SkLanguage& lang) |
| : INHERITED(index, style, isFixedPitch, familyName) |
| - , fPathName(pathName) { } |
| + , fPathName(pathName) |
| + , fLang(lang) { } |
| virtual void onGetFontDescriptor(SkFontDescriptor* desc, |
| bool* serialize) const SK_OVERRIDE { |
| @@ -77,8 +83,10 @@ public: |
| } |
| private: |
| - SkString fPathName; |
| + const SkString fPathName; |
| + const SkLanguage fLang; |
| + friend class SkFontMgr_Android; |
|
djsollen
2014/07/31 14:51:37
why!! A simple get function makes it clear that y
bungeman-skia
2014/07/31 22:15:53
As discussed since this is all hidden away in the
|
| typedef SkTypeface_Android INHERITED; |
| }; |
| @@ -120,33 +128,43 @@ void get_path_for_sys_fonts(SkString* full, const SkString& name) { |
| class SkFontStyleSet_Android : public SkFontStyleSet { |
| public: |
| - explicit SkFontStyleSet_Android(FontFamily* family) { |
| + explicit SkFontStyleSet_Android(const FontFamily& family) { |
| + const SkString* cannonicalName = NULL; |
| + if (family.fNames.count() > 0) { |
| + cannonicalName = &family.fNames[0]; |
| + } |
| // TODO? make this lazy |
| - for (int i = 0; i < family->fFontFiles.count(); ++i) { |
| - const SkString& fileName = family->fFontFiles[i].fFileName; |
| + for (int i = 0; i < family.fFontFiles.count(); ++i) { |
| + const FontFileInfo& fontFile = family.fFontFiles[i]; |
| SkString pathName; |
| - get_path_for_sys_fonts(&pathName, fileName); |
| + get_path_for_sys_fonts(&pathName, fontFile.fFileName); |
| SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(pathName.c_str())); |
| if (!stream.get()) { |
| - DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, fileName.c_str())); |
| + DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, pathName.c_str())); |
| continue; |
| } |
| - const int ttcIndex = family->fFontFiles[i].fIndex; |
| + const int ttcIndex = family.fFontFiles[i].fIndex; |
| SkString fontName; |
| SkTypeface::Style style; |
| bool isFixedWidth; |
| if (!SkTypeface_FreeType::ScanFont(stream.get(), ttcIndex, |
| &fontName, &style, &isFixedWidth)) { |
| - DEBUG_FONT(("---- SystemFonts[%d] file=%s (INVALID)", i, fileName.c_str())); |
| + DEBUG_FONT(("---- SystemFonts[%d] file=%s (INVALID)", i, pathName.c_str())); |
| continue; |
| } |
| + const SkLanguage& lang = family.fFontFiles[i].fPaintOptions.getLanguage(); |
| + |
| + if (cannonicalName != NULL) { |
| + fontName = *cannonicalName; |
|
djsollen
2014/07/31 14:51:37
what is the benefit of passing the same name for e
bungeman-skia
2014/07/31 22:15:53
The name is the family name as specified by the Fo
|
| + } |
| + |
| fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem, |
| (pathName, ttcIndex, |
| - style, isFixedWidth, fontName))); |
| + style, isFixedWidth, fontName, lang))); |
| } |
| } |
| @@ -164,7 +182,7 @@ public: |
| name->reset(); |
| } |
| } |
| - virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { |
| + virtual SkTypeface_AndroidSystem* createTypeface(int index) SK_OVERRIDE { |
| if (index < 0 || fStyles.count() <= index) { |
| return NULL; |
| } |
| @@ -175,11 +193,11 @@ public: |
| * TODO: consider replacing with SkStyleSet_Indirect::matchStyle(); |
| * this simpler version using match_score() passes all our tests. |
| */ |
| - virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE { |
| + virtual SkTypeface_AndroidSystem* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE { |
| if (0 == fStyles.count()) { |
| return NULL; |
| } |
| - SkTypeface* closest = fStyles[0]; |
| + SkTypeface_AndroidSystem* closest = fStyles[0]; |
| int minScore = std::numeric_limits<int>::max(); |
| for (int i = 0; i < fStyles.count(); ++i) { |
| SkFontStyle style = this->style(i); |
| @@ -213,7 +231,7 @@ private: |
| return score; |
| } |
| - SkTArray<SkAutoTUnref<SkTypeface>, true> fStyles; |
| + SkTArray<SkAutoTUnref<SkTypeface_AndroidSystem>, true> fStyles; |
| friend struct NameToFamily; |
| friend class SkFontMgr_Android; |
| @@ -235,7 +253,8 @@ class SkFontMgr_Android : public SkFontMgr { |
| public: |
| SkFontMgr_Android() { |
| SkTDArray<FontFamily*> fontFamilies; |
| - SkFontConfigParser::GetFontFamilies(fontFamilies); |
| + SkFontConfigParser::GetFontFamilies(fontFamilies, |
| + SkPaintOptionsAndroid::kCompact_Variant); |
|
djsollen
2014/07/31 14:51:37
document why we ignore the compact variant for fal
bungeman-skia
2014/07/31 22:15:53
Eck, I don't think we want to. Now that I've done
|
| this->buildNameToFamilyMap(fontFamilies); |
| this->findDefaultFont(); |
| } |
| @@ -273,6 +292,12 @@ protected: |
| return SkRef(fNameToFamilyMap[i].styleSet); |
| } |
| } |
| + // TODO: eventually we should not need to name fallback families. |
| + for (int i = 0; i < fFallbackNameToFamilyMap.count(); ++i) { |
| + if (fFallbackNameToFamilyMap[i].name.equals(tolc.lc())) { |
| + return SkRef(fFallbackNameToFamilyMap[i].styleSet); |
| + } |
| + } |
| return NULL; |
| } |
| @@ -294,6 +319,36 @@ protected: |
| return NULL; |
| } |
| + virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], |
| + const SkFontStyle& style, |
| + const char bpc47[], |
| + uint32_t character) const SK_OVERRIDE |
| + { |
| + SkLanguage lang(bpc47); |
| + 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; |
| + } |
| + |
| + 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(); |
| + } |
| + } |
| + } while (!lang.getTag().isEmpty() && (lang = lang.getParent(), true)); |
| + return NULL; |
| + } |
| + |
| virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE { |
| SkAutoTUnref<SkStream> stream(new SkMemoryStream(data)); |
| return this->createFromStream(stream, ttcIndex); |
| @@ -347,15 +402,33 @@ private: |
| SkTypeface* fDefaultTypeface; |
| SkTDArray<NameToFamily> fNameToFamilyMap; |
| + SkTDArray<NameToFamily> fFallbackNameToFamilyMap; |
| void buildNameToFamilyMap(SkTDArray<FontFamily*> families) { |
| for (int i = 0; i < families.count(); i++) { |
| - fFontStyleSets.push_back().reset( |
| - SkNEW_ARGS(SkFontStyleSet_Android, (families[i]))); |
| - for (int j = 0; j < families[i]->fNames.count(); j++) { |
| - NameToFamily* nextEntry = fNameToFamilyMap.append(); |
| - SkNEW_PLACEMENT_ARGS(&nextEntry->name, SkString, (families[i]->fNames[j])); |
| - nextEntry->styleSet = fFontStyleSets.back().get(); |
| + FontFamily& family = *families[i]; |
| + |
| + SkTDArray<NameToFamily>* nameToFamily = &fNameToFamilyMap; |
| + if (family.fIsFallbackFont) { |
| + nameToFamily = &fFallbackNameToFamilyMap; |
| + |
| + if (0 == family.fNames.count()) { |
| + SkString& fallbackName = family.fNames.push_back(); |
| + fallbackName.printf("%.2x##fallback", i); |
| + } |
| + } |
| + |
| + SkFontStyleSet_Android* newSet = SkNEW_ARGS(SkFontStyleSet_Android, (family)); |
| + if (0 == newSet->count()) { |
| + SkDELETE(newSet); |
| + continue; |
| + } |
| + fFontStyleSets.push_back().reset(newSet); |
| + |
| + for (int j = 0; j < family.fNames.count(); j++) { |
| + NameToFamily* nextEntry = nameToFamily->append(); |
| + SkNEW_PLACEMENT_ARGS(&nextEntry->name, SkString, (family.fNames[j])); |
| + nextEntry->styleSet = newSet; |
| } |
| } |
| } |