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;
70 virtual ~FontFaceSet();
72 DEFINE_ATTRIBUTE_EVENT_LISTENER(loading);
73 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingdone);
74 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingerror);
76 bool check(const String& font, const String& text, ExceptionState&);
77 ScriptPromise load(ScriptState*, const String& font, const String& text);
78 ScriptPromise ready(ScriptState*);
80 void add(FontFace*, ExceptionState&);
82 bool remove(FontFace*, ExceptionState&);
83 void forEach(PassOwnPtr<FontFaceSetForEachCallback>, ScriptValue& thisArg) const;
84 void forEach(PassOwnPtr<FontFaceSetForEachCallback>) const;
85 bool has(FontFace*, ExceptionState&) const;
87 unsigned long size() const;
88 AtomicString status() const;
90 virtual ExecutionContext* executionContext() const OVERRIDE;
91 virtual const AtomicString& interfaceName() const OVERRIDE;
93 Document* document() const;
96 void beginFontLoading(FontFace*);
97 void fontLoaded(FontFace*);
98 void loadError(FontFace*);
101 virtual void suspend() OVERRIDE;
102 virtual void resume() OVERRIDE;
103 virtual void stop() OVERRIDE;
105 static PassRefPtrWillBeRawPtr<FontFaceSet> from(Document&);
106 static void didLayout(Document&);
108 void addFontFacesToFontFaceCache(FontFaceCache*, CSSFontSelector*);
111 virtual void trace(Visitor*) OVERRIDE;
115 static PassRefPtrWillBeRawPtr<FontFaceSet> create(Document& document)
117 return adoptRefWillBeNoop(new FontFaceSet(document));
120 class FontLoadHistogram {
122 enum Status { NoWebFonts, HadBlankText, DidNotHaveBlankText, Reported };
123 FontLoadHistogram() : m_status(NoWebFonts), m_count(0), m_recorded(false) { }
124 void incrementCount() { m_count++; }
125 void updateStatus(FontFace*);
134 FontFaceSet(Document&);
136 bool hasLoadedFonts() const { return !m_loadedFonts.isEmpty() || !m_failedFonts.isEmpty(); }
138 bool inActiveDocumentContext() const;
139 void forEachInternal(PassOwnPtr<FontFaceSetForEachCallback>, ScriptValue* thisArg) const;
140 void addToLoadingFonts(PassRefPtrWillBeRawPtr<FontFace>);
141 void removeFromLoadingFonts(PassRefPtrWillBeRawPtr<FontFace>);
142 void fireLoadingEvent();
143 void fireDoneEventIfPossible();
144 bool resolveFontStyle(const String&, Font&);
145 void handlePendingEventsAndPromisesSoon();
146 void handlePendingEventsAndPromises();
147 const WillBeHeapListHashSet<RefPtrWillBeMember<FontFace> >& cssConnectedFontFaceList() const;
148 bool isCSSConnectedFontFace(FontFace*) const;
150 WillBeHeapHashSet<RefPtrWillBeMember<FontFace> > m_loadingFonts;
151 bool m_shouldFireLoadingEvent;
152 Vector<OwnPtr<FontsReadyPromiseResolver> > m_readyResolvers;
153 FontFaceArray m_loadedFonts;
154 FontFaceArray m_failedFonts;
155 WillBeHeapListHashSet<RefPtrWillBeMember<FontFace> > m_nonCSSConnectedFaces;
157 AsyncMethodRunner<FontFaceSet> m_asyncRunner;
159 FontLoadHistogram m_histogram;
164 #endif // FontFaceSet_h