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 }
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; }
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(); }
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(); }
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; }
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(); }
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(); }
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; }
void CSSFontFaceSource::load(CSSFontSelector& fontSelector) { setStatus(Status::Loading); fontSelector.beginLoadingFontSoon(m_font.get()); }