mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Rename spread method to gradient spread so it matches the other gradient attribute names (#4404)
* Rename spread method to gradient spread so it matches the other gradient attribute names * Keep the legacy gradient struct's spread method field name matching its on-disk key
This commit is contained in:
@@ -25,8 +25,8 @@ pub use graphene_hash;
|
||||
pub use graphene_hash::CacheHash;
|
||||
pub use list::{
|
||||
ATTR_BACKGROUND, ATTR_BLEND_MODE, ATTR_CLIP, ATTR_CLIPPING_MASK, ATTR_DIMENSIONS, ATTR_EDITOR_CLICK_TARGET, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_EDITOR_TEXT_FRAME, ATTR_END,
|
||||
ATTR_FONT, ATTR_FONT_SIZE, ATTR_GRADIENT_TYPE, ATTR_LETTER_SPACING, ATTR_LETTER_TILT, ATTR_LINE_HEIGHT, ATTR_LOCATION, ATTR_MAX_HEIGHT, ATTR_MAX_WIDTH, ATTR_NAME, ATTR_OPACITY, ATTR_OPACITY_FILL,
|
||||
ATTR_SPREAD_METHOD, ATTR_START, ATTR_TEXT_ALIGN, ATTR_TRANSFORM, ATTR_TYPE,
|
||||
ATTR_FONT, ATTR_FONT_SIZE, ATTR_GRADIENT_SPREAD, ATTR_GRADIENT_TYPE, ATTR_LETTER_SPACING, ATTR_LETTER_TILT, ATTR_LINE_HEIGHT, ATTR_LOCATION, ATTR_MAX_HEIGHT, ATTR_MAX_WIDTH, ATTR_NAME,
|
||||
ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_START, ATTR_TEXT_ALIGN, ATTR_TRANSFORM, ATTR_TYPE,
|
||||
};
|
||||
pub use memo::MemoHash;
|
||||
pub use no_std_types::AsU32;
|
||||
|
||||
@@ -55,9 +55,9 @@ pub const ATTR_DIMENSIONS: &str = "dimensions";
|
||||
pub const ATTR_BACKGROUND: &str = "background";
|
||||
/// `bool` for whether an artboard clips content to its bounds.
|
||||
pub const ATTR_CLIP: &str = "clip";
|
||||
// TODO: Consider adding "spread_method_left" and "spread_method_right" override attributes to allow setting different spread methods on each side of a gradient
|
||||
/// Gradient's `GradientSpreadMethod` (`Pad`, `Reflect`, or `Repeat`).
|
||||
pub const ATTR_SPREAD_METHOD: &str = "spread_method";
|
||||
// TODO: Consider adding "gradient_spread_left" and "gradient_spread_right" override attributes to allow setting different gradient spreads on each side of a gradient
|
||||
/// Gradient's `GradientSpread` (`Pad`, `Reflect`, or `Repeat`).
|
||||
pub const ATTR_GRADIENT_SPREAD: &str = "gradient_spread";
|
||||
/// Gradient's `GradientType` (`Linear` or `Radial`).
|
||||
pub const ATTR_GRADIENT_TYPE: &str = "gradient_type";
|
||||
/// Gradient stop's `f64` position from 0 to 1 along the gradient, on the `List<Color>` inside a `Gradient`.
|
||||
@@ -1229,7 +1229,7 @@ impl<T: CacheHash> CacheHash for List<T> {
|
||||
self.element.cache_hash(state);
|
||||
|
||||
// Hash every attribute attribute (key + values) rather than just the well-known ones, so changes to user-defined keys
|
||||
// (e.g., gradient_type, spread_method) invalidate downstream graph caches as expected
|
||||
// (e.g., gradient_type, gradient_spread) invalidate downstream graph caches as expected
|
||||
for (key, attribute) in &self.attributes.attributes {
|
||||
std::hash::Hash::hash(key.as_str(), state);
|
||||
attribute.cache_hash_dyn(state);
|
||||
|
||||
@@ -666,8 +666,8 @@ mod tests {
|
||||
|
||||
#[cfg(test)]
|
||||
mod graphic_is_opaque_tests {
|
||||
use core_types::ATTR_SPREAD_METHOD;
|
||||
use vector_types::{GradientSpreadMethod, GradientStop};
|
||||
use core_types::ATTR_GRADIENT_SPREAD;
|
||||
use vector_types::{GradientSpread, GradientStop};
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -678,7 +678,7 @@ mod graphic_is_opaque_tests {
|
||||
|
||||
fn gradient_graphic(gradient: Gradient) -> Graphic {
|
||||
let mut gradient_list = List::new_from_element(gradient);
|
||||
gradient_list.set_attribute(ATTR_SPREAD_METHOD, 0, GradientSpreadMethod::Pad);
|
||||
gradient_list.set_attribute(ATTR_GRADIENT_SPREAD, 0, GradientSpread::Pad);
|
||||
Graphic::Gradient(gradient_list)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ pub mod migrations {
|
||||
pub start: DVec2,
|
||||
pub end: DVec2,
|
||||
#[serde(default)]
|
||||
pub spread_method: vector::style::GradientSpreadMethod,
|
||||
pub spread_method: vector::style::GradientSpread,
|
||||
#[serde(default)]
|
||||
pub absolute: bool,
|
||||
#[serde(default)]
|
||||
|
||||
@@ -3,14 +3,14 @@ use crate::{Render, RenderSvgSegmentList, SvgRender};
|
||||
use core_types::color::SRGBA8;
|
||||
use core_types::list::List;
|
||||
use core_types::uuid::generate_uuid;
|
||||
use core_types::{ATTR_GRADIENT_TYPE, ATTR_SPREAD_METHOD, ATTR_TRANSFORM, Color};
|
||||
use core_types::{ATTR_GRADIENT_SPREAD, ATTR_GRADIENT_TYPE, ATTR_TRANSFORM, Color};
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graphic_types::Graphic;
|
||||
use graphic_types::vector_types::gradient::GradientType;
|
||||
use graphic_types::vector_types::vector::style::{PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
|
||||
use std::fmt::Write;
|
||||
use vector_types::Gradient;
|
||||
use vector_types::gradient::GradientSpreadMethod;
|
||||
use vector_types::gradient::GradientSpread;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum PaintTarget {
|
||||
@@ -95,7 +95,7 @@ impl RenderExt for List<Gradient> {
|
||||
let Some(stops) = self.element(0) else { return 0 };
|
||||
let gradient_type: GradientType = self.attribute_cloned_or_default(ATTR_GRADIENT_TYPE, 0);
|
||||
let local_gradient_transform: DAffine2 = self.attribute_cloned_or_default(ATTR_TRANSFORM, 0);
|
||||
let spread_method: GradientSpreadMethod = self.attribute_cloned_or_default(ATTR_SPREAD_METHOD, 0);
|
||||
let gradient_spread: GradientSpread = self.attribute_cloned_or_default(ATTR_GRADIENT_SPREAD, 0);
|
||||
|
||||
for (position, color, original_midpoint) in stops.interpolated_samples() {
|
||||
stop.push_str("<stop");
|
||||
@@ -134,10 +134,10 @@ impl RenderExt for List<Gradient> {
|
||||
format!(r#" gradientTransform="{gradient_transform}""#)
|
||||
};
|
||||
|
||||
let spread_method = if spread_method == GradientSpreadMethod::Pad {
|
||||
let gradient_spread = if gradient_spread == GradientSpread::Pad {
|
||||
String::new()
|
||||
} else {
|
||||
format!(r#" spreadMethod="{}""#, spread_method.svg_name())
|
||||
format!(r#" spreadMethod="{}""#, gradient_spread.svg_name())
|
||||
};
|
||||
|
||||
let gradient_id = generate_uuid();
|
||||
@@ -146,14 +146,14 @@ impl RenderExt for List<Gradient> {
|
||||
GradientType::Linear => {
|
||||
let _ = write!(
|
||||
svg_defs,
|
||||
r#"<linearGradient id="{}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="1" y2="0"{spread_method}{gradient_transform}>{}</linearGradient>"#,
|
||||
r#"<linearGradient id="{}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="1" y2="0"{gradient_spread}{gradient_transform}>{}</linearGradient>"#,
|
||||
gradient_id, stop
|
||||
);
|
||||
}
|
||||
GradientType::Radial => {
|
||||
let _ = write!(
|
||||
svg_defs,
|
||||
r#"<radialGradient id="{}" gradientUnits="userSpaceOnUse" cx="0" cy="0" r="1"{spread_method}{gradient_transform}>{}</radialGradient>"#,
|
||||
r#"<radialGradient id="{}" gradientUnits="userSpaceOnUse" cx="0" cy="0" r="1"{gradient_spread}{gradient_transform}>{}</radialGradient>"#,
|
||||
gradient_id, stop
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ use core_types::transform::Footprint;
|
||||
use core_types::uuid::{NodeId, generate_uuid};
|
||||
use core_types::{
|
||||
ATTR_BACKGROUND, ATTR_BLEND_MODE, ATTR_CLIP, ATTR_CLIPPING_MASK, ATTR_DIMENSIONS, ATTR_EDITOR_CLICK_TARGET, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_EDITOR_TEXT_FRAME, ATTR_FONT,
|
||||
ATTR_FONT_SIZE, ATTR_GRADIENT_TYPE, ATTR_LETTER_SPACING, ATTR_LETTER_TILT, ATTR_LINE_HEIGHT, ATTR_LOCATION, ATTR_MAX_HEIGHT, ATTR_MAX_WIDTH, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_SPREAD_METHOD,
|
||||
ATTR_FONT_SIZE, ATTR_GRADIENT_SPREAD, ATTR_GRADIENT_TYPE, ATTR_LETTER_SPACING, ATTR_LETTER_TILT, ATTR_LINE_HEIGHT, ATTR_LOCATION, ATTR_MAX_HEIGHT, ATTR_MAX_WIDTH, ATTR_OPACITY, ATTR_OPACITY_FILL,
|
||||
ATTR_TEXT_ALIGN, ATTR_TRANSFORM,
|
||||
};
|
||||
use dyn_any::DynAny;
|
||||
@@ -39,7 +39,7 @@ use std::fmt::Write;
|
||||
use std::hash::Hash;
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use vector_types::gradient::GradientSpreadMethod;
|
||||
use vector_types::gradient::GradientSpread;
|
||||
use vello::*;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
@@ -424,7 +424,7 @@ fn create_peniko_gradient_brush(gradient_list: &List<Gradient>, multiplied_trans
|
||||
|
||||
let gradient_type: GradientType = gradient_list.attribute_cloned_or_default(ATTR_GRADIENT_TYPE, 0);
|
||||
let gradient_transform: DAffine2 = gradient_list.attribute_cloned_or_default(ATTR_TRANSFORM, 0);
|
||||
let spread_method: GradientSpreadMethod = gradient_list.attribute_cloned_or_default(ATTR_SPREAD_METHOD, 0);
|
||||
let gradient_spread: GradientSpread = gradient_list.attribute_cloned_or_default(ATTR_GRADIENT_SPREAD, 0);
|
||||
|
||||
let peniko_stops = peniko_color_stops(stops);
|
||||
|
||||
@@ -446,10 +446,10 @@ fn create_peniko_gradient_brush(gradient_list: &List<Gradient>, multiplied_trans
|
||||
}
|
||||
.into(),
|
||||
},
|
||||
extend: match spread_method {
|
||||
GradientSpreadMethod::Pad => peniko::Extend::Pad,
|
||||
GradientSpreadMethod::Reflect => peniko::Extend::Reflect,
|
||||
GradientSpreadMethod::Repeat => peniko::Extend::Repeat,
|
||||
extend: match gradient_spread {
|
||||
GradientSpread::Pad => peniko::Extend::Pad,
|
||||
GradientSpread::Reflect => peniko::Extend::Reflect,
|
||||
GradientSpread::Repeat => peniko::Extend::Repeat,
|
||||
},
|
||||
stops: peniko_stops,
|
||||
interpolation_alpha_space: peniko::InterpolationAlphaSpace::Premultiplied,
|
||||
@@ -2094,7 +2094,7 @@ impl Render for List<Gradient> {
|
||||
let blend_mode: BlendMode = self.attribute_cloned_or_default(ATTR_BLEND_MODE, index);
|
||||
let opacity_attr: f64 = self.attribute_cloned_or(ATTR_OPACITY, index, 1.);
|
||||
let opacity_fill_attr: f64 = self.attribute_cloned_or(ATTR_OPACITY_FILL, index, 1.);
|
||||
let spread_method: GradientSpreadMethod = self.attribute_cloned_or_default(ATTR_SPREAD_METHOD, index);
|
||||
let gradient_spread: GradientSpread = self.attribute_cloned_or_default(ATTR_GRADIENT_SPREAD, index);
|
||||
let gradient_type: GradientType = self.attribute_cloned_or_default(ATTR_GRADIENT_TYPE, index);
|
||||
let tag = if thumbnail_rect.is_some() { "rect" } else { "polyline" };
|
||||
render.leaf_tag(tag, |attributes| {
|
||||
@@ -2133,10 +2133,10 @@ impl Render for List<Gradient> {
|
||||
};
|
||||
|
||||
let gradient_id = generate_uuid();
|
||||
let spread_method_attribute = if spread_method == GradientSpreadMethod::Pad {
|
||||
let gradient_spread_attribute = if gradient_spread == GradientSpread::Pad {
|
||||
String::new()
|
||||
} else {
|
||||
format!(r#" spreadMethod="{}""#, spread_method.svg_name())
|
||||
format!(r#" spreadMethod="{}""#, gradient_spread.svg_name())
|
||||
};
|
||||
|
||||
// The unit gradient line is the +X unit vector in local space, before the item's transform is applied
|
||||
@@ -2144,13 +2144,13 @@ impl Render for List<Gradient> {
|
||||
GradientType::Linear => {
|
||||
let _ = write!(
|
||||
&mut attributes.0.svg_defs,
|
||||
r#"<linearGradient id="{gradient_id}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="1" y2="0"{spread_method_attribute}{gradient_transform_attribute}>{stop_string}</linearGradient>"#
|
||||
r#"<linearGradient id="{gradient_id}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="1" y2="0"{gradient_spread_attribute}{gradient_transform_attribute}>{stop_string}</linearGradient>"#
|
||||
);
|
||||
}
|
||||
GradientType::Radial => {
|
||||
let _ = write!(
|
||||
&mut attributes.0.svg_defs,
|
||||
r#"<radialGradient id="{gradient_id}" gradientUnits="userSpaceOnUse" cx="0" cy="0" r="1"{spread_method_attribute}{gradient_transform_attribute}>{stop_string}</radialGradient>"#
|
||||
r#"<radialGradient id="{gradient_id}" gradientUnits="userSpaceOnUse" cx="0" cy="0" r="1"{gradient_spread_attribute}{gradient_transform_attribute}>{stop_string}</radialGradient>"#
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -2176,10 +2176,10 @@ impl Render for List<Gradient> {
|
||||
return;
|
||||
}
|
||||
|
||||
for (((index, gradient), spread_method), gradient_type) in self
|
||||
for (((index, gradient), gradient_spread), gradient_type) in self
|
||||
.iter_element_values()
|
||||
.enumerate()
|
||||
.zip(self.iter_attribute_values_or_default::<GradientSpreadMethod>(ATTR_SPREAD_METHOD))
|
||||
.zip(self.iter_attribute_values_or_default::<GradientSpread>(ATTR_GRADIENT_SPREAD))
|
||||
.zip(self.iter_attribute_values_or_default::<GradientType>(ATTR_GRADIENT_TYPE))
|
||||
{
|
||||
let transform: DAffine2 = self.attribute_cloned_or_default(ATTR_TRANSFORM, index);
|
||||
@@ -2193,10 +2193,10 @@ impl Render for List<Gradient> {
|
||||
|
||||
let stops = peniko_color_stops(gradient);
|
||||
|
||||
let extend = match spread_method {
|
||||
GradientSpreadMethod::Pad => peniko::Extend::Pad,
|
||||
GradientSpreadMethod::Reflect => peniko::Extend::Reflect,
|
||||
GradientSpreadMethod::Repeat => peniko::Extend::Repeat,
|
||||
let extend = match gradient_spread {
|
||||
GradientSpread::Pad => peniko::Extend::Pad,
|
||||
GradientSpread::Reflect => peniko::Extend::Reflect,
|
||||
GradientSpread::Repeat => peniko::Extend::Repeat,
|
||||
};
|
||||
|
||||
// The unit gradient line is the +X unit vector in local space, before the item's transform is applied.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use core_types::Color;
|
||||
use core_types::color::SRGBA8;
|
||||
use core_types::list::{ATTR_MIDPOINT, ATTR_POSITION, ATTR_SPREAD_METHOD, Item, List};
|
||||
use core_types::list::{ATTR_GRADIENT_SPREAD, ATTR_MIDPOINT, ATTR_POSITION, Item, List};
|
||||
use core_types::render_complexity::RenderComplexity;
|
||||
use dyn_any::DynAny;
|
||||
use glam::{DAffine2, DVec2};
|
||||
@@ -102,9 +102,9 @@ impl GradientStops<SRGBA8> {
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct GradientRamp<C = Color> {
|
||||
pub stops: GradientStops<C>,
|
||||
#[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "GradientSpreadMethod::is_default"))]
|
||||
#[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "GradientSpread::is_default"))]
|
||||
#[cfg_attr(feature = "wasm", tsify(optional))]
|
||||
pub spread_method: GradientSpreadMethod,
|
||||
pub gradient_spread: GradientSpread,
|
||||
}
|
||||
|
||||
unsafe impl<C: dyn_any::StaticTypeSized> dyn_any::StaticType for GradientRamp<C> {
|
||||
@@ -115,7 +115,7 @@ impl<C> From<GradientStops<C>> for GradientRamp<C> {
|
||||
fn from(stops: GradientStops<C>) -> Self {
|
||||
Self {
|
||||
stops,
|
||||
spread_method: Default::default(),
|
||||
gradient_spread: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ impl From<&Gradient> for GradientRamp {
|
||||
fn from(gradient: &Gradient) -> Self {
|
||||
Self {
|
||||
stops: gradient.into(),
|
||||
spread_method: Default::default(),
|
||||
gradient_spread: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,8 +152,8 @@ impl From<&GradientRamp> for Gradient {
|
||||
impl From<GradientRamp> for Item<Gradient> {
|
||||
fn from(ramp: GradientRamp) -> Self {
|
||||
let mut item = Item::new_from_element(Gradient::from(ramp.stops));
|
||||
if !ramp.spread_method.is_default() {
|
||||
item.set_attribute(ATTR_SPREAD_METHOD, ramp.spread_method);
|
||||
if !ramp.gradient_spread.is_default() {
|
||||
item.set_attribute(ATTR_GRADIENT_SPREAD, ramp.gradient_spread);
|
||||
}
|
||||
item
|
||||
}
|
||||
@@ -163,7 +163,7 @@ impl From<&Item<Gradient>> for GradientRamp {
|
||||
fn from(item: &Item<Gradient>) -> Self {
|
||||
Self {
|
||||
stops: item.element().into(),
|
||||
spread_method: item.attribute_cloned_or_default(ATTR_SPREAD_METHOD),
|
||||
gradient_spread: item.attribute_cloned_or_default(ATTR_GRADIENT_SPREAD),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,7 @@ impl From<&GradientRamp> for GradientRamp<SRGBA8> {
|
||||
fn from(ramp: &GradientRamp) -> Self {
|
||||
Self {
|
||||
stops: ramp.into(),
|
||||
spread_method: ramp.spread_method,
|
||||
gradient_spread: ramp.gradient_spread,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,7 +198,7 @@ impl From<&Gradient> for GradientRamp<SRGBA8> {
|
||||
fn from(gradient: &Gradient) -> Self {
|
||||
Self {
|
||||
stops: gradient.into(),
|
||||
spread_method: Default::default(),
|
||||
gradient_spread: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -206,7 +206,7 @@ impl From<&Gradient> for GradientRamp<SRGBA8> {
|
||||
impl From<&GradientRamp<SRGBA8>> for GradientRamp {
|
||||
fn from(ramp: &GradientRamp<SRGBA8>) -> Self {
|
||||
Self {
|
||||
spread_method: ramp.spread_method,
|
||||
gradient_spread: ramp.gradient_spread,
|
||||
..Self::from(&ramp.stops)
|
||||
}
|
||||
}
|
||||
@@ -600,12 +600,12 @@ impl Gradient {
|
||||
stops
|
||||
}
|
||||
|
||||
/// Samples the gradient's color at `t`. Given a `t` outside the 0 to 1 range, the `spread_method` determines how the gradient extends.
|
||||
pub fn evaluate(&self, t: f64, spread_method: GradientSpreadMethod) -> Color {
|
||||
let t = match spread_method {
|
||||
GradientSpreadMethod::Pad => t.clamp(0., 1.),
|
||||
GradientSpreadMethod::Repeat => t.rem_euclid(1.),
|
||||
GradientSpreadMethod::Reflect => {
|
||||
/// Samples the gradient's color at `t`. Given a `t` outside the 0 to 1 range, the `gradient_spread` determines how the gradient extends.
|
||||
pub fn evaluate(&self, t: f64, gradient_spread: GradientSpread) -> Color {
|
||||
let t = match gradient_spread {
|
||||
GradientSpread::Pad => t.clamp(0., 1.),
|
||||
GradientSpread::Repeat => t.rem_euclid(1.),
|
||||
GradientSpread::Reflect => {
|
||||
let cycle = t.rem_euclid(2.);
|
||||
if cycle > 1. { 2. - cycle } else { cycle }
|
||||
}
|
||||
@@ -784,7 +784,7 @@ impl Gradient {
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, graphene_hash::CacheHash, DynAny, node_macro::ChoiceType)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[widget(Radio)]
|
||||
pub enum GradientSpreadMethod {
|
||||
pub enum GradientSpread {
|
||||
/// Extends the end colors outward.
|
||||
#[default]
|
||||
Pad,
|
||||
@@ -795,12 +795,12 @@ pub enum GradientSpreadMethod {
|
||||
// TODO: Add a "Clear" variant that returns transparent black outside the gradient's range
|
||||
}
|
||||
|
||||
impl GradientSpreadMethod {
|
||||
impl GradientSpread {
|
||||
pub fn svg_name(&self) -> &'static str {
|
||||
match self {
|
||||
GradientSpreadMethod::Pad => "pad",
|
||||
GradientSpreadMethod::Reflect => "reflect",
|
||||
GradientSpreadMethod::Repeat => "repeat",
|
||||
GradientSpread::Pad => "pad",
|
||||
GradientSpread::Reflect => "reflect",
|
||||
GradientSpread::Repeat => "repeat",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -905,39 +905,39 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spread_method_serializes_only_when_not_default() {
|
||||
fn gradient_spread_serializes_only_when_not_default() {
|
||||
let default_spread = GradientRamp::from(Gradient::from(vec![Color::BLACK, Color::WHITE]));
|
||||
let json = serde_json::to_string(&default_spread).unwrap();
|
||||
assert!(!json.contains("spread_method"), "the default Pad spread method must not serialize: {json}");
|
||||
assert!(!json.contains("gradient_spread"), "the default Pad gradient spread must not serialize: {json}");
|
||||
assert_eq!(serde_json::from_str::<GradientRamp>(&json).unwrap(), default_spread);
|
||||
|
||||
let repeating = GradientRamp {
|
||||
spread_method: GradientSpreadMethod::Repeat,
|
||||
gradient_spread: GradientSpread::Repeat,
|
||||
..default_spread.clone()
|
||||
};
|
||||
let json = serde_json::to_string(&repeating).unwrap();
|
||||
assert!(json.contains(r#""spread_method":"Repeat""#), "a non-default spread method must serialize: {json}");
|
||||
assert!(json.contains(r#""gradient_spread":"Repeat""#), "a non-default gradient spread must serialize: {json}");
|
||||
assert_eq!(serde_json::from_str::<GradientRamp>(&json).unwrap(), repeating);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spread_method_round_trips_through_the_item_attribute() {
|
||||
fn gradient_spread_round_trips_through_the_item_attribute() {
|
||||
let ramp = GradientRamp {
|
||||
spread_method: GradientSpreadMethod::Repeat,
|
||||
gradient_spread: GradientSpread::Repeat,
|
||||
..GradientRamp::from(Gradient::from(vec![Color::BLACK, Color::WHITE]))
|
||||
};
|
||||
|
||||
let item = Item::<Gradient>::from(ramp.clone());
|
||||
assert_eq!(
|
||||
item.attribute_cloned_or_default::<GradientSpreadMethod>(ATTR_SPREAD_METHOD),
|
||||
GradientSpreadMethod::Repeat,
|
||||
"the runtime item should carry the spread method as its attribute"
|
||||
item.attribute_cloned_or_default::<GradientSpread>(ATTR_GRADIENT_SPREAD),
|
||||
GradientSpread::Repeat,
|
||||
"the runtime item should carry the gradient spread as its attribute"
|
||||
);
|
||||
assert_eq!(GradientRamp::from(&item), ramp);
|
||||
|
||||
let padded = Item::<Gradient>::from(GradientRamp::from(Gradient::from(vec![Color::BLACK, Color::WHITE])));
|
||||
assert!(
|
||||
padded.attribute::<GradientSpreadMethod>(ATTR_SPREAD_METHOD).is_none(),
|
||||
padded.attribute::<GradientSpread>(ATTR_GRADIENT_SPREAD).is_none(),
|
||||
"the default Pad must stay absent rather than materialize"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ pub mod vector;
|
||||
|
||||
// Re-export commonly used types at the crate root
|
||||
pub use core_types as gcore;
|
||||
pub use gradient::{Gradient, GradientRamp, GradientSpreadMethod, GradientStop, GradientType};
|
||||
pub use gradient::{Gradient, GradientRamp, GradientSpread, GradientStop, GradientType};
|
||||
pub use math::{QuadExt, RectExt};
|
||||
pub use subpath::Subpath;
|
||||
pub use vector::Vector;
|
||||
|
||||
Reference in New Issue
Block a user