Changeset 50496 in webkit


Ignore:
Timestamp:
Nov 3, 2009 7:37:32 PM (14 years ago)
Author:
Simon Hausmann
Message:

WebCore: [Qt] Handle fonts like the other ports

Patch by Benjamin Poulain <benjamin.poulain@nokia.com> on 2009-11-02
Reviewed by Simon Hausmann.

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.

https://bugs.webkit.org/show_bug.cgi?id=29856

Test: svg/text/text-font-invalid.html

  • 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/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::FontPlatformData::FontPlatformData):
Added a boolean to identify deleted value in the hash table.
(WebCore::FontPlatformData::isHashTableDeletedValue):
(WebCore::FontPlatformData::hash):
(WebCore::FontPlatformData::operator==):

  • platform/graphics/qt/FontPlatformDataQt.cpp:

(WebCore::FontPlatformData::FontPlatformData):

LayoutTests: Add a new test to reproduce 29856. The bug only happen
when the SVG file is used as an image.
https://bugs.webkit.org/show_bug.cgi?id=29856

Patch by Benjamin Poulain <benjamin.poulain@nokia.com> on 2009-11-02
Reviewed by Simon Hausmann.

  • svg/text/text-font-invalid-expected.txt: Added.
  • svg/text/resources/text-font-invalid.svg: Added.
  • svg/text/text-font-invalid.html: Added.
Location:
trunk
Files:
4 added
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r50495 r50496  
     12009-11-02  Benjamin Poulain  <benjamin.poulain@nokia.com>
     2
     3        Reviewed by Simon Hausmann.
     4
     5        Add a new test to reproduce 29856. The bug only happen
     6        when the SVG file is used as an image.
     7        https://bugs.webkit.org/show_bug.cgi?id=29856
     8
     9        * svg/text/text-font-invalid-expected.txt: Added.
     10        * svg/text/resources/text-font-invalid.svg: Added.
     11        * svg/text/text-font-invalid.html: Added.
     12
    1132009-11-04  Roland Steiner  <rolandsteiner@chromium.org>
    214
  • trunk/WebCore/ChangeLog

    r50493 r50496  
     12009-11-02  Benjamin Poulain  <benjamin.poulain@nokia.com>
     2
     3        Reviewed by Simon Hausmann.
     4
     5        [Qt] Handle fonts like the other ports
     6
     7        Remove FontFallbackListQt and rely on the common FontFallbackList
     8        to handle the fonts. FontCache and FontPlatformData have been
     9        updated to work with the common FontFallbackList.
     10
     11        In the previous implementation, FontPlatformDataCacheKey
     12        was a clone of FontPlatformData with the hashing
     13        capabilities added in order to use it as a key in the cache's
     14        hashmap. FontPlatformData has been modified to handle the hashing
     15        function directly so the data are not copied twice in memory.
     16
     17        FontFallbackList::fontDataAt() from FontFallbackListQt was a copy of
     18        code from FontCache::getFontData() and FontFallbackList::fontDataAt().
     19        The behavior is similar except currFamily->family().length() was
     20        not tested and the fallback fonts selector were not used.
     21
     22        https://bugs.webkit.org/show_bug.cgi?id=29856
     23
     24        Test: svg/text/text-font-invalid.html
     25
     26        * WebCore.pro:
     27        * platform/graphics/qt/FontCacheQt.cpp:
     28        (WebCore::FontCache::platformInit):
     29        (WebCore::FontCache::getFontDataForCharacters):
     30        (WebCore::FontCache::getSimilarFontPlatformData):
     31        (WebCore::FontCache::getLastResortFallbackFont):
     32        (WebCore::FontCache::getTraitsInFamily):
     33        (WebCore::FontCache::createFontPlatformData):
     34        * platform/graphics/qt/FontFallbackListQt.cpp:
     35        Removed. We now use the implementation from FontFallbackList.cpp
     36        * platform/graphics/qt/FontPlatformData.h:
     37        Add hashing capabilities to be able to use the data with the FontCache.
     38        This was previously done in FontCacheQt.cpp
     39        (WebCore::FontPlatformData::FontPlatformData):
     40        Added a boolean to identify deleted value in the hash table.
     41        (WebCore::FontPlatformData::isHashTableDeletedValue):
     42        (WebCore::FontPlatformData::hash):
     43        (WebCore::FontPlatformData::operator==):
     44        * platform/graphics/qt/FontPlatformDataQt.cpp:
     45        (WebCore::FontPlatformData::FontPlatformData):
     46
    1472009-11-03  Dan Bernstein  <mitz@apple.com>
    248
  • trunk/WebCore/WebCore.pro

    r50456 r50496  
    11881188    platform/graphics/filters/FEGaussianBlur.cpp \
    11891189    platform/graphics/FontDescription.cpp \
     1190    platform/graphics/FontFallbackList.cpp \
    11901191    platform/graphics/FontFamily.cpp \
    11911192    platform/graphics/BitmapImage.cpp \
     
    11981199    platform/graphics/FontData.cpp \
    11991200    platform/graphics/Font.cpp \
     1201    platform/graphics/FontCache.cpp \
    12001202    platform/graphics/GeneratedImage.cpp \
    12011203    platform/graphics/Gradient.cpp \
     
    23832385    platform/graphics/qt/FontCacheQt.cpp \
    23842386    platform/graphics/qt/FontCustomPlatformData.cpp \
    2385     platform/graphics/qt/FontFallbackListQt.cpp \
    23862387    platform/graphics/qt/GlyphPageTreeNodeQt.cpp \
    23872388    platform/graphics/qt/SimpleFontDataQt.cpp \
  • trunk/WebCore/platform/graphics/qt/FontCacheQt.cpp

    r49020 r50496  
    3939namespace WebCore {
    4040
    41 FontCache* fontCache()
     41void FontCache::platformInit()
    4242{
    43     DEFINE_STATIC_LOCAL(FontCache, globalFontCache, ());
    44     return &globalFontCache;
    4543}
    4644
    47 FontCache::FontCache()
     45const SimpleFontData* FontCache::getFontDataForCharacters(const Font&, const UChar*, int)
    4846{
     47    return 0;
     48}
     49
     50FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font)
     51{
     52    return new FontPlatformData(font.fontDescription());
     53}
     54
     55FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription&)
     56{
     57    return new FontPlatformData();
    4958}
    5059
     
    5362}
    5463
    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)
     64FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString&)
    18165{
    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    return new FontPlatformData(fontDescription);
    29167}
    29268
  • trunk/WebCore/platform/graphics/qt/FontPlatformData.h

    r46428 r50496  
    2727#include "FontDescription.h"
    2828#include <QFont>
     29#include <QHash>
    2930
    3031namespace WebCore {
     
    4142    FontPlatformData(const FontDescription&, int wordSpacing = 0, int letterSpacing = 0);
    4243    FontPlatformData(const QFont&, bool bold);
     44
     45    FontPlatformData(WTF::HashTableDeletedValueType)
     46        : m_isDeletedValue(true)
     47    {
     48    }
     49
     50    bool isHashTableDeletedValue() const { return m_isDeletedValue; }
    4351
    4452    static inline QFont::Weight toQFontWeight(FontWeight fontWeight)
     
    7078    bool smallCaps() const { return m_font.capitalization() == QFont::SmallCaps; }
    7179    int pixelSize() const { return m_font.pixelSize(); }
     80    unsigned hash() const
     81    {
     82        float size = m_size;
     83        return qHash(m_isDeletedValue)
     84               ^ qHash(m_bold)
     85               ^ qHash(m_oblique)
     86               ^ qHash(*reinterpret_cast<quint32*>(&size))
     87               ^ qHash(m_font.toString());
     88    }
     89
     90    bool operator==(const FontPlatformData& other) const
     91    {
     92        return (m_isDeletedValue && m_isDeletedValue == other.m_isDeletedValue)
     93                || (m_bold == other.m_bold
     94                    && m_oblique == other.m_oblique
     95                    && m_size == other.m_size
     96                    && m_font == m_font);
     97    }
    7298
    7399#ifndef NDEBUG
     
    75101#endif
    76102
     103    QFont m_font;
    77104    float m_size;
    78     bool m_bold;
    79     bool m_oblique;
    80     QFont m_font;
     105    bool m_bold : 1;
     106    bool m_oblique : 1;
     107    bool m_isDeletedValue : 1;
    81108};
    82109
  • trunk/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp

    r46428 r50496  
    3131    , m_bold(false)
    3232    , m_oblique(false)
     33    , m_isDeletedValue(false)
    3334{
    3435    QString familyName;
     
    5657
    5758FontPlatformData::FontPlatformData(const QFont& font, bool bold)
    58     : m_size(font.pointSize())
     59    : m_font(font)
     60    , m_size(font.pointSize())
    5961    , m_bold(bold)
    6062    , m_oblique(false)
    61     , m_font(font)
     63    , m_isDeletedValue(false)
    6264{
    6365}
     
    6870    , m_bold(bold)
    6971    , m_oblique(oblique)
     72    , m_isDeletedValue(false)
    7073{
    7174}
     
    7376
    7477FontPlatformData::FontPlatformData()
    75     : m_size(0.0f)
     78    : m_size(m_font.pointSize())
    7679    , m_bold(false)
    7780    , m_oblique(false)
     81    , m_isDeletedValue(false)
    7882{
    7983}
Note: See TracChangeset for help on using the changeset viewer.