| OLD | NEW |
| 1 /* libs/graphics/ports/SkFontHost_fontconfig.cpp | 1 /* libs/graphics/ports/SkFontHost_fontconfig.cpp |
| 2 ** | 2 ** |
| 3 ** Copyright 2008, Google Inc. | 3 ** Copyright 2008, Google Inc. |
| 4 ** | 4 ** |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | 5 ** Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 ** you may not use this file except in compliance with the License. | 6 ** you may not use this file except in compliance with the License. |
| 7 ** You may obtain a copy of the License at | 7 ** You may obtain a copy of the License at |
| 8 ** | 8 ** |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | 9 ** http://www.apache.org/licenses/LICENSE-2.0 |
| 10 ** | 10 ** |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 | 52 |
| 53 static FontConfigInterface* GetFcImpl() { | 53 static FontConfigInterface* GetFcImpl() { |
| 54 if (!global_fc_impl) | 54 if (!global_fc_impl) |
| 55 global_fc_impl = new FontConfigDirect; | 55 global_fc_impl = new FontConfigDirect; |
| 56 return global_fc_impl; | 56 return global_fc_impl; |
| 57 } | 57 } |
| 58 | 58 |
| 59 static SkMutex global_fc_map_lock; | 59 static SkMutex global_fc_map_lock; |
| 60 static std::map<uint32_t, SkTypeface *> global_fc_typefaces; | 60 static std::map<uint32_t, SkTypeface *> global_fc_typefaces; |
| 61 | 61 |
| 62 static SkMutex global_remote_font_map_lock; |
| 63 static std::map<uint32_t, std::pair<uint8_t*, size_t> > global_remote_fonts; |
| 64 static unsigned global_next_remote_font_id; |
| 65 |
| 62 // This is the maximum size of the font cache. | 66 // This is the maximum size of the font cache. |
| 63 static const unsigned kFontCacheMemoryBudget = 2 * 1024 * 1024; // 2MB | 67 static const unsigned kFontCacheMemoryBudget = 2 * 1024 * 1024; // 2MB |
| 64 | 68 |
| 65 // UniqueIds are encoded as (fileid << 8) | style | 69 // UniqueIds are encoded as (fileid << 8) | style |
| 66 | 70 |
| 67 static unsigned UniqueIdToFileId(unsigned uniqueid) | 71 static unsigned UniqueIdToFileId(unsigned uniqueid) |
| 68 { | 72 { |
| 69 return uniqueid >> 8; | 73 return uniqueid >> 8; |
| 70 } | 74 } |
| 71 | 75 |
| 72 static SkTypeface::Style UniqueIdToStyle(unsigned uniqueid) | 76 static SkTypeface::Style UniqueIdToStyle(unsigned uniqueid) |
| 73 { | 77 { |
| 74 return static_cast<SkTypeface::Style>(uniqueid & 0xff); | 78 return static_cast<SkTypeface::Style>(uniqueid & 0xff); |
| 75 } | 79 } |
| 76 | 80 |
| 77 static unsigned FileIdAndStyleToUniqueId(unsigned fileid, | 81 static unsigned FileIdAndStyleToUniqueId(unsigned fileid, |
| 78 SkTypeface::Style style) | 82 SkTypeface::Style style) |
| 79 { | 83 { |
| 80 SkASSERT(style & 0xff == style); | 84 SkASSERT(style & 0xff == style); |
| 81 return (fileid << 8) | static_cast<int>(style); | 85 return (fileid << 8) | static_cast<int>(style); |
| 82 } | 86 } |
| 83 | 87 |
| 88 static const unsigned kRemoteFontMask = 0x00800000u; |
| 89 |
| 90 static bool IsRemoteFont(unsigned fileid) |
| 91 { |
| 92 return fileid & kRemoteFontMask; |
| 93 } |
| 94 |
| 84 class FontConfigTypeface : public SkTypeface { | 95 class FontConfigTypeface : public SkTypeface { |
| 85 public: | 96 public: |
| 86 FontConfigTypeface(Style style, uint32_t id) | 97 FontConfigTypeface(Style style, uint32_t id) |
| 87 : SkTypeface(style, id) | 98 : SkTypeface(style, id) |
| 88 { } | 99 { } |
| 100 |
| 101 ~FontConfigTypeface() |
| 102 { |
| 103 const uint32_t id = uniqueID(); |
| 104 if (IsRemoteFont(UniqueIdToFileId(id))) { |
| 105 SkAutoMutexAcquire ac(global_remote_font_map_lock); |
| 106 std::map<uint32_t, std::pair<uint8_t*, size_t> >::iterator iter |
| 107 = global_remote_fonts.find(id); |
| 108 if (iter != global_remote_fonts.end()) { |
| 109 sk_free(iter->second.first); // remove the font on memory. |
| 110 global_remote_fonts.erase(iter); |
| 111 } |
| 112 } |
| 113 } |
| 89 }; | 114 }; |
| 90 | 115 |
| 91 // static | 116 // static |
| 92 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, | 117 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, |
| 93 const char familyName[], | 118 const char familyName[], |
| 94 SkTypeface::Style style) | 119 SkTypeface::Style style) |
| 95 { | 120 { |
| 96 std::string resolved_family_name; | 121 std::string resolved_family_name; |
| 97 | 122 |
| 98 if (familyFace) { | 123 if (familyFace) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 128 SkAutoMutexAcquire ac(global_fc_map_lock); | 153 SkAutoMutexAcquire ac(global_fc_map_lock); |
| 129 global_fc_typefaces[id] = typeface; | 154 global_fc_typefaces[id] = typeface; |
| 130 } | 155 } |
| 131 | 156 |
| 132 return typeface; | 157 return typeface; |
| 133 } | 158 } |
| 134 | 159 |
| 135 // static | 160 // static |
| 136 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) | 161 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) |
| 137 { | 162 { |
| 138 SkASSERT(!"SkFontHost::CreateTypefaceFromStream unimplemented"); | 163 if (!stream) |
| 139 return NULL; | 164 return NULL; |
| 165 |
| 166 const size_t length = stream->read(0, 0); |
| 167 if (!length) |
| 168 return NULL; |
| 169 if (length >= 1024 * 1024 * 1024) |
| 170 return NULL; // don't accept too large fonts (>= 1GB) for safety. |
| 171 |
| 172 uint8_t* font = (uint8_t*)sk_malloc_throw(length); |
| 173 if (stream->read(font, length) != length) { |
| 174 sk_free(font); |
| 175 return NULL; |
| 176 } |
| 177 |
| 178 SkTypeface::Style style = static_cast<SkTypeface::Style>(0); |
| 179 unsigned id = 0; |
| 180 { |
| 181 SkAutoMutexAcquire ac(global_remote_font_map_lock); |
| 182 id = FileIdAndStyleToUniqueId( |
| 183 global_next_remote_font_id | kRemoteFontMask, style); |
| 184 |
| 185 if (++global_next_remote_font_id >= kRemoteFontMask) |
| 186 global_next_remote_font_id = 0; |
| 187 |
| 188 if (!global_remote_fonts.insert( |
| 189 std::make_pair(id, std::make_pair(font, length))).second) { |
| 190 sk_free(font); |
| 191 return NULL; |
| 192 } |
| 193 } |
| 194 |
| 195 SkTypeface* typeface = SkNEW_ARGS(FontConfigTypeface, (style, id)); |
| 196 return typeface; |
| 140 } | 197 } |
| 141 | 198 |
| 142 // static | 199 // static |
| 143 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) | 200 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) |
| 144 { | 201 { |
| 145 SkASSERT(!"SkFontHost::CreateTypefaceFromFile unimplemented"); | 202 SkASSERT(!"SkFontHost::CreateTypefaceFromFile unimplemented"); |
| 146 return NULL; | 203 return NULL; |
| 147 } | 204 } |
| 148 | 205 |
| 149 // static | 206 // static |
| 150 bool SkFontHost::ValidFontID(SkFontID uniqueID) { | 207 bool SkFontHost::ValidFontID(SkFontID uniqueID) { |
| 151 SkAutoMutexAcquire ac(global_fc_map_lock); | 208 if (IsRemoteFont(UniqueIdToFileId(uniqueID))) { |
| 152 return global_fc_typefaces.find(uniqueID) != global_fc_typefaces.end(); | 209 // remote font |
| 210 SkAutoMutexAcquire ac(global_remote_font_map_lock); |
| 211 return global_remote_fonts.find(uniqueID) != global_remote_fonts.end(); |
| 212 } else { |
| 213 // local font |
| 214 SkAutoMutexAcquire ac(global_fc_map_lock); |
| 215 return global_fc_typefaces.find(uniqueID) != global_fc_typefaces.end(); |
| 216 } |
| 153 } | 217 } |
| 154 | 218 |
| 155 void SkFontHost::Serialize(const SkTypeface*, SkWStream*) { | 219 void SkFontHost::Serialize(const SkTypeface*, SkWStream*) { |
| 156 SkASSERT(!"SkFontHost::Serialize unimplemented"); | 220 SkASSERT(!"SkFontHost::Serialize unimplemented"); |
| 157 } | 221 } |
| 158 | 222 |
| 159 SkTypeface* SkFontHost::Deserialize(SkStream* stream) { | 223 SkTypeface* SkFontHost::Deserialize(SkStream* stream) { |
| 160 SkASSERT(!"SkFontHost::Deserialize unimplemented"); | 224 SkASSERT(!"SkFontHost::Deserialize unimplemented"); |
| 161 return NULL; | 225 return NULL; |
| 162 } | 226 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 private: | 281 private: |
| 218 const int fd_; | 282 const int fd_; |
| 219 }; | 283 }; |
| 220 | 284 |
| 221 /////////////////////////////////////////////////////////////////////////////// | 285 /////////////////////////////////////////////////////////////////////////////// |
| 222 | 286 |
| 223 // static | 287 // static |
| 224 SkStream* SkFontHost::OpenStream(uint32_t id) | 288 SkStream* SkFontHost::OpenStream(uint32_t id) |
| 225 { | 289 { |
| 226 const unsigned fileid = UniqueIdToFileId(id); | 290 const unsigned fileid = UniqueIdToFileId(id); |
| 291 |
| 292 if (IsRemoteFont(fileid)) { |
| 293 // remote font |
| 294 SkAutoMutexAcquire ac(global_remote_font_map_lock); |
| 295 std::map<uint32_t, std::pair<uint8_t*, size_t> >::const_iterator iter |
| 296 = global_remote_fonts.find(id); |
| 297 if (iter == global_remote_fonts.end()) |
| 298 return NULL; |
| 299 return SkNEW_ARGS( |
| 300 SkMemoryStream, (iter->second.first, iter->second.second)); |
| 301 } |
| 302 |
| 303 // system font |
| 227 const int fd = GetFcImpl()->Open(fileid); | 304 const int fd = GetFcImpl()->Open(fileid); |
| 228 if (fd < 0) | 305 if (fd < 0) |
| 229 return NULL; | 306 return NULL; |
| 230 | 307 |
| 231 return SkNEW_ARGS(SkFileDescriptorStream, (fd)); | 308 return SkNEW_ARGS(SkFileDescriptorStream, (fd)); |
| 232 } | 309 } |
| 233 | 310 |
| 234 size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) | 311 size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) |
| 235 { | 312 { |
| 236 if (sizeAllocatedSoFar > kFontCacheMemoryBudget) | 313 if (sizeAllocatedSoFar > kFontCacheMemoryBudget) |
| 237 return sizeAllocatedSoFar - kFontCacheMemoryBudget; | 314 return sizeAllocatedSoFar - kFontCacheMemoryBudget; |
| 238 else | 315 else |
| 239 return 0; // nothing to do | 316 return 0; // nothing to do |
| 240 } | 317 } |
| OLD | NEW |