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