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