diff options
author | jshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-06 18:03:51 +0000 |
---|---|---|
committer | jshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-06 18:03:51 +0000 |
commit | 1c0d89daeb89cb344f5852720ff4ea6edad8aad3 (patch) | |
tree | 14451754940535e9d86a0f60e374a4760176a143 /skia | |
parent | 897bd8cbf71370ec7a57446bc27e858336682632 (diff) | |
download | chromium_src-1c0d89daeb89cb344f5852720ff4ea6edad8aad3.zip chromium_src-1c0d89daeb89cb344f5852720ff4ea6edad8aad3.tar.gz chromium_src-1c0d89daeb89cb344f5852720ff4ea6edad8aad3.tar.bz2 |
Make SkFontHost_fontconfig support TTC font files.
In addition to this change, third_party/skia/src/port/SkFontHost_Freetype.cpp
needs a couple of lines changed.
The Skia part is at http://codereview.appspot.com/1847046/show
BUG=50389
TEST=Install ttf-wqy-microhei package on Ubuntu and go to http://i18nl10n.com/chrome/ttc2.html. Latin letters in the 1st line should be monospaced while they're proportional in the second line.
Review URL: http://codereview.chromium.org/2870073
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55262 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r-- | skia/ext/SkFontHost_fontconfig.cpp | 67 | ||||
-rw-r--r-- | skia/ext/SkFontHost_fontconfig_direct.cpp | 55 | ||||
-rw-r--r-- | skia/ext/SkFontHost_fontconfig_direct.h | 7 | ||||
-rw-r--r-- | skia/ext/SkFontHost_fontconfig_impl.h | 22 | ||||
-rw-r--r-- | skia/ext/SkFontHost_fontconfig_ipc.cpp | 20 | ||||
-rw-r--r-- | skia/ext/SkFontHost_fontconfig_ipc.h | 6 |
6 files changed, 119 insertions, 58 deletions
diff --git a/skia/ext/SkFontHost_fontconfig.cpp b/skia/ext/SkFontHost_fontconfig.cpp index 97d300b..68a3820 100644 --- a/skia/ext/SkFontHost_fontconfig.cpp +++ b/skia/ext/SkFontHost_fontconfig.cpp @@ -67,9 +67,11 @@ static unsigned global_next_remote_font_id; // This is the maximum size of the font cache. static const unsigned kFontCacheMemoryBudget = 2 * 1024 * 1024; // 2MB -// UniqueIds are encoded as (fileid << 8) | style +// UniqueIds are encoded as (filefaceid << 8) | style +// For system fonts, filefaceid = (fileid << 4) | face_index. +// For remote fonts, filefaceid = fileid. -static unsigned UniqueIdToFileId(unsigned uniqueid) +static unsigned UniqueIdToFileFaceId(unsigned uniqueid) { return uniqueid >> 8; } @@ -79,18 +81,18 @@ static SkTypeface::Style UniqueIdToStyle(unsigned uniqueid) return static_cast<SkTypeface::Style>(uniqueid & 0xff); } -static unsigned FileIdAndStyleToUniqueId(unsigned fileid, - SkTypeface::Style style) +static unsigned FileFaceIdAndStyleToUniqueId(unsigned filefaceid, + SkTypeface::Style style) { SkASSERT((style & 0xff) == style); - return (fileid << 8) | static_cast<int>(style); + return (filefaceid << 8) | static_cast<int>(style); } static const unsigned kRemoteFontMask = 0x00800000u; -static bool IsRemoteFont(unsigned fileid) +static bool IsRemoteFont(unsigned filefaceid) { - return fileid & kRemoteFontMask; + return filefaceid & kRemoteFontMask; } class FontConfigTypeface : public SkTypeface { @@ -102,7 +104,7 @@ public: ~FontConfigTypeface() { const uint32_t id = uniqueID(); - if (IsRemoteFont(UniqueIdToFileId(id))) { + if (IsRemoteFont(UniqueIdToFileFaceId(id))) { SkAutoMutexAcquire ac(global_remote_font_map_lock); std::map<uint32_t, std::pair<uint8_t*, size_t> >::iterator iter = global_remote_fonts.find(id); @@ -125,9 +127,9 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, if (familyFace) { // Given the fileid we can ask fontconfig for the familyname of the // font. - const unsigned fileid = UniqueIdToFileId(familyFace->uniqueID()); - if (!GetFcImpl()->Match( - &resolved_family_name, NULL, true /* fileid valid */, fileid, "", + const unsigned filefaceid = UniqueIdToFileFaceId(familyFace->uniqueID()); + if (!GetFcImpl()->Match(&resolved_family_name, NULL, + true /* filefaceid valid */, filefaceid, "", NULL, 0, NULL, NULL)) { return NULL; } @@ -137,8 +139,9 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, bool bold = style & SkTypeface::kBold; bool italic = style & SkTypeface::kItalic; - unsigned fileid; - if (!GetFcImpl()->Match(NULL, &fileid, false, -1, /* no fileid */ + unsigned filefaceid; + if (!GetFcImpl()->Match(NULL, &filefaceid, + false, -1, /* no filefaceid */ resolved_family_name, data, bytelength, &bold, &italic)) { return NULL; @@ -147,7 +150,8 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, (bold ? SkTypeface::kBold : 0) | (italic ? SkTypeface::kItalic : 0)); - const unsigned id = FileIdAndStyleToUniqueId(fileid, resulting_style); + const unsigned id = FileFaceIdAndStyleToUniqueId(filefaceid, + resulting_style); SkTypeface* typeface = SkNEW_ARGS(FontConfigTypeface, (resulting_style, id)); { @@ -180,7 +184,7 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) unsigned id = 0; { SkAutoMutexAcquire ac(global_remote_font_map_lock); - id = FileIdAndStyleToUniqueId( + id = FileFaceIdAndStyleToUniqueId( global_next_remote_font_id | kRemoteFontMask, style); if (++global_next_remote_font_id >= kRemoteFontMask) @@ -206,7 +210,7 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) // static bool SkFontHost::ValidFontID(SkFontID uniqueID) { - if (IsRemoteFont(UniqueIdToFileId(uniqueID))) { + if (IsRemoteFont(UniqueIdToFileFaceId(uniqueID))) { // remote font SkAutoMutexAcquire ac(global_remote_font_map_lock); return global_remote_fonts.find(uniqueID) != global_remote_fonts.end(); @@ -301,9 +305,9 @@ class SkFileDescriptorStream : public SkStream { // static SkStream* SkFontHost::OpenStream(uint32_t id) { - const unsigned fileid = UniqueIdToFileId(id); + const unsigned filefaceid = UniqueIdToFileFaceId(id); - if (IsRemoteFont(fileid)) { + if (IsRemoteFont(filefaceid)) { // remote font SkAutoMutexAcquire ac(global_remote_font_map_lock); std::map<uint32_t, std::pair<uint8_t*, size_t> >::const_iterator iter @@ -315,7 +319,7 @@ SkStream* SkFontHost::OpenStream(uint32_t id) } // system font - const int fd = GetFcImpl()->Open(fileid); + const int fd = GetFcImpl()->Open(filefaceid); if (fd < 0) return NULL; @@ -329,3 +333,28 @@ size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) else return 0; // nothing to do } + +// static +size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length, + int32_t* index) { + const unsigned filefaceid = UniqueIdToFileFaceId(fontID); + + if (IsRemoteFont(filefaceid)) + return 0; + + if (index) { + *index = filefaceid & 0xfu; + // 1 is a bogus return value. + // We had better change the signature of this function in Skia + // to return bool to indicate success/failure and have another + // out param for fileName length. + if (!path) + return 1; + } + + if (path) + SkASSERT(!"SkFontHost::GetFileName does not support the font path " + "retrieval."); + + return 0; +} diff --git a/skia/ext/SkFontHost_fontconfig_direct.cpp b/skia/ext/SkFontHost_fontconfig_direct.cpp index 15238bd..fd2853c 100644 --- a/skia/ext/SkFontHost_fontconfig_direct.cpp +++ b/skia/ext/SkFontHost_fontconfig_direct.cpp @@ -88,6 +88,17 @@ bool IsMetricCompatibleReplacement(const char* font_a, const char* font_b) return class_a != OTHER && class_a == class_b; } +inline unsigned FileFaceIdToFileId(unsigned filefaceid) +{ + return filefaceid >> 4; +} + +inline unsigned FileIdAndFaceIndexToFileFaceId(unsigned fileid, int face_index) +{ + SkASSERT((face_index & 0xfu) == face_index); + return (fileid << 4) | face_index; +} + } // anonymous namespace FontConfigDirect::FontConfigDirect() @@ -111,8 +122,8 @@ static bool IsFallbackFontAllowed(const std::string& family) } bool FontConfigDirect::Match(std::string* result_family, - unsigned* result_fileid, - bool fileid_valid, unsigned fileid, + unsigned* result_filefaceid, + bool filefaceid_valid, unsigned filefaceid, const std::string& family, const void* data, size_t characters_bytes, bool* is_bold, bool* is_italic) { @@ -122,15 +133,21 @@ bool FontConfigDirect::Match(std::string* result_family, SkAutoMutexAcquire ac(mutex_); FcPattern* pattern = FcPatternCreate(); - if (fileid_valid) { + if (filefaceid_valid) { const std::map<unsigned, std::string>::const_iterator - i = fileid_to_filename_.find(fileid); + i = fileid_to_filename_.find(FileFaceIdToFileId(filefaceid)); if (i == fileid_to_filename_.end()) { FcPatternDestroy(pattern); return false; } - - FcPatternAddString(pattern, FC_FILE, (FcChar8*) i->second.c_str()); + int face_index = filefaceid & 0xfu; + 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. + if (family.empty()) + FcPatternAddInteger(pattern, FC_INDEX, face_index); } if (!family.empty()) { FcPatternAddString(pattern, FC_FAMILY, (FcChar8*) family.c_str()); @@ -272,12 +289,18 @@ bool FontConfigDirect::Match(std::string* result_family, FcFontSetDestroy(font_set); return false; } - const std::string filename((char *) c_filename); + int face_index; + if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) { + FcFontSetDestroy(font_set); + return false; + } + const std::string filename(reinterpret_cast<char*>(c_filename)); - unsigned out_fileid; - if (fileid_valid) { - out_fileid = fileid; + unsigned out_filefaceid; + if (filefaceid_valid) { + out_filefaceid = filefaceid; } else { + unsigned out_fileid; const std::map<std::string, unsigned>::const_iterator i = filename_to_fileid_.find(filename); if (i == filename_to_fileid_.end()) { @@ -287,10 +310,14 @@ bool FontConfigDirect::Match(std::string* result_family, } else { out_fileid = i->second; } + // fileid stored in filename_to_fileid_ and fileid_to_filename_ is + // unique only up to the font file. We have to encode face_index for + // the out param. + out_filefaceid = FileIdAndFaceIndexToFileFaceId(out_fileid, face_index); } - if (result_fileid) - *result_fileid = out_fileid; + if (result_filefaceid) + *result_filefaceid = out_filefaceid; FcChar8* c_family; if (FcPatternGetString(match, FC_FAMILY, 0, &c_family)) { @@ -332,10 +359,10 @@ bool FontConfigDirect::Match(std::string* result_family, return true; } -int FontConfigDirect::Open(unsigned fileid) { +int FontConfigDirect::Open(unsigned filefaceid) { SkAutoMutexAcquire ac(mutex_); const std::map<unsigned, std::string>::const_iterator - i = fileid_to_filename_.find(fileid); + i = fileid_to_filename_.find(FileFaceIdToFileId(filefaceid)); if (i == fileid_to_filename_.end()) return -1; diff --git a/skia/ext/SkFontHost_fontconfig_direct.h b/skia/ext/SkFontHost_fontconfig_direct.h index 8606523..e338633 100644 --- a/skia/ext/SkFontHost_fontconfig_direct.h +++ b/skia/ext/SkFontHost_fontconfig_direct.h @@ -30,15 +30,16 @@ class FontConfigDirect : public FontConfigInterface { FontConfigDirect(); // FontConfigInterface implementation. Thread safe. - virtual bool Match(std::string* result_family, unsigned* result_fileid, - bool fileid_valid, unsigned fileid, + virtual bool Match(std::string* result_family, unsigned* result_filefaceid, + bool filefaceid_valid, unsigned filefaceid, const std::string& family, const void* characters, size_t characters_bytes, bool* is_bold, bool* is_italic); - virtual int Open(unsigned fileid); + virtual int Open(unsigned filefaceid); private: SkMutex mutex_; + // fileid stored in two maps below are unique per font file. std::map<unsigned, std::string> fileid_to_filename_; std::map<std::string, unsigned> filename_to_fileid_; unsigned next_file_id_; diff --git a/skia/ext/SkFontHost_fontconfig_impl.h b/skia/ext/SkFontHost_fontconfig_impl.h index c34f3d9..49ccc9d 100644 --- a/skia/ext/SkFontHost_fontconfig_impl.h +++ b/skia/ext/SkFontHost_fontconfig_impl.h @@ -34,10 +34,10 @@ class FontConfigInterface { /** Performs config match * * @param result_family (output) on success, the resulting family name. - * @param result_fileid (output) on success, the resulting file id. - * @param fileid_valid if true, then |fileid| is valid - * @param fileid the fileid (as returned by this function) which we are - * trying to match. + * @param result_filefaceid (output) on success, the resulting fileface id. + * @param filefaceid_valid if true, then |filefaceid| is valid + * @param filefaceid the filefaceid (as returned by this function) + * which we are trying to match. * @param family (optional) the family of the font that we are trying to * match. If the length of the |family| is greater then * kMaxFontFamilyLength, this function should immediately return false. @@ -46,21 +46,25 @@ class FontConfigInterface { * @param is_bold (optional, set to NULL to ignore, in/out) * @param is_italic (optional, set to NULL to ignore, in/out) * @return true iff successful. + * Note that |filefaceid| uniquely identifies <font file, face_index) : + * system font: filefaceid = + * (fileid(unique per font file) << 4 | face_index) + * remote font: filefaceid = fileid */ virtual bool Match( std::string* result_family, - unsigned* result_fileid, - bool fileid_valid, - unsigned fileid, + unsigned* result_filefaceid, + bool filefaceid_valid, + unsigned filefaceid, const std::string& family, const void* characters, size_t characters_bytes, bool* is_bold, bool* is_italic) = 0; - /** Open a font file given the fileid as returned by Match + /** Open a font file given the filefaceid as returned by Match. */ - virtual int Open(unsigned fileid) = 0; + virtual int Open(unsigned filefaceid) = 0; static const unsigned kMaxFontFamilyLength = 2048; }; diff --git a/skia/ext/SkFontHost_fontconfig_ipc.cpp b/skia/ext/SkFontHost_fontconfig_ipc.cpp index 0c95072..23a07f4 100644 --- a/skia/ext/SkFontHost_fontconfig_ipc.cpp +++ b/skia/ext/SkFontHost_fontconfig_ipc.cpp @@ -37,8 +37,8 @@ FontConfigIPC::~FontConfigIPC() { } bool FontConfigIPC::Match(std::string* result_family, - unsigned* result_fileid, - bool fileid_valid, unsigned fileid, + unsigned* result_filefaceid, + bool filefaceid_valid, unsigned filefaceid, const std::string& family, const void* characters, size_t characters_bytes, bool* is_bold, bool* is_italic) { @@ -47,9 +47,9 @@ bool FontConfigIPC::Match(std::string* result_family, Pickle request; request.WriteInt(METHOD_MATCH); - request.WriteBool(fileid_valid); - if (fileid_valid) - request.WriteUInt32(fileid); + request.WriteBool(filefaceid_valid); + if (filefaceid_valid) + request.WriteUInt32(filefaceid); request.WriteBool(is_bold && *is_bold); request.WriteBool(is_bold && *is_italic); @@ -74,17 +74,17 @@ bool FontConfigIPC::Match(std::string* result_family, if (!result) return false; - uint32_t reply_fileid; + uint32_t reply_filefaceid; std::string reply_family; bool resulting_bold, resulting_italic; - if (!reply.ReadUInt32(&iter, &reply_fileid) || + if (!reply.ReadUInt32(&iter, &reply_filefaceid) || !reply.ReadString(&iter, &reply_family) || !reply.ReadBool(&iter, &resulting_bold) || !reply.ReadBool(&iter, &resulting_italic)) { return false; } - *result_fileid = reply_fileid; + *result_filefaceid = reply_filefaceid; if (result_family) *result_family = reply_family; @@ -96,10 +96,10 @@ bool FontConfigIPC::Match(std::string* result_family, return true; } -int FontConfigIPC::Open(unsigned fileid) { +int FontConfigIPC::Open(unsigned filefaceid) { Pickle request; request.WriteInt(METHOD_OPEN); - request.WriteUInt32(fileid); + request.WriteUInt32(filefaceid); int result_fd = -1; uint8_t reply_buf[256]; diff --git a/skia/ext/SkFontHost_fontconfig_ipc.h b/skia/ext/SkFontHost_fontconfig_ipc.h index aacec8c..9a10c6e 100644 --- a/skia/ext/SkFontHost_fontconfig_ipc.h +++ b/skia/ext/SkFontHost_fontconfig_ipc.h @@ -32,12 +32,12 @@ class FontConfigIPC : public FontConfigInterface { ~FontConfigIPC(); // FontConfigInterface implementation. - virtual bool Match(std::string* result_family, unsigned* result_fileid, - bool fileid_valid, unsigned fileid, + virtual bool Match(std::string* result_family, unsigned* result_filefaceid, + bool filefaceid_valid, unsigned filefaceid, const std::string& family, const void* characters, size_t characters_bytes, bool* is_bold, bool* is_italic); - virtual int Open(unsigned fileid); + virtual int Open(unsigned filefaceid); enum Method { METHOD_MATCH = 0, |