Changeset 177229 in webkit


Ignore:
Timestamp:
Dec 12, 2014, 12:31:30 PM (10 years ago)
Author:
Antti Koivisto
Message:

FontGlyphs::glyphDataAndPageForCharacter cleanups
https://bugs.webkit.org/show_bug.cgi?id=139584

Reviewed by Andreas Kling.

Split it up and use helper functions.

  • WebCore.exp.in:
  • platform/graphics/FontGlyphs.cpp:

(WebCore::FontGlyphs::determinePitch):
(WebCore::FontGlyphs::realizeFontDataAt):
(WebCore::FontGlyphs::glyphDataAndPageForSystemFallback):
(WebCore::FontGlyphs::glyphDataAndPageForVariant):

Add private helpers.

(WebCore::FontGlyphs::glyphDataAndPageForCharacter):

Do the m_pages cache lookup only once and use the pointer reference afterwards.

  • platform/graphics/FontGlyphs.h:

(WebCore::FontGlyphs::fontSelector):
(WebCore::FontGlyphs::widthCache):
(WebCore::FontGlyphs::primaryFontData):
(WebCore::FontGlyphs::isFixedPitch):
(WebCore::FontGlyphs::primarySimpleFontData):

Also removed the mutable attribute from the fields (almost everything was marked mutable) and made the inteface
non-const. The FontGlyphs member of Font is already mutable so this is not needed.

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r177228 r177229  
     12014-12-12  Antti Koivisto  <antti@apple.com>
     2
     3        FontGlyphs::glyphDataAndPageForCharacter cleanups
     4        https://bugs.webkit.org/show_bug.cgi?id=139584
     5
     6        Reviewed by Andreas Kling.
     7
     8        Split it up and use helper functions.
     9
     10        * WebCore.exp.in:
     11        * platform/graphics/FontGlyphs.cpp:
     12        (WebCore::FontGlyphs::determinePitch):
     13        (WebCore::FontGlyphs::realizeFontDataAt):
     14        (WebCore::FontGlyphs::glyphDataAndPageForSystemFallback):
     15        (WebCore::FontGlyphs::glyphDataAndPageForVariant):
     16
     17            Add private helpers.
     18
     19        (WebCore::FontGlyphs::glyphDataAndPageForCharacter):
     20
     21            Do the m_pages cache lookup only once and use the pointer reference afterwards.
     22
     23        * platform/graphics/FontGlyphs.h:
     24        (WebCore::FontGlyphs::fontSelector):
     25        (WebCore::FontGlyphs::widthCache):
     26        (WebCore::FontGlyphs::primaryFontData):
     27        (WebCore::FontGlyphs::isFixedPitch):
     28        (WebCore::FontGlyphs::primarySimpleFontData):
     29
     30            Also removed the mutable attribute from the fields (almost everything was marked mutable) and made the inteface
     31            non-const. The FontGlyphs member of Font is already mutable so this is not needed.
     32
    1332014-12-12  Chris Dumez  <cdumez@apple.com>
    234
  • trunk/Source/WebCore/WebCore.exp.in

    r177196 r177229  
    7878__ZN7WebCore10FloatPointC1ERKNS_8IntPointE
    7979__ZN7WebCore10FontGlyphs15releaseFontDataEv
     80__ZN7WebCore10FontGlyphs17realizeFontDataAtERKNS_15FontDescriptionEj
    8081__ZN7WebCore10JSDocument6s_infoE
    8182__ZN7WebCore10JSDocument9toWrappedEN3JSC7JSValueE
     
    15841585__ZNK7WebCore10Credential7isEmptyEv
    15851586__ZNK7WebCore10FloatPointcv7CGPointEv
    1586 __ZNK7WebCore10FontGlyphs17realizeFontDataAtERKNS_15FontDescriptionEj
    15871587__ZNK7WebCore10LayoutRect8containsERKS0_
    15881588__ZNK7WebCore10PluginData16supportsMimeTypeERKN3WTF6StringENS0_18AllowedPluginTypesE
  • trunk/Source/WebCore/platform/graphics/FontGlyphs.cpp

    r176903 r177229  
    7575}
    7676
    77 void FontGlyphs::determinePitch(const FontDescription& description) const
     77void FontGlyphs::determinePitch(const FontDescription& description)
    7878{
    7979    const FontData* fontData = primaryFontData(description);
     
    9090}
    9191
    92 const FontData* FontGlyphs::realizeFontDataAt(const FontDescription& description, unsigned realizedFontIndex) const
     92const FontData* FontGlyphs::realizeFontDataAt(const FontDescription& description, unsigned realizedFontIndex)
    9393{
    9494    if (realizedFontIndex < m_realizedFontData.size())
     
    257257}
    258258
    259 std::pair<GlyphData, GlyphPage*> FontGlyphs::glyphDataAndPageForCharacter(const FontDescription& description, UChar32 c, bool mirror, FontDataVariant variant) const
    260 {
    261     ASSERT(isMainThread());
    262 
    263     if (variant == AutoVariant) {
    264         if (description.smallCaps() && !primarySimpleFontData(description)->isSVGFont()) {
    265             UChar32 upperC = u_toupper(c);
    266             if (upperC != c) {
    267                 c = upperC;
    268                 variant = SmallCapsVariant;
    269             } else
    270                 variant = NormalVariant;
    271         } else
    272             variant = NormalVariant;
    273     }
    274 
    275     if (mirror)
    276         c = u_charMirror(c);
    277 
    278     unsigned pageNumber = (c / GlyphPage::size);
    279 
    280     GlyphPageTreeNode* node = pageNumber ? m_pages.get(pageNumber) : m_pageZero;
    281     if (!node) {
    282         node = GlyphPageTreeNode::getRootChild(realizeFontDataAt(description, 0), pageNumber);
    283         if (pageNumber)
    284             m_pages.set(pageNumber, node);
    285         else
    286             m_pageZero = node;
    287     }
    288 
    289     GlyphPage* page = 0;
    290     if (variant == NormalVariant) {
    291         // Fastest loop, for the common case (normal variant).
    292         while (true) {
    293             page = node->page();
    294             if (page) {
    295                 GlyphData data = page->glyphDataForCharacter(c);
    296                 if (data.fontData && (data.fontData->platformData().orientation() == Horizontal || data.fontData->isTextOrientationFallback()))
    297                     return std::make_pair(data, page);
    298 
    299                 if (data.fontData) {
    300                     if (Font::isCJKIdeographOrSymbol(c)) {
    301                         if (!data.fontData->hasVerticalGlyphs()) {
    302                             // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs
    303                             // to make sure you get a square (even for broken glyphs like symbols used for punctuation).
    304                             variant = BrokenIdeographVariant;
    305                             break;
    306                         }
    307 #if PLATFORM(COCOA)
    308                         else if (data.fontData->platformData().syntheticOblique())
    309                             return glyphDataAndPageForCJKCharacterWithoutSyntheticItalic(c, data, page, pageNumber);
    310 #endif
    311                     } else
    312                         return glyphDataAndPageForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, page, pageNumber);
    313 
    314                     return std::make_pair(data, page);
    315                 }
    316 
    317                 if (node->isSystemFallback())
    318                     break;
    319             }
    320 
    321             node = node->getChild(realizeFontDataAt(description, node->level()), pageNumber);
    322             if (pageNumber)
    323                 m_pages.set(pageNumber, node);
    324             else
    325                 m_pageZero = node;
    326         }
    327     }
    328     if (variant != NormalVariant) {
    329         while (true) {
    330             page = node->page();
    331             if (page) {
    332                 GlyphData data = page->glyphDataForCharacter(c);
    333                 if (data.fontData) {
    334                     // The variantFontData function should not normally return 0.
    335                     // But if it does, we will just render the capital letter big.
    336                     RefPtr<SimpleFontData> variantFontData = data.fontData->variantFontData(description, variant);
    337                     if (!variantFontData)
    338                         return std::make_pair(data, page);
    339 
    340                     GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootChild(variantFontData.get(), pageNumber);
    341                     GlyphPage* variantPage = variantNode->page();
    342                     if (variantPage) {
    343                         GlyphData data = variantPage->glyphDataForCharacter(c);
    344                         if (data.fontData)
    345                             return std::make_pair(data, variantPage);
    346                     }
    347 
    348                     // Do not attempt system fallback off the variantFontData. This is the very unlikely case that
    349                     // a font has the lowercase character but the small caps font does not have its uppercase version.
    350                     return std::make_pair(variantFontData->missingGlyphData(), page);
    351                 }
    352 
    353                 if (node->isSystemFallback())
    354                     break;
    355             }
    356 
    357             node = node->getChild(realizeFontDataAt(description, node->level()), pageNumber);
    358             if (pageNumber)
    359                 m_pages.set(pageNumber, node);
    360             else
    361                 m_pageZero = node;
    362         }
    363     }
    364 
    365     ASSERT(page);
    366     ASSERT(node->isSystemFallback());
    367 
     259std::pair<GlyphData, GlyphPage*> FontGlyphs::glyphDataAndPageForSystemFallback(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned pageNumber, GlyphPageTreeNode& node)
     260{
     261    ASSERT(node.page());
     262    ASSERT(node.isSystemFallback());
    368263    // System fallback is character-dependent. When we get here, we
    369264    // know that the character in question isn't in the system fallback
     
    393288        // Cache it so we don't have to do system fallback again next time.
    394289        if (variant == NormalVariant) {
    395             page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
    396             data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyphPageTreeLevel(), node->level()));
     290            node.page()->setGlyphDataForCharacter(c, data.glyph, data.fontData);
     291            data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyphPageTreeLevel(), node.level()));
    397292            if (!Font::isCJKIdeographOrSymbol(c) && data.fontData->platformData().orientation() != Horizontal && !data.fontData->isTextOrientationFallback())
    398293                return glyphDataAndPageForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, fallbackPage, pageNumber);
    399294        }
    400         return std::make_pair(data, page);
     295        return std::make_pair(data, node.page());
    401296    }
    402297
     
    405300    GlyphData data = primarySimpleFontData(description)->missingGlyphData();
    406301    if (variant == NormalVariant) {
    407         page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
    408         data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyphPageTreeLevel(), node->level()));
    409     }
    410     return std::make_pair(data, page);
    411 }
    412 
    413 
    414 }
     302        node.page()->setGlyphDataForCharacter(c, data.glyph, data.fontData);
     303        data.fontData->setMaxGlyphPageTreeLevel(std::max(data.fontData->maxGlyphPageTreeLevel(), node.level()));
     304    }
     305    return std::make_pair(data, node.page());
     306}
     307
     308std::pair<GlyphData, GlyphPage*> FontGlyphs::glyphDataAndPageForVariant(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned pageNumber, GlyphPageTreeNode*& node)
     309{
     310    while (true) {
     311        if (GlyphPage* page = node->page()) {
     312            GlyphData data = page->glyphDataForCharacter(c);
     313            if (data.fontData) {
     314                // The variantFontData function should not normally return 0.
     315                // But if it does, we will just render the capital letter big.
     316                RefPtr<SimpleFontData> variantFontData = data.fontData->variantFontData(description, variant);
     317                if (!variantFontData)
     318                    return std::make_pair(data, page);
     319
     320                GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootChild(variantFontData.get(), pageNumber);
     321                GlyphPage* variantPage = variantNode->page();
     322                if (variantPage) {
     323                    GlyphData data = variantPage->glyphDataForCharacter(c);
     324                    if (data.fontData)
     325                        return std::make_pair(data, variantPage);
     326                }
     327
     328                // Do not attempt system fallback off the variantFontData. This is the very unlikely case that
     329                // a font has the lowercase character but the small caps font does not have its uppercase version.
     330                return std::make_pair(variantFontData->missingGlyphData(), page);
     331            }
     332
     333            if (node->isSystemFallback())
     334                return glyphDataAndPageForSystemFallback(c, description, variant, pageNumber, *node);
     335        }
     336
     337        node = node->getChild(realizeFontDataAt(description, node->level()), pageNumber);
     338    }
     339}
     340
     341std::pair<GlyphData, GlyphPage*> FontGlyphs::glyphDataAndPageForCharacter(const FontDescription& description, UChar32 c, bool mirror, FontDataVariant variant)
     342{
     343    ASSERT(isMainThread());
     344
     345    if (variant == AutoVariant) {
     346        if (description.smallCaps() && !primarySimpleFontData(description)->isSVGFont()) {
     347            UChar32 upperC = u_toupper(c);
     348            if (upperC != c) {
     349                c = upperC;
     350                variant = SmallCapsVariant;
     351            } else
     352                variant = NormalVariant;
     353        } else
     354            variant = NormalVariant;
     355    }
     356
     357    if (mirror)
     358        c = u_charMirror(c);
     359
     360    const unsigned pageNumber = (c / GlyphPage::size);
     361
     362    GlyphPageTreeNode*& node = pageNumber ? m_pages.add(pageNumber, nullptr).iterator->value : m_pageZero;
     363    if (!node)
     364        node = GlyphPageTreeNode::getRootChild(realizeFontDataAt(description, 0), pageNumber);
     365
     366    if (variant != NormalVariant)
     367        return glyphDataAndPageForVariant(c, description, variant, pageNumber, node);
     368
     369    while (true) {
     370        if (GlyphPage* page = node->page()) {
     371            GlyphData data = page->glyphDataForCharacter(c);
     372            if (data.fontData) {
     373                if (data.fontData->platformData().orientation() == Vertical && !data.fontData->isTextOrientationFallback()) {
     374                    if (!Font::isCJKIdeographOrSymbol(c))
     375                        return glyphDataAndPageForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data, page, pageNumber);
     376
     377                    if (!data.fontData->hasVerticalGlyphs()) {
     378                        // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs
     379                        // to make sure you get a square (even for broken glyphs like symbols used for punctuation).
     380                        return glyphDataAndPageForVariant(c, description, BrokenIdeographVariant, pageNumber, node);
     381                    }
     382#if PLATFORM(COCOA)
     383                    if (data.fontData->platformData().syntheticOblique())
     384                        return glyphDataAndPageForCJKCharacterWithoutSyntheticItalic(c, data, page, pageNumber);
     385#endif
     386                }
     387
     388                return std::make_pair(data, page);
     389            }
     390
     391            if (node->isSystemFallback())
     392                return glyphDataAndPageForSystemFallback(c, description, variant, pageNumber, *node);
     393        }
     394
     395        node = node->getChild(realizeFontDataAt(description, node->level()), pageNumber);
     396    }
     397}
     398
     399}
  • trunk/Source/WebCore/platform/graphics/FontGlyphs.h

    r172862 r177229  
    7676    bool isForPlatformFont() const { return m_isForPlatformFont; }
    7777
    78     std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(const FontDescription&, UChar32, bool mirror, FontDataVariant) const;
    79    
    80     bool isFixedPitch(const FontDescription&) const;
    81     void determinePitch(const FontDescription&) const;
     78    std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacter(const FontDescription&, UChar32, bool mirror, FontDataVariant);
     79
     80    bool isFixedPitch(const FontDescription&);
     81    void determinePitch(const FontDescription&);
    8282
    8383    bool loadingCustomFonts() const { return m_loadingCustomFonts; }
    8484
    85     FontSelector* fontSelector() const { return m_fontSelector.get(); }
     85    FontSelector* fontSelector() { return m_fontSelector.get(); }
    8686    // FIXME: It should be possible to combine fontSelectorVersion and generation.
    8787    unsigned fontSelectorVersion() const { return m_fontSelectorVersion; }
    8888    unsigned generation() const { return m_generation; }
    8989
    90     WidthCache& widthCache() const { return m_widthCache; }
     90    WidthCache& widthCache() { return m_widthCache; }
     91    const WidthCache& widthCache() const { return m_widthCache; }
    9192
    92     const SimpleFontData* primarySimpleFontData(const FontDescription&) const;
    93     const FontData* primaryFontData(const FontDescription& description) const { return realizeFontDataAt(description, 0); }
    94     WEBCORE_EXPORT const FontData* realizeFontDataAt(const FontDescription&, unsigned index) const;
     93    const SimpleFontData* primarySimpleFontData(const FontDescription&);
     94    const FontData* primaryFontData(const FontDescription& description) { return realizeFontDataAt(description, 0); }
     95    WEBCORE_EXPORT const FontData* realizeFontDataAt(const FontDescription&, unsigned index);
    9596
    9697private:
     
    9899    FontGlyphs(const FontPlatformData&);
    99100
     101    std::pair<GlyphData, GlyphPage*> glyphDataAndPageForSystemFallback(UChar32, const FontDescription&, FontDataVariant, unsigned pageNumber, GlyphPageTreeNode&);
     102    std::pair<GlyphData, GlyphPage*> glyphDataAndPageForVariant(UChar32, const FontDescription&, FontDataVariant, unsigned pageNumber, GlyphPageTreeNode*&);
     103
    100104    WEBCORE_EXPORT void releaseFontData();
    101105   
    102     mutable Vector<RefPtr<FontData>, 1> m_realizedFontData;
    103     mutable GlyphPages m_pages;
    104     mutable GlyphPageTreeNode* m_pageZero;
    105     mutable const SimpleFontData* m_cachedPrimarySimpleFontData;
     106    Vector<RefPtr<FontData>, 1> m_realizedFontData;
     107    GlyphPages m_pages;
     108    GlyphPageTreeNode* m_pageZero;
     109    const SimpleFontData* m_cachedPrimarySimpleFontData;
    106110    RefPtr<FontSelector> m_fontSelector;
    107     mutable WidthCache m_widthCache;
     111    WidthCache m_widthCache;
    108112    unsigned m_fontSelectorVersion;
    109     mutable int m_familyIndex;
     113    int m_familyIndex;
    110114    unsigned short m_generation;
    111     mutable unsigned m_pitch : 3; // Pitch
    112     mutable bool m_loadingCustomFonts : 1;
    113     bool m_isForPlatformFont : 1;
     115    unsigned m_pitch : 3; // Pitch
     116    unsigned m_loadingCustomFonts : 1;
     117    unsigned m_isForPlatformFont : 1;
    114118};
    115119
    116 inline bool FontGlyphs::isFixedPitch(const FontDescription& description) const
     120inline bool FontGlyphs::isFixedPitch(const FontDescription& description)
    117121{
    118122    if (m_pitch == UnknownPitch)
     
    121125};
    122126
    123 inline const SimpleFontData* FontGlyphs::primarySimpleFontData(const FontDescription& description) const
     127inline const SimpleFontData* FontGlyphs::primarySimpleFontData(const FontDescription& description)
    124128{
    125129    ASSERT(isMainThread());
Note: See TracChangeset for help on using the changeset viewer.