fonts: Simplify FontContext in two ways that affect the unit test (#33541)

This is done by no longer forwarding compositor-bound messages through
SystemFontService and making `FontContext` non-generic:

- Messages from the `FontContext` to the `Compositor` no longer need to be
  forwarded through the `SystemFontService`. Instead send these messages
  directly through the script IPC channel to the `Compositor`.

- Instead of adding a mock `SystemFontServiceProxy`, simply implement a
  mock `SystemFontService` on the other side of an IPC channel in the
  `font_context` unit test. This allows making `FontContext`
  non-generic, greatly simplifying the code. The extra complexity moves
  into the unit test.

These changes necessitate adding a new kind of `FontIdentifier`,
`FontIdentifier::Mock` due to the fact that local fonts have
platform-specific identifiers. This avoids having to pretend like the
system font service can have web fonts -- which was always a bit of a
hack.

These two changes are combined into one PR because they both require
extensive and similar chages in the font_context unit test which
dependended on the details of both of them.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2024-09-25 22:15:47 +02:00 committed by GitHub
parent 1daa0b4fc7
commit ac567645a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 482 additions and 425 deletions

View file

@ -9,6 +9,7 @@ use std::fs::{create_dir_all, File};
use std::io::Write;
use std::iter::once;
use std::rc::Rc;
use std::sync::Arc;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use base::cross_process_instant::CrossProcessInstant;
@ -23,7 +24,7 @@ use embedder_traits::Cursor;
use euclid::{Point2D, Rect, Scale, Transform3D, Vector2D};
use fnv::{FnvHashMap, FnvHashSet};
use image::{DynamicImage, ImageFormat};
use ipc_channel::ipc;
use ipc_channel::ipc::{self, IpcSharedMemory};
use libc::c_void;
use log::{debug, error, info, trace, warn};
use pixels::{CorsStatus, Image, PixelFormat};
@ -43,9 +44,10 @@ use webrender_api::units::{
};
use webrender_api::{
self, BuiltDisplayList, DirtyRect, DisplayListPayload, DocumentId, Epoch as WebRenderEpoch,
ExternalScrollId, FontInstanceOptions, HitTestFlags, PipelineId as WebRenderPipelineId,
PropertyBinding, ReferenceFrameKind, RenderReasons, SampledScrollOffset, ScrollLocation,
SpaceAndClipInfo, SpatialId, SpatialTreeItemKey, TransformStyle,
ExternalScrollId, FontInstanceFlags, FontInstanceKey, FontInstanceOptions, FontKey,
HitTestFlags, PipelineId as WebRenderPipelineId, PropertyBinding, ReferenceFrameKind,
RenderReasons, SampledScrollOffset, ScrollLocation, SpaceAndClipInfo, SpatialId,
SpatialTreeItemKey, TransformStyle,
};
use webrender_traits::display_list::{HitTestInfo, ScrollTree};
use webrender_traits::{
@ -841,6 +843,23 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
.send_transaction(self.webrender_document, txn);
},
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::AddFont(
data,
index,
key_sender,
)) => {
let _ = key_sender.send(self.add_font(index, data));
},
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::AddFontInstance(
font_key,
size,
flags,
sender,
)) => {
let _ = sender.send(self.add_font_instance(font_key, size, flags));
},
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::RemoveFonts(
keys,
instance_keys,
@ -865,47 +884,24 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
.send_transaction(self.webrender_document, txn);
},
ForwardedToCompositorMsg::Font(FontToCompositorMsg::AddFontInstance(
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::AddFontInstance(
font_key,
size,
flags,
sender,
)) => {
let key = self.webrender_api.generate_font_instance_key();
let mut transaction = Transaction::new();
let font_instance_options = FontInstanceOptions {
flags,
..Default::default()
};
transaction.add_font_instance(
key,
font_key,
size,
Some(font_instance_options),
None,
Vec::new(),
);
self.webrender_api
.send_transaction(self.webrender_document, transaction);
let _ = sender.send(key);
let _ = sender.send(self.add_font_instance(font_key, size, flags));
},
ForwardedToCompositorMsg::Font(FontToCompositorMsg::AddFont(
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::AddFont(
key_sender,
index,
data,
)) => {
let font_key = self.webrender_api.generate_font_key();
let mut transaction = Transaction::new();
transaction.add_raw_font(font_key, (**data).into(), index);
self.webrender_api
.send_transaction(self.webrender_document, transaction);
let _ = key_sender.send(font_key);
let _ = key_sender.send(self.add_font(index, data));
},
ForwardedToCompositorMsg::Font(FontToCompositorMsg::AddSystemFont(
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::AddSystemFont(
key_sender,
native_handle,
)) => {
@ -960,16 +956,26 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
self.remove_pipeline_root_layer(pipeline_id);
let _ = sender.send(());
},
CompositorMsg::Forwarded(ForwardedToCompositorMsg::Font(
CompositorMsg::Forwarded(ForwardedToCompositorMsg::SystemFontService(
FontToCompositorMsg::AddFontInstance(_, _, _, sender),
)) => {
let _ = sender.send(self.webrender_api.generate_font_instance_key());
},
CompositorMsg::Forwarded(ForwardedToCompositorMsg::Font(
CompositorMsg::Forwarded(ForwardedToCompositorMsg::Layout(
ScriptToCompositorMsg::AddFontInstance(_, _, _, sender),
)) => {
let _ = sender.send(self.webrender_api.generate_font_instance_key());
},
CompositorMsg::Forwarded(ForwardedToCompositorMsg::SystemFontService(
FontToCompositorMsg::AddFont(sender, _, _),
)) => {
let _ = sender.send(self.webrender_api.generate_font_key());
},
CompositorMsg::Forwarded(ForwardedToCompositorMsg::Layout(
ScriptToCompositorMsg::AddFont(_, _, sender),
)) => {
let _ = sender.send(self.webrender_api.generate_font_key());
},
CompositorMsg::Forwarded(ForwardedToCompositorMsg::Canvas(
CanvasToCompositorMsg::GenerateKey(sender),
)) => {
@ -2518,4 +2524,40 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
eprintln!("Unable to write servo version for WebRender Capture: {error:?}");
}
}
fn add_font_instance(
&mut self,
font_key: FontKey,
size: f32,
flags: FontInstanceFlags,
) -> FontInstanceKey {
let instance_key = self.webrender_api.generate_font_instance_key();
let mut transaction = Transaction::new();
let font_instance_options = FontInstanceOptions {
flags,
..Default::default()
};
transaction.add_font_instance(
instance_key,
font_key,
size,
Some(font_instance_options),
None,
Vec::new(),
);
self.webrender_api
.send_transaction(self.webrender_document, transaction);
instance_key
}
fn add_font(&mut self, index: u32, data: Arc<IpcSharedMemory>) -> FontKey {
let font_key = self.webrender_api.generate_font_key();
let mut transaction = Transaction::new();
transaction.add_raw_font(font_key, (**data).into(), index);
self.webrender_api
.send_transaction(self.webrender_document, transaction);
font_key
}
}