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",
"servo_config",
"servo_malloc_size_of",
"strum",
"stylo",
"webrender_api",
"webxr-api",

View file

@ -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,

View file

@ -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()),
}
}

View file

@ -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"] }

View file

@ -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<LineCapStyle, ()> {
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<LineJoinStyle, ()> {
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<RepetitionStyle, ()> {
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)]
/// <https://drafts.fxtf.org/compositing/#compositemode>
#[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<CompositionStyle, ()> {
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)]
/// <https://drafts.fxtf.org/compositing/#ltblendmodegt>
#[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<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)]
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<TextAlign, ()> {
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<TextBaseline, ()> {
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<Direction, ()> {
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,