From ef7be66c56c45c28ce0be1e40d2e45b242b8d5ce Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:03:41 +0200 Subject: [PATCH] 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> --- Cargo.lock | 1 + components/canvas/raqote_backend.rs | 16 +- components/script/canvas_state.rs | 4 +- components/shared/canvas/Cargo.toml | 1 + components/shared/canvas/canvas.rs | 262 ++++++++-------------------- 5 files changed, 82 insertions(+), 202 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1671ae9bad..2754fae3e45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -825,6 +825,7 @@ dependencies = [ "serde_bytes", "servo_config", "servo_malloc_size_of", + "strum", "stylo", "webrender_api", "webxr-api", diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs index e2817796343..4ce709fca56 100644 --- a/components/canvas/raqote_backend.rs +++ b/components/canvas/raqote_backend.rs @@ -894,14 +894,14 @@ impl ToRaqoteStyle for CompositionStyle { fn to_raqote_style(self) -> Self::Target { match self { - CompositionStyle::SrcIn => raqote::BlendMode::SrcIn, - CompositionStyle::SrcOut => raqote::BlendMode::SrcOut, - CompositionStyle::SrcOver => raqote::BlendMode::SrcOver, - CompositionStyle::SrcAtop => raqote::BlendMode::SrcAtop, - CompositionStyle::DestIn => raqote::BlendMode::DstIn, - CompositionStyle::DestOut => raqote::BlendMode::DstOut, - CompositionStyle::DestOver => raqote::BlendMode::DstOver, - CompositionStyle::DestAtop => raqote::BlendMode::DstAtop, + CompositionStyle::SourceIn => raqote::BlendMode::SrcIn, + CompositionStyle::SourceOut => raqote::BlendMode::SrcOut, + CompositionStyle::SourceOver => raqote::BlendMode::SrcOver, + CompositionStyle::SourceAtop => raqote::BlendMode::SrcAtop, + CompositionStyle::DestinationIn => raqote::BlendMode::DstIn, + CompositionStyle::DestinationOut => raqote::BlendMode::DstOut, + CompositionStyle::DestinationOver => raqote::BlendMode::DstOver, + CompositionStyle::DestinationAtop => raqote::BlendMode::DstAtop, CompositionStyle::Copy => raqote::BlendMode::Src, CompositionStyle::Lighter => raqote::BlendMode::Add, CompositionStyle::Xor => raqote::BlendMode::Xor, diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index 323fb97d2e3..72da50677ee 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -1197,8 +1197,8 @@ impl CanvasState { // https://html.spec.whatwg.org/multipage/#dom-context-2d-globalcompositeoperation pub(crate) fn global_composite_operation(&self) -> DOMString { match self.state.borrow().global_composition { - CompositionOrBlending::Composition(op) => DOMString::from(op.to_str()), - CompositionOrBlending::Blending(op) => DOMString::from(op.to_str()), + CompositionOrBlending::Composition(op) => DOMString::from(op.to_string()), + CompositionOrBlending::Blending(op) => DOMString::from(op.to_string()), } } diff --git a/components/shared/canvas/Cargo.toml b/components/shared/canvas/Cargo.toml index d6e96711e1d..463d52b8c87 100644 --- a/components/shared/canvas/Cargo.toml +++ b/components/shared/canvas/Cargo.toml @@ -26,6 +26,7 @@ pixels = { path = "../../pixels" } serde = { workspace = true } serde_bytes = { workspace = true } servo_config = { path = "../../config" } +strum = { workspace = true } stylo = { workspace = true } webrender_api = { workspace = true } webxr-api = { workspace = true, features = ["ipc"] } diff --git a/components/shared/canvas/canvas.rs b/components/shared/canvas/canvas.rs index f33bb2b0732..b303fdb6ed0 100644 --- a/components/shared/canvas/canvas.rs +++ b/components/shared/canvas/canvas.rs @@ -11,6 +11,7 @@ use malloc_size_of_derive::MallocSizeOf; use pixels::IpcSnapshot; use serde::{Deserialize, Serialize}; use serde_bytes::ByteBuf; +use strum::{Display, EnumString}; use style::color::AbsoluteColor; use style::properties::style_structs::Font as FontStyleStruct; @@ -239,47 +240,26 @@ pub enum FillOrStrokeStyle { Surface(SurfaceStyle), } -#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] +#[derive( + Clone, Copy, Debug, Display, Deserialize, EnumString, MallocSizeOf, PartialEq, Serialize, +)] pub enum LineCapStyle { Butt = 0, Round = 1, Square = 2, } -impl FromStr for LineCapStyle { - type Err = (); - - fn from_str(string: &str) -> Result { - match string { - "butt" => Ok(LineCapStyle::Butt), - "round" => Ok(LineCapStyle::Round), - "square" => Ok(LineCapStyle::Square), - _ => Err(()), - } - } -} - -#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] +#[derive( + Clone, Copy, Debug, Deserialize, Display, EnumString, MallocSizeOf, PartialEq, Serialize, +)] pub enum LineJoinStyle { Round = 0, Bevel = 1, Miter = 2, } -impl FromStr for LineJoinStyle { - type Err = (); - - fn from_str(string: &str) -> Result { - match string { - "round" => Ok(LineJoinStyle::Round), - "bevel" => Ok(LineJoinStyle::Bevel), - "miter" => Ok(LineJoinStyle::Miter), - _ => Err(()), - } - } -} - -#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, Display, EnumString, PartialEq, Serialize)] +#[strum(serialize_all = "kebab-case")] pub enum RepetitionStyle { Repeat, RepeatX, @@ -287,79 +267,35 @@ pub enum RepetitionStyle { NoRepeat, } -impl FromStr for RepetitionStyle { - type Err = (); - - fn from_str(string: &str) -> Result { - match string { - "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)] +/// +#[derive( + Clone, Copy, Debug, Deserialize, Display, EnumString, MallocSizeOf, PartialEq, Serialize, +)] +#[strum(serialize_all = "kebab-case")] pub enum CompositionStyle { - SrcIn, - SrcOut, - SrcOver, - SrcAtop, - DestIn, - DestOut, - DestOver, - DestAtop, - Copy, - Lighter, - Xor, Clear, + Copy, + SourceOver, + DestinationOver, + SourceIn, + DestinationIn, + SourceOut, + DestinationOut, + SourceAtop, + DestinationAtop, + Xor, + Lighter, + // PlusDarker, + // PlusLighter, } -impl FromStr for CompositionStyle { - type Err = (); - - fn from_str(string: &str) -> Result { - match string { - "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)] +/// +#[derive( + Clone, Copy, Debug, Deserialize, Display, EnumString, MallocSizeOf, PartialEq, Serialize, +)] +#[strum(serialize_all = "kebab-case")] pub enum BlendingStyle { + // Normal, Multiply, Screen, Overlay, @@ -377,53 +313,6 @@ pub enum BlendingStyle { Luminosity, } -impl FromStr for BlendingStyle { - type Err = (); - - fn from_str(string: &str) -> Result { - 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)] pub enum CompositionOrBlending { Composition(CompositionStyle), @@ -432,7 +321,7 @@ pub enum CompositionOrBlending { impl Default for 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 { #[default] Start, @@ -462,22 +362,18 @@ pub enum TextAlign { Center, } -impl FromStr for TextAlign { - type Err = (); - - fn from_str(string: &str) -> Result { - match string { - "start" => Ok(TextAlign::Start), - "end" => Ok(TextAlign::End), - "left" => Ok(TextAlign::Left), - "right" => Ok(TextAlign::Right), - "center" => Ok(TextAlign::Center), - _ => Err(()), - } - } -} - -#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)] +#[derive( + Clone, + Copy, + Debug, + Default, + Deserialize, + Display, + EnumString, + MallocSizeOf, + PartialEq, + Serialize, +)] pub enum TextBaseline { Top, Hanging, @@ -488,23 +384,18 @@ pub enum TextBaseline { Bottom, } -impl FromStr for TextBaseline { - type Err = (); - - fn from_str(string: &str) -> Result { - match string { - "top" => Ok(TextBaseline::Top), - "hanging" => Ok(TextBaseline::Hanging), - "middle" => Ok(TextBaseline::Middle), - "alphabetic" => Ok(TextBaseline::Alphabetic), - "ideographic" => Ok(TextBaseline::Ideographic), - "bottom" => Ok(TextBaseline::Bottom), - _ => Err(()), - } - } -} - -#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)] +#[derive( + Clone, + Copy, + Debug, + Default, + Deserialize, + Display, + EnumString, + MallocSizeOf, + PartialEq, + Serialize, +)] pub enum Direction { Ltr, Rtl, @@ -512,19 +403,6 @@ pub enum Direction { Inherit, } -impl FromStr for Direction { - type Err = (); - - fn from_str(string: &str) -> Result { - match string { - "ltr" => Ok(Direction::Ltr), - "rtl" => Ok(Direction::Rtl), - "inherit" => Ok(Direction::Inherit), - _ => Err(()), - } - } -} - #[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, Serialize)] pub struct TextMetrics { pub width: f32,