Changeset 178180 in webkit


Ignore:
Timestamp:
Jan 9, 2015 11:33:40 AM (9 years ago)
Author:
Antti Koivisto
Message:

FontCache should only deal with SimpleFontData
https://bugs.webkit.org/show_bug.cgi?id=140293

Reviewed by Andreas Kling.

FontCache::fontForFamilyAtIndex hands out FontData objects and calls to FontSelector. That sort
of code does not belong to the cache layer. Move the functionality up to FontGlyphs.

  • platform/graphics/Font.cpp:

(WebCore::Font::operator==):
(WebCore::Font::drawText):
(WebCore::Font::drawEmphasisMarks):
(WebCore::Font::isLoadingCustomFonts):

  • platform/graphics/Font.h:

(WebCore::Font::loadingCustomFonts): Deleted.

  • platform/graphics/FontCache.cpp:

(WebCore::FontCache::similarFontPlatformData):

Generic null implementation to reduce #ifs.

(WebCore::FontCache::fontForFamilyAtIndex): Deleted.

  • platform/graphics/FontCache.h:

Unfriend FontGlyphs.

  • platform/graphics/FontGlyphs.cpp:

(WebCore::FontGlyphs::FontGlyphs):
(WebCore::FontGlyphs::isLoadingCustomFonts):

We can figure thus out cheaply without caching a bit.

(WebCore::realizeNextFamily):
(WebCore::FontGlyphs::realizeFontDataAt):

Reorganize a bit to make the logic clearer.
Get rid of the strange cAllFamiliesScanned constant.

(WebCore::FontGlyphs::glyphDataForVariant):
(WebCore::FontGlyphs::glyphDataForNormalVariant):

Loop until null, that always works.

  • platform/graphics/FontGlyphs.h:

(WebCore::FontGlyphs::loadingCustomFonts): Deleted.

  • platform/graphics/ios/FontCacheIOS.mm:

(WebCore::FontCache::similarFontPlatformData):

  • platform/graphics/mac/FontCacheMac.mm:

(WebCore::FontCache::similarFontPlatformData):

  • platform/graphics/mac/FontMac.mm:

(WebCore::Font::dashesForIntersectionsWithRect):

Location:
trunk/Source/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r178177 r178180  
     12015-01-09  Antti Koivisto  <antti@apple.com>
     2
     3        FontCache should only deal with SimpleFontData
     4        https://bugs.webkit.org/show_bug.cgi?id=140293
     5
     6        Reviewed by Andreas Kling.
     7
     8        FontCache::fontForFamilyAtIndex hands out FontData objects and calls to FontSelector. That sort
     9        of code does not belong to the cache layer. Move the functionality up to FontGlyphs.
     10
     11        * platform/graphics/Font.cpp:
     12        (WebCore::Font::operator==):
     13        (WebCore::Font::drawText):
     14        (WebCore::Font::drawEmphasisMarks):
     15        (WebCore::Font::isLoadingCustomFonts):
     16        * platform/graphics/Font.h:
     17        (WebCore::Font::loadingCustomFonts): Deleted.
     18        * platform/graphics/FontCache.cpp:
     19        (WebCore::FontCache::similarFontPlatformData):
     20
     21            Generic null implementation to reduce #ifs.
     22
     23        (WebCore::FontCache::fontForFamilyAtIndex): Deleted.
     24        * platform/graphics/FontCache.h:
     25
     26            Unfriend FontGlyphs.
     27
     28        * platform/graphics/FontGlyphs.cpp:
     29        (WebCore::FontGlyphs::FontGlyphs):
     30        (WebCore::FontGlyphs::isLoadingCustomFonts):
     31
     32            We can figure thus out cheaply without caching a bit.
     33
     34        (WebCore::realizeNextFamily):
     35        (WebCore::FontGlyphs::realizeFontDataAt):
     36
     37            Reorganize a bit to make the logic clearer.
     38            Get rid of the strange cAllFamiliesScanned constant.
     39
     40        (WebCore::FontGlyphs::glyphDataForVariant):
     41        (WebCore::FontGlyphs::glyphDataForNormalVariant):
     42
     43            Loop until null, that always works.
     44
     45        * platform/graphics/FontGlyphs.h:
     46        (WebCore::FontGlyphs::loadingCustomFonts): Deleted.
     47        * platform/graphics/ios/FontCacheIOS.mm:
     48        (WebCore::FontCache::similarFontPlatformData):
     49        * platform/graphics/mac/FontCacheMac.mm:
     50        (WebCore::FontCache::similarFontPlatformData):
     51        * platform/graphics/mac/FontMac.mm:
     52        (WebCore::Font::dashesForIntersectionsWithRect):
     53
    1542015-01-09  Csaba Osztrogonác  <ossy@webkit.org>
    255
  • trunk/Source/WebCore/platform/graphics/Font.cpp

    r177957 r178180  
    183183bool Font::operator==(const Font& other) const
    184184{
    185     // Our FontData don't have to be checked, since checking the font description will be fine.
    186     // FIXME: This does not work if the font was made with the FontPlatformData constructor.
    187     if (loadingCustomFonts() || other.loadingCustomFonts())
     185    if (isLoadingCustomFonts() || other.isLoadingCustomFonts())
    188186        return false;
    189187
     
    338336    // except if the 'force' argument is set to true (in which case it will use a fallback
    339337    // font).
    340     if (loadingCustomFonts() && customFontNotReadyAction == DoNotPaintIfFontNotReady)
     338    if (isLoadingCustomFonts() && customFontNotReadyAction == DoNotPaintIfFontNotReady)
    341339        return 0;
    342340
     
    356354void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
    357355{
    358     if (loadingCustomFonts())
     356    if (isLoadingCustomFonts())
    359357        return;
    360358
     
    10841082    return true;
    10851083}
     1084
     1085bool Font::isLoadingCustomFonts() const
     1086{
     1087    return m_glyphs && m_glyphs->isLoadingCustomFonts();
     1088}
    10861089   
    10871090GlyphToPathTranslator::GlyphUnderlineType computeUnderlineType(const TextRun& textRun, const GlyphBuffer& glyphBuffer, int index)
  • trunk/Source/WebCore/platform/graphics/Font.h

    r177957 r178180  
    290290
    291291private:
    292     bool loadingCustomFonts() const
    293     {
    294         return m_glyphs && m_glyphs->loadingCustomFonts();
    295     }
     292    bool isLoadingCustomFonts() const;
    296293
    297294    TypesettingFeatures computeTypesettingFeatures() const
  • trunk/Source/WebCore/platform/graphics/FontCache.cpp

    r178133 r178180  
    491491}
    492492
    493 RefPtr<FontData> FontCache::fontForFamilyAtIndex(const FontDescription& description, int& familyIndex, FontSelector* fontSelector)
    494 {
    495     ASSERT(familyIndex != cAllFamiliesScanned);
    496     RefPtr<FontData> result;
    497 
    498     bool isFirst = !familyIndex;
    499     int familyCount = description.familyCount();
    500     for (;familyIndex < familyCount && !result; ++familyIndex) {
    501         const AtomicString& family = description.familyAt(familyIndex);
    502         if (family.isEmpty())
    503             continue;
    504         if (fontSelector)
    505             result = fontSelector->getFontData(description, family);
    506         if (!result)
    507             result = fontForFamily(description, family);
    508     }
    509     if (familyIndex == familyCount)
    510         familyIndex = cAllFamiliesScanned;
    511 
    512 #if PLATFORM(COCOA)
    513     if (!result) {
    514         // We didn't find a font. Try to find a similar font using our own specific knowledge about our platform.
    515         // For example on OS X, we know to map any families containing the words Arabic, Pashto, or Urdu to the
    516         // Geeza Pro font.
    517         result = similarFontPlatformData(description);
    518     }
    519 #endif
    520 
    521     if (!result && isFirst) {
    522         // If it's the primary font that we couldn't find, we try the following. In all other cases, we will
    523         // just use per-character system fallback.
    524         if (fontSelector) {
    525             // Try the user's preferred standard font.
    526             if (RefPtr<FontData> data = fontSelector->getFontData(description, standardFamily))
    527                 return data.release();
    528         }
    529         // Still no result.  Hand back our last resort fallback font.
    530         result = lastResortFallbackFont(description);
    531     }
    532     return result.release();
    533 }
    534 
    535493static HashSet<FontSelector*>* gClients;
    536494
     
    582540}
    583541
     542#if !PLATFORM(COCOA)
     543RefPtr<SimpleFontData> FontCache::similarFontPlatformData(const FontDescription&)
     544{
     545    return nullptr;
     546}
     547#endif
     548
    584549} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/FontCache.h

    r178142 r178180  
    5353class Font;
    5454class FontPlatformData;
    55 class FontData;
    5655class FontSelector;
    5756class OpenTypeVerticalData;
     
    112111    friend FontCache& fontCache();
    113112
    114     RefPtr<FontData> fontForFamilyAtIndex(const FontDescription&, int& familyIndex, FontSelector*);
    115 
    116113    // This method is implemented by the platform.
    117114    RefPtr<SimpleFontData> systemFallbackForCharacters(const FontDescription&, const SimpleFontData* originalFontData, bool isPlatformFont, const UChar* characters, int length);
     
    134131    WEBCORE_EXPORT RefPtr<SimpleFontData> fontForFamily(const FontDescription&, const AtomicString&, bool checkingAlternateName = false);
    135132    WEBCORE_EXPORT Ref<SimpleFontData> lastResortFallbackFont(const FontDescription&);
     133    WEBCORE_EXPORT Ref<SimpleFontData> fontForPlatformData(const FontPlatformData&);
     134    RefPtr<SimpleFontData> similarFontPlatformData(const FontDescription&);
    136135
    137136    void addClient(FontSelector*);
     
    184183#endif
    185184    std::unique_ptr<FontPlatformData> createFontPlatformData(const FontDescription&, const AtomicString& family);
    186 #if PLATFORM(COCOA)
    187     PassRefPtr<SimpleFontData> similarFontPlatformData(const FontDescription&);
    188 #endif
    189 
    190     WEBCORE_EXPORT Ref<SimpleFontData> fontForPlatformData(const FontPlatformData&);
    191185
    192186    // Don't purge if this count is > 0;
     
    197191#endif
    198192    friend class SimpleFontData;
    199     friend class FontGlyphs;
    200193};
    201194
  • trunk/Source/WebCore/platform/graphics/FontGlyphs.cpp

    r178133 r178180  
    4242    , m_fontSelector(fontSelector)
    4343    , m_fontSelectorVersion(m_fontSelector ? m_fontSelector->version() : 0)
    44     , m_familyIndex(0)
    4544    , m_generation(fontCache().generation())
    46     , m_pitch(UnknownPitch)
    47     , m_loadingCustomFonts(false)
    48     , m_isForPlatformFont(false)
    4945{
    5046}
     
    5450    , m_fontSelector(0)
    5551    , m_fontSelectorVersion(0)
    56     , m_familyIndex(cAllFamiliesScanned)
    5752    , m_generation(fontCache().generation())
    58     , m_pitch(UnknownPitch)
    59     , m_loadingCustomFonts(false)
    6053    , m_isForPlatformFont(true)
    6154{
     
    8275}
    8376
    84 const FontData* FontGlyphs::realizeFontDataAt(const FontDescription& description, unsigned realizedFontIndex)
    85 {
    86     if (realizedFontIndex < m_realizedFontData.size())
    87         return m_realizedFontData[realizedFontIndex].get(); // This fallback font is already in our list.
    88 
    89     // Make sure we're not passing in some crazy value here.
    90     ASSERT(realizedFontIndex == m_realizedFontData.size());
    91 
    92     if (m_familyIndex <= cAllFamiliesScanned) {
    93         if (!m_fontSelector)
    94             return 0;
    95 
    96         size_t index = cAllFamiliesScanned - m_familyIndex;
    97         if (index == m_fontSelector->fallbackFontDataCount())
    98             return 0;
    99 
    100         m_familyIndex--;
    101         RefPtr<FontData> fallback = m_fontSelector->getFallbackFontData(description, index);
    102         if (fallback)
    103             m_realizedFontData.append(fallback);
    104         return fallback.get();
    105     }
    106 
    107     // Ask the font cache for the font data.
    108     // We are obtaining this font for the first time. We keep track of the families we've looked at before
    109     // in |m_familyIndex|, so that we never scan the same spot in the list twice. fontForFamilyAtIndex will adjust our
    110     // |m_familyIndex| as it scans for the right font to make.
     77bool FontGlyphs::isLoadingCustomFonts() const
     78{
     79    for (auto& font : m_realizedFontData) {
     80        if (font->isLoading())
     81            return true;
     82    }
     83    return false;
     84}
     85
     86static RefPtr<FontData> realizeNextFamily(const FontDescription& description, unsigned& index, FontSelector* fontSelector)
     87{
     88    ASSERT(index < description.familyCount());
     89
     90    while (index < description.familyCount()) {
     91        const AtomicString& family = description.familyAt(index++);
     92        if (family.isEmpty())
     93            continue;
     94        if (fontSelector) {
     95            if (auto font = fontSelector->getFontData(description, family))
     96                return font;
     97        }
     98        if (auto font = fontCache().fontForFamily(description, family))
     99            return font;
     100    }
     101    // We didn't find a font. Try to find a similar font using our own specific knowledge about our platform.
     102    // For example on OS X, we know to map any families containing the words Arabic, Pashto, or Urdu to the
     103    // Geeza Pro font.
     104    return fontCache().similarFontPlatformData(description);
     105}
     106
     107const FontData* FontGlyphs::realizeFontDataAt(const FontDescription& description, unsigned index)
     108{
     109    if (index < m_realizedFontData.size())
     110        return &m_realizedFontData[index].get();
     111
     112    ASSERT(index == m_realizedFontData.size());
    111113    ASSERT(fontCache().generation() == m_generation);
    112     RefPtr<FontData> result = fontCache().fontForFamilyAtIndex(description, m_familyIndex, m_fontSelector.get());
    113     if (result) {
    114         m_realizedFontData.append(result);
    115         if (result->isLoading())
    116             m_loadingCustomFonts = true;
    117     }
     114
     115    if (!index) {
     116        RefPtr<FontData> result = realizeNextFamily(description, m_lastRealizedFamilyIndex, m_fontSelector.get());
     117        if (!result && m_fontSelector)
     118            result = m_fontSelector->getFontData(description, standardFamily);
     119        if (!result)
     120            result = fontCache().lastResortFallbackFont(description);
     121
     122        m_realizedFontData.append(*result);
     123        return result.get();
     124    }
     125
     126    RefPtr<FontData> result;
     127    if (m_lastRealizedFamilyIndex < description.familyCount())
     128        result = realizeNextFamily(description, m_lastRealizedFamilyIndex, m_fontSelector.get());
     129
     130    if (!result && m_fontSelector) {
     131        ASSERT(m_lastRealizedFamilyIndex >= description.familyCount());
     132
     133        unsigned fontSelectorFallbackIndex = m_lastRealizedFamilyIndex - description.familyCount();
     134        if (fontSelectorFallbackIndex == m_fontSelector->fallbackFontDataCount())
     135            return nullptr;
     136        ++m_lastRealizedFamilyIndex;
     137        result = m_fontSelector->getFallbackFontData(description, fontSelectorFallbackIndex);
     138    }
     139    if (!result)
     140        return nullptr;
     141
     142    m_realizedFontData.append(*result);
    118143    return result.get();
    119144}
     
    269294}
    270295
    271 GlyphData FontGlyphs::glyphDataForVariant(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned fallbackLevel)
    272 {
    273     for (; fallbackLevel <= description.familyCount(); ++fallbackLevel) {
    274         auto* fontData = realizeFontDataAt(description, fallbackLevel);
    275         if (!fontData)
    276             break;
    277 
     296GlyphData FontGlyphs::glyphDataForVariant(UChar32 c, const FontDescription& description, FontDataVariant variant, unsigned fallbackIndex)
     297{
     298    while (auto* fontData = realizeFontDataAt(description, fallbackIndex++)) {
    278299        auto* simpleFontData = fontData->simpleFontDataForCharacter(c);
    279300        GlyphData data = simpleFontData ? simpleFontData->glyphDataForCharacter(c) : GlyphData();
     
    296317    const unsigned pageNumber = c / GlyphPage::size;
    297318
    298     for (unsigned fallbackLevel = 0; fallbackLevel <= description.familyCount(); ++fallbackLevel) {
    299         auto* fontData = realizeFontDataAt(description, fallbackLevel);
    300         if (!fontData)
    301             break;
     319    for (unsigned fallbackIndex = 0; auto* fontData = realizeFontDataAt(description, fallbackIndex); ++fallbackIndex) {
    302320        auto* simpleFontData = fontData->simpleFontDataForCharacter(c);
    303321        auto* page = simpleFontData ? simpleFontData->glyphPage(pageNumber) : nullptr;
     
    313331                    // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs
    314332                    // to make sure you get a square (even for broken glyphs like symbols used for punctuation).
    315                     return glyphDataForVariant(c, description, BrokenIdeographVariant, fallbackLevel);
     333                    return glyphDataForVariant(c, description, BrokenIdeographVariant, fallbackIndex);
    316334                }
    317335#if PLATFORM(COCOA)
  • trunk/Source/WebCore/platform/graphics/FontGlyphs.h

    r178133 r178180  
    4141class FontSelector;
    4242
    43 const int cAllFamiliesScanned = -1;
    44 
    4543class FontGlyphs : public RefCounted<FontGlyphs> {
    4644    WTF_MAKE_NONCOPYABLE(FontGlyphs);
     
    5856    void determinePitch(const FontDescription&);
    5957
    60     bool loadingCustomFonts() const { return m_loadingCustomFonts; }
     58    bool isLoadingCustomFonts() const;
    6159
    6260    FontSelector* fontSelector() { return m_fontSelector.get(); }
     
    7775    GlyphData glyphDataForSystemFallback(UChar32, const FontDescription&, FontDataVariant);
    7876    GlyphData glyphDataForNormalVariant(UChar32, const FontDescription&);
    79     GlyphData glyphDataForVariant(UChar32, const FontDescription&, FontDataVariant, unsigned fallbackLevel);
    80    
    81     Vector<RefPtr<FontData>, 1> m_realizedFontData;
     77    GlyphData glyphDataForVariant(UChar32, const FontDescription&, FontDataVariant, unsigned fallbackIndex);
     78
     79    Vector<Ref<FontData>, 1> m_realizedFontData;
    8280
    8381    RefPtr<GlyphPage> m_cachedPageZero;
     
    9088    WidthCache m_widthCache;
    9189    unsigned m_fontSelectorVersion;
    92     int m_familyIndex;
    9390    unsigned short m_generation;
    94     unsigned m_pitch : 3; // Pitch
    95     unsigned m_loadingCustomFonts : 1;
    96     unsigned m_isForPlatformFont : 1;
     91    unsigned m_lastRealizedFamilyIndex { 0 };
     92    Pitch m_pitch { UnknownPitch };
     93    bool m_isForPlatformFont { false };
    9794};
    9895
  • trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp

    r177221 r178180  
    293293DashArray Font::dashesForIntersectionsWithRect(const TextRun& run, const FloatPoint& textOrigin, const FloatRect& lineExtents) const
    294294{
    295     if (loadingCustomFonts())
     295    if (isLoadingCustomFonts())
    296296        return DashArray();
    297297
  • trunk/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm

    r178133 r178180  
    447447}
    448448
    449 PassRefPtr<SimpleFontData> FontCache::similarFontPlatformData(const FontDescription& description)
     449RefPtr<SimpleFontData> FontCache::similarFontPlatformData(const FontDescription& description)
    450450{
    451451    // Attempt to find an appropriate font using a match based on the presence of keywords in
  • trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm

    r178133 r178180  
    406406}
    407407
    408 PassRefPtr<SimpleFontData> FontCache::similarFontPlatformData(const FontDescription& description)
     408RefPtr<SimpleFontData> FontCache::similarFontPlatformData(const FontDescription& description)
    409409{
    410410    // Attempt to find an appropriate font using a match based on
  • trunk/Source/WebCore/platform/graphics/mac/FontMac.mm

    r177955 r178180  
    529529DashArray Font::dashesForIntersectionsWithRect(const TextRun& run, const FloatPoint& textOrigin, const FloatRect& lineExtents) const
    530530{
    531     if (loadingCustomFonts())
     531    if (isLoadingCustomFonts())
    532532        return DashArray();
    533533
Note: See TracChangeset for help on using the changeset viewer.