void CSSFontFace::fontLoaded(CSSFontFaceSource* source)
{
    if (source != m_activeSource)
        return;

    // FIXME: Can we assert that m_segmentedFontFaces is not empty? That may
    // require stopping in-progress font loading when the last
    // CSSSegmentedFontFace is removed.
    if (m_segmentedFontFaces.isEmpty())
        return;

    // Use one of the CSSSegmentedFontFaces' font selector. They all have
    // the same font selector, so it's wasteful to store it in the CSSFontFace.
    CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector();
    fontSelector->fontLoaded();

#if ENABLE(FONT_LOAD_EVENTS)
    if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading) {
        if (source->ensureFontData())
            notifyFontLoader(Loaded);
        else if (!isValid())
            notifyFontLoader(Error);
    }
#endif

    HashSet<CSSSegmentedFontFace*>::iterator end = m_segmentedFontFaces.end();
    for (HashSet<CSSSegmentedFontFace*>::iterator it = m_segmentedFontFaces.begin(); it != end; ++it)
        (*it)->fontLoaded(this);

#if ENABLE(FONT_LOAD_EVENTS)
    if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
        notifyLoadingDone();
#endif
}
Beispiel #2
0
bool FontFaceSet::check(const String& fontString, const String& text, ExceptionState& exceptionState)
{
    if (!inActiveDocumentContext())
        return false;

    Font font;
    if (!resolveFontStyle(fontString, font)) {
        exceptionState.ThrowDOMException(SyntaxError, "Could not resolve '" + fontString + "' as a font.");
        return false;
    }

    CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
    FontFaceCache* fontFaceCache = fontSelector->fontFaceCache();

    bool hasLoadedFaces = false;
    for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
        CSSSegmentedFontFace* face = fontFaceCache->get(font.fontDescription(), f->family());
        if (face) {
            if (!face->checkFont(nullToSpace(text)))
                return false;
            hasLoadedFaces = true;
        }
    }
    if (hasLoadedFaces)
        return true;
    for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
        if (fontSelector->isPlatformFontAvailable(font.fontDescription(), f->family()))
            return true;
    }
    return false;
}
Beispiel #3
0
void FontFaceSet::clearForBinding(ScriptState*, ExceptionState&) {
  if (!inActiveDocumentContext() || m_nonCSSConnectedFaces.isEmpty())
    return;
  CSSFontSelector* fontSelector = document()->styleEngine().fontSelector();
  FontFaceCache* fontFaceCache = fontSelector->fontFaceCache();
  for (const auto& fontFace : m_nonCSSConnectedFaces) {
    fontFaceCache->removeFontFace(fontFace.get(), false);
    if (fontFace->loadStatus() == FontFace::Loading)
      removeFromLoadingFonts(fontFace);
  }
  m_nonCSSConnectedFaces.clear();
  fontSelector->fontFaceInvalidated();
}
Beispiel #4
0
void FontFaceSet::clear()
{
    if (!inActiveDocumentContext() || m_nonCSSConnectedFaces.isEmpty())
        return;
    CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
    FontFaceCache* fontFaceCache = fontSelector->fontFaceCache();
    for (ListHashSet<RefPtr<FontFace> >::iterator it = m_nonCSSConnectedFaces.begin(); it != m_nonCSSConnectedFaces.end(); ++it) {
        fontFaceCache->removeFontFace(it->get(), false);
        if ((*it)->loadStatus() == FontFace::Loading)
            removeFromLoadingFonts(*it);
    }
    m_nonCSSConnectedFaces.clear();
    fontSelector->fontFaceInvalidated();
}
Beispiel #5
0
void FontFace::load(ExecutionContext* context)
{
    if (m_status != Unloaded)
        return;

    FontDescription fontDescription;
    FontFamily fontFamily;
    fontFamily.setFamily(m_family);
    fontDescription.setFamily(fontFamily);
    fontDescription.setTraits(traits());

    CSSFontSelector* fontSelector = toDocument(context)->styleEngine()->fontSelector();
    m_cssFontFace->load(fontDescription, fontSelector);
    fontSelector->loadPendingFonts();
}
void ScopedStyleResolver::addFontFaceRules(const RuleSet& ruleSet)
{
    // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment.
    if (!treeScope().rootNode().isDocumentNode())
        return;

    Document& document = treeScope().document();
    CSSFontSelector* cssFontSelector = document.styleEngine().fontSelector();
    const WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace>> fontFaceRules = ruleSet.fontFaceRules();
    for (auto& fontFaceRule : fontFaceRules) {
        if (RefPtrWillBeRawPtr<FontFace> fontFace = FontFace::create(&document, fontFaceRule))
            cssFontSelector->fontFaceCache()->add(cssFontSelector, fontFaceRule, fontFace);
    }
    if (fontFaceRules.size())
        document.styleResolver()->invalidateMatchedPropertiesCache();
}
bool FontFaceSet::deleteForBinding(ScriptState*, FontFace* fontFace, ExceptionState&)
{
    ASSERT(fontFace);
    if (!inActiveDocumentContext())
        return false;
    WillBeHeapListHashSet<RefPtrWillBeMember<FontFace>>::iterator it = m_nonCSSConnectedFaces.find(fontFace);
    if (it != m_nonCSSConnectedFaces.end()) {
        m_nonCSSConnectedFaces.remove(it);
        CSSFontSelector* fontSelector = document()->styleEngine().fontSelector();
        fontSelector->fontFaceCache()->removeFontFace(fontFace, false);
        if (fontFace->loadStatus() == FontFace::Loading)
            removeFromLoadingFonts(fontFace);
        fontSelector->fontFaceInvalidated();
        return true;
    }
    return false;
}
PassRefPtrWillBeRawPtr<FontFaceSet> FontFaceSet::addForBinding(ScriptState*, FontFace* fontFace, ExceptionState&)
{
    ASSERT(fontFace);
    if (!inActiveDocumentContext())
        return this;
    if (m_nonCSSConnectedFaces.contains(fontFace))
        return this;
    if (isCSSConnectedFontFace(fontFace))
        return this;
    CSSFontSelector* fontSelector = document()->styleEngine().fontSelector();
    m_nonCSSConnectedFaces.add(fontFace);
    fontSelector->fontFaceCache()->addFontFace(fontSelector, fontFace, false);
    if (fontFace->loadStatus() == FontFace::Loading)
        addToLoadingFonts(fontFace);
    fontSelector->fontFaceInvalidated();
    return this;
}
Beispiel #9
0
void CSSFontFace::fontLoaded(CSSFontFaceSource* source)
{
    if (source != m_activeSource)
        return;

    // FIXME: Can we assert that m_segmentedFontFaces is not empty? That may
    // require stopping in-progress font loading when the last
    // CSSSegmentedFontFace is removed.
    if (m_segmentedFontFaces.isEmpty())
        return;

    HashSet<CSSSegmentedFontFace*>::iterator end = m_segmentedFontFaces.end();
    for (HashSet<CSSSegmentedFontFace*>::iterator it = m_segmentedFontFaces.begin(); it != end; ++it)
        (*it)->fontLoaded(this);

    // Use one of the CSSSegmentedFontFaces' font selector. They all have
    // the same font selector, so it's wasteful to store it in the CSSFontFace.
    CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector();
    fontSelector->fontLoaded();
}
Beispiel #10
0
void FontFaceSet::add(FontFace* fontFace, ExceptionState& exceptionState)
{
    if (!inActiveDocumentContext())
        return;
    if (!fontFace) {
        exceptionState.ThrowTypeError("The argument is not a FontFace.");
        return;
    }
    if (m_nonCSSConnectedFaces.contains(fontFace))
        return;
    if (isCSSConnectedFontFace(fontFace)) {
        exceptionState.ThrowDOMException(InvalidModificationError, "Cannot add a CSS-connected FontFace.");
        return;
    }
    CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
    m_nonCSSConnectedFaces.add(fontFace);
    fontSelector->fontFaceCache()->addFontFace(fontSelector, fontFace, false);
    if (fontFace->loadStatus() == FontFace::Loading)
        addToLoadingFonts(fontFace);
    fontSelector->fontFaceInvalidated();
}
Beispiel #11
0
bool FontFaceSet::remove(FontFace* fontFace, ExceptionState& exceptionState)
{
    if (!inActiveDocumentContext())
        return false;
    if (!fontFace) {
        exceptionState.ThrowTypeError("The argument is not a FontFace.");
        return false;
    }
    ListHashSet<RefPtr<FontFace> >::iterator it = m_nonCSSConnectedFaces.find(fontFace);
    if (it != m_nonCSSConnectedFaces.end()) {
        m_nonCSSConnectedFaces.remove(it);
        CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
        fontSelector->fontFaceCache()->removeFontFace(fontFace, false);
        if (fontFace->loadStatus() == FontFace::Loading)
            removeFromLoadingFonts(fontFace);
        fontSelector->fontFaceInvalidated();
        return true;
    }
    if (isCSSConnectedFontFace(fontFace))
        exceptionState.ThrowDOMException(InvalidModificationError, "Cannot delete a CSS-connected FontFace.");
    return false;
}
Beispiel #12
0
void CSSFontFaceSource::load(CSSFontSelector& fontSelector)
{
    setStatus(Status::Loading);

    fontSelector.beginLoadingFontSoon(m_font.get());
}