/*
 * Copyright (C) 2007-2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "CSSFontFace.h"

#include "CSSFontFaceSource.h"
#include "CSSFontFaceSrcValue.h"
#include "CSSFontFeatureValue.h"
#include "CSSFontSelector.h"
#include "CSSFontStyleRangeValue.h"
#include "CSSPrimitiveValueMappings.h"
#include "CSSUnicodeRangeValue.h"
#include "CSSValue.h"
#include "CSSValueList.h"
#include "Document.h"
#include "Font.h"
#include "FontCache.h"
#include "FontDescription.h"
#include "FontFace.h"
#include "FontVariantBuilder.h"
#include "Settings.h"
#include "StyleBuilderConverter.h"
#include "StyleProperties.h"
#include "StyleRule.h"

namespace WebCore {

template<typename T> void iterateClients(HashSet<CSSFontFace::Client*>& clients, T callback)
{
    Vector<Ref<CSSFontFace::Client>> clientsCopy;
    clientsCopy.reserveInitialCapacity(clients.size());
    for (auto* client : clients)
        clientsCopy.uncheckedAppend(*client);

    for (auto* client : clients)
        callback(*client);
}

void CSSFontFace::appendSources(CSSFontFace& fontFace, CSSValueList& srcList, Document* document, bool isInitiatingElementInUserAgentShadowTree)
{
    for (auto& src : srcList) {
        // An item in the list either specifies a string (local font name) or a URL (remote font to download).
        CSSFontFaceSrcValue& item = downcast<CSSFontFaceSrcValue>(src.get());
        std::unique_ptr<CSSFontFaceSource> source;
        SVGFontFaceElement* fontFaceElement = nullptr;
        bool foundSVGFont = false;

#if ENABLE(SVG_FONTS)
        foundSVGFont = item.isSVGFontFaceSrc() || item.svgFontFaceElement();
        fontFaceElement = item.svgFontFaceElement();
#endif
        if (!item.isLocal()) {
            const Settings* settings = document ? &document->settings() : nullptr;
            bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
            if (allowDownloading && item.isSupportedFormat() && document) {
                if (CachedFont* cachedFont = item.cachedFont(document, foundSVGFont, isInitiatingElementInUserAgentShadowTree))
                    source = std::make_unique<CSSFontFaceSource>(fontFace, item.resource(), cachedFont);
            }
        } else
            source = std::make_unique<CSSFontFaceSource>(fontFace, item.resource(), nullptr, fontFaceElement);

        if (source)
            fontFace.adoptSource(WTFMove(source));
    }
    fontFace.sourcesPopulated();
}

CSSFontFace::CSSFontFace(CSSFontSelector* fontSelector, StyleRuleFontFace* cssConnection, FontFace* wrapper, bool isLocalFallback)
    : m_fontSelector(fontSelector)
    , m_cssConnection(cssConnection)
    , m_wrapper(makeWeakPtr(wrapper))
    , m_isLocalFallback(isLocalFallback)
    , m_mayBePurged(!wrapper)
    , m_timeoutTimer(*this, &CSSFontFace::timeoutFired)
{
}

CSSFontFace::~CSSFontFace() = default;

bool CSSFontFace::setFamilies(CSSValue& family)
{
    if (!is<CSSValueList>(family))
        return false;

    CSSValueList& familyList = downcast<CSSValueList>(family);
    if (!familyList.length())
        return false;

    RefPtr<CSSValueList> oldFamilies = m_families;
    m_families = &familyList;

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontFamily, &family);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this, oldFamilies.get());
    });

    return true;
}

static FontSelectionRange calculateWeightRange(CSSValue& value)
{
    if (value.isValueList()) {
        auto& valueList = downcast<CSSValueList>(value);
        ASSERT(valueList.length() == 2);
        if (valueList.length() != 2)
            return { normalWeightValue(), normalWeightValue() };
        ASSERT(valueList.item(0)->isPrimitiveValue());
        ASSERT(valueList.item(1)->isPrimitiveValue());
        auto& value0 = downcast<CSSPrimitiveValue>(*valueList.item(0));
        auto& value1 = downcast<CSSPrimitiveValue>(*valueList.item(1));
        auto result0 = StyleBuilderConverter::convertFontWeightFromValue(value0);
        auto result1 = StyleBuilderConverter::convertFontWeightFromValue(value1);
        return { result0, result1 };
    }

    ASSERT(is<CSSPrimitiveValue>(value));
    auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
    FontSelectionValue result = StyleBuilderConverter::convertFontWeightFromValue(primitiveValue);
    return { result, result };
}

void CSSFontFace::setWeight(CSSValue& weight)
{
    auto range = calculateWeightRange(weight);
    if (m_fontSelectionCapabilities.weight == range)
        return;

    setWeight(range);

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontWeight, &weight);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });
}

static FontSelectionRange calculateStretchRange(CSSValue& value)
{
    if (value.isValueList()) {
        auto& valueList = downcast<CSSValueList>(value);
        ASSERT(valueList.length() == 2);
        if (valueList.length() != 2)
            return { normalStretchValue(), normalStretchValue() };
        ASSERT(valueList.item(0)->isPrimitiveValue());
        ASSERT(valueList.item(1)->isPrimitiveValue());
        auto& value0 = downcast<CSSPrimitiveValue>(*valueList.item(0));
        auto& value1 = downcast<CSSPrimitiveValue>(*valueList.item(1));
        auto result0 = StyleBuilderConverter::convertFontStretchFromValue(value0);
        auto result1 = StyleBuilderConverter::convertFontStretchFromValue(value1);
        return { result0, result1 };
    }

    ASSERT(is<CSSPrimitiveValue>(value));
    const auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
    FontSelectionValue result = StyleBuilderConverter::convertFontStretchFromValue(primitiveValue);
    return { result, result };
}

void CSSFontFace::setStretch(CSSValue& style)
{
    auto range = calculateStretchRange(style);
    if (m_fontSelectionCapabilities.width == range)
        return;

    setStretch(range);

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontStretch, &style);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });
}

static FontSelectionRange calculateItalicRange(CSSValue& value)
{
    if (value.isFontStyleValue()) {
        auto result = StyleBuilderConverter::convertFontStyleFromValue(value);
        return { result.valueOr(normalItalicValue()), result.valueOr(normalItalicValue()) };
    }

    ASSERT(value.isFontStyleRangeValue());
    auto& rangeValue = downcast<CSSFontStyleRangeValue>(value);
    ASSERT(rangeValue.fontStyleValue->isValueID());
    auto valueID = rangeValue.fontStyleValue->valueID();
    if (!rangeValue.obliqueValues) {
        if (valueID == CSSValueNormal)
            return { normalItalicValue(), normalItalicValue() };
        ASSERT(valueID == CSSValueItalic || valueID == CSSValueOblique);
        return { italicValue(), italicValue() };
    }
    ASSERT(valueID == CSSValueOblique);
    auto length = rangeValue.obliqueValues->length();
    if (length == 1) {
        auto& primitiveValue = downcast<CSSPrimitiveValue>(*rangeValue.obliqueValues->item(0));
        FontSelectionValue result(primitiveValue.value<float>(CSSPrimitiveValue::CSS_DEG));
        return { result, result };
    }
    ASSERT(length == 2);
    auto& primitiveValue1 = downcast<CSSPrimitiveValue>(*rangeValue.obliqueValues->item(0));
    auto& primitiveValue2 = downcast<CSSPrimitiveValue>(*rangeValue.obliqueValues->item(1));
    FontSelectionValue result1(primitiveValue1.value<float>(CSSPrimitiveValue::CSS_DEG));
    FontSelectionValue result2(primitiveValue2.value<float>(CSSPrimitiveValue::CSS_DEG));
    return { result1, result2 };
}

void CSSFontFace::setStyle(CSSValue& style)
{
    auto range = calculateItalicRange(style);
    if (m_fontSelectionCapabilities.slope == range)
        return;

    setStyle(range);

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontStyle, &style);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });
}

bool CSSFontFace::setUnicodeRange(CSSValue& unicodeRange)
{
    if (!is<CSSValueList>(unicodeRange))
        return false;

    Vector<UnicodeRange> ranges;
    auto& list = downcast<CSSValueList>(unicodeRange);
    for (auto& rangeValue : list) {
        auto& range = downcast<CSSUnicodeRangeValue>(rangeValue.get());
        ranges.append({ range.from(), range.to() });
    }

    if (ranges == m_ranges)
        return true;

    m_ranges = WTFMove(ranges);

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyUnicodeRange, &unicodeRange);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });

    return true;
}

bool CSSFontFace::setVariantLigatures(CSSValue& variantLigatures)
{
    auto ligatures = extractFontVariantLigatures(variantLigatures);

    if (m_variantSettings.commonLigatures == ligatures.commonLigatures
        && m_variantSettings.discretionaryLigatures == ligatures.discretionaryLigatures
        && m_variantSettings.historicalLigatures == ligatures.historicalLigatures
        && m_variantSettings.contextualAlternates == ligatures.contextualAlternates)
        return true;

    m_variantSettings.commonLigatures = ligatures.commonLigatures;
    m_variantSettings.discretionaryLigatures = ligatures.discretionaryLigatures;
    m_variantSettings.historicalLigatures = ligatures.historicalLigatures;
    m_variantSettings.contextualAlternates = ligatures.contextualAlternates;

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontVariantLigatures, &variantLigatures);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });

    return true;
}

bool CSSFontFace::setVariantPosition(CSSValue& variantPosition)
{
    if (!is<CSSPrimitiveValue>(variantPosition))
        return false;

    FontVariantPosition position = downcast<CSSPrimitiveValue>(variantPosition);

    if (m_variantSettings.position == position)
        return true;

    m_variantSettings.position = position;

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontVariantPosition, &variantPosition);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });

    return true;
}

bool CSSFontFace::setVariantCaps(CSSValue& variantCaps)
{
    if (!is<CSSPrimitiveValue>(variantCaps))
        return false;

    FontVariantCaps caps = downcast<CSSPrimitiveValue>(variantCaps);

    if (m_variantSettings.caps == caps)
        return true;

    m_variantSettings.caps = caps;

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontVariantCaps, &variantCaps);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });

    return true;
}

bool CSSFontFace::setVariantNumeric(CSSValue& variantNumeric)
{
    auto numeric = extractFontVariantNumeric(variantNumeric);

    if (m_variantSettings.numericFigure == numeric.figure
        && m_variantSettings.numericSpacing == numeric.spacing
        && m_variantSettings.numericFraction == numeric.fraction
        && m_variantSettings.numericOrdinal == numeric.ordinal
        && m_variantSettings.numericSlashedZero == numeric.slashedZero)
        return true;

    m_variantSettings.numericFigure = numeric.figure;
    m_variantSettings.numericSpacing = numeric.spacing;
    m_variantSettings.numericFraction = numeric.fraction;
    m_variantSettings.numericOrdinal = numeric.ordinal;
    m_variantSettings.numericSlashedZero = numeric.slashedZero;

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontVariantNumeric, &variantNumeric);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });

    return true;
}

bool CSSFontFace::setVariantAlternates(CSSValue& variantAlternates)
{
    if (!is<CSSPrimitiveValue>(variantAlternates))
        return false;

    FontVariantAlternates alternates = downcast<CSSPrimitiveValue>(variantAlternates);

    if (m_variantSettings.alternates == alternates)
        return true;

    m_variantSettings.alternates = alternates;

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontVariantAlternates, &variantAlternates);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });

    return true;
}

bool CSSFontFace::setVariantEastAsian(CSSValue& variantEastAsian)
{
    auto eastAsian = extractFontVariantEastAsian(variantEastAsian);

    if (m_variantSettings.eastAsianVariant == eastAsian.variant
        && m_variantSettings.eastAsianWidth == eastAsian.width
        && m_variantSettings.eastAsianRuby == eastAsian.ruby)
        return true;

    m_variantSettings.eastAsianVariant = eastAsian.variant;
    m_variantSettings.eastAsianWidth = eastAsian.width;
    m_variantSettings.eastAsianRuby = eastAsian.ruby;

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontVariantEastAsian, &variantEastAsian);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });

    return true;
}

void CSSFontFace::setFeatureSettings(CSSValue& featureSettings)
{
    // Can only call this with a primitive value of normal, or a value list containing font feature values.
    ASSERT(is<CSSPrimitiveValue>(featureSettings) || is<CSSValueList>(featureSettings));

    FontFeatureSettings settings;

    if (is<CSSValueList>(featureSettings)) {
        auto& list = downcast<CSSValueList>(featureSettings);
        for (auto& rangeValue : list) {
            auto& feature = downcast<CSSFontFeatureValue>(rangeValue.get());
            settings.insert({ feature.tag(), feature.value() });
        }
    }

    if (m_featureSettings == settings)
        return;

    m_featureSettings = WTFMove(settings);

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontFeatureSettings, &featureSettings);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });
}

void CSSFontFace::setLoadingBehavior(CSSValue& loadingBehaviorValue)
{
    auto loadingBehavior = static_cast<FontLoadingBehavior>(downcast<CSSPrimitiveValue>(loadingBehaviorValue));

    if (m_loadingBehavior == loadingBehavior)
        return;

    m_loadingBehavior = loadingBehavior;

    if (m_cssConnection)
        m_cssConnection->mutableProperties().setProperty(CSSPropertyFontDisplay, &loadingBehaviorValue);

    iterateClients(m_clients, [&](Client& client) {
        client.fontPropertyChanged(*this);
    });
}

bool CSSFontFace::rangesMatchCodePoint(UChar32 character) const
{
    if (m_ranges.isEmpty())
        return true;

    for (auto& range : m_ranges) {
        if (range.from <= character && character <= range.to)
            return true;
    }
    return false;
}

void CSSFontFace::fontLoadEventOccurred()
{
    // If the font is already in the cache, CSSFontFaceSource may report it's loaded before it is added here as a source.
    // Let's not pump the state machine until we've got all our sources. font() and load() are smart enough to act correctly
    // when a source is failed or succeeded before we have asked it to load.
    if (m_sourcesPopulated)
        pump(ExternalResourceDownloadPolicy::Forbid);

    ASSERT(m_fontSelector);
    m_fontSelector->fontLoaded();

    iterateClients(m_clients, [&](Client& client) {
        client.fontLoaded(*this);
    });
}

void CSSFontFace::timeoutFired()
{
    Ref<CSSFontFace> protectedThis(*this);
    
    switch (status()) {
    case Status::Loading:
        setStatus(Status::TimedOut);
        break;
    case Status::TimedOut:
        // Cancelling the network request here could lead to a situation where a site's font never gets
        // shown as the user navigates around to different pages on the site. This would occur if the
        // download always takes longer than the timeout (even though the user may spend substantial time
        // on each page). Therefore, we shouldn't cancel the network request here, but should use the
        // loading infrastructure's timeout policies instead.
        setStatus(Status::Failure);
        break;
    default:
        ASSERT_NOT_REACHED();
        break;
    }

    fontLoadEventOccurred();
}

bool CSSFontFace::computeFailureState() const
{
    if (status() == Status::Failure)
        return true;
    for (auto& source : m_sources) {
        if (source->status() != CSSFontFaceSource::Status::Failure)
            return false;
    }
    return true;
}

void CSSFontFace::addClient(Client& client)
{
    m_clients.add(&client);
}

void CSSFontFace::removeClient(Client& client)
{
    ASSERT(m_clients.contains(&client));
    m_clients.remove(&client);
}

void CSSFontFace::initializeWrapper()
{
    switch (m_status) {
    case Status::Pending:
        break;
    case Status::Loading:
        m_wrapper->fontStateChanged(*this, Status::Pending, Status::Loading);
        break;
    case Status::TimedOut:
        m_wrapper->fontStateChanged(*this, Status::Pending, Status::Loading);
        m_wrapper->fontStateChanged(*this, Status::Loading, Status::TimedOut);
        break;
    case Status::Success:
        m_wrapper->fontStateChanged(*this, Status::Pending, Status::Loading);
        m_wrapper->fontStateChanged(*this, Status::Pending, Status::Success);
        break;
    case Status::Failure:
        m_wrapper->fontStateChanged(*this, Status::Pending, Status::Loading);
        m_wrapper->fontStateChanged(*this, Status::Pending, Status::Failure);
        break;
    }
    m_mayBePurged = false;
}

Ref<FontFace> CSSFontFace::wrapper()
{
    if (m_wrapper)
        return *m_wrapper.get();

    auto wrapper = FontFace::create(*this);
    m_wrapper = makeWeakPtr(wrapper.get());
    initializeWrapper();
    return wrapper;
}

void CSSFontFace::setWrapper(FontFace& newWrapper)
{
    m_wrapper = makeWeakPtr(newWrapper);
    initializeWrapper();
}

void CSSFontFace::adoptSource(std::unique_ptr<CSSFontFaceSource>&& source)
{
    m_sources.append(WTFMove(source));

    // We should never add sources in the middle of loading.
    ASSERT(!m_sourcesPopulated);
}

AllowUserInstalledFonts CSSFontFace::allowUserInstalledFonts() const
{
    if (m_fontSelector && m_fontSelector->document())
        return m_fontSelector->document()->settings().shouldAllowUserInstalledFonts() ? AllowUserInstalledFonts::Yes : AllowUserInstalledFonts::No;
    return AllowUserInstalledFonts::Yes;
}

static Settings::FontLoadTimingOverride fontLoadTimingOverride(CSSFontSelector* fontSelector)
{
    auto overrideValue = Settings::FontLoadTimingOverride::None;
    if (fontSelector && fontSelector->document())
        overrideValue = fontSelector->document()->settings().fontLoadTimingOverride();
    return overrideValue;
}

auto CSSFontFace::fontLoadTiming() const -> FontLoadTiming
{
    switch (fontLoadTimingOverride(m_fontSelector.get())) {
    case Settings::FontLoadTimingOverride::None:
        switch (m_loadingBehavior) {
        case FontLoadingBehavior::Auto:
        case FontLoadingBehavior::Block:
            return { 3_s, Seconds::infinity() };
        case FontLoadingBehavior::Swap:
            return { 0_s, Seconds::infinity() };
        case FontLoadingBehavior::Fallback:
            return { 0.1_s, 3_s };
        case FontLoadingBehavior::Optional:
            return { 0.1_s, 0_s };
        }
        RELEASE_ASSERT_NOT_REACHED();
    case Settings::FontLoadTimingOverride::Block:
        return { Seconds::infinity(), 0_s };
    case Settings::FontLoadTimingOverride::Swap:
        return { 0_s, Seconds::infinity() };
    case Settings::FontLoadTimingOverride::Failure:
        return { 0_s, 0_s };
    }
    RELEASE_ASSERT_NOT_REACHED();
}

void CSSFontFace::setStatus(Status newStatus)
{
    switch (newStatus) {
    case Status::Pending:
        ASSERT_NOT_REACHED();
        break;
    case Status::Loading:
        ASSERT(m_status == Status::Pending);
        break;
    case Status::TimedOut:
        ASSERT(m_status == Status::Loading);
        break;
    case Status::Success:
        ASSERT(m_status == Status::Loading || m_status == Status::TimedOut);
        break;
    case Status::Failure:
        ASSERT(m_status == Status::Loading || m_status == Status::TimedOut);
        break;
    }

    iterateClients(m_clients, [&](Client& client) {
        client.fontStateChanged(*this, m_status, newStatus);
    });

    m_status = newStatus;

    Seconds blockPeriodTimeout;
    Seconds swapPeriodTimeout;
    auto timeouts = fontLoadTiming();
    blockPeriodTimeout = timeouts.blockPeriod;
    swapPeriodTimeout = timeouts.swapPeriod;

    // Transfer across 0-delay timers synchronously. Layouts/script may
    // take arbitrarily long time, and we shouldn't be in a 0-duration
    // state for an arbitrarily long time. Also it's necessary for
    // testing so we don't have a race with the font load.
    switch (newStatus) {
    case Status::Pending:
        ASSERT_NOT_REACHED();
        break;
    case Status::Loading:
        if (blockPeriodTimeout == 0_s)
            setStatus(Status::TimedOut);
        else if (std::isfinite(blockPeriodTimeout.value()))
            m_timeoutTimer.startOneShot(blockPeriodTimeout);
        break;
    case Status::TimedOut:
        if (swapPeriodTimeout == 0_s)
            setStatus(Status::Failure);
        else if (std::isfinite(swapPeriodTimeout.value()))
            m_timeoutTimer.startOneShot(swapPeriodTimeout);
        break;
    case Status::Success:
    case Status::Failure:
        m_timeoutTimer.stop();
        break;
    }
}

void CSSFontFace::fontLoaded(CSSFontFaceSource&)
{
    Ref<CSSFontFace> protectedThis(*this);
    
    fontLoadEventOccurred();
}

bool CSSFontFace::shouldIgnoreFontLoadCompletions() const
{
    if (m_fontSelector && m_fontSelector->document())
        return m_fontSelector->document()->settings().shouldIgnoreFontLoadCompletions();
    return false;
}

void CSSFontFace::opportunisticallyStartFontDataURLLoading(CSSFontSelector& fontSelector)
{
    // We don't want to go crazy here and blow the cache. Usually these data URLs are the first item in the src: list, so let's just check that one.
    if (!m_sources.isEmpty())
        m_sources[0]->opportunisticallyStartFontDataURLLoading(fontSelector);
}

size_t CSSFontFace::pump(ExternalResourceDownloadPolicy policy)
{
    if (status() == Status::Failure)
        return 0;

    size_t i;
    for (i = 0; i < m_sources.size(); ++i) {
        auto& source = m_sources[i];

        if (source->status() == CSSFontFaceSource::Status::Pending) {
            ASSERT(m_status == Status::Pending || m_status == Status::Loading || m_status == Status::TimedOut);
            // This is a little tricky. After calling CSSFontFace::font(Forbid), a font must never fail later in
            // this turn of the runloop because the return value of CSSFontFace::font() shouldn't get nulled out
            // from under an existing FontRanges object. Remote fonts are all downloaded asynchronously, so this
            // isn't a problem for them because CSSFontFace::font() will always return the interstitial font.
            // However, local fonts may synchronously fail when you call load() on them. Therefore, we have to call
            // load() here in order to guarantee that, if the font synchronously fails, it happens now during the
            // first call to CSSFontFace::font() and the FontRanges object sees a consistent view of the
            // CSSFontFace. This means we eagerly create some internal font objects when they may not be needed,
            // but it seems that this behavior is a requirement of the design of FontRanges. FIXME: Perhaps rethink
            // this design.
            if (policy == ExternalResourceDownloadPolicy::Allow || !source->requiresExternalResource()) {
                if (m_status == Status::Pending)
                    setStatus(Status::Loading);
                source->load(m_fontSelector.get());
            }
        }

        switch (source->status()) {
        case CSSFontFaceSource::Status::Pending:
            ASSERT(policy == ExternalResourceDownloadPolicy::Forbid);
            return i;
        case CSSFontFaceSource::Status::Loading:
            ASSERT(m_status == Status::Pending || m_status == Status::Loading || m_status == Status::TimedOut || m_status == Status::Failure);
            if (m_status == Status::Pending)
                setStatus(Status::Loading);
            return i;
        case CSSFontFaceSource::Status::Success:
            ASSERT(m_status == Status::Pending || m_status == Status::Loading || m_status == Status::TimedOut || m_status == Status::Success || m_status == Status::Failure);
            if (m_status == Status::Pending)
                setStatus(Status::Loading);
            if (m_status == Status::Loading || m_status == Status::TimedOut)
                setStatus(Status::Success);
            return i;
        case CSSFontFaceSource::Status::Failure:
            if (m_status == Status::Pending)
                setStatus(Status::Loading);
            break;
        }
    }
    if (m_sources.isEmpty() && m_status == Status::Pending)
        setStatus(Status::Loading);
    if (m_status == Status::Loading || m_status == Status::TimedOut)
        setStatus(Status::Failure);
    return m_sources.size();
}

void CSSFontFace::load()
{
    pump(ExternalResourceDownloadPolicy::Allow);
}

static Font::Visibility visibility(CSSFontFace::Status status, CSSFontFace::FontLoadTiming timing)
{
    switch (status) {
    case CSSFontFace::Status::Pending:
        return timing.blockPeriod == 0_s ? Font::Visibility::Visible : Font::Visibility::Invisible;
    case CSSFontFace::Status::Loading:
        return Font::Visibility::Invisible;
    case CSSFontFace::Status::TimedOut:
    case CSSFontFace::Status::Failure:
    case CSSFontFace::Status::Success:
    default:
        return Font::Visibility::Visible;
    }
}

RefPtr<Font> CSSFontFace::font(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, ExternalResourceDownloadPolicy policy)
{
    if (computeFailureState())
        return nullptr;

    Ref<CSSFontFace> protectedThis(*this);
    
    // Our status is derived from the first non-failed source. However, this source may
    // return null from font(), which means we need to continue looping through the remainder
    // of the sources to try to find a font to use. These subsequent tries should not affect
    // our own state, though.
    size_t startIndex = pump(policy);

    if (computeFailureState())
        return nullptr;

    for (size_t i = startIndex; i < m_sources.size(); ++i) {
        auto& source = m_sources[i];
        if (source->status() == CSSFontFaceSource::Status::Pending && (policy == ExternalResourceDownloadPolicy::Allow || !source->requiresExternalResource()))
            source->load(m_fontSelector.get());

        switch (source->status()) {
        case CSSFontFaceSource::Status::Pending:
        case CSSFontFaceSource::Status::Loading: {
            Font::Visibility visibility = WebCore::visibility(status(), fontLoadTiming());
            return Font::create(FontCache::singleton().lastResortFallbackFont(fontDescription)->platformData(), Font::Origin::Local, Font::Interstitial::Yes, visibility);
        }
        case CSSFontFaceSource::Status::Success:
            if (RefPtr<Font> result = source->font(fontDescription, syntheticBold, syntheticItalic, m_featureSettings, m_variantSettings, m_fontSelectionCapabilities))
                return result;
            break;
        case CSSFontFaceSource::Status::Failure:
            break;
        }
    }

    return nullptr;
}

bool CSSFontFace::purgeable() const
{
    return cssConnection() && m_mayBePurged;
}

void CSSFontFace::updateStyleIfNeeded()
{
    if (m_fontSelector && m_fontSelector->document())
        m_fontSelector->document()->updateStyleIfNeeded();
}

#if ENABLE(SVG_FONTS)
bool CSSFontFace::hasSVGFontFaceSource() const
{
    size_t size = m_sources.size();
    for (size_t i = 0; i < size; i++) {
        if (m_sources[i]->isSVGFontFaceSource())
            return true;
    }
    return false;
}
#endif

}
