Changeset 147889 in webkit


Ignore:
Timestamp:
Apr 7, 2013 6:01:22 PM (11 years ago)
Author:
benjamin@webkit.org
Message:

Do not allocate static AtomicStrings when searching for alternate font names
https://bugs.webkit.org/show_bug.cgi?id=114110

Reviewed by Geoffrey Garen.

FontCache's alternateFamilyName does some font name substitutions
when a font is not found for a given name.

In the vast majority of cases, no substitutions are made and
alternateFamilyName returns the null atom.
Given the usage the function had a couple of problems:
-It created 6 static AtomicString.
-It did a case insensitive comparison with 6 differents strings

before failing.

This patch aims at solving both issues.

Instead of creating all AtomicString statically, the alternate name
are simply created on the fly as needed. Because the operation is so
unfrequent, and it uses the fast constructor, doing so should not slow
down the function.

To avoid comparing the input to every string, every time, the length of
the input is first evaluated, and we only do the necessary string comparisons.

On x86_64, this reduces the binary size by 2128 bytes.

  • platform/graphics/FontCache.cpp:

(WebCore::familyNameEqualIgnoringCase):
When comparing strings, we know:
-The family name is non null.
-The length of both strings is equal.
-The length is not null.
Make the comparison accordingly.

(WebCore::alternateFamilyName):
(WebCore::FontCache::getCachedFontPlatformData):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r147888 r147889  
     12013-04-07  Benjamin Poulain  <benjamin@webkit.org>
     2
     3        Do not allocate static AtomicStrings when searching for alternate font names
     4        https://bugs.webkit.org/show_bug.cgi?id=114110
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        FontCache's alternateFamilyName does some font name substitutions
     9        when a font is not found for a given name.
     10
     11        In the vast majority of cases, no substitutions are made and
     12        alternateFamilyName returns the null atom.
     13        Given the usage the function had a couple of problems:
     14        -It created 6 static AtomicString.
     15        -It did a case insensitive comparison with 6 differents strings
     16         before failing.
     17
     18        This patch aims at solving both issues.
     19
     20        Instead of creating all AtomicString statically, the alternate name
     21        are simply created on the fly as needed. Because the operation is so
     22        unfrequent, and it uses the fast constructor, doing so should not slow
     23        down the function.
     24
     25        To avoid comparing the input to every string, every time, the length of
     26        the input is first evaluated, and we only do the necessary string comparisons.
     27
     28        On x86_64, this reduces the binary size by 2128 bytes.
     29
     30        * platform/graphics/FontCache.cpp:
     31        (WebCore::familyNameEqualIgnoringCase):
     32        When comparing strings, we know:
     33        -The family name is non null.
     34        -The length of both strings is equal.
     35        -The length is not null.
     36        Make the comparison accordingly.
     37
     38        (WebCore::alternateFamilyName):
     39        (WebCore::FontCache::getCachedFontPlatformData):
     40
    1412013-04-07  Zan Dobersek  <zdobersek@igalia.com>
    242
  • trunk/Source/WebCore/platform/graphics/FontCache.cpp

    r147888 r147889  
    133133static FontPlatformDataCache* gFontPlatformDataCache = 0;
    134134
    135 static const AtomicString& alternateFamilyName(const AtomicString& familyName)
    136 {
    137     // Alias Courier <-> Courier New
    138     DEFINE_STATIC_LOCAL(AtomicString, courier, ("Courier", AtomicString::ConstructFromLiteral));
    139     DEFINE_STATIC_LOCAL(AtomicString, courierNew, ("Courier New", AtomicString::ConstructFromLiteral));
    140     if (equalIgnoringCase(familyName, courier))
    141         return courierNew;
     135static bool familyNameEqualIgnoringCase(const AtomicString& familyName, const char* reference, unsigned length)
     136{
     137    ASSERT(length > 0);
     138    ASSERT(familyName.length() == length);
     139    ASSERT(strlen(reference) == length);
     140    const AtomicStringImpl* familyNameImpl = familyName.impl();
     141    if (familyNameImpl->is8Bit())
     142        return equalIgnoringCase(familyNameImpl->characters8(), reinterpret_cast<const LChar*>(reference), length);
     143    return equalIgnoringCase(familyNameImpl->characters16(), reinterpret_cast<const LChar*>(reference), length);
     144}
     145
     146template<size_t length>
     147static inline bool familyNameEqualIgnoringCase(const AtomicString& familyName, const char (&reference)[length])
     148{
     149    return familyNameEqualIgnoringCase(familyName, reference, length - 1);
     150}
     151
     152static const AtomicString alternateFamilyName(const AtomicString& familyName)
     153{
     154    // Alias Courier and Courier New.
     155    // Alias Times and Times New Roman.
     156    // Alias Arial and Helvetica.
     157    switch (familyName.length()) {
     158    case 5:
     159        if (familyNameEqualIgnoringCase(familyName, "Arial"))
     160            return AtomicString("Helvetica", AtomicString::ConstructFromLiteral);
     161        if (familyNameEqualIgnoringCase(familyName, "Times"))
     162            return AtomicString("Times New Roman", AtomicString::ConstructFromLiteral);
     163        break;
     164    case 7:
     165        if (familyNameEqualIgnoringCase(familyName, "Courier"))
     166            return AtomicString("Courier New", AtomicString::ConstructFromLiteral);
     167        break;
     168    case 9:
     169        if (familyNameEqualIgnoringCase(familyName, "Helvetica"))
     170            return AtomicString("Arial", AtomicString::ConstructFromLiteral);
     171        break;
    142172#if !OS(WINDOWS)
    143173    // On Windows, Courier New (truetype font) is always present and
    144174    // Courier is a bitmap font. So, we don't want to map Courier New to
    145175    // Courier.
    146     if (equalIgnoringCase(familyName, courierNew))
    147         return courier;
    148 #endif
    149 
    150     // Alias Times and Times New Roman.
    151     DEFINE_STATIC_LOCAL(AtomicString, times, ("Times", AtomicString::ConstructFromLiteral));
    152     DEFINE_STATIC_LOCAL(AtomicString, timesNewRoman, ("Times New Roman", AtomicString::ConstructFromLiteral));
    153     if (equalIgnoringCase(familyName, times))
    154         return timesNewRoman;
    155     if (equalIgnoringCase(familyName, timesNewRoman))
    156         return times;
    157    
    158     // Alias Arial and Helvetica
    159     DEFINE_STATIC_LOCAL(AtomicString, arial, ("Arial", AtomicString::ConstructFromLiteral));
    160     DEFINE_STATIC_LOCAL(AtomicString, helvetica, ("Helvetica", AtomicString::ConstructFromLiteral));
    161     if (equalIgnoringCase(familyName, arial))
    162         return helvetica;
    163     if (equalIgnoringCase(familyName, helvetica))
    164         return arial;
    165 
     176    case 11:
     177        if (familyNameEqualIgnoringCase(familyName, "Courier New"))
     178            return AtomicString("Courier", AtomicString::ConstructFromLiteral);
     179        break;
     180#endif // !OS(WINDOWS)
     181    case 15:
     182        if (familyNameEqualIgnoringCase(familyName, "Times New Roman"))
     183            return AtomicString("Times", AtomicString::ConstructFromLiteral);
     184        break;
    166185#if OS(WINDOWS)
    167186    // On Windows, bitmap fonts are blocked altogether so that we have to
    168187    // alias MS Sans Serif (bitmap font) -> Microsoft Sans Serif (truetype font)
    169     DEFINE_STATIC_LOCAL(AtomicString, msSans, ("MS Sans Serif", AtomicString::ConstructFromLiteral));
    170     DEFINE_STATIC_LOCAL(AtomicString, microsoftSans, ("Microsoft Sans Serif", AtomicString::ConstructFromLiteral));
    171     if (equalIgnoringCase(familyName, msSans))
    172         return microsoftSans;
     188    case 13:
     189        if (familyNameEqualIgnoringCase(familyName, "MS Sans Serif"))
     190            return AtomicString("Microsoft Sans Serif", AtomicString::ConstructFromLiteral);
     191        break;
    173192
    174193    // Alias MS Serif (bitmap) -> Times New Roman (truetype font). There's no
    175194    // 'Microsoft Sans Serif-equivalent' for Serif.
    176     DEFINE_STATIC_LOCAL(AtomicString, msSerif, ("MS Serif", AtomicString::ConstructFromLiteral));
    177     if (equalIgnoringCase(familyName, msSerif))
    178         return timesNewRoman;
    179 #endif
     195    case 8:
     196        if (familyNameEqualIgnoringCase(familyName, "MS Serif"))
     197            return AtomicString("Times New Roman", AtomicString::ConstructFromLiteral);
     198        break;
     199#endif // OS(WINDOWS)
     200
     201    }
    180202
    181203    return nullAtom;
     
    213235            // We were unable to find a font.  We have a small set of fonts that we alias to other names,
    214236            // e.g., Arial/Helvetica, Courier/Courier New, etc.  Try looking up the font under the aliased name.
    215             const AtomicString& alternateName = alternateFamilyName(familyName);
     237            const AtomicString alternateName = alternateFamilyName(familyName);
    216238            if (!alternateName.isNull()) {
    217239                FontPlatformData* fontPlatformDataForAlternateName = getCachedFontPlatformData(fontDescription, alternateName, true);
Note: See TracChangeset for help on using the changeset viewer.