canvas: Use strum::{Display, EnumString} for canvas enums (#37670)

This makes it easier to add variants, I also added some spec links and
reordered enum variants to match the spec.

Testing: Just refactor, but the code is covered by WPT tests.

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
sagudev 2025-06-24 15:03:41 +02:00 committed by GitHub
parent 2dc62c504f
commit ef7be66c56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 82 additions and 202 deletions

1
Cargo.lock generated
View file

@ -825,6 +825,7 @@ dependencies = [
"serde_bytes", "serde_bytes",
"servo_config", "servo_config",
"servo_malloc_size_of", "servo_malloc_size_of",
"strum",
"stylo", "stylo",
"webrender_api", "webrender_api",
"webxr-api", "webxr-api",

View file

@ -894,14 +894,14 @@ impl ToRaqoteStyle for CompositionStyle {
fn to_raqote_style(self) -> Self::Target { fn to_raqote_style(self) -> Self::Target {
match self { match self {
CompositionStyle::SrcIn => raqote::BlendMode::SrcIn, CompositionStyle::SourceIn => raqote::BlendMode::SrcIn,
CompositionStyle::SrcOut => raqote::BlendMode::SrcOut, CompositionStyle::SourceOut => raqote::BlendMode::SrcOut,
CompositionStyle::SrcOver => raqote::BlendMode::SrcOver, CompositionStyle::SourceOver => raqote::BlendMode::SrcOver,
CompositionStyle::SrcAtop => raqote::BlendMode::SrcAtop, CompositionStyle::SourceAtop => raqote::BlendMode::SrcAtop,
CompositionStyle::DestIn => raqote::BlendMode::DstIn, CompositionStyle::DestinationIn => raqote::BlendMode::DstIn,
CompositionStyle::DestOut => raqote::BlendMode::DstOut, CompositionStyle::DestinationOut => raqote::BlendMode::DstOut,
CompositionStyle::DestOver => raqote::BlendMode::DstOver, CompositionStyle::DestinationOver => raqote::BlendMode::DstOver,
CompositionStyle::DestAtop => raqote::BlendMode::DstAtop, CompositionStyle::DestinationAtop => raqote::BlendMode::DstAtop,
CompositionStyle::Copy => raqote::BlendMode::Src, CompositionStyle::Copy => raqote::BlendMode::Src,
CompositionStyle::Lighter => raqote::BlendMode::Add, CompositionStyle::Lighter => raqote::BlendMode::Add,
CompositionStyle::Xor => raqote::BlendMode::Xor, CompositionStyle::Xor => raqote::BlendMode::Xor,

View file

@ -1197,8 +1197,8 @@ impl CanvasState {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalcompositeoperation // https://html.spec.whatwg.org/multipage/#dom-context-2d-globalcompositeoperation
pub(crate) fn global_composite_operation(&self) -> DOMString { pub(crate) fn global_composite_operation(&self) -> DOMString {
match self.state.borrow().global_composition { match self.state.borrow().global_composition {
CompositionOrBlending::Composition(op) => DOMString::from(op.to_str()), CompositionOrBlending::Composition(op) => DOMString::from(op.to_string()),
CompositionOrBlending::Blending(op) => DOMString::from(op.to_str()), CompositionOrBlending::Blending(op) => DOMString::from(op.to_string()),
} }
} }

View file

@ -26,6 +26,7 @@ pixels = { path = "../../pixels" }
serde = { workspace = true } serde = { workspace = true }
serde_bytes = { workspace = true } serde_bytes = { workspace = true }
servo_config = { path = "../../config" } servo_config = { path = "../../config" }
strum = { workspace = true }
stylo = { workspace = true } stylo = { workspace = true }
webrender_api = { workspace = true } webrender_api = { workspace = true }
webxr-api = { workspace = true, features = ["ipc"] } webxr-api = { workspace = true, features = ["ipc"] }

View file

@ -11,6 +11,7 @@ use malloc_size_of_derive::MallocSizeOf;
use pixels::IpcSnapshot; use pixels::IpcSnapshot;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf; use serde_bytes::ByteBuf;
use strum::{Display, EnumString};
use style::color::AbsoluteColor; use style::color::AbsoluteColor;
use style::properties::style_structs::Font as FontStyleStruct; use style::properties::style_structs::Font as FontStyleStruct;
@ -239,47 +240,26 @@ pub enum FillOrStrokeStyle {
Surface(SurfaceStyle), Surface(SurfaceStyle),
} }
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] #[derive(
Clone, Copy, Debug, Display, Deserialize, EnumString, MallocSizeOf, PartialEq, Serialize,
)]
pub enum LineCapStyle { pub enum LineCapStyle {
Butt = 0, Butt = 0,
Round = 1, Round = 1,
Square = 2, Square = 2,
} }
impl FromStr for LineCapStyle { #[derive(
type Err = (); Clone, Copy, Debug, Deserialize, Display, EnumString, MallocSizeOf, PartialEq, Serialize,
)]
fn from_str(string: &str) -> Result<LineCapStyle, ()> {
match string {
"butt" => Ok(LineCapStyle::Butt),
"round" => Ok(LineCapStyle::Round),
"square" => Ok(LineCapStyle::Square),
_ => Err(()),
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum LineJoinStyle { pub enum LineJoinStyle {
Round = 0, Round = 0,
Bevel = 1, Bevel = 1,
Miter = 2, Miter = 2,
} }
impl FromStr for LineJoinStyle { #[derive(Clone, Copy, Debug, Deserialize, Display, EnumString, PartialEq, Serialize)]
type Err = (); #[strum(serialize_all = "kebab-case")]
fn from_str(string: &str) -> Result<LineJoinStyle, ()> {
match string {
"round" => Ok(LineJoinStyle::Round),
"bevel" => Ok(LineJoinStyle::Bevel),
"miter" => Ok(LineJoinStyle::Miter),
_ => Err(()),
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum RepetitionStyle { pub enum RepetitionStyle {
Repeat, Repeat,
RepeatX, RepeatX,
@ -287,79 +267,35 @@ pub enum RepetitionStyle {
NoRepeat, NoRepeat,
} }
impl FromStr for RepetitionStyle { /// <https://drafts.fxtf.org/compositing/#compositemode>
type Err = (); #[derive(
Clone, Copy, Debug, Deserialize, Display, EnumString, MallocSizeOf, PartialEq, Serialize,
fn from_str(string: &str) -> Result<RepetitionStyle, ()> { )]
match string { #[strum(serialize_all = "kebab-case")]
"repeat" => Ok(RepetitionStyle::Repeat),
"repeat-x" => Ok(RepetitionStyle::RepeatX),
"repeat-y" => Ok(RepetitionStyle::RepeatY),
"no-repeat" => Ok(RepetitionStyle::NoRepeat),
_ => Err(()),
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum CompositionStyle { pub enum CompositionStyle {
SrcIn,
SrcOut,
SrcOver,
SrcAtop,
DestIn,
DestOut,
DestOver,
DestAtop,
Copy,
Lighter,
Xor,
Clear, Clear,
Copy,
SourceOver,
DestinationOver,
SourceIn,
DestinationIn,
SourceOut,
DestinationOut,
SourceAtop,
DestinationAtop,
Xor,
Lighter,
// PlusDarker,
// PlusLighter,
} }
impl FromStr for CompositionStyle { /// <https://drafts.fxtf.org/compositing/#ltblendmodegt>
type Err = (); #[derive(
Clone, Copy, Debug, Deserialize, Display, EnumString, MallocSizeOf, PartialEq, Serialize,
fn from_str(string: &str) -> Result<CompositionStyle, ()> { )]
match string { #[strum(serialize_all = "kebab-case")]
"source-in" => Ok(CompositionStyle::SrcIn),
"source-out" => Ok(CompositionStyle::SrcOut),
"source-over" => Ok(CompositionStyle::SrcOver),
"source-atop" => Ok(CompositionStyle::SrcAtop),
"destination-in" => Ok(CompositionStyle::DestIn),
"destination-out" => Ok(CompositionStyle::DestOut),
"destination-over" => Ok(CompositionStyle::DestOver),
"destination-atop" => Ok(CompositionStyle::DestAtop),
"copy" => Ok(CompositionStyle::Copy),
"lighter" => Ok(CompositionStyle::Lighter),
"xor" => Ok(CompositionStyle::Xor),
"clear" => Ok(CompositionStyle::Clear),
_ => Err(()),
}
}
}
impl CompositionStyle {
pub fn to_str(&self) -> &str {
match *self {
CompositionStyle::SrcIn => "source-in",
CompositionStyle::SrcOut => "source-out",
CompositionStyle::SrcOver => "source-over",
CompositionStyle::SrcAtop => "source-atop",
CompositionStyle::DestIn => "destination-in",
CompositionStyle::DestOut => "destination-out",
CompositionStyle::DestOver => "destination-over",
CompositionStyle::DestAtop => "destination-atop",
CompositionStyle::Copy => "copy",
CompositionStyle::Lighter => "lighter",
CompositionStyle::Xor => "xor",
CompositionStyle::Clear => "clear",
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum BlendingStyle { pub enum BlendingStyle {
// Normal,
Multiply, Multiply,
Screen, Screen,
Overlay, Overlay,
@ -377,53 +313,6 @@ pub enum BlendingStyle {
Luminosity, Luminosity,
} }
impl FromStr for BlendingStyle {
type Err = ();
fn from_str(string: &str) -> Result<BlendingStyle, ()> {
match string {
"multiply" => Ok(BlendingStyle::Multiply),
"screen" => Ok(BlendingStyle::Screen),
"overlay" => Ok(BlendingStyle::Overlay),
"darken" => Ok(BlendingStyle::Darken),
"lighten" => Ok(BlendingStyle::Lighten),
"color-dodge" => Ok(BlendingStyle::ColorDodge),
"color-burn" => Ok(BlendingStyle::ColorBurn),
"hard-light" => Ok(BlendingStyle::HardLight),
"soft-light" => Ok(BlendingStyle::SoftLight),
"difference" => Ok(BlendingStyle::Difference),
"exclusion" => Ok(BlendingStyle::Exclusion),
"hue" => Ok(BlendingStyle::Hue),
"saturation" => Ok(BlendingStyle::Saturation),
"color" => Ok(BlendingStyle::Color),
"luminosity" => Ok(BlendingStyle::Luminosity),
_ => Err(()),
}
}
}
impl BlendingStyle {
pub fn to_str(&self) -> &str {
match *self {
BlendingStyle::Multiply => "multiply",
BlendingStyle::Screen => "screen",
BlendingStyle::Overlay => "overlay",
BlendingStyle::Darken => "darken",
BlendingStyle::Lighten => "lighten",
BlendingStyle::ColorDodge => "color-dodge",
BlendingStyle::ColorBurn => "color-burn",
BlendingStyle::HardLight => "hard-light",
BlendingStyle::SoftLight => "soft-light",
BlendingStyle::Difference => "difference",
BlendingStyle::Exclusion => "exclusion",
BlendingStyle::Hue => "hue",
BlendingStyle::Saturation => "saturation",
BlendingStyle::Color => "color",
BlendingStyle::Luminosity => "luminosity",
}
}
}
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] #[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum CompositionOrBlending { pub enum CompositionOrBlending {
Composition(CompositionStyle), Composition(CompositionStyle),
@ -432,7 +321,7 @@ pub enum CompositionOrBlending {
impl Default for CompositionOrBlending { impl Default for CompositionOrBlending {
fn default() -> CompositionOrBlending { fn default() -> CompositionOrBlending {
CompositionOrBlending::Composition(CompositionStyle::SrcOver) CompositionOrBlending::Composition(CompositionStyle::SourceOver)
} }
} }
@ -452,7 +341,18 @@ impl FromStr for CompositionOrBlending {
} }
} }
#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)] #[derive(
Clone,
Copy,
Debug,
Default,
Deserialize,
Display,
EnumString,
MallocSizeOf,
PartialEq,
Serialize,
)]
pub enum TextAlign { pub enum TextAlign {
#[default] #[default]
Start, Start,
@ -462,22 +362,18 @@ pub enum TextAlign {
Center, Center,
} }
impl FromStr for TextAlign { #[derive(
type Err = (); Clone,
Copy,
fn from_str(string: &str) -> Result<TextAlign, ()> { Debug,
match string { Default,
"start" => Ok(TextAlign::Start), Deserialize,
"end" => Ok(TextAlign::End), Display,
"left" => Ok(TextAlign::Left), EnumString,
"right" => Ok(TextAlign::Right), MallocSizeOf,
"center" => Ok(TextAlign::Center), PartialEq,
_ => Err(()), Serialize,
} )]
}
}
#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum TextBaseline { pub enum TextBaseline {
Top, Top,
Hanging, Hanging,
@ -488,23 +384,18 @@ pub enum TextBaseline {
Bottom, Bottom,
} }
impl FromStr for TextBaseline { #[derive(
type Err = (); Clone,
Copy,
fn from_str(string: &str) -> Result<TextBaseline, ()> { Debug,
match string { Default,
"top" => Ok(TextBaseline::Top), Deserialize,
"hanging" => Ok(TextBaseline::Hanging), Display,
"middle" => Ok(TextBaseline::Middle), EnumString,
"alphabetic" => Ok(TextBaseline::Alphabetic), MallocSizeOf,
"ideographic" => Ok(TextBaseline::Ideographic), PartialEq,
"bottom" => Ok(TextBaseline::Bottom), Serialize,
_ => Err(()), )]
}
}
}
#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Direction { pub enum Direction {
Ltr, Ltr,
Rtl, Rtl,
@ -512,19 +403,6 @@ pub enum Direction {
Inherit, Inherit,
} }
impl FromStr for Direction {
type Err = ();
fn from_str(string: &str) -> Result<Direction, ()> {
match string {
"ltr" => Ok(Direction::Ltr),
"rtl" => Ok(Direction::Rtl),
"inherit" => Ok(Direction::Inherit),
_ => Err(()),
}
}
}
#[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, Serialize)]
pub struct TextMetrics { pub struct TextMetrics {
pub width: f32, pub width: f32,