Ignore:
Timestamp:
Jun 22, 2017, 7:17:21 PM (8 years ago)
Author:
[email protected]
Message:

@font-face rules with invalid primary fonts never download their secondary fonts
https://bugs.webkit.org/show_bug.cgi?id=173138
<rdar://problem/32554450>

Reviewed by Simon Fraser.

Source/WebCore:

We have logic in CSSFontAccessor::font() which disallows downloading a CSSFontFace if that CSSFontFace
is already in the Succeeded state. However, it was possible for a succeeded CSSFontFace to still fail
to create a font. In this situation, we wouldn't be able to use the downloaded font, and we wouldn't
try to download the next item in the src: list because the CSSFontFace is succeeded.

This patch strengthens the meaning of the Succeeded state. Previously, it just meant that the bytes
in the file were downloaded successfully. This patch extends this to also mean that the bytes in the
file can be successfully interpreted as a font. This way, the CSSFontFace in the example above won't be
set to the Succeeded state, so we will continue follow the src: list and download the secondary fonts.

This has an added benefit that the CSS Font Loading API's promises will be called more appropriately.
The transition to the Succeeded state will trigger a resolve of the promise. Now, these promises will
only be resolved if the fonts are actually parsed and understood by our text system.

Test: fast/text/font-fallback-invalid-load.html

  • css/CSSFontFaceSource.cpp:

(WebCore::CSSFontFaceSource::fontLoaded): Move to the failed state if we can't understand the font
data. This is the crux of this patch.
(WebCore::CSSFontFaceSource::font): This function should only be called if we are in the Succeeded
state, which means now we know we should always be able to understand the bytes of the file. Therefore,
we can change some if statements into ASSERT()s.

  • loader/cache/CachedSVGFont.cpp:

(WebCore::CachedSVGFont::createFont): Ditto.
(WebCore::CachedSVGFont::ensureCustomFontData): Similarly to CSSFontFaceSource::fontLoaded(), this
adds another check to our criteria for transitioning into the Succeeded state, which will guarantee that
later we will always be able to create the font object.

LayoutTests:

  • fast/text/font-fallback-invalid-load-expected.html: Added.
  • fast/text/font-fallback-invalid-load.html: Added.
  • fast/text/resources/bogus.svg: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/css/CSSFontFaceSource.cpp

    r218264 r218733  
    109109    ASSERT_UNUSED(loadedFont, &loadedFont == m_font.get());
    110110
     111    Ref<CSSFontFace> protectedFace(m_face);
     112
    111113    // If the font is in the cache, this will be synchronously called from CachedFont::addClient().
    112114    if (m_status == Status::Pending)
     
    121123        return;
    122124
    123     if (m_font->errorOccurred())
     125    if (m_font->errorOccurred() || !m_font->ensureCustomFontData(m_familyNameOrURI))
    124126        setStatus(Status::Failure);
    125127    else
     
    194196
    195197    if (m_font) {
    196         if (!m_font->ensureCustomFontData(m_familyNameOrURI))
    197             return nullptr;
    198 
    199         return m_font->createFont(fontDescription, m_familyNameOrURI, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities);
     198        auto success = m_font->ensureCustomFontData(m_familyNameOrURI);
     199        ASSERT_UNUSED(success, success);
     200
     201        ASSERT(status() == Status::Success);
     202        auto result = m_font->createFont(fontDescription, m_familyNameOrURI, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities);
     203        ASSERT(result);
     204        return result;
    200205    }
    201206
Note: See TracChangeset for help on using the changeset viewer.