diff options
author | 2013-02-26 22:58:09 +0000 | |
---|---|---|
committer | 2013-02-26 22:58:09 +0000 | |
commit | ee619a059a2cd7259226dc0c86a000e3bf5834de (patch) | |
tree | 0a92174ec140426ddc1a16613c3c7eaafb66f247 | |
parent | 8d38d516c0f17d8d9f6b170055ac05ac181c0554 (diff) |
fix getFamilyName by calling FcFreeTypeQuery
git-svn-id: http://skia.googlecode.com/svn/trunk@7874 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/ports/SkFontConfigInterface_direct.cpp | 104 | ||||
-rw-r--r-- | src/ports/SkFontHost_fontconfig.cpp | 30 |
2 files changed, 67 insertions, 67 deletions
diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp index bba1eaff04..0fac111c7d 100644 --- a/src/ports/SkFontConfigInterface_direct.cpp +++ b/src/ports/SkFontConfigInterface_direct.cpp @@ -347,11 +347,8 @@ bool SkFontConfigInterfaceDirect::match(const char familyName[], SkTypeface::Style style, unsigned* result_filefaceid, SkTypeface::Style* result_style) { - if (NULL == familyName) { - familyName = "sans-serif"; - } - size_t familyLen = strlen(familyName); - if (familyLen > kMaxFontFamilyLength) { + std::string familyStr(familyName ? familyName : ""); + if (familyStr.length() > kMaxFontFamilyLength) { return false; } @@ -359,7 +356,7 @@ bool SkFontConfigInterfaceDirect::match(const char familyName[], // search our cache { - FontMatchKey key = FontMatchKey(familyName, style); + FontMatchKey key = FontMatchKey(familyStr, style); const std::map<FontMatchKey, FontMatch>::const_iterator i = font_match_cache_.find(key); if (i != font_match_cache_.end()) { @@ -371,7 +368,9 @@ bool SkFontConfigInterfaceDirect::match(const char familyName[], FcPattern* pattern = FcPatternCreate(); - FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); + if (familyName) { + FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); + } FcPatternAddInteger(pattern, FC_WEIGHT, (style & SkTypeface::kBold) ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); @@ -421,7 +420,7 @@ bool SkFontConfigInterfaceDirect::match(const char familyName[], return false; } - FcPattern* match = MatchFont(font_set, post_config_family, familyName); + FcPattern* match = MatchFont(font_set, post_config_family, familyStr); if (!match) { FcPatternDestroy(pattern); FcFontSetDestroy(font_set); @@ -467,7 +466,7 @@ bool SkFontConfigInterfaceDirect::match(const char familyName[], FcFontSetDestroy(font_set); if (success) { - font_match_cache_[FontMatchKey(familyName, style)] = font_match; + font_match_cache_[FontMatchKey(familyStr, style)] = font_match; *result_filefaceid = font_match.filefaceid; *result_style = font_match.style; } @@ -475,11 +474,15 @@ bool SkFontConfigInterfaceDirect::match(const char familyName[], return success; } +#include <fontconfig/fcfreetype.h> + bool SkFontConfigInterfaceDirect::getFamilyName(unsigned filefaceid, SkString* result_family) { SkAutoMutexAcquire ac(mutex_); +#if 0 FcPattern* pattern = FcPatternCreate(); + SkString filename; { const std::map<unsigned, std::string>::const_iterator @@ -489,11 +492,9 @@ bool SkFontConfigInterfaceDirect::getFamilyName(unsigned filefaceid, return false; } int face_index = filefaceid & 0xfu; + filename.set(i->second.c_str()); FcPatternAddString(pattern, FC_FILE, reinterpret_cast<const FcChar8*>(i->second.c_str())); - // face_index is added only when family is empty because it is not - // necessary to uniquiely identify a font if both file and - // family are given. FcPatternAddInteger(pattern, FC_INDEX, face_index); } @@ -502,67 +503,50 @@ bool SkFontConfigInterfaceDirect::getFamilyName(unsigned filefaceid, FcConfigSubstitute(NULL, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); - // Font matching: - // CSS often specifies a fallback list of families: - // font-family: a, b, c, serif; - // However, fontconfig will always do its best to find *a* font when asked - // for something so we need a way to tell if the match which it has found is - // "good enough" for us. Otherwise, we can return NULL which gets piped up - // and lets WebKit know to try the next CSS family name. However, fontconfig - // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we - // wish to support that. - // - // Thus, if a specific family is requested we set @family_requested. Then we - // record two strings: the family name after config processing and the - // family name after resolving. If the two are equal, it's a good match. - // - // So consider the case where a user has mapped Arial to Helvetica in their - // config. - // requested family: "Arial" - // post_config_family: "Helvetica" - // post_match_family: "Helvetica" - // -> good match - // - // and for a missing font: - // requested family: "Monaco" - // post_config_family: "Monaco" - // post_match_family: "Times New Roman" - // -> BAD match - // - // However, we special-case fallback fonts; see IsFallbackFontAllowed(). - FcChar8* post_config_family; - FcPatternGetString(pattern, FC_FAMILY, 0, &post_config_family); -SkDebugf("--- post_config_family <%s>\n", post_config_family); FcResult result; FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); - if (!font_set) { + if (!font_set || font_set->nfont <= 0) { FcPatternDestroy(pattern); return false; } - FcPattern* match = MatchFont(font_set, post_config_family, (const char*)post_config_family); - if (!match) { - FcPatternDestroy(pattern); - FcFontSetDestroy(font_set); - return false; + bool found = false; + for (int i = 0; i < font_set->nfont; ++i) { + FcChar8* file; + FcPatternGetString(font_set->fonts[i], FC_FILE, 0, &file); + if (filename.equals((const char*)file)) { + FcChar8* family; + FcPatternGetString(font_set->fonts[i], FC_FAMILY, 0, &family); + result_family->set((const char*)family); + found = true; + break; + } } FcPatternDestroy(pattern); - - FontMatch font_match; - font_match.filefaceid = filefaceid; - - bool success = GetFontProperties(match, - &font_match.family, - &font_match.style); FcFontSetDestroy(font_set); + return found; +#else + const std::map<unsigned, std::string>::const_iterator + i = fileid_to_filename_.find(FileFaceIdToFileId(filefaceid)); + if (i == fileid_to_filename_.end()) { + return false; + } - if (success) { -SkDebugf("--- font_match.family <%s>\n", font_match.family.c_str()); - result_family->set(font_match.family.c_str()); + int face_index = filefaceid & 0xfu; + int count; + FcPattern* pattern = FcFreeTypeQuery((const FcChar8*)i->second.c_str(), + face_index, NULL, &count); + if (!pattern || count <= 0) { + return false; } - return success; + FcChar8* family; + FcPatternGetString(pattern, FC_FAMILY, 0, &family); + + result_family->set((const char*)family); + return true; +#endif } SkStream* SkFontConfigInterfaceDirect::openStream(unsigned filefaceid) { diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp index 913d6efff6..ccf2eb0773 100644 --- a/src/ports/SkFontHost_fontconfig.cpp +++ b/src/ports/SkFontHost_fontconfig.cpp @@ -219,6 +219,7 @@ void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { desc.setFamilyName("sans-serif"); } +//SkDebugf("Serialize: <%s>\n", desc.getFamilyName()); // would also like other names (see SkFontDescriptor.h) desc.serialize(stream); @@ -229,15 +230,30 @@ void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { } SkTypeface* SkFontHost::Deserialize(SkStream* stream) { - SkFontDescriptor desc(stream); + SkFontDescriptor descriptor(stream); + const char* familyName = descriptor.getFamilyName(); + const SkTypeface::Style style = descriptor.getStyle(); - // by convention, Serialize will have also written the actual sfnt data. - // for now, we just want to skip it. - size_t size = stream->readPackedUInt(); - stream->skip(size); + const uint32_t customFontDataLength = stream->readPackedUInt(); + if (customFontDataLength > 0) { +#if 0 // need to support inline data... - return SkFontHost::CreateTypeface(NULL, desc.getFamilyName(), - desc.getStyle()); + // generate a new stream to store the custom typeface + SkMemoryStream* fontStream = new SkMemoryStream(customFontDataLength - 1); + stream->read((void*)fontStream->getMemoryBase(), customFontDataLength - 1); + + SkTypeface* face = CreateTypefaceFromStream(fontStream); + + fontStream->unref(); + return face; +#else + stream->skip(customFontDataLength); + return NULL; +#endif + } else { +//SkDebugf("Deserialize:<%s> %d\n", familyName, style); + return SkFontHost::CreateTypeface(NULL, familyName, style); + } } /////////////////////////////////////////////////////////////////////////////// |