diff options
author | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-07 06:23:46 +0000 |
---|---|---|
committer | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-07 06:23:46 +0000 |
commit | 610f34b334120e8ebdc4a96b4f621f00bf82a4ac (patch) | |
tree | 24a617172745602d3edb75bca24a0605f87c4ae2 /skia | |
parent | 5684fc932039a4d5c54464e56f4f8a045fe76024 (diff) | |
download | chromium_src-610f34b334120e8ebdc4a96b4f621f00bf82a4ac.zip chromium_src-610f34b334120e8ebdc4a96b4f621f00bf82a4ac.tar.gz chromium_src-610f34b334120e8ebdc4a96b4f621f00bf82a4ac.tar.bz2 |
Implemented SkFontHost::CreateTypefaceFromStream() function. This change is necessary in order to support @font-face on Linux.
Changes on WebCore side: https://bugs.webkit.org/show_bug.cgi?id=28015
BUG=18490
TEST=please see the bug descripion.
Review URL: http://codereview.chromium.org/160635
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22724 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r-- | skia/ext/SkFontHost_fontconfig.cpp | 85 |
1 files changed, 81 insertions, 4 deletions
diff --git a/skia/ext/SkFontHost_fontconfig.cpp b/skia/ext/SkFontHost_fontconfig.cpp index 2ecbe6c..1c46194 100644 --- a/skia/ext/SkFontHost_fontconfig.cpp +++ b/skia/ext/SkFontHost_fontconfig.cpp @@ -59,6 +59,10 @@ static FontConfigInterface* GetFcImpl() { static SkMutex global_fc_map_lock; static std::map<uint32_t, SkTypeface *> global_fc_typefaces; +static SkMutex global_remote_font_map_lock; +static std::map<uint32_t, std::pair<uint8_t*, size_t> > global_remote_fonts; +static unsigned global_next_remote_font_id; + // This is the maximum size of the font cache. static const unsigned kFontCacheMemoryBudget = 2 * 1024 * 1024; // 2MB @@ -81,11 +85,32 @@ static unsigned FileIdAndStyleToUniqueId(unsigned fileid, return (fileid << 8) | static_cast<int>(style); } +static const unsigned kRemoteFontMask = 0x00800000u; + +static bool IsRemoteFont(unsigned fileid) +{ + return fileid & kRemoteFontMask; +} + class FontConfigTypeface : public SkTypeface { public: FontConfigTypeface(Style style, uint32_t id) : SkTypeface(style, id) { } + + ~FontConfigTypeface() + { + const uint32_t id = uniqueID(); + if (IsRemoteFont(UniqueIdToFileId(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); + if (iter != global_remote_fonts.end()) { + sk_free(iter->second.first); // remove the font on memory. + global_remote_fonts.erase(iter); + } + } + } }; // static @@ -135,8 +160,40 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, // static SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { - SkASSERT(!"SkFontHost::CreateTypefaceFromStream unimplemented"); - return NULL; + if (!stream) + return NULL; + + const size_t length = stream->read(0, 0); + if (!length) + return NULL; + if (length >= 1024 * 1024 * 1024) + return NULL; // don't accept too large fonts (>= 1GB) for safety. + + uint8_t* font = (uint8_t*)sk_malloc_throw(length); + if (stream->read(font, length) != length) { + sk_free(font); + return NULL; + } + + SkTypeface::Style style = static_cast<SkTypeface::Style>(0); + unsigned id = 0; + { + SkAutoMutexAcquire ac(global_remote_font_map_lock); + id = FileIdAndStyleToUniqueId( + global_next_remote_font_id | kRemoteFontMask, style); + + if (++global_next_remote_font_id >= kRemoteFontMask) + global_next_remote_font_id = 0; + + if (!global_remote_fonts.insert( + std::make_pair(id, std::make_pair(font, length))).second) { + sk_free(font); + return NULL; + } + } + + SkTypeface* typeface = SkNEW_ARGS(FontConfigTypeface, (style, id)); + return typeface; } // static @@ -148,8 +205,15 @@ SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) // static bool SkFontHost::ValidFontID(SkFontID uniqueID) { - SkAutoMutexAcquire ac(global_fc_map_lock); - return global_fc_typefaces.find(uniqueID) != global_fc_typefaces.end(); + if (IsRemoteFont(UniqueIdToFileId(uniqueID))) { + // remote font + SkAutoMutexAcquire ac(global_remote_font_map_lock); + return global_remote_fonts.find(uniqueID) != global_remote_fonts.end(); + } else { + // local font + SkAutoMutexAcquire ac(global_fc_map_lock); + return global_fc_typefaces.find(uniqueID) != global_fc_typefaces.end(); + } } void SkFontHost::Serialize(const SkTypeface*, SkWStream*) { @@ -224,6 +288,19 @@ class SkFileDescriptorStream : public SkStream { SkStream* SkFontHost::OpenStream(uint32_t id) { const unsigned fileid = UniqueIdToFileId(id); + + if (IsRemoteFont(fileid)) { + // remote font + SkAutoMutexAcquire ac(global_remote_font_map_lock); + std::map<uint32_t, std::pair<uint8_t*, size_t> >::const_iterator iter + = global_remote_fonts.find(id); + if (iter == global_remote_fonts.end()) + return NULL; + return SkNEW_ARGS( + SkMemoryStream, (iter->second.first, iter->second.second)); + } + + // system font const int fd = GetFcImpl()->Open(fileid); if (fd < 0) return NULL; |