script: Move the FontContext to Window (#34845)

This will allow using layout's `FontContext` in `Window` letting script
manage font selection and download.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
Martin Robinson 2025-01-07 05:44:31 +01:00 committed by GitHub
parent fe8a22b72c
commit 7142a96d36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 61 additions and 45 deletions

View file

@ -28,6 +28,7 @@ use dom_struct::dom_struct;
use embedder_traits::{EmbedderMsg, PromptDefinition, PromptOrigin, PromptResult};
use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect};
use euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
use fonts::FontContext;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use js::conversions::ToJSValConvertible;
@ -207,6 +208,11 @@ pub struct Window {
#[no_trace]
#[ignore_malloc_size_of = "TODO: Add MallocSizeOf support to layout"]
layout: RefCell<Box<dyn Layout>>,
/// A [`FontContext`] which is used to store and match against fonts for this `Window` and to
/// trigger the download of web fonts.
#[no_trace]
#[conditional_malloc_size_of]
font_context: Arc<FontContext>,
navigator: MutNullableDom<Navigator>,
#[ignore_malloc_size_of = "Arc"]
#[no_trace]
@ -1942,9 +1948,8 @@ impl Window {
/// should happen as part of the HTML event loop via *update the rendering*. Currerntly, the
/// only exceptions are script queries and scroll requests.
pub(crate) fn reflow(&self, reflow_goal: ReflowGoal, can_gc: CanGc) -> bool {
// Fetch the pending web fonts before layout, in case a font loads during
// the layout.
let pending_web_fonts = self.layout.borrow().waiting_for_web_fonts_to_load();
// Count the pending web fonts before layout, in case a font loads during the layout.
let waiting_for_web_fonts_to_load = self.font_context.web_fonts_still_loading() != 0;
self.Document().ensure_safe_to_run_script_or_layout();
@ -1988,7 +1993,7 @@ impl Window {
// Thus, we are queueing promise resolution here. This reflow should have been triggered by
// a "rendering opportunity" in `ScriptThread::handle_web_font_loaded, which should also
// make sure a microtask checkpoint happens, triggering the promise callback.
if !pending_web_fonts && is_ready_state_complete {
if !waiting_for_web_fonts_to_load && is_ready_state_complete {
font_face_set.fulfill_ready_promise_if_needed();
}
@ -2017,7 +2022,7 @@ impl Window {
is_ready_state_complete &&
!reftest_wait &&
!pending_images &&
!pending_web_fonts
!waiting_for_web_fonts_to_load
{
debug!(
"{:?}: Sending DocumentState::Idle to Constellation",
@ -2674,6 +2679,7 @@ impl Window {
runtime: Rc<Runtime>,
script_chan: MainThreadScriptChan,
layout: Box<dyn Layout>,
font_context: Arc<FontContext>,
image_cache_chan: Sender<ImageCacheMsg>,
image_cache: Arc<dyn ImageCache>,
resource_threads: ResourceThreads,
@ -2737,6 +2743,7 @@ impl Window {
),
script_chan,
layout: RefCell::new(layout),
font_context,
image_cache_chan,
image_cache,
navigator: Default::default(),

View file

@ -47,7 +47,7 @@ use devtools_traits::{
};
use embedder_traits::EmbedderMsg;
use euclid::default::{Point2D, Rect};
use fonts::SystemFontServiceProxy;
use fonts::{FontContext, SystemFontServiceProxy};
use headers::{HeaderMapExt, LastModified, ReferrerPolicy as ReferrerPolicyHeader};
use html5ever::{local_name, namespace_url, ns};
use hyper_serde::Serde;
@ -3142,6 +3142,12 @@ impl ScriptThread {
incomplete.navigation_start,
);
let font_context = Arc::new(FontContext::new(
self.system_font_service.clone(),
self.compositor_api.clone(),
self.resource_threads.clone(),
));
let layout_config = LayoutConfig {
id: incomplete.pipeline_id,
url: final_url.clone(),
@ -3149,8 +3155,7 @@ impl ScriptThread {
constellation_chan: self.senders.layout_to_constellation_ipc_sender.clone(),
script_chan: self.senders.constellation_sender.clone(),
image_cache: self.image_cache.clone(),
system_font_service: self.system_font_service.clone(),
resource_threads: self.resource_threads.clone(),
font_context: font_context.clone(),
time_profiler_chan: self.senders.time_profiler_sender.clone(),
compositor_api: self.compositor_api.clone(),
paint_time_metrics,
@ -3162,6 +3167,7 @@ impl ScriptThread {
self.js_runtime.clone(),
self.senders.self_sender.clone(),
self.layout_factory.create(layout_config),
font_context,
self.senders.image_cache_sender.clone(),
self.image_cache.clone(),
self.resource_threads.clone(),