Changeset 51699 in webkit
- Timestamp:
- Dec 4, 2009 9:50:42 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 1 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r51697 r51699 1 2009-12-04 Benjamin Poulain <benjamin.poulain@nokia.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 [Qt] WebKit crashes when loading certain SVG images 6 https://bugs.webkit.org/show_bug.cgi?id=29443 7 8 Remove FontFallbackListQt and rely on the common FontFallbackList 9 to handle the fonts. FontCache and FontPlatformData have been 10 updated to work with the common FontFallbackList. 11 12 In the previous implementation, FontPlatformDataCacheKey 13 was a clone of FontPlatformData with the hashing 14 capabilities added in order to use it as a key in the cache's 15 hashmap. FontPlatformData has been modified to handle the hashing 16 function directly so the data are not copied twice in memory. 17 18 FontFallbackList::fontDataAt() from FontFallbackListQt was a copy of 19 code from FontCache::getFontData() and FontFallbackList::fontDataAt(). 20 The behavior is similar except currFamily->family().length() was 21 not tested and the fallback fonts selector were not used. 22 23 Existing tests cover the change. 24 25 * WebCore.pro: 26 * platform/graphics/qt/FontCacheQt.cpp: 27 (WebCore::FontCache::platformInit): 28 (WebCore::FontCache::getFontDataForCharacters): 29 (WebCore::FontCache::getSimilarFontPlatformData): 30 (WebCore::FontCache::getLastResortFallbackFont): 31 (WebCore::FontCache::getTraitsInFamily): 32 (WebCore::FontCache::createFontPlatformData): 33 * platform/graphics/qt/FontCustomPlatformData.cpp: 34 (WebCore::FontCustomPlatformData::fontPlatformData): 35 * platform/graphics/qt/FontFallbackListQt.cpp: 36 Removed. We now use the implementation from FontFallbackList.cpp 37 * platform/graphics/qt/FontPlatformData.h: 38 Add hashing capabilities to be able to use the data with the FontCache. 39 This was previously done in FontCacheQt.cpp 40 (WebCore::FontPlatformDataPrivate::FontPlatformDataPrivate): 41 (WebCore::FontPlatformData::FontPlatformData): 42 (WebCore::FontPlatformData::isHashTableDeletedValue): 43 (WebCore::FontPlatformData::font): 44 (WebCore::FontPlatformData::size): 45 (WebCore::FontPlatformData::family): 46 (WebCore::FontPlatformData::bold): 47 (WebCore::FontPlatformData::italic): 48 (WebCore::FontPlatformData::smallCaps): 49 (WebCore::FontPlatformData::pixelSize): 50 * platform/graphics/qt/FontPlatformDataQt.cpp: 51 (WebCore::FontPlatformData::FontPlatformData): 52 (WebCore::FontPlatformData::~FontPlatformData): 53 (WebCore::FontPlatformData::operator=): 54 (WebCore::FontPlatformData::operator==): 55 (WebCore::FontPlatformData::hash): 56 1 57 2009-12-04 Adam Treat <atreat@rim.com> 2 58 -
trunk/WebCore/WebCore.pro
r51644 r51699 1196 1196 platform/graphics/filters/FEGaussianBlur.cpp \ 1197 1197 platform/graphics/FontDescription.cpp \ 1198 platform/graphics/FontFallbackList.cpp \ 1198 1199 platform/graphics/FontFamily.cpp \ 1199 1200 platform/graphics/BitmapImage.cpp \ … … 1206 1207 platform/graphics/FontData.cpp \ 1207 1208 platform/graphics/Font.cpp \ 1209 platform/graphics/FontCache.cpp \ 1208 1210 platform/graphics/GeneratedImage.cpp \ 1209 1211 platform/graphics/Gradient.cpp \ … … 2393 2395 platform/graphics/qt/FontCacheQt.cpp \ 2394 2396 platform/graphics/qt/FontCustomPlatformData.cpp \ 2395 platform/graphics/qt/FontFallbackListQt.cpp \2396 2397 platform/graphics/qt/GlyphPageTreeNodeQt.cpp \ 2397 2398 platform/graphics/qt/SimpleFontDataQt.cpp \ -
trunk/WebCore/platform/graphics/qt/FontCacheQt.cpp
r50675 r51699 39 39 namespace WebCore { 40 40 41 FontCache* fontCache()41 void FontCache::platformInit() 42 42 { 43 DEFINE_STATIC_LOCAL(FontCache, globalFontCache, ());44 return &globalFontCache;45 43 } 46 44 47 FontCache::FontCache()45 const SimpleFontData* FontCache::getFontDataForCharacters(const Font&, const UChar*, int) 48 46 { 47 return 0; 48 } 49 50 FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font) 51 { 52 return new FontPlatformData(font.fontDescription()); 53 } 54 55 FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription) 56 { 57 return new FontPlatformData(fontDescription); 49 58 } 50 59 … … 53 62 } 54 63 55 // This type must be consistent with FontPlatformData's ctor - the one which 56 // gets FontDescription as it's parameter. 57 class FontPlatformDataCacheKey { 58 public: 59 FontPlatformDataCacheKey(const FontDescription& description) 60 : m_familyName() 61 , m_size(description.computedPixelSize()) 62 , m_bold(false) 63 , m_italic(description.italic()) 64 , m_smallCaps(description.smallCaps()) 65 , m_hash(0) 66 { 67 // FIXME: Map all FontWeight values to QFont weights in FontPlatformData's ctor and follow it here 68 if (FontPlatformData::toQFontWeight(description.weight()) > QFont::Normal) 69 m_bold = true; 70 71 const FontFamily* family = &description.family(); 72 while (family) { 73 m_familyName.append(family->family()); 74 family = family->next(); 75 if (family) 76 m_familyName.append(','); 77 } 78 79 computeHash(); 80 } 81 82 FontPlatformDataCacheKey(const FontPlatformData& fontData) 83 : m_familyName(static_cast<String>(fontData.family())) 84 , m_size(fontData.pixelSize()) 85 , m_bold(fontData.bold()) 86 , m_italic(fontData.italic()) 87 , m_smallCaps(fontData.smallCaps()) 88 , m_hash(0) 89 { 90 computeHash(); 91 } 92 93 FontPlatformDataCacheKey(HashTableDeletedValueType) : m_size(hashTableDeletedSize()) { } 94 bool isHashTableDeletedValue() const { return m_size == hashTableDeletedSize(); } 95 96 enum HashTableEmptyValueType { HashTableEmptyValue }; 97 98 FontPlatformDataCacheKey(HashTableEmptyValueType) 99 : m_familyName() 100 , m_size(0) 101 , m_bold(false) 102 , m_italic(false) 103 , m_smallCaps(false) 104 , m_hash(0) 105 { 106 } 107 108 bool operator==(const FontPlatformDataCacheKey& other) const 109 { 110 if (m_hash != other.m_hash) 111 return false; 112 113 return equalIgnoringCase(m_familyName, other.m_familyName) && m_size == other.m_size && 114 m_bold == other.m_bold && m_italic == other.m_italic && m_smallCaps == other.m_smallCaps; 115 } 116 117 unsigned hash() const 118 { 119 return m_hash; 120 } 121 122 void computeHash() 123 { 124 unsigned hashCodes[] = { 125 CaseFoldingHash::hash(m_familyName), 126 m_size | static_cast<unsigned>(m_bold << (sizeof(unsigned) * 8 - 1)) 127 | static_cast<unsigned>(m_italic) << (sizeof(unsigned) * 8 - 2) 128 | static_cast<unsigned>(m_smallCaps) << (sizeof(unsigned) * 8 - 3) 129 }; 130 m_hash = StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); 131 } 132 133 private: 134 String m_familyName; 135 int m_size; 136 bool m_bold; 137 bool m_italic; 138 bool m_smallCaps; 139 unsigned m_hash; 140 141 static unsigned hashTableDeletedSize() { return 0xFFFFFFFFU; } 142 }; 143 144 struct FontPlatformDataCacheKeyHash { 145 static unsigned hash(const FontPlatformDataCacheKey& key) 146 { 147 return key.hash(); 148 } 149 150 static bool equal(const FontPlatformDataCacheKey& a, const FontPlatformDataCacheKey& b) 151 { 152 return a == b; 153 } 154 155 static const bool safeToCompareToEmptyOrDeleted = true; 156 }; 157 158 struct FontPlatformDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformDataCacheKey> { 159 static const bool needsDestruction = true; 160 static const FontPlatformDataCacheKey& emptyValue() 161 { 162 DEFINE_STATIC_LOCAL(FontPlatformDataCacheKey, key, (FontPlatformDataCacheKey::HashTableEmptyValue)); 163 return key; 164 } 165 static void constructDeletedValue(FontPlatformDataCacheKey& slot) 166 { 167 new (&slot) FontPlatformDataCacheKey(HashTableDeletedValue); 168 } 169 static bool isDeletedValue(const FontPlatformDataCacheKey& value) 170 { 171 return value.isHashTableDeletedValue(); 172 } 173 }; 174 175 typedef HashMap<FontPlatformDataCacheKey, FontPlatformData*, FontPlatformDataCacheKeyHash, FontPlatformDataCacheKeyTraits> FontPlatformDataCache; 176 177 // using Q_GLOBAL_STATIC leads to crash. TODO investigate the way to fix this. 178 static FontPlatformDataCache* gFontPlatformDataCache = 0; 179 180 FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& description, const AtomicString&, bool) 64 FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString&) 181 65 { 182 if (!gFontPlatformDataCache) 183 gFontPlatformDataCache = new FontPlatformDataCache; 184 185 FontPlatformDataCacheKey key(description); 186 FontPlatformData* platformData = gFontPlatformDataCache->get(key); 187 if (!platformData) { 188 platformData = new FontPlatformData(description); 189 gFontPlatformDataCache->add(key, platformData); 190 } 191 return platformData; 192 } 193 194 typedef HashMap<FontPlatformDataCacheKey, std::pair<SimpleFontData*, unsigned>, FontPlatformDataCacheKeyHash, FontPlatformDataCacheKeyTraits> FontDataCache; 195 196 static FontDataCache* gFontDataCache = 0; 197 198 static const int cMaxInactiveFontData = 40; 199 static const int cTargetInactiveFontData = 32; 200 201 static ListHashSet<const SimpleFontData*>* gInactiveFontDataSet = 0; 202 203 SimpleFontData* FontCache::getCachedFontData(const FontPlatformData* fontPlatformData) 204 { 205 if (!gFontDataCache) { 206 gFontDataCache = new FontDataCache; 207 gInactiveFontDataSet = new ListHashSet<const SimpleFontData*>; 208 } 209 210 FontPlatformDataCacheKey key(*fontPlatformData); 211 FontDataCache::iterator it = gFontDataCache->find(key); 212 if (it == gFontDataCache->end()) { 213 SimpleFontData* fontData = new SimpleFontData(*fontPlatformData); 214 gFontDataCache->add(key, std::pair<SimpleFontData*, unsigned>(fontData, 1)); 215 return fontData; 216 } 217 if (!it->second.second++) { 218 ASSERT(gInactiveFontDataSet->contains(it->second.first)); 219 gInactiveFontDataSet->remove(it->second.first); 220 } 221 return it->second.first; 222 } 223 224 FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription&) 225 { 226 return 0; 227 } 228 229 void FontCache::releaseFontData(const WebCore::SimpleFontData* fontData) 230 { 231 ASSERT(gFontDataCache); 232 ASSERT(!fontData->isCustomFont()); 233 234 FontPlatformDataCacheKey key(fontData->platformData()); 235 FontDataCache::iterator it = gFontDataCache->find(key); 236 ASSERT(it != gFontDataCache->end()); 237 if (!--it->second.second) { 238 gInactiveFontDataSet->add(it->second.first); 239 if (gInactiveFontDataSet->size() > cMaxInactiveFontData) 240 purgeInactiveFontData(gInactiveFontDataSet->size() - cTargetInactiveFontData); 241 } 242 } 243 244 void FontCache::purgeInactiveFontData(int count) 245 { 246 static bool isPurging; // Guard against reentry when e.g. a deleted FontData releases its small caps FontData. 247 if (isPurging) 248 return; 249 250 isPurging = true; 251 252 ListHashSet<const SimpleFontData*>::iterator it = gInactiveFontDataSet->begin(); 253 ListHashSet<const SimpleFontData*>::iterator end = gInactiveFontDataSet->end(); 254 for (int i = 0; i < count && it != end; ++i, ++it) { 255 FontPlatformDataCacheKey key = (*it)->platformData(); 256 pair<SimpleFontData*, unsigned> fontDataPair = gFontDataCache->take(key); 257 ASSERT(fontDataPair.first != 0); 258 ASSERT(!fontDataPair.second); 259 delete fontDataPair.first; 260 261 FontPlatformData* platformData = gFontPlatformDataCache->take(key); 262 if (platformData) 263 delete platformData; 264 } 265 266 if (it == end) { 267 // Removed everything 268 gInactiveFontDataSet->clear(); 269 } else { 270 for (int i = 0; i < count; ++i) 271 gInactiveFontDataSet->remove(gInactiveFontDataSet->begin()); 272 } 273 274 isPurging = false; 275 } 276 277 void FontCache::addClient(FontSelector*) 278 { 279 } 280 281 void FontCache::removeClient(FontSelector*) 282 { 283 } 284 285 void FontCache::invalidate() 286 { 287 if (!gFontPlatformDataCache || !gFontDataCache) 288 return; 289 290 purgeInactiveFontData(); 66 // FIXME : we must take into account the familly name (second argument) 67 return new FontPlatformData(fontDescription); 291 68 } 292 69 -
trunk/WebCore/platform/graphics/qt/FontCustomPlatformData.cpp
r39207 r51699 44 44 font.setItalic(italic); 45 45 46 return FontPlatformData(font , bold);46 return FontPlatformData(font); 47 47 } 48 48 -
trunk/WebCore/platform/graphics/qt/FontPlatformData.h
r51179 r51699 27 27 #include "FontDescription.h" 28 28 #include <QFont> 29 #include <QHash> 29 30 30 31 namespace WebCore { 31 32 32 33 class String; 34 class FontPlatformDataPrivate { 35 public: 36 FontPlatformDataPrivate() 37 : refCount(1) 38 , size(font.pointSizeF()) 39 , bold(font.bold()) 40 , oblique(false) 41 {} 42 FontPlatformDataPrivate(const float size, const bool bold, const bool oblique) 43 : refCount(1) 44 , size(size) 45 , bold(bold) 46 , oblique(oblique) 47 {} 48 FontPlatformDataPrivate(const QFont& font) 49 : refCount(1) 50 , font(font) 51 , size(font.pointSizeF()) 52 , bold(font.bold()) 53 , oblique(false) 54 {} 55 unsigned refCount; 56 QFont font; 57 float size; 58 bool bold : 1; 59 bool oblique : 1; 60 }; 33 61 34 class FontPlatformData : public FastAllocBase 35 { 62 63 64 class FontPlatformData : public FastAllocBase { 36 65 public: 37 #if ENABLE(SVG_FONTS)38 66 FontPlatformData(float size, bool bold, bool oblique); 39 #endif 40 FontPlatformData(); 67 FontPlatformData(const FontPlatformData &); 41 68 FontPlatformData(const FontDescription&, int wordSpacing = 0, int letterSpacing = 0); 42 FontPlatformData(const QFont&, bool bold); 69 FontPlatformData(const QFont& font) 70 : m_data(new FontPlatformDataPrivate(font)) 71 {} 72 FontPlatformData(WTF::HashTableDeletedValueType) 73 : m_data(reinterpret_cast<FontPlatformDataPrivate*>(-1)) 74 {} 75 76 ~FontPlatformData(); 77 78 FontPlatformData& operator=(const FontPlatformData&); 79 bool operator==(const FontPlatformData&) const; 80 81 bool isHashTableDeletedValue() const 82 { 83 return m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1); 84 } 43 85 44 86 static inline QFont::Weight toQFontWeight(FontWeight fontWeight) … … 63 105 } 64 106 65 QFont font() const { return m_font; } 66 float size() const { return m_size; } 67 QString family() const { return m_font.family(); } 68 bool bold() const { return m_bold; } 69 bool italic() const { return m_font.italic(); } 70 bool smallCaps() const { return m_font.capitalization() == QFont::SmallCaps; } 71 int pixelSize() const { return m_font.pixelSize(); } 107 QFont font() const 108 { 109 Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); 110 if (m_data) 111 return m_data->font; 112 return QFont(); 113 } 114 float size() const 115 { 116 Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); 117 if (m_data) 118 return m_data->size; 119 return 0.0f; 120 } 121 QString family() const 122 { 123 Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); 124 if (m_data) 125 return m_data->font.family(); 126 return QString(); 127 } 128 bool bold() const 129 { 130 Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); 131 if (m_data) 132 return m_data->bold; 133 return false; 134 } 135 bool italic() const 136 { 137 Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); 138 if (m_data) 139 return m_data->font.italic(); 140 return false; 141 } 142 bool smallCaps() const 143 { 144 Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); 145 if (m_data) 146 return m_data->font.capitalization() == QFont::SmallCaps; 147 return false; 148 } 149 int pixelSize() const 150 { 151 Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); 152 if (m_data) 153 return m_data->font.pixelSize(); 154 return 0; 155 } 156 unsigned hash() const; 72 157 73 158 #ifndef NDEBUG 74 159 String description() const; 75 160 #endif 76 77 float m_size; 78 bool m_bold; 79 bool m_oblique; 80 QFont m_font; 161 private: 162 FontPlatformDataPrivate* m_data; 81 163 }; 82 164 -
trunk/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
r50510 r51699 27 27 namespace WebCore { 28 28 29 static inline bool isEmtpyValue(const float size, const bool bold, const bool oblique) 30 { 31 // this is the empty value by definition of the trait FontDataCacheKeyTraits 32 return !bold && !oblique && size == 0.f; 33 } 34 35 FontPlatformData::FontPlatformData(float size, bool bold, bool oblique) 36 { 37 if (isEmtpyValue(size, bold, oblique)) 38 m_data = 0; 39 else 40 m_data = new FontPlatformDataPrivate(size, bold, oblique); 41 } 42 43 FontPlatformData::FontPlatformData(const FontPlatformData &other) : m_data(other.m_data) 44 { 45 if (m_data && m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)) 46 ++m_data->refCount; 47 } 48 29 49 FontPlatformData::FontPlatformData(const FontDescription& description, int wordSpacing, int letterSpacing) 30 : m_size(0.0f) 31 , m_bold(false) 32 , m_oblique(false) 50 : m_data(new FontPlatformDataPrivate()) 33 51 { 34 52 QString familyName; … … 40 58 familyName += QLatin1Char(','); 41 59 } 60 QFont& font = m_data->font; 61 font.setFamily(familyName); 62 font.setPixelSize(qRound(description.computedSize())); 63 font.setItalic(description.italic()); 64 font.setWeight(toQFontWeight(description.weight())); 65 font.setWordSpacing(wordSpacing); 66 font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing); 67 const bool smallCaps = description.smallCaps(); 68 font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase); 42 69 43 m_font.setFamily(familyName); 44 m_font.setPixelSize(qRound(description.computedSize())); 45 m_font.setItalic(description.italic()); 46 47 m_font.setWeight(toQFontWeight(description.weight())); 48 m_bold = m_font.bold(); 49 50 bool smallCaps = description.smallCaps(); 51 m_font.setCapitalization(smallCaps ? QFont::SmallCaps : QFont::MixedCase); 52 m_font.setWordSpacing(wordSpacing); 53 m_font.setLetterSpacing(QFont::AbsoluteSpacing, letterSpacing); 54 m_size = m_font.pointSize(); 70 m_data->bold = font.bold(); 71 m_data->size = font.pointSizeF(); 55 72 } 56 73 57 FontPlatformData::FontPlatformData(const QFont& font, bool bold) 58 : m_size(font.pointSize()) 59 , m_bold(bold) 60 , m_oblique(false) 61 , m_font(font) 74 FontPlatformData::~FontPlatformData() 62 75 { 76 if (!m_data || m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1)) 77 return; 78 --m_data->refCount; 79 if (!m_data->refCount) 80 delete m_data; 63 81 } 64 82 65 #if ENABLE(SVG_FONTS) 66 FontPlatformData::FontPlatformData(float size, bool bold, bool oblique) 67 : m_size(size) 68 , m_bold(bold) 69 , m_oblique(oblique) 83 FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other) 70 84 { 85 if (m_data == other.m_data) 86 return *this; 87 if (m_data && m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)) { 88 --m_data->refCount; 89 if (!m_data->refCount) 90 delete m_data; 91 } 92 m_data = other.m_data; 93 if (m_data && m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)) 94 ++m_data->refCount; 95 return *this; 71 96 } 72 #endif73 97 74 FontPlatformData::FontPlatformData() 75 : m_size(0.0f) 76 , m_bold(false) 77 , m_oblique(false) 98 bool FontPlatformData::operator==(const FontPlatformData& other) const 78 99 { 100 if (m_data == other.m_data) 101 return true; 102 103 if (!m_data || !other.m_data 104 || m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1) || other.m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1)) 105 return false; 106 107 const bool equals = (m_data->size == other.m_data->size 108 && m_data->bold == other.m_data->bold 109 && m_data->oblique == other.m_data->oblique 110 && m_data->font == other.m_data->font); 111 return equals; 112 } 113 114 unsigned FontPlatformData::hash() const 115 { 116 if (!m_data) 117 return 0; 118 if (m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1)) 119 return 1; 120 return qHash(m_data->font.toString()) 121 ^ qHash(*reinterpret_cast<quint32*>(&m_data->size)) 122 ^ qHash(m_data->bold) 123 ^ qHash(m_data->oblique); 79 124 } 80 125
Note: See TracChangeset
for help on using the changeset viewer.