2 * Copyright (C) 2013 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 #include "bindings/core/v8/ScriptPromise.h"
30 #include "core/css/FontFace.h"
31 #include "core/css/FontFaceSetForEachCallback.h"
32 #include "core/dom/ActiveDOMObject.h"
33 #include "core/events/EventListener.h"
34 #include "core/events/EventTarget.h"
35 #include "platform/AsyncMethodRunner.h"
36 #include "platform/RefCountedSupplement.h"
37 #include "wtf/PassRefPtr.h"
38 #include "wtf/RefCounted.h"
39 #include "wtf/Vector.h"
41 // Mac OS X 10.6 SDK defines check() macro that interfares with our check() method
49 class CSSFontFaceSource;
50 class CSSFontSelector;
57 class FontsReadyPromiseResolver;
58 class ExecutionContext;
61 class FontFaceSet final : public GarbageCollectedFinalized<FontFaceSet>, public HeapSupplement<Document>, public ActiveDOMObject, public EventTargetWithInlineData {
62 USING_GARBAGE_COLLECTED_MIXIN(FontFaceSet);
63 typedef HeapSupplement<Document> SupplementType;
65 class FontFaceSet final : public RefCountedSupplement<Document, FontFaceSet>, public ActiveDOMObject, public EventTargetWithInlineData {
66 DEFINE_EVENT_TARGET_REFCOUNTING(RefCounted<FontFaceSet>);
67 typedef RefCountedSupplement<Document, FontFaceSet> SupplementType;
69 DEFINE_WRAPPERTYPEINFO();
71 virtual ~FontFaceSet();
73 DEFINE_ATTRIBUTE_EVENT_LISTENER(loading);
74 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingdone);
75 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingerror);
77 bool check(const String& font, const String& text, ExceptionState&);
78 ScriptPromise load(ScriptState*, const String& font, const String& text);
79 ScriptPromise ready(ScriptState*);
81 void add(FontFace*, ExceptionState&);
83 bool remove(FontFace*, ExceptionState&);
84 void forEach(FontFaceSetForEachCallback*, const ScriptValue& thisArg) const;
85 void forEach(FontFaceSetForEachCallback*) const;
86 bool has(FontFace*, ExceptionState&) const;
88 unsigned long size() const;
89 AtomicString status() const;
91 virtual ExecutionContext* executionContext() const override;
92 virtual const AtomicString& interfaceName() const override;
94 Document* document() const;
97 void beginFontLoading(FontFace*);
98 void fontLoaded(FontFace*);
99 void loadError(FontFace*);
102 virtual void suspend() override;
103 virtual void resume() override;
104 virtual void stop() override;
106 static PassRefPtrWillBeRawPtr<FontFaceSet> from(Document&);
107 static void didLayout(Document&);
109 void addFontFacesToFontFaceCache(FontFaceCache*, CSSFontSelector*);
112 virtual void trace(Visitor*) override;
116 static PassRefPtrWillBeRawPtr<FontFaceSet> create(Document& document)
118 return adoptRefWillBeNoop(new FontFaceSet(document));
121 class FontLoadHistogram {
123 enum Status { NoWebFonts, HadBlankText, DidNotHaveBlankText, Reported };
124 FontLoadHistogram() : m_status(NoWebFonts), m_count(0), m_recorded(false) { }
125 void incrementCount() { m_count++; }
126 void updateStatus(FontFace*);
135 FontFaceSet(Document&);
137 bool hasLoadedFonts() const { return !m_loadedFonts.isEmpty() || !m_failedFonts.isEmpty(); }
139 bool inActiveDocumentContext() const;
140 void forEachInternal(FontFaceSetForEachCallback*, const ScriptValue* thisArg) const;
141 void addToLoadingFonts(PassRefPtrWillBeRawPtr<FontFace>);
142 void removeFromLoadingFonts(PassRefPtrWillBeRawPtr<FontFace>);
143 void fireLoadingEvent();
144 void fireDoneEventIfPossible();
145 bool resolveFontStyle(const String&, Font&);
146 void handlePendingEventsAndPromisesSoon();
147 void handlePendingEventsAndPromises();
148 const WillBeHeapListHashSet<RefPtrWillBeMember<FontFace> >& cssConnectedFontFaceList() const;
149 bool isCSSConnectedFontFace(FontFace*) const;
151 WillBeHeapHashSet<RefPtrWillBeMember<FontFace> > m_loadingFonts;
152 bool m_shouldFireLoadingEvent;
153 Vector<OwnPtr<FontsReadyPromiseResolver> > m_readyResolvers;
154 FontFaceArray m_loadedFonts;
155 FontFaceArray m_failedFonts;
156 WillBeHeapListHashSet<RefPtrWillBeMember<FontFace> > m_nonCSSConnectedFaces;
158 AsyncMethodRunner<FontFaceSet> m_asyncRunner;
160 FontLoadHistogram m_histogram;
165 #endif // FontFaceSet_h