/*
 * 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 = makeUnique<CSSFontFaceSource>(fontFace, item.resource(), cachedFont);
            }
        } else
            source = makeUnique<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;
}

FontFace* CSSFontFace::existingWrapper()
{
    return m_wrapper.get();
}

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;
}

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

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 (policy == ExternalResourceDownloadPolicy::Allow && 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 (policy == ExternalResourceDownloadPolicy::Allow && 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 (policy == ExternalResourceDownloadPolicy::Allow && 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

}
