1 /* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 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. 12 * 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 23 * DAMAGE. 24 */ 25 26 #ifndef FontFaceSet_h 27 #define FontFaceSet_h 28 29 #include "bindings/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" 40 41 // Mac OS X 10.6 SDK defines check() macro that interfares with our check() method 42 #ifdef check 43 #undef check 44 #endif 45 46 namespace WebCore { 47 48 class CSSFontFace; 49 class CSSFontFaceSource; 50 class CSSFontSelector; 51 class Dictionary; 52 class Document; 53 class ExceptionState; 54 class Font; 55 class FontFaceCache; 56 class FontResource; 57 class FontsReadyPromiseResolver; 58 class ExecutionContext; 59 60 #if ENABLE(OILPAN) 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; 64 #else 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; 68 #endif 69 public: 70 virtual ~FontFaceSet(); 71 72 DEFINE_ATTRIBUTE_EVENT_LISTENER(loading); 73 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingdone); 74 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingerror); 75 76 bool check(const String& font, const String& text, ExceptionState&); 77 ScriptPromise load(ScriptState*, const String& font, const String& text); 78 ScriptPromise ready(ScriptState*); 79 80 void add(FontFace*, ExceptionState&); 81 void clear(); 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; 86 87 unsigned long size() const; 88 AtomicString status() const; 89 90 virtual ExecutionContext* executionContext() const OVERRIDE; 91 virtual const AtomicString& interfaceName() const OVERRIDE; 92 93 Document* document() const; 94 95 void didLayout(); 96 void beginFontLoading(FontFace*); 97 void fontLoaded(FontFace*); 98 void loadError(FontFace*); 99 100 // ActiveDOMObject 101 virtual void suspend() OVERRIDE; 102 virtual void resume() OVERRIDE; 103 virtual void stop() OVERRIDE; 104 105 static PassRefPtrWillBeRawPtr<FontFaceSet> from(Document&); 106 static void didLayout(Document&); 107 108 void addFontFacesToFontFaceCache(FontFaceCache*, CSSFontSelector*); 109 110 #if ENABLE(OILPAN) 111 virtual void trace(Visitor*) OVERRIDE; 112 #endif 113 114 private: 115 static PassRefPtrWillBeRawPtr<FontFaceSet> create(Document& document) 116 { 117 return adoptRefWillBeNoop(new FontFaceSet(document)); 118 } 119 120 class FontLoadHistogram { 121 public: 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*); 126 void record(); 127 128 private: 129 Status m_status; 130 int m_count; 131 bool m_recorded; 132 }; 133 134 FontFaceSet(Document&); 135 136 bool hasLoadedFonts() const { return !m_loadedFonts.isEmpty() || !m_failedFonts.isEmpty(); } 137 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 ListHashSet<RefPtrWillBeMember<FontFace> >& cssConnectedFontFaceList() const; 148 bool isCSSConnectedFontFace(FontFace*) const; 149 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 // FIXME: Oilpan: replace with a HeapListHashSet or HeapLinkedHashSet. 156 ListHashSet<RefPtrWillBeMember<FontFace> > m_nonCSSConnectedFaces; 157 158 AsyncMethodRunner<FontFaceSet> m_asyncRunner; 159 160 FontLoadHistogram m_histogram; 161 }; 162 163 } // namespace WebCore 164 165 #endif // FontFaceSet_h 166