Skip to content
Permalink
Browse files
2009-12-04 Benjamin Poulain <benjamin.poulain@nokia.com>
        Reviewed by Kenneth Rohde Christiansen.

        [Qt] WebKit crashes when loading certain SVG images
        https://bugs.webkit.org/show_bug.cgi?id=29443

        Remove FontFallbackListQt and rely on the common FontFallbackList
        to handle the fonts. FontCache and FontPlatformData have been
        updated to work with the common FontFallbackList.

        In the previous implementation, FontPlatformDataCacheKey
        was a clone of FontPlatformData with the hashing
        capabilities added in order to use it as a key in the cache's
        hashmap. FontPlatformData has been modified to handle the hashing
        function directly so the data are not copied twice in memory.

        FontFallbackList::fontDataAt() from FontFallbackListQt was a copy of
        code from FontCache::getFontData() and FontFallbackList::fontDataAt().
        The behavior is similar except currFamily->family().length() was
        not tested and the fallback fonts selector were not used.

        Existing tests cover the change.

        * WebCore.pro:
        * platform/graphics/qt/FontCacheQt.cpp:
        (WebCore::FontCache::platformInit):
        (WebCore::FontCache::getFontDataForCharacters):
        (WebCore::FontCache::getSimilarFontPlatformData):
        (WebCore::FontCache::getLastResortFallbackFont):
        (WebCore::FontCache::getTraitsInFamily):
        (WebCore::FontCache::createFontPlatformData):
        * platform/graphics/qt/FontCustomPlatformData.cpp:
        (WebCore::FontCustomPlatformData::fontPlatformData):
        * platform/graphics/qt/FontFallbackListQt.cpp:
        Removed. We now use the implementation from FontFallbackList.cpp
        * platform/graphics/qt/FontPlatformData.h:
        Add hashing capabilities to be able to use the data with the FontCache.
        This was previously done in FontCacheQt.cpp
        (WebCore::FontPlatformDataPrivate::FontPlatformDataPrivate):
        (WebCore::FontPlatformData::FontPlatformData):
        (WebCore::FontPlatformData::isHashTableDeletedValue):
        (WebCore::FontPlatformData::font):
        (WebCore::FontPlatformData::size):
        (WebCore::FontPlatformData::family):
        (WebCore::FontPlatformData::bold):
        (WebCore::FontPlatformData::italic):
        (WebCore::FontPlatformData::smallCaps):
        (WebCore::FontPlatformData::pixelSize):
        * platform/graphics/qt/FontPlatformDataQt.cpp:
        (WebCore::FontPlatformData::FontPlatformData):
        (WebCore::FontPlatformData::~FontPlatformData):
        (WebCore::FontPlatformData::operator=):
        (WebCore::FontPlatformData::operator==):
        (WebCore::FontPlatformData::hash):

Canonical link: https://commits.webkit.org/43126@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@51699 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
eseidel committed Dec 4, 2009
1 parent 23e0c15 commit 87e5ea0c487b3c669e72c43797f9e93433f62cf7
Showing 7 changed files with 244 additions and 421 deletions.
@@ -1,3 +1,59 @@
2009-12-04 Benjamin Poulain <benjamin.poulain@nokia.com>

Reviewed by Kenneth Rohde Christiansen.

[Qt] WebKit crashes when loading certain SVG images
https://bugs.webkit.org/show_bug.cgi?id=29443

Remove FontFallbackListQt and rely on the common FontFallbackList
to handle the fonts. FontCache and FontPlatformData have been
updated to work with the common FontFallbackList.

In the previous implementation, FontPlatformDataCacheKey
was a clone of FontPlatformData with the hashing
capabilities added in order to use it as a key in the cache's
hashmap. FontPlatformData has been modified to handle the hashing
function directly so the data are not copied twice in memory.

FontFallbackList::fontDataAt() from FontFallbackListQt was a copy of
code from FontCache::getFontData() and FontFallbackList::fontDataAt().
The behavior is similar except currFamily->family().length() was
not tested and the fallback fonts selector were not used.

Existing tests cover the change.

* WebCore.pro:
* platform/graphics/qt/FontCacheQt.cpp:
(WebCore::FontCache::platformInit):
(WebCore::FontCache::getFontDataForCharacters):
(WebCore::FontCache::getSimilarFontPlatformData):
(WebCore::FontCache::getLastResortFallbackFont):
(WebCore::FontCache::getTraitsInFamily):
(WebCore::FontCache::createFontPlatformData):
* platform/graphics/qt/FontCustomPlatformData.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData):
* platform/graphics/qt/FontFallbackListQt.cpp:
Removed. We now use the implementation from FontFallbackList.cpp
* platform/graphics/qt/FontPlatformData.h:
Add hashing capabilities to be able to use the data with the FontCache.
This was previously done in FontCacheQt.cpp
(WebCore::FontPlatformDataPrivate::FontPlatformDataPrivate):
(WebCore::FontPlatformData::FontPlatformData):
(WebCore::FontPlatformData::isHashTableDeletedValue):
(WebCore::FontPlatformData::font):
(WebCore::FontPlatformData::size):
(WebCore::FontPlatformData::family):
(WebCore::FontPlatformData::bold):
(WebCore::FontPlatformData::italic):
(WebCore::FontPlatformData::smallCaps):
(WebCore::FontPlatformData::pixelSize):
* platform/graphics/qt/FontPlatformDataQt.cpp:
(WebCore::FontPlatformData::FontPlatformData):
(WebCore::FontPlatformData::~FontPlatformData):
(WebCore::FontPlatformData::operator=):
(WebCore::FontPlatformData::operator==):
(WebCore::FontPlatformData::hash):

2009-12-04 Adam Treat <atreat@rim.com>

Reviewed by Dan Bernstein.
@@ -1195,6 +1195,7 @@ SOURCES += \
platform/image-decoders/qt/RGBA32BufferQt.cpp \
platform/graphics/filters/FEGaussianBlur.cpp \
platform/graphics/FontDescription.cpp \
platform/graphics/FontFallbackList.cpp \
platform/graphics/FontFamily.cpp \
platform/graphics/BitmapImage.cpp \
platform/graphics/Color.cpp \
@@ -1205,6 +1206,7 @@ SOURCES += \
platform/graphics/FloatSize.cpp \
platform/graphics/FontData.cpp \
platform/graphics/Font.cpp \
platform/graphics/FontCache.cpp \
platform/graphics/GeneratedImage.cpp \
platform/graphics/Gradient.cpp \
platform/graphics/GraphicsContext.cpp \
@@ -2392,7 +2394,6 @@ SOURCES += \
platform/qt/SharedBufferQt.cpp \
platform/graphics/qt/FontCacheQt.cpp \
platform/graphics/qt/FontCustomPlatformData.cpp \
platform/graphics/qt/FontFallbackListQt.cpp \
platform/graphics/qt/GlyphPageTreeNodeQt.cpp \
platform/graphics/qt/SimpleFontDataQt.cpp \
platform/qt/KURLQt.cpp \
@@ -38,256 +38,33 @@ using namespace WTF;

namespace WebCore {

FontCache* fontCache()
void FontCache::platformInit()
{
DEFINE_STATIC_LOCAL(FontCache, globalFontCache, ());
return &globalFontCache;
}

FontCache::FontCache()
{
}

void FontCache::getTraitsInFamily(const AtomicString&, Vector<unsigned>&)
{
}

// This type must be consistent with FontPlatformData's ctor - the one which
// gets FontDescription as it's parameter.
class FontPlatformDataCacheKey {
public:
FontPlatformDataCacheKey(const FontDescription& description)
: m_familyName()
, m_size(description.computedPixelSize())
, m_bold(false)
, m_italic(description.italic())
, m_smallCaps(description.smallCaps())
, m_hash(0)
{
// FIXME: Map all FontWeight values to QFont weights in FontPlatformData's ctor and follow it here
if (FontPlatformData::toQFontWeight(description.weight()) > QFont::Normal)
m_bold = true;

const FontFamily* family = &description.family();
while (family) {
m_familyName.append(family->family());
family = family->next();
if (family)
m_familyName.append(',');
}

computeHash();
}

FontPlatformDataCacheKey(const FontPlatformData& fontData)
: m_familyName(static_cast<String>(fontData.family()))
, m_size(fontData.pixelSize())
, m_bold(fontData.bold())
, m_italic(fontData.italic())
, m_smallCaps(fontData.smallCaps())
, m_hash(0)
{
computeHash();
}

FontPlatformDataCacheKey(HashTableDeletedValueType) : m_size(hashTableDeletedSize()) { }
bool isHashTableDeletedValue() const { return m_size == hashTableDeletedSize(); }

enum HashTableEmptyValueType { HashTableEmptyValue };

FontPlatformDataCacheKey(HashTableEmptyValueType)
: m_familyName()
, m_size(0)
, m_bold(false)
, m_italic(false)
, m_smallCaps(false)
, m_hash(0)
{
}

bool operator==(const FontPlatformDataCacheKey& other) const
{
if (m_hash != other.m_hash)
return false;

return equalIgnoringCase(m_familyName, other.m_familyName) && m_size == other.m_size &&
m_bold == other.m_bold && m_italic == other.m_italic && m_smallCaps == other.m_smallCaps;
}

unsigned hash() const
{
return m_hash;
}

void computeHash()
{
unsigned hashCodes[] = {
CaseFoldingHash::hash(m_familyName),
m_size | static_cast<unsigned>(m_bold << (sizeof(unsigned) * 8 - 1))
| static_cast<unsigned>(m_italic) << (sizeof(unsigned) * 8 - 2)
| static_cast<unsigned>(m_smallCaps) << (sizeof(unsigned) * 8 - 3)
};
m_hash = StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
}

private:
String m_familyName;
int m_size;
bool m_bold;
bool m_italic;
bool m_smallCaps;
unsigned m_hash;

static unsigned hashTableDeletedSize() { return 0xFFFFFFFFU; }
};

struct FontPlatformDataCacheKeyHash {
static unsigned hash(const FontPlatformDataCacheKey& key)
{
return key.hash();
}

static bool equal(const FontPlatformDataCacheKey& a, const FontPlatformDataCacheKey& b)
{
return a == b;
}

static const bool safeToCompareToEmptyOrDeleted = true;
};

struct FontPlatformDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformDataCacheKey> {
static const bool needsDestruction = true;
static const FontPlatformDataCacheKey& emptyValue()
{
DEFINE_STATIC_LOCAL(FontPlatformDataCacheKey, key, (FontPlatformDataCacheKey::HashTableEmptyValue));
return key;
}
static void constructDeletedValue(FontPlatformDataCacheKey& slot)
{
new (&slot) FontPlatformDataCacheKey(HashTableDeletedValue);
}
static bool isDeletedValue(const FontPlatformDataCacheKey& value)
{
return value.isHashTableDeletedValue();
}
};

typedef HashMap<FontPlatformDataCacheKey, FontPlatformData*, FontPlatformDataCacheKeyHash, FontPlatformDataCacheKeyTraits> FontPlatformDataCache;

// using Q_GLOBAL_STATIC leads to crash. TODO investigate the way to fix this.
static FontPlatformDataCache* gFontPlatformDataCache = 0;

FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& description, const AtomicString&, bool)
{
if (!gFontPlatformDataCache)
gFontPlatformDataCache = new FontPlatformDataCache;

FontPlatformDataCacheKey key(description);
FontPlatformData* platformData = gFontPlatformDataCache->get(key);
if (!platformData) {
platformData = new FontPlatformData(description);
gFontPlatformDataCache->add(key, platformData);
}
return platformData;
}

typedef HashMap<FontPlatformDataCacheKey, std::pair<SimpleFontData*, unsigned>, FontPlatformDataCacheKeyHash, FontPlatformDataCacheKeyTraits> FontDataCache;

static FontDataCache* gFontDataCache = 0;

static const int cMaxInactiveFontData = 40;
static const int cTargetInactiveFontData = 32;

static ListHashSet<const SimpleFontData*>* gInactiveFontDataSet = 0;

SimpleFontData* FontCache::getCachedFontData(const FontPlatformData* fontPlatformData)
{
if (!gFontDataCache) {
gFontDataCache = new FontDataCache;
gInactiveFontDataSet = new ListHashSet<const SimpleFontData*>;
}

FontPlatformDataCacheKey key(*fontPlatformData);
FontDataCache::iterator it = gFontDataCache->find(key);
if (it == gFontDataCache->end()) {
SimpleFontData* fontData = new SimpleFontData(*fontPlatformData);
gFontDataCache->add(key, std::pair<SimpleFontData*, unsigned>(fontData, 1));
return fontData;
}
if (!it->second.second++) {
ASSERT(gInactiveFontDataSet->contains(it->second.first));
gInactiveFontDataSet->remove(it->second.first);
}
return it->second.first;
}

FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription&)
const SimpleFontData* FontCache::getFontDataForCharacters(const Font&, const UChar*, int)
{
return 0;
}

void FontCache::releaseFontData(const WebCore::SimpleFontData* fontData)
{
ASSERT(gFontDataCache);
ASSERT(!fontData->isCustomFont());

FontPlatformDataCacheKey key(fontData->platformData());
FontDataCache::iterator it = gFontDataCache->find(key);
ASSERT(it != gFontDataCache->end());
if (!--it->second.second) {
gInactiveFontDataSet->add(it->second.first);
if (gInactiveFontDataSet->size() > cMaxInactiveFontData)
purgeInactiveFontData(gInactiveFontDataSet->size() - cTargetInactiveFontData);
}
}

void FontCache::purgeInactiveFontData(int count)
FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font)
{
static bool isPurging; // Guard against reentry when e.g. a deleted FontData releases its small caps FontData.
if (isPurging)
return;

isPurging = true;

ListHashSet<const SimpleFontData*>::iterator it = gInactiveFontDataSet->begin();
ListHashSet<const SimpleFontData*>::iterator end = gInactiveFontDataSet->end();
for (int i = 0; i < count && it != end; ++i, ++it) {
FontPlatformDataCacheKey key = (*it)->platformData();
pair<SimpleFontData*, unsigned> fontDataPair = gFontDataCache->take(key);
ASSERT(fontDataPair.first != 0);
ASSERT(!fontDataPair.second);
delete fontDataPair.first;

FontPlatformData* platformData = gFontPlatformDataCache->take(key);
if (platformData)
delete platformData;
}

if (it == end) {
// Removed everything
gInactiveFontDataSet->clear();
} else {
for (int i = 0; i < count; ++i)
gInactiveFontDataSet->remove(gInactiveFontDataSet->begin());
}

isPurging = false;
return new FontPlatformData(font.fontDescription());
}

void FontCache::addClient(FontSelector*)
FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription)
{
return new FontPlatformData(fontDescription);
}

void FontCache::removeClient(FontSelector*)
void FontCache::getTraitsInFamily(const AtomicString&, Vector<unsigned>&)
{
}

void FontCache::invalidate()
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString&)
{
if (!gFontPlatformDataCache || !gFontDataCache)
return;

purgeInactiveFontData();
// FIXME : we must take into account the familly name (second argument)
return new FontPlatformData(fontDescription);
}

} // namespace WebCore
@@ -43,7 +43,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
font.setWeight(QFont::Bold);
font.setItalic(italic);

return FontPlatformData(font, bold);
return FontPlatformData(font);
}

FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)

0 comments on commit 87e5ea0

Please sign in to comment.