script/dom/
fontfaceset.rs1use std::rc::Rc;
6
7use dom_struct::dom_struct;
8use fonts::FontContextWebFontMethods;
9use js::rust::HandleObject;
10
11use super::bindings::reflector::DomGlobal;
12use super::types::Window;
13use crate::dom::bindings::codegen::Bindings::FontFaceSetBinding::FontFaceSetMethods;
14use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
15use crate::dom::bindings::refcounted::TrustedPromise;
16use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
17use crate::dom::bindings::root::DomRoot;
18use crate::dom::bindings::str::DOMString;
19use crate::dom::eventtarget::EventTarget;
20use crate::dom::fontface::FontFace;
21use crate::dom::globalscope::GlobalScope;
22use crate::dom::promise::Promise;
23use crate::script_runtime::CanGc;
24
25#[dom_struct]
27pub(crate) struct FontFaceSet {
28 target: EventTarget,
29
30 #[ignore_malloc_size_of = "Rc"]
32 promise: Rc<Promise>,
33}
34
35impl FontFaceSet {
36 fn new_inherited(global: &GlobalScope, can_gc: CanGc) -> Self {
37 FontFaceSet {
38 target: EventTarget::new_inherited(),
39 promise: Promise::new(global, can_gc),
40 }
41 }
42
43 pub(crate) fn new(
44 global: &GlobalScope,
45 proto: Option<HandleObject>,
46 can_gc: CanGc,
47 ) -> DomRoot<Self> {
48 reflect_dom_object_with_proto(
49 Box::new(FontFaceSet::new_inherited(global, can_gc)),
50 global,
51 proto,
52 can_gc,
53 )
54 }
55
56 pub(super) fn handle_font_face_status_changed(&self, font_face: &FontFace) {
57 if font_face.loaded() {
58 let Some(window) = DomRoot::downcast::<Window>(self.global()) else {
59 return;
60 };
61
62 let (family_name, template) = font_face
63 .template()
64 .expect("A loaded web font should have a template");
65 window
66 .font_context()
67 .add_template_to_font_context(family_name, template);
68 window.Document().dirty_all_nodes();
69 }
70 }
71
72 pub(crate) fn fulfill_ready_promise_if_needed(&self, can_gc: CanGc) -> bool {
74 if self.promise.is_fulfilled() {
75 return false;
76 }
77 self.promise.resolve_native(self, can_gc);
78 true
79 }
80
81 pub(crate) fn waiting_to_fullfill_promise(&self) -> bool {
82 !self.promise.is_fulfilled()
83 }
84}
85
86impl FontFaceSetMethods<crate::DomTypeHolder> for FontFaceSet {
87 fn Ready(&self) -> Rc<Promise> {
89 self.promise.clone()
90 }
91
92 fn Add(&self, font_face: &FontFace) -> DomRoot<FontFaceSet> {
94 font_face.set_associated_font_face_set(self);
95 self.handle_font_face_status_changed(font_face);
96 DomRoot::from_ref(self)
97 }
98
99 fn Load(&self, _font: DOMString, _text: DOMString, can_gc: CanGc) -> Rc<Promise> {
101 let promise = Promise::new(&self.global(), can_gc);
104
105 let trusted = TrustedPromise::new(promise.clone());
111 self.global()
113 .task_manager()
114 .font_loading_task_source()
115 .queue(task!(resolve_font_face_set_load_task: move || {
116 let promise = trusted.root();
117
118 let matched_fonts = Vec::<&FontFace>::new();
124 promise.resolve_native(&matched_fonts, CanGc::note());
125 }));
126
127 promise
129 }
130}