mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Rename GradientStops to Gradient and the legacy Gradient/Fill structs to LegacyGradient/LegacyFill
This commit is contained in:
committed by
Dennis Kobert
parent
149e1fc4e0
commit
9dd1e2bdf9
@@ -16,7 +16,7 @@ pub trait BoundingBox {
|
||||
/// Returns the bounding box to use when sizing this value's thumbnail in the Layers panel.
|
||||
///
|
||||
/// Diverges from `bounding_box` for types where the rendering bounds wouldn't make a useful thumbnail frame.
|
||||
/// For instance, `GradientStops` is `Infinite` for rendering but returns the line's AABB here, so a `List<Graphic>`
|
||||
/// For instance, `Gradient` is `Infinite` for rendering but returns the line's AABB here, so a `List<Graphic>`
|
||||
/// group of a gradient and a vector frames around the vector's geometry rather than infinity.
|
||||
/// Types with no meaningful contribution (e.g., `Color`) return `Infinite` from both; the runtime substitutes a
|
||||
/// small fallback rectangle at the end if no finite bounds remain after combining.
|
||||
|
||||
@@ -13,7 +13,7 @@ use core_types::node::Node;
|
||||
use core_types::record::{Group, GroupItem, LevelStatus, materialize_level};
|
||||
use core_types::uuid::NodeId;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use vector_types::GradientStops;
|
||||
use vector_types::Gradient;
|
||||
|
||||
/// The outcome of materializing a leveled wire into a group.
|
||||
// The group is the render path's success payload; boxing it would add a heap allocation per materialized level.
|
||||
@@ -93,7 +93,7 @@ pub fn batch_to_legacy(layout: &core_types::record::Layout, batch: core_types::n
|
||||
.or_else(|| typed::<Raster<CPU>>(&item))
|
||||
.or_else(|| typed::<Raster<GPU>>(&item))
|
||||
.or_else(|| typed::<Color>(&item))
|
||||
.or_else(|| typed::<GradientStops>(&item))
|
||||
.or_else(|| typed::<Gradient>(&item))
|
||||
.or_else(|| typed::<String>(&item))
|
||||
.or_else(|| typed::<f64>(&item))
|
||||
.or_else(|| typed::<u64>(&item))
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::markers::{ATTR_FILL, ATTR_STROKE};
|
||||
use core_types::Color;
|
||||
use core_types::list::{Item, List};
|
||||
use raster_types::{CPU, GPU, Raster};
|
||||
use vector_types::{GradientStops, Vector};
|
||||
use vector_types::{Gradient, Vector};
|
||||
|
||||
/// One typed run as an owned list, elements cloned and every attribute copied
|
||||
/// through its erased read. Content keeps its native form; the legacy
|
||||
@@ -69,7 +69,7 @@ pub fn group_to_legacy_graphic(group: &core_types::record::Group) -> Graphic<'st
|
||||
.or_else(|| run_to_legacy_list::<Raster<CPU>>(item).map(|list| detable_items(list, Graphic::RasterCPU)))
|
||||
.or_else(|| run_to_legacy_list::<Raster<GPU>>(item).map(|list| detable_items(list, Graphic::RasterGPU)))
|
||||
.or_else(|| run_to_legacy_list::<Color>(item).map(|list| detable_items(list, Graphic::Color)))
|
||||
.or_else(|| run_to_legacy_list::<GradientStops>(item).map(|list| detable_items(list, Graphic::Gradient)))
|
||||
.or_else(|| run_to_legacy_list::<Gradient>(item).map(|list| detable_items(list, Graphic::Gradient)))
|
||||
.or_else(|| run_to_legacy_list::<String>(item).map(|list| detable_items(list, Graphic::Text)));
|
||||
if let Some(typed) = typed {
|
||||
return Graphic::Graphic(typed);
|
||||
@@ -93,7 +93,7 @@ pub fn group_to_legacy_list(group: &core_types::record::Group) -> List<Graphic<'
|
||||
.or_else(|| run_to_legacy_list::<Raster<CPU>>(item).map(|list| detable_items(list, Graphic::RasterCPU)))
|
||||
.or_else(|| run_to_legacy_list::<Raster<GPU>>(item).map(|list| detable_items(list, Graphic::RasterGPU)))
|
||||
.or_else(|| run_to_legacy_list::<Color>(item).map(|list| detable_items(list, Graphic::Color)))
|
||||
.or_else(|| run_to_legacy_list::<GradientStops>(item).map(|list| detable_items(list, Graphic::Gradient)))
|
||||
.or_else(|| run_to_legacy_list::<Gradient>(item).map(|list| detable_items(list, Graphic::Gradient)))
|
||||
.or_else(|| run_to_legacy_list::<String>(item).map(|list| detable_items(list, Graphic::Text)))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ use core_types::{ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_OPACITY, ATTR_
|
||||
use dyn_any::DynAny;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use raster_types::{CPU, GPU, Raster};
|
||||
use vector_types::GradientStops;
|
||||
use vector_types::Gradient;
|
||||
pub use vector_types::Vector;
|
||||
|
||||
/// The possible forms of graphical content that can be rendered by the Render node into either an image or SVG syntax.
|
||||
@@ -38,7 +38,7 @@ pub enum Graphic<'e> {
|
||||
RasterCPU(Raster<CPU>),
|
||||
RasterGPU(Raster<GPU>),
|
||||
Color(Color),
|
||||
Gradient(GradientStops),
|
||||
Gradient(Gradient),
|
||||
Text(String),
|
||||
Group(core_types::record::Group<'e>),
|
||||
}
|
||||
@@ -101,7 +101,7 @@ into_graphic_element! {
|
||||
RasterCPU: Raster<CPU>;
|
||||
RasterGPU: Raster<GPU>;
|
||||
Color: Color;
|
||||
Gradient: GradientStops;
|
||||
Gradient: Gradient;
|
||||
Text: String;
|
||||
}
|
||||
|
||||
@@ -146,9 +146,9 @@ impl From<Color> for Graphic<'_> {
|
||||
}
|
||||
// Note: List<Color> -> Option<Color> is in gcore (Color is defined there)
|
||||
|
||||
// GradientStops
|
||||
impl From<GradientStops> for Graphic<'_> {
|
||||
fn from(gradient: GradientStops) -> Self {
|
||||
// Gradient
|
||||
impl From<Gradient> for Graphic<'_> {
|
||||
fn from(gradient: Gradient) -> Self {
|
||||
Graphic::Gradient(gradient)
|
||||
}
|
||||
}
|
||||
@@ -251,7 +251,7 @@ impl TryFromGraphic for Color {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFromGraphic for GradientStops {
|
||||
impl TryFromGraphic for Gradient {
|
||||
fn try_from_graphic(graphic: Graphic) -> Option<List<Self>> {
|
||||
if let Graphic::Gradient(t) = graphic { Some(List::new_from_element(t)) } else { None }
|
||||
}
|
||||
@@ -306,7 +306,7 @@ impl IntoGraphicList for List<Color> {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoGraphicList for List<GradientStops> {
|
||||
impl IntoGraphicList for List<Gradient> {
|
||||
fn into_graphic_list(self) -> List<Graphic<'static>> {
|
||||
detable_items(self, Graphic::Gradient)
|
||||
}
|
||||
@@ -612,7 +612,7 @@ mod graphic_is_opaque_tests {
|
||||
Graphic::Color(color)
|
||||
}
|
||||
|
||||
fn gradient_graphic(gradient: GradientStops) -> Graphic<'static> {
|
||||
fn gradient_graphic(gradient: Gradient) -> Graphic<'static> {
|
||||
Graphic::Gradient(gradient)
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@ mod graphic_is_opaque_tests {
|
||||
fn gradient_with_all_opaque_stops_is_opaque() {
|
||||
let color_1 = Color::from_rgbaf32(1., 0., 0., 1.).unwrap();
|
||||
let color_2 = Color::from_rgbaf32(1., 0., 0., 1.).unwrap();
|
||||
let gradient = GradientStops::new(vec![
|
||||
let gradient = Gradient::new(vec![
|
||||
GradientStop {
|
||||
position: 0.,
|
||||
midpoint: 0.5,
|
||||
@@ -658,7 +658,7 @@ mod graphic_is_opaque_tests {
|
||||
fn gradient_with_transparent_stop_is_not_opaque() {
|
||||
let color_1 = Color::from_rgbaf32(1., 0., 0., 0.5).unwrap();
|
||||
let color_2 = Color::from_rgbaf32(1., 0., 0., 1.).unwrap();
|
||||
let gradient = GradientStops::new(vec![
|
||||
let gradient = Gradient::new(vec![
|
||||
GradientStop {
|
||||
position: 0.,
|
||||
midpoint: 0.5,
|
||||
|
||||
@@ -13,7 +13,7 @@ use core_types::uuid::NodeId;
|
||||
use core_types::{ATTR_EDITOR_LAYER_PATH, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_TRANSFORM, Color};
|
||||
use glam::{DAffine2, DVec2};
|
||||
use raster_types::{CPU, GPU, Raster};
|
||||
use vector_types::{GradientStops, Vector};
|
||||
use vector_types::{Gradient, Vector};
|
||||
|
||||
/// One run's attribute tokens, minted once so the lane loops read at an offset.
|
||||
struct RunAttrs {
|
||||
@@ -117,7 +117,7 @@ pub(in crate::graphic) fn group_bounding_box(group: &core_types::record::Group,
|
||||
.or_else(|| typed_run::<Raster<CPU>>(item, transform, include_stroke, thumbnail))
|
||||
.or_else(|| typed_run::<Raster<GPU>>(item, transform, include_stroke, thumbnail))
|
||||
.or_else(|| typed_run::<Color>(item, transform, include_stroke, thumbnail))
|
||||
.or_else(|| typed_run::<GradientStops>(item, transform, include_stroke, thumbnail))
|
||||
.or_else(|| typed_run::<Gradient>(item, transform, include_stroke, thumbnail))
|
||||
.or_else(|| typed_run::<String>(item, transform, include_stroke, thumbnail))
|
||||
.unwrap_or(RenderBoundingBox::Infinite)
|
||||
}
|
||||
@@ -497,7 +497,7 @@ pub(in crate::graphic) fn group_render_complexity(group: &core_types::record::Gr
|
||||
.or_else(|| typed_run::<Raster<CPU>>(item))
|
||||
.or_else(|| typed_run::<Raster<GPU>>(item))
|
||||
.or_else(|| typed_run::<Color>(item))
|
||||
.or_else(|| typed_run::<GradientStops>(item))
|
||||
.or_else(|| typed_run::<Gradient>(item))
|
||||
.or_else(|| typed_run::<String>(item))
|
||||
.unwrap_or(item.len())
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ pub mod migrations {
|
||||
use dyn_any::DynAny;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use vector_types::vector::{PointDomain, RegionDomain, SegmentDomain, misc::HandleId, style::Stroke};
|
||||
use vector_types::{GradientStops, Vector, vector};
|
||||
use vector_types::{Gradient, Vector, vector};
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, graphene_hash::CacheHash, DynAny, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Gradient {
|
||||
pub stops: GradientStops,
|
||||
pub struct LegacyGradient {
|
||||
pub stops: Gradient,
|
||||
pub gradient_type: vector::style::GradientType,
|
||||
pub start: DVec2,
|
||||
pub end: DVec2,
|
||||
@@ -39,11 +39,11 @@ pub mod migrations {
|
||||
pub transform: DAffine2,
|
||||
}
|
||||
|
||||
impl Gradient {
|
||||
impl LegacyGradient {
|
||||
/// Converts a legacy bounding-box-relative gradient (`start`/`end` in [0,1]) into an absolute one in the geometry's local space.
|
||||
/// `bounding_box` maps [0,1] onto the geometry's bounding box; `layer_transform` is the layer's own transform,
|
||||
/// used to bake the elliptical adjustment that reproduces the legacy isotropic radial through a non-uniform layer.
|
||||
pub fn to_absolute(&self, bounding_box: DAffine2, layer_transform: DAffine2) -> Gradient {
|
||||
pub fn to_absolute(&self, bounding_box: DAffine2, layer_transform: DAffine2) -> LegacyGradient {
|
||||
let start = bounding_box.transform_point2(self.start);
|
||||
let end = bounding_box.transform_point2(self.end);
|
||||
let direction = end - start;
|
||||
@@ -66,7 +66,7 @@ pub mod migrations {
|
||||
DAffine2::IDENTITY
|
||||
};
|
||||
|
||||
Gradient {
|
||||
LegacyGradient {
|
||||
start,
|
||||
end,
|
||||
transform,
|
||||
@@ -83,15 +83,15 @@ pub mod migrations {
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, graphene_hash::CacheHash, DynAny, serde::Serialize, serde::Deserialize)]
|
||||
pub enum Fill {
|
||||
pub enum LegacyFill {
|
||||
#[default]
|
||||
None,
|
||||
Solid(Color),
|
||||
Gradient(Gradient),
|
||||
Gradient(LegacyGradient),
|
||||
}
|
||||
|
||||
/// The legacy `fill` field is intentionally omitted because vector payload migration only
|
||||
/// recovers editable vector data. The fill/stroke paints are migrated from the the node inputs.
|
||||
/// recovers editable vector data. The fill/stroke paints are migrated from the node inputs.
|
||||
#[derive(serde::Deserialize)]
|
||||
#[cfg_attr(test, derive(Default, serde::Serialize))]
|
||||
pub(super) struct PathStyle {
|
||||
@@ -165,7 +165,7 @@ pub mod migrations {
|
||||
.unwrap()
|
||||
.as_object_mut()
|
||||
.unwrap()
|
||||
.insert("fill".into(), serde_json::to_value(legacy::Fill::default()).unwrap());
|
||||
.insert("fill".into(), serde_json::to_value(legacy::LegacyFill::default()).unwrap());
|
||||
let migrated = migrate_to_optional_vector(value).unwrap().unwrap();
|
||||
|
||||
assert_eq!(migrated.stroke.unwrap().weight, 12.);
|
||||
|
||||
@@ -11,7 +11,7 @@ use graphic_types::vector_types::gradient::GradientType;
|
||||
use graphic_types::vector_types::markers::{GradientType as GradientTypeAttr, SpreadMethod};
|
||||
use graphic_types::vector_types::vector::style::{PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
|
||||
use std::fmt::Write;
|
||||
use vector_types::GradientStops;
|
||||
use vector_types::Gradient;
|
||||
use vector_types::gradient::GradientSpreadMethod;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
@@ -83,7 +83,7 @@ impl RenderExt for List<Color> {
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderExt for List<GradientStops> {
|
||||
impl RenderExt for List<Gradient> {
|
||||
type Output = u64;
|
||||
|
||||
/// Adds the gradient def through mutating the first argument, returning the gradient ID.
|
||||
@@ -103,7 +103,7 @@ impl RenderExt for List<GradientStops> {
|
||||
|
||||
/// Adds the gradient def through mutating `svg_defs`, returning the gradient
|
||||
/// ID, over any gradient lane source.
|
||||
pub fn render_gradient_paint<S: core_types::lane::LaneSource<Element = GradientStops>>(source: &S, svg_defs: &mut String, item_transform: DAffine2, element_transform: DAffine2) -> u64 {
|
||||
pub fn render_gradient_paint<S: core_types::lane::LaneSource<Element = Gradient>>(source: &S, svg_defs: &mut String, item_transform: DAffine2, element_transform: DAffine2) -> u64 {
|
||||
let mut stop = String::new();
|
||||
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ use graphene_resource::Resource;
|
||||
use graphic_types::graphic::{PaintColumns, PaintOverlay, PaintReach, has_paint, is_paint_present, paint_graphics, set_paint_attribute, vector_can_reduce_to_clip_path};
|
||||
use graphic_types::markers::{EditorMergedLayers, Fill, Stroke};
|
||||
use graphic_types::raster_types::{BitmapMut, CPU, GPU, Image, Raster, Texture};
|
||||
use graphic_types::vector_types::gradient::{GradientStops, GradientType};
|
||||
use graphic_types::vector_types::gradient::{Gradient, GradientType};
|
||||
use graphic_types::vector_types::markers::{GradientType as GradientTypeAttr, SpreadMethod};
|
||||
use graphic_types::vector_types::subpath::Subpath;
|
||||
use graphic_types::vector_types::vector::click_target::{ClickTarget, FreePoint};
|
||||
@@ -400,7 +400,7 @@ pub(crate) fn gradient_placement(transform: DAffine2, gradient_type: GradientTyp
|
||||
}
|
||||
}
|
||||
|
||||
fn create_peniko_gradient_brush<S: LaneSource<Element = GradientStops>>(gradient_list: &S, multiplied_transform: &DAffine2) -> Option<(peniko::Brush, DAffine2)> {
|
||||
fn create_peniko_gradient_brush<S: LaneSource<Element = Gradient>>(gradient_list: &S, multiplied_transform: &DAffine2) -> Option<(peniko::Brush, DAffine2)> {
|
||||
let stops = gradient_list.element(0)?;
|
||||
|
||||
let gradient_type: GradientType = gradient_list.attr::<GradientTypeAttr>(0);
|
||||
@@ -694,7 +694,7 @@ fn collect_group_row_metadata(group: &Group, metadata: &mut RenderMetadata, elem
|
||||
.or_else(|| lane_zero_transform::<Raster<CPU>>(item))
|
||||
.or_else(|| lane_zero_transform::<Raster<GPU>>(item))
|
||||
.or_else(|| lane_zero_transform::<Color>(item))
|
||||
.or_else(|| lane_zero_transform::<GradientStops>(item))
|
||||
.or_else(|| lane_zero_transform::<Gradient>(item))
|
||||
.or_else(|| lane_zero_transform::<String>(item));
|
||||
if let Some(transform) = transform {
|
||||
metadata.local_transforms.insert(element_id, transform);
|
||||
@@ -741,7 +741,7 @@ fn render_group_svg<'a>(group: &'a Group, reach: PaintReach<'a>, render: &mut Sv
|
||||
} else if item.typed_lanes::<Raster<GPU>>().is_some() {
|
||||
} else if let Some(run) = RunView::<Color>::new(item) {
|
||||
render_color_svg(&run, render, render_params)
|
||||
} else if let Some(run) = RunView::<GradientStops>::new(item) {
|
||||
} else if let Some(run) = RunView::<Gradient>::new(item) {
|
||||
render_gradient_svg(&run, render, render_params)
|
||||
} else if let Some(run) = RunView::<String>::new(item) {
|
||||
render_text_svg(&run, render, render_params)
|
||||
@@ -763,7 +763,7 @@ fn render_group_vello<'a>(group: &'a Group, reach: PaintReach<'a>, scene: &mut S
|
||||
render_raster_gpu_vello(&run, scene, transform, context, render_params)
|
||||
} else if let Some(run) = RunView::<Color>::new(item) {
|
||||
render_color_vello(&run, scene, render_params)
|
||||
} else if let Some(run) = RunView::<GradientStops>::new(item) {
|
||||
} else if let Some(run) = RunView::<Gradient>::new(item) {
|
||||
render_gradient_vello(&run, scene, transform, render_params)
|
||||
} else if let Some(run) = RunView::<String>::new(item) {
|
||||
render_text_vello(&run, scene, transform, render_params)
|
||||
@@ -786,7 +786,7 @@ fn collect_group_metadata<'a>(group: &'a Group, reach: PaintReach<'a>, metadata:
|
||||
collect_raster_metadata(&run, metadata, footprint, element_id)
|
||||
} else if let Some(run) = RunView::<Raster<GPU>>::new(item) {
|
||||
collect_raster_metadata(&run, metadata, footprint, element_id)
|
||||
} else if item.typed_lanes::<Color>().is_some() || item.typed_lanes::<GradientStops>().is_some() {
|
||||
} else if item.typed_lanes::<Color>().is_some() || item.typed_lanes::<Gradient>().is_some() {
|
||||
} else if let Some(run) = RunView::<String>::new(item) {
|
||||
collect_text_metadata(&run, metadata, footprint, element_id)
|
||||
}
|
||||
@@ -2282,7 +2282,7 @@ impl Render for List<Color> {
|
||||
}
|
||||
}
|
||||
|
||||
fn render_gradient_svg<S: LaneSource<Element = GradientStops>>(source: &S, render: &mut SvgRender, render_params: &RenderParams) {
|
||||
fn render_gradient_svg<S: LaneSource<Element = Gradient>>(source: &S, render: &mut SvgRender, render_params: &RenderParams) {
|
||||
// For thumbnails the gradient fills a finite rect at the footprint's document space bounds, with a 1-unit margin to cover the `as u32` truncation of `Footprint::resolution`.
|
||||
// The viewBox crops the overshoot. Canvas rendering keeps the polyline path since Chrome rejects rects larger than ~20 million.
|
||||
let thumbnail_rect = if render_params.thumbnail {
|
||||
@@ -2374,7 +2374,7 @@ fn render_gradient_svg<S: LaneSource<Element = GradientStops>>(source: &S, rende
|
||||
}
|
||||
}
|
||||
|
||||
fn render_gradient_vello<S: LaneSource<Element = GradientStops>>(source: &S, scene: &mut Scene, parent_transform: DAffine2, render_params: &RenderParams) {
|
||||
fn render_gradient_vello<S: LaneSource<Element = Gradient>>(source: &S, scene: &mut Scene, parent_transform: DAffine2, render_params: &RenderParams) {
|
||||
use vello::peniko;
|
||||
|
||||
if let RenderMode::Outline = render_params.render_mode {
|
||||
@@ -2458,7 +2458,7 @@ fn render_gradient_vello<S: LaneSource<Element = GradientStops>>(source: &S, sce
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for List<GradientStops> {
|
||||
impl Render for List<Gradient> {
|
||||
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) {
|
||||
render_gradient_svg(self, render, render_params)
|
||||
}
|
||||
@@ -2926,7 +2926,7 @@ impl Render for RunView<'_, Color> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for RunView<'_, GradientStops> {
|
||||
impl Render for RunView<'_, Gradient> {
|
||||
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) {
|
||||
render_gradient_svg(self, render, render_params)
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@ pub enum GradientType {
|
||||
// TODO: Someday we could switch this to a Box[T] to avoid over-allocation
|
||||
/// A list of colors (linear, unassociated alpha) associated with positions (in the range 0 to 1) along a gradient.
|
||||
///
|
||||
/// Not exposed via Tsify; use [`GradientStopsUI`] at the JS boundary.
|
||||
/// Not exposed via Tsify; use [`GradientUI`] at the JS boundary.
|
||||
#[derive(Debug, Clone, PartialEq, graphene_hash::CacheHash, DynAny)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
||||
pub struct GradientStops {
|
||||
pub struct Gradient {
|
||||
/// The position of this stop, a factor from 0-1 along the length of the full gradient.
|
||||
pub position: Vec<f64>,
|
||||
/// The midpoint to the right of this stop, a factor from 0-1 along the distance to the next stop. The final stop's midpoint is ignored.
|
||||
@@ -29,18 +29,18 @@ pub struct GradientStops {
|
||||
pub color: Vec<Color>,
|
||||
}
|
||||
|
||||
/// JS-boundary version of [`GradientStops`] where stop colors are [`SRGBA8`] byte triples instead of linear-light [`Color`].
|
||||
/// JS-boundary version of [`Gradient`] where stop colors are [`SRGBA8`] byte triples instead of linear-light [`Color`].
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify), tsify(from_wasm_abi))]
|
||||
#[derive(Debug, Clone, PartialEq, Default, DynAny)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct GradientStopsUI {
|
||||
pub struct GradientUI {
|
||||
pub position: Vec<f64>,
|
||||
pub midpoint: Vec<f64>,
|
||||
pub color: Vec<SRGBA8>,
|
||||
}
|
||||
|
||||
impl From<&GradientStops> for GradientStopsUI {
|
||||
fn from(s: &GradientStops) -> Self {
|
||||
impl From<&Gradient> for GradientUI {
|
||||
fn from(s: &Gradient) -> Self {
|
||||
Self {
|
||||
position: s.position.clone(),
|
||||
midpoint: s.midpoint.clone(),
|
||||
@@ -49,8 +49,8 @@ impl From<&GradientStops> for GradientStopsUI {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&GradientStopsUI> for GradientStops {
|
||||
fn from(s: &GradientStopsUI) -> Self {
|
||||
impl From<&GradientUI> for Gradient {
|
||||
fn from(s: &GradientUI) -> Self {
|
||||
Self {
|
||||
position: s.position.clone(),
|
||||
midpoint: s.midpoint.clone(),
|
||||
@@ -59,7 +59,7 @@ impl From<&GradientStopsUI> for GradientStops {
|
||||
}
|
||||
}
|
||||
|
||||
impl GradientStopsUI {
|
||||
impl GradientUI {
|
||||
/// CSS `linear-gradient(...)` string. Stops are emitted as `#rrggbbaa` hex (already gamma-encoded bytes).
|
||||
pub fn to_css_linear_gradient(&self) -> String {
|
||||
if self.position.len() <= 1 {
|
||||
@@ -67,7 +67,7 @@ impl GradientStopsUI {
|
||||
return format!("linear-gradient(to right, #{hex} 0%, #{hex} 100%)");
|
||||
}
|
||||
// Sample via the midpoint-aware subdivision used for SVG/Vello stops so browser interpolation matches
|
||||
let stops: GradientStops = self.into();
|
||||
let stops: Gradient = self.into();
|
||||
let pieces = stops
|
||||
.interpolated_samples()
|
||||
.into_iter()
|
||||
@@ -83,7 +83,7 @@ impl GradientStopsUI {
|
||||
}
|
||||
|
||||
// TODO: Eventually remove this migration document upgrade code
|
||||
impl<'de> serde::Deserialize<'de> for GradientStops {
|
||||
impl<'de> serde::Deserialize<'de> for Gradient {
|
||||
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
#[derive(serde::Deserialize)]
|
||||
struct NewFormat {
|
||||
@@ -117,7 +117,7 @@ impl<'de> serde::Deserialize<'de> for GradientStops {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GradientStops {
|
||||
impl Default for Gradient {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
position: vec![0., 1.],
|
||||
@@ -127,7 +127,7 @@ impl Default for GradientStops {
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderComplexity for GradientStops {
|
||||
impl RenderComplexity for Gradient {
|
||||
fn render_complexity(&self) -> usize {
|
||||
1
|
||||
}
|
||||
@@ -158,7 +158,7 @@ pub struct GradientStop {
|
||||
}
|
||||
|
||||
pub struct GradientStopsIter<'a> {
|
||||
stops: &'a GradientStops,
|
||||
stops: &'a Gradient,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ impl<'a> Iterator for GradientStopsIter<'a> {
|
||||
|
||||
impl ExactSizeIterator for GradientStopsIter<'_> {}
|
||||
|
||||
impl<'a> IntoIterator for &'a GradientStops {
|
||||
impl<'a> IntoIterator for &'a Gradient {
|
||||
type Item = GradientStop;
|
||||
type IntoIter = GradientStopsIter<'a>;
|
||||
|
||||
@@ -196,7 +196,7 @@ impl<'a> IntoIterator for &'a GradientStops {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for GradientStops {
|
||||
impl IntoIterator for Gradient {
|
||||
type Item = GradientStop;
|
||||
type IntoIter = std::vec::IntoIter<GradientStop>;
|
||||
|
||||
@@ -211,7 +211,7 @@ impl IntoIterator for GradientStops {
|
||||
}
|
||||
}
|
||||
|
||||
impl GradientStops {
|
||||
impl Gradient {
|
||||
pub fn new(stops: impl IntoIterator<Item = GradientStop>) -> Self {
|
||||
let mut position = Vec::new();
|
||||
let mut midpoint = Vec::new();
|
||||
@@ -465,7 +465,7 @@ impl GradientStops {
|
||||
let color = a.color.lerp(&b.color, time as f32);
|
||||
GradientStop { position, midpoint: 0.5, color }
|
||||
});
|
||||
GradientStops::new(stops)
|
||||
Gradient::new(stops)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,19 +540,19 @@ pub fn initial_gradient_transform_for_bounding_box(bounds: [DVec2; 2]) -> DAffin
|
||||
}
|
||||
|
||||
// TODO: Eventually remove this migration document upgrade code
|
||||
pub fn migrate_to_gradient_stops<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<GradientStops, D::Error> {
|
||||
pub fn migrate_to_gradient<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Gradient, D::Error> {
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct LegacyTable {
|
||||
#[serde(alias = "instances", alias = "instance")]
|
||||
element: Vec<GradientStops>,
|
||||
element: Vec<Gradient>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[cfg_attr(feature = "serde", serde(untagged))]
|
||||
enum GradientStopsFormat {
|
||||
Stops(GradientStops),
|
||||
Stops(Gradient),
|
||||
List(LegacyTable),
|
||||
}
|
||||
|
||||
@@ -562,7 +562,7 @@ pub fn migrate_to_gradient_stops<'de, D: serde::Deserializer<'de>>(deserializer:
|
||||
})
|
||||
}
|
||||
|
||||
impl core_types::bounds::BoundingBox for GradientStops {
|
||||
impl core_types::bounds::BoundingBox for Gradient {
|
||||
fn bounding_box(&self, _transform: DAffine2, _include_stroke: bool) -> core_types::bounds::RenderBoundingBox {
|
||||
core_types::bounds::RenderBoundingBox::Infinite
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ pub mod vector;
|
||||
|
||||
// Re-export commonly used types at the crate root
|
||||
pub use core_types as gcore;
|
||||
pub use gradient::{GradientSpreadMethod, GradientStop, GradientStops, GradientType};
|
||||
pub use gradient::{Gradient, GradientSpreadMethod, GradientStop, GradientType};
|
||||
pub use markers::{ATTR_EDITOR_CLICK_TARGET, ATTR_GRADIENT_TYPE, ATTR_SPREAD_METHOD};
|
||||
pub use math::{QuadExt, RectExt};
|
||||
pub use subpath::Subpath;
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::f64::consts::{PI, TAU};
|
||||
|
||||
/// Describes an editable fill choice, storing color or gradient stops without gradient placement metadata.
|
||||
///
|
||||
/// Can be None, a solid [Color], or a linear/radial [GradientStops].
|
||||
/// Can be None, a solid [Color], or a linear/radial [Gradient].
|
||||
///
|
||||
/// In the future we'll probably also add a pattern fill.
|
||||
///
|
||||
@@ -22,11 +22,11 @@ pub enum FillChoice {
|
||||
#[default]
|
||||
None,
|
||||
Solid(Color),
|
||||
Gradient(GradientStops),
|
||||
Gradient(Gradient),
|
||||
}
|
||||
|
||||
// TODO: Deprecate [`FillChoice`] and keep this, renamed, as the main widget-controlling type
|
||||
/// JS-boundary version of [`FillChoice`] where the solid color is [`SRGBA8`] and the gradient is [`GradientStopsUI`].
|
||||
/// JS-boundary version of [`FillChoice`] where the solid color is [`SRGBA8`] and the gradient is [`GradientUI`].
|
||||
#[cfg_attr(feature = "wasm", derive(tsify::Tsify), tsify(from_wasm_abi))]
|
||||
#[derive(Default, Debug, Clone, PartialEq, DynAny)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
@@ -34,7 +34,7 @@ pub enum FillChoiceUI {
|
||||
#[default]
|
||||
None,
|
||||
Solid(SRGBA8),
|
||||
Gradient(GradientStopsUI),
|
||||
Gradient(GradientUI),
|
||||
}
|
||||
|
||||
impl From<&FillChoice> for FillChoiceUI {
|
||||
@@ -42,7 +42,7 @@ impl From<&FillChoice> for FillChoiceUI {
|
||||
match value {
|
||||
FillChoice::None => Self::None,
|
||||
FillChoice::Solid(color) => Self::Solid(SRGBA8::from(*color)),
|
||||
FillChoice::Gradient(stops) => Self::Gradient(GradientStopsUI::from(stops)),
|
||||
FillChoice::Gradient(stops) => Self::Gradient(GradientUI::from(stops)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ impl From<&FillChoiceUI> for FillChoice {
|
||||
match value {
|
||||
FillChoiceUI::None => Self::None,
|
||||
FillChoiceUI::Solid(srgba) => Self::Solid(Color::from(*srgba)),
|
||||
FillChoiceUI::Gradient(stops) => Self::Gradient(GradientStops::from(stops)),
|
||||
FillChoiceUI::Gradient(stops) => Self::Gradient(Gradient::from(stops)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ impl FillChoiceUI {
|
||||
Some(*c)
|
||||
}
|
||||
|
||||
pub fn as_gradient(&self) -> Option<&GradientStopsUI> {
|
||||
pub fn as_gradient(&self) -> Option<&GradientUI> {
|
||||
let Self::Gradient(g) = self else { return None };
|
||||
Some(g)
|
||||
}
|
||||
@@ -88,7 +88,7 @@ impl FillChoice {
|
||||
Some(*color)
|
||||
}
|
||||
|
||||
pub fn as_gradient(&self) -> Option<&GradientStops> {
|
||||
pub fn as_gradient(&self) -> Option<&Gradient> {
|
||||
let Self::Gradient(gradient) = self else { return None };
|
||||
Some(gradient)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user