1 2 // Copyright 2017 The Chromium Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 6 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_FONT_FACE_SET_H_ 7 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_FONT_FACE_SET_H_ 8 9 #include "base/macros.h" 10 #include "third_party/blink/public/platform/task_type.h" 11 #include "third_party/blink/renderer/bindings/core/v8/iterable.h" 12 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" 13 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" 14 #include "third_party/blink/renderer/core/css/font_face.h" 15 #include "third_party/blink/renderer/core/dom/events/event_listener.h" 16 #include "third_party/blink/renderer/core/dom/events/event_target.h" 17 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" 18 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" 19 #include "third_party/blink/renderer/platform/fonts/font_selector.h" 20 21 // Mac OS X 10.6 SDK defines check() macro that interferes with our check() 22 // method 23 #ifdef check 24 #undef check 25 #endif 26 27 namespace blink { 28 29 class FontFaceCache; 30 31 using FontFaceSetIterable = SetlikeIterable<Member<FontFace>>; 32 33 class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData, 34 public ExecutionContextClient, 35 public FontFaceSetIterable, 36 public FontFace::LoadFontCallback { 37 DEFINE_WRAPPERTYPEINFO(); 38 39 public: FontFaceSet(ExecutionContext & context)40 FontFaceSet(ExecutionContext& context) 41 : ExecutionContextClient(&context), 42 ready_(MakeGarbageCollected<ReadyProperty>(GetExecutionContext())) {} 43 ~FontFaceSet() override = default; 44 45 DEFINE_ATTRIBUTE_EVENT_LISTENER(loading, kLoading) 46 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingdone, kLoadingdone) 47 DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingerror, kLoadingerror) 48 49 bool check(const String& font, const String& text, ExceptionState&); 50 ScriptPromise load(ScriptState*, const String& font, const String& text); 51 virtual ScriptPromise ready(ScriptState*) = 0; 52 GetExecutionContext()53 ExecutionContext* GetExecutionContext() const override { 54 return ExecutionContextClient::GetExecutionContext(); 55 } 56 InterfaceName()57 const AtomicString& InterfaceName() const override { 58 return event_target_names::kFontFaceSet; 59 } 60 61 FontFaceSet* addForBinding(ScriptState*, FontFace*, ExceptionState&); 62 void clearForBinding(ScriptState*, ExceptionState&); 63 bool deleteForBinding(ScriptState*, FontFace*, ExceptionState&); 64 bool hasForBinding(ScriptState*, FontFace*, ExceptionState&) const; 65 66 void AddFontFacesToFontFaceCache(FontFaceCache*); 67 68 wtf_size_t size() const; 69 virtual AtomicString status() const = 0; 70 71 void Trace(Visitor*) override; 72 73 protected: 74 static const int kDefaultFontSize; 75 static const char kDefaultFontFamily[]; 76 77 virtual bool ResolveFontStyle(const String&, Font&) = 0; 78 virtual bool InActiveContext() const = 0; 79 virtual FontSelector* GetFontSelector() const = 0; 80 virtual const HeapLinkedHashSet<Member<FontFace>>& CSSConnectedFontFaceList() 81 const = 0; IsCSSConnectedFontFace(FontFace * font_face)82 bool IsCSSConnectedFontFace(FontFace* font_face) const { 83 return CSSConnectedFontFaceList().Contains(font_face); 84 } 85 86 virtual void FireDoneEventIfPossible() = 0; 87 88 void AddToLoadingFonts(FontFace*); 89 void RemoveFromLoadingFonts(FontFace*); 90 void HandlePendingEventsAndPromisesSoon(); 91 bool ShouldSignalReady() const; 92 void FireDoneEvent(); 93 94 using ReadyProperty = ScriptPromiseProperty<Member<FontFaceSet>, 95 Member<DOMException>>; 96 97 bool is_loading_ = false; 98 bool should_fire_loading_event_ = false; 99 bool pending_task_queued_ = false; 100 HeapLinkedHashSet<Member<FontFace>> non_css_connected_faces_; 101 HeapHashSet<Member<FontFace>> loading_fonts_; 102 FontFaceArray loaded_fonts_; 103 FontFaceArray failed_fonts_; 104 Member<ReadyProperty> ready_; 105 106 class IterationSource final : public FontFaceSetIterable::IterationSource { 107 public: IterationSource(const HeapVector<Member<FontFace>> & font_faces)108 explicit IterationSource(const HeapVector<Member<FontFace>>& font_faces) 109 : index_(0), font_faces_(font_faces) {} 110 bool Next(ScriptState*, 111 Member<FontFace>&, 112 Member<FontFace>&, 113 ExceptionState&) override; 114 Trace(Visitor * visitor)115 void Trace(Visitor* visitor) override { 116 visitor->Trace(font_faces_); 117 FontFaceSetIterable::IterationSource::Trace(visitor); 118 } 119 120 private: 121 wtf_size_t index_; 122 HeapVector<Member<FontFace>> font_faces_; 123 }; 124 125 class LoadFontPromiseResolver final 126 : public GarbageCollected<LoadFontPromiseResolver>, 127 public FontFace::LoadFontCallback { 128 USING_GARBAGE_COLLECTED_MIXIN(LoadFontPromiseResolver); 129 130 public: LoadFontPromiseResolver(FontFaceArray faces,ScriptState * script_state)131 LoadFontPromiseResolver(FontFaceArray faces, ScriptState* script_state) 132 : num_loading_(faces.size()), 133 error_occured_(false), 134 resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)) { 135 font_faces_.swap(faces); 136 } 137 138 void LoadFonts(); Promise()139 ScriptPromise Promise() { return resolver_->Promise(); } 140 141 void NotifyLoaded(FontFace*) override; 142 void NotifyError(FontFace*) override; 143 144 void Trace(Visitor*) override; 145 146 private: 147 HeapVector<Member<FontFace>> font_faces_; 148 int num_loading_; 149 bool error_occured_; 150 Member<ScriptPromiseResolver> resolver_; 151 }; 152 153 private: 154 FontFaceSetIterable::IterationSource* StartIteration( 155 ScriptState*, 156 ExceptionState&) override; 157 158 void HandlePendingEventsAndPromises(); 159 void FireLoadingEvent(); 160 DISALLOW_COPY_AND_ASSIGN(FontFaceSet); 161 }; 162 163 } // namespace blink 164 165 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_FONT_FACE_SET_H_ 166