This commit is contained in:
Usman Yahaya Baba 2025-06-03 22:50:21 +02:00 committed by GitHub
commit d3a6479834
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 110 additions and 19 deletions

1
.gitignore vendored
View file

@ -71,3 +71,4 @@ support/macos/Brewfile.lock.json
# direnv
.envrc
tests/wpt/web-platform-tests/

View file

@ -16,7 +16,11 @@ use fonts_traits::StylesheetWebFontLoadFinishedCallback;
use log::{debug, trace};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use malloc_size_of_derive::MallocSizeOf;
use net_traits::request::{Destination, Referrer, RequestBuilder};
use net_traits::policy_container::PolicyContainer;
use net_traits::request::{
CredentialsMode, Destination, InsecureRequestsPolicy, Referrer, RequestBuilder, RequestMode,
ServiceWorkersMode,
};
use net_traits::{CoreResourceThread, FetchResponseMsg, ResourceThreads, fetch_async};
use parking_lot::{Mutex, RwLock};
use servo_arc::Arc as ServoArc;
@ -83,6 +87,14 @@ pub struct FontContext {
have_removed_web_fonts: AtomicBool,
}
#[derive(Clone, Debug)]
pub struct WebFontDocumentContext {
pub policy_container: PolicyContainer,
pub document_url: ServoUrl,
pub has_trustworthy_ancestor_origin: bool,
pub insecure_requests_policy: InsecureRequestsPolicy,
}
impl MallocSizeOf for FontContext {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
let font_cache_size = self
@ -387,6 +399,7 @@ pub(crate) struct WebFontDownloadState {
local_fonts: HashMap<Atom, Option<FontTemplateRef>>,
font_context: Arc<FontContext>,
initiator: WebFontLoadInitiator,
document_context: WebFontDocumentContext,
}
impl WebFontDownloadState {
@ -397,6 +410,7 @@ impl WebFontDownloadState {
initiator: WebFontLoadInitiator,
sources: Vec<Source>,
local_fonts: HashMap<Atom, Option<FontTemplateRef>>,
document_context: WebFontDocumentContext,
) -> WebFontDownloadState {
match initiator {
WebFontLoadInitiator::Stylesheet(ref stylesheet, _) => {
@ -421,6 +435,7 @@ impl WebFontDownloadState {
local_fonts,
font_context,
initiator,
document_context,
}
}
@ -487,6 +502,7 @@ pub trait FontContextWebFontMethods {
guard: &SharedRwLockReadGuard,
device: &Device,
finished_callback: StylesheetWebFontLoadFinishedCallback,
document_context: &WebFontDocumentContext,
) -> usize;
fn load_web_font_for_script(
&self,
@ -494,6 +510,7 @@ pub trait FontContextWebFontMethods {
source_list: SourceList,
descriptors: CSSFontFaceDescriptors,
finished_callback: ScriptWebFontLoadFinishedCallback,
document_context: &WebFontDocumentContext,
);
fn add_template_to_font_context(
&self,
@ -513,6 +530,7 @@ impl FontContextWebFontMethods for Arc<FontContext> {
guard: &SharedRwLockReadGuard,
device: &Device,
finished_callback: StylesheetWebFontLoadFinishedCallback,
document_context: &WebFontDocumentContext,
) -> usize {
let mut number_loading = 0;
for rule in stylesheet.effective_rules(device, guard) {
@ -535,6 +553,7 @@ impl FontContextWebFontMethods for Arc<FontContext> {
font_face.sources(),
css_font_face_descriptors,
completion_handler,
document_context,
);
}
@ -643,9 +662,16 @@ impl FontContextWebFontMethods for Arc<FontContext> {
sources: SourceList,
descriptors: CSSFontFaceDescriptors,
finished_callback: ScriptWebFontLoadFinishedCallback,
document_context: &WebFontDocumentContext,
) {
let completion_handler = WebFontLoadInitiator::Script(finished_callback);
self.start_loading_one_web_font(webview_id, &sources, descriptors, completion_handler);
self.start_loading_one_web_font(
webview_id,
&sources,
descriptors,
completion_handler,
document_context,
);
}
fn add_template_to_font_context(
@ -667,6 +693,7 @@ impl FontContext {
source_list: &SourceList,
css_font_face_descriptors: CSSFontFaceDescriptors,
completion_handler: WebFontLoadInitiator,
document_context: &WebFontDocumentContext,
) {
let sources: Vec<Source> = source_list
.0
@ -708,6 +735,7 @@ impl FontContext {
completion_handler,
sources,
local_fonts,
document_context.clone(),
));
}
@ -792,10 +820,23 @@ impl RemoteWebFontDownloader {
None => return,
};
// FIXME: This shouldn't use NoReferrer, but the current documents url
let request =
RequestBuilder::new(state.webview_id, url.clone().into(), Referrer::NoReferrer)
.destination(Destination::Font);
let document_context = &state.document_context;
let document_origin = document_context.document_url.origin();
let request = RequestBuilder::new(
state.webview_id,
url.clone().into(),
Referrer::ReferrerUrl(document_context.document_url.clone()),
)
.destination(Destination::Font)
.origin(document_origin)
.mode(RequestMode::CorsMode)
.credentials_mode(CredentialsMode::CredentialsSameOrigin)
.service_workers_mode(ServiceWorkersMode::All)
.policy_container(document_context.policy_container.clone())
.insecure_requests_policy(document_context.insecure_requests_policy)
.has_trustworthy_ancestor_origin(document_context.has_trustworthy_ancestor_origin);
let core_resource_thread_clone = state.core_resource_thread.clone();

View file

@ -20,7 +20,7 @@ use embedder_traits::{Theme, UntrustedNodeAddress, ViewportDetails};
use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect};
use euclid::{Point2D, Scale, Size2D, Vector2D};
use fnv::FnvHashMap;
use fonts::{FontContext, FontContextWebFontMethods};
use fonts::{FontContext, FontContextWebFontMethods, WebFontDocumentContext};
use fonts_traits::StylesheetWebFontLoadFinishedCallback;
use fxhash::FxHashMap;
use ipc_channel::ipc::IpcSender;
@ -197,11 +197,16 @@ impl Layout for LayoutThread {
self.epoch.get()
}
fn load_web_fonts_from_stylesheet(&self, stylesheet: ServoArc<Stylesheet>) {
fn load_web_fonts_from_stylesheet(
&self,
stylesheet: ServoArc<Stylesheet>,
document_context: &WebFontDocumentContext,
) {
let guard = stylesheet.shared_lock.read();
self.load_all_web_fonts_from_stylesheet_with_guard(
&DocumentStyleSheet(stylesheet.clone()),
&guard,
document_context,
);
}
@ -213,10 +218,11 @@ impl Layout for LayoutThread {
&mut self,
stylesheet: ServoArc<Stylesheet>,
before_stylesheet: Option<ServoArc<Stylesheet>>,
document_context: &WebFontDocumentContext,
) {
let guard = stylesheet.shared_lock.read();
let stylesheet = DocumentStyleSheet(stylesheet.clone());
self.load_all_web_fonts_from_stylesheet_with_guard(&stylesheet, &guard);
self.load_all_web_fonts_from_stylesheet_with_guard(&stylesheet, &guard, document_context);
match before_stylesheet {
Some(insertion_point) => self.stylist.insert_stylesheet_before(
@ -559,6 +565,7 @@ impl LayoutThread {
&self,
stylesheet: &DocumentStyleSheet,
guard: &SharedRwLockReadGuard,
document_context: &WebFontDocumentContext,
) {
if !stylesheet.is_effective_for_device(self.stylist.device(), guard) {
return;
@ -578,6 +585,7 @@ impl LayoutThread {
guard,
self.stylist.device(),
Arc::new(web_font_finished_loading_callback) as StylesheetWebFontLoadFinishedCallback,
document_context,
);
}
@ -713,7 +721,11 @@ impl LayoutThread {
for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets {
self.stylist
.append_stylesheet(stylesheet.clone(), guards.ua_or_user);
self.load_all_web_fonts_from_stylesheet_with_guard(stylesheet, guards.ua_or_user);
self.load_all_web_fonts_from_stylesheet_with_guard(
stylesheet,
guards.ua_or_user,
&reflow_request.document_context,
);
}
if self.stylist.quirks_mode() != QuirksMode::NoQuirks {
@ -724,6 +736,7 @@ impl LayoutThread {
self.load_all_web_fonts_from_stylesheet_with_guard(
&ua_stylesheets.quirks_mode_stylesheet,
guards.ua_or_user,
&reflow_request.document_context,
);
}
}

View file

@ -35,6 +35,7 @@ use embedder_traits::{
};
use encoding_rs::{Encoding, UTF_8};
use euclid::default::{Point2D, Rect, Size2D};
use fonts::WebFontDocumentContext;
use html5ever::{LocalName, Namespace, QualName, local_name, ns};
use hyper_serde::Serde;
use ipc_channel::ipc;
@ -4922,9 +4923,13 @@ impl Document {
.cloned();
if self.has_browsing_context() {
// Construct WebFontDocumentContext for font fetching
let document_context = self.window.new_document_context();
self.window.layout_mut().add_stylesheet(
sheet.clone(),
insertion_point.as_ref().map(|s| s.sheet.clone()),
&document_context,
);
}
@ -4938,10 +4943,14 @@ impl Document {
}
/// Given a stylesheet, load all web fonts from it in Layout.
pub(crate) fn load_web_fonts_from_stylesheet(&self, stylesheet: Arc<Stylesheet>) {
pub(crate) fn load_web_fonts_from_stylesheet(
&self,
stylesheet: Arc<Stylesheet>,
document_context: &WebFontDocumentContext,
) {
self.window
.layout()
.load_web_fonts_from_stylesheet(stylesheet);
.load_web_fonts_from_stylesheet(stylesheet, document_context);
}
/// Remove a stylesheet owned by `owner` from the list of document sheets.

View file

@ -540,6 +540,9 @@ impl FontFaceMethods<crate::DomTypeHolder> for FontFace {
)
.expect("Parsing shouldn't fail as descriptors are valid by construction");
// Construct a WebFontDocumentContext object for the current document.
let document_context = global.as_window().new_document_context();
// Step 4. Using the value of font faces [[Urls]] slot, attempt to load a font as defined
// in [CSS-FONTS-3], as if it was the value of a @font-face rules src descriptor.
// TODO: FontFaceSet is not supported on Workers yet. The `as_window` call below should be
@ -549,6 +552,7 @@ impl FontFaceMethods<crate::DomTypeHolder> for FontFace {
sources,
(&parsed_font_face_rule).into(),
finished_callback,
&document_context,
);
// Step 3. Set font faces status attribute to "loading", return font faces

View file

@ -38,7 +38,7 @@ use embedder_traits::{
};
use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect};
use euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
use fonts::FontContext;
use fonts::{FontContext, WebFontDocumentContext};
use ipc_channel::ipc::{self, IpcSender};
use js::conversions::ToJSValConvertible;
use js::glue::DumpJSStack;
@ -793,6 +793,15 @@ impl Window {
})
);
}
pub fn new_document_context(&self) -> WebFontDocumentContext {
WebFontDocumentContext {
policy_container: self.global().policy_container(),
document_url: self.global().api_base_url(),
has_trustworthy_ancestor_origin: self.global().has_trustworthy_ancestor_origin(),
insecure_requests_policy: self.global().insecure_requests_policy(),
}
}
}
// https://html.spec.whatwg.org/multipage/#atob
@ -2194,6 +2203,9 @@ impl Window {
let highlighted_dom_node = document.highlighted_dom_node().map(|node| node.to_opaque());
//Construct a new document context for the reflow.
let document_context = self.new_document_context();
// Send new document and relevant styles to layout.
let reflow = ReflowRequest {
reflow_info: Reflow {
@ -2214,6 +2226,7 @@ impl Window {
.take_image_animate_set(),
theme: self.theme.get(),
highlighted_dom_node,
document_context,
};
let Some(results) = self.layout.borrow_mut().reflow(reflow) else {

View file

@ -244,10 +244,12 @@ impl FetchResponseListener for StylesheetContext {
Some(&loader),
win.css_error_reporter(),
);
// Construct a new WebFontDocumentContext for the stylesheet
let document_context = win.new_document_context();
// Layout knows about this stylesheet, because Stylo added it to the Stylist,
// but Layout doesn't know about any new web fonts that it contains.
document.load_web_fonts_from_stylesheet(stylesheet.clone());
document.load_web_fonts_from_stylesheet(stylesheet.clone(), &document_context);
},
}

View file

@ -23,7 +23,7 @@ use constellation_traits::{LoadData, ScrollState};
use embedder_traits::{Theme, UntrustedNodeAddress, ViewportDetails};
use euclid::default::{Point2D, Rect};
use fnv::FnvHashMap;
use fonts::{FontContext, SystemFontServiceProxy};
use fonts::{FontContext, SystemFontServiceProxy, WebFontDocumentContext};
use fxhash::FxHashMap;
use ipc_channel::ipc::IpcSender;
use libc::c_void;
@ -209,7 +209,11 @@ pub trait Layout {
/// Load all fonts from the given stylesheet, returning the number of fonts that
/// need to be loaded.
fn load_web_fonts_from_stylesheet(&self, stylesheet: ServoArc<Stylesheet>);
fn load_web_fonts_from_stylesheet(
&self,
stylesheet: ServoArc<Stylesheet>,
font_context: &WebFontDocumentContext,
);
/// Add a stylesheet to this Layout. This will add it to the Layout's `Stylist` as well as
/// loading all web fonts defined in the stylesheet. The second stylesheet is the insertion
@ -218,6 +222,7 @@ pub trait Layout {
&mut self,
stylesheet: ServoArc<Stylesheet>,
before_stylsheet: Option<ServoArc<Stylesheet>>,
font_context: &WebFontDocumentContext,
);
/// Inform the layout that its ScriptThread is about to exit.
@ -444,6 +449,8 @@ pub struct ReflowRequest {
pub theme: Theme,
/// The node highlighted by the devtools, if any
pub highlighted_dom_node: Option<OpaqueNode>,
/// The current font context.
pub document_context: WebFontDocumentContext,
}
/// A pending restyle.

View file

@ -1,3 +0,0 @@
[internal-stylesheet.html]
[Font from internal stylesheet.]
expected: FAIL

View file

@ -1,3 +1,7 @@
@font-face {
font-family: Ahem;
src: url('/fonts/Ahem.ttf');
}
body {
font-family: 'ahem';
font-size: 100px;