script: Load and rasterize favicons before passing them to the embedder (#38949)

Currently the embedding API only provides the embedder with the URL for
a favicon. This is not great, for multiple reasons:
* Loading the icon should happen according to the fetch spec which is
not easy for the embedder to recreate (consider CSP, timing information
etc)
* Rasterizing a svg favicon is not trivial

With this change, servo fetches and rasterizes the icon to a bitmap
which is then passed to the embedder.

Testing: I'm not sure how I can write tests for the embedding api. I've
tested the correctness manually using
https://github.com/servo/servo/pull/36680.
Prepares for https://github.com/servo/servo/pull/36680

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-08-27 16:28:42 +02:00 committed by GitHub
parent a5d890c13a
commit dcd25072d3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 373 additions and 159 deletions

View file

@ -17,6 +17,7 @@ use std::collections::HashMap;
use std::ffi::c_void;
use std::fmt::{Debug, Display, Error, Formatter};
use std::hash::Hash;
use std::ops::Range;
use std::path::PathBuf;
use std::sync::Arc;
@ -24,7 +25,7 @@ use base::id::{PipelineId, WebViewId};
use crossbeam_channel::Sender;
use euclid::{Point2D, Scale, Size2D};
use http::{HeaderMap, Method, StatusCode};
use ipc_channel::ipc::IpcSender;
use ipc_channel::ipc::{IpcSender, IpcSharedMemory};
use log::warn;
use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf;
@ -358,6 +359,54 @@ impl TraversalId {
}
}
#[derive(Clone, Copy, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum PixelFormat {
/// Luminance channel only
K8,
/// Luminance + alpha
KA8,
/// RGB, 8 bits per channel
RGB8,
/// RGB + alpha, 8 bits per channel
RGBA8,
/// BGR + alpha, 8 bits per channel
BGRA8,
}
/// A raster image buffer.
#[derive(Clone, Deserialize, Serialize)]
pub struct Image {
pub width: u32,
pub height: u32,
pub format: PixelFormat,
/// A shared memory block containing the data of one or more image frames.
data: IpcSharedMemory,
range: Range<usize>,
}
impl Image {
pub fn new(
width: u32,
height: u32,
data: IpcSharedMemory,
range: Range<usize>,
format: PixelFormat,
) -> Self {
Self {
width,
height,
format,
data,
range,
}
}
/// Return the bytes belonging to the first image frame.
pub fn data(&self) -> &[u8] {
&self.data[self.range.clone()]
}
}
#[derive(Deserialize, IntoStaticStr, Serialize)]
pub enum EmbedderMsg {
/// A status message to be displayed by the browser chrome.
@ -411,7 +460,7 @@ pub enum EmbedderMsg {
/// Changes the cursor.
SetCursor(WebViewId, Cursor),
/// A favicon was detected
NewFavicon(WebViewId, ServoUrl),
NewFavicon(WebViewId, Image),
/// The history state has changed.
HistoryChanged(WebViewId, Vec<ServoUrl>, usize),
/// A history traversal operation completed.