mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 15:28:12 +08:00
Add conversion from Fill to Table<Graphic>
This commit is contained in:
@@ -4,7 +4,7 @@ use core_types::list::List;
|
|||||||
use core_types::ops::ListConvert;
|
use core_types::ops::ListConvert;
|
||||||
use core_types::render_complexity::RenderComplexity;
|
use core_types::render_complexity::RenderComplexity;
|
||||||
use core_types::uuid::NodeId;
|
use core_types::uuid::NodeId;
|
||||||
use core_types::{ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_TRANSFORM, Color};
|
use core_types::{ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_GRADIENT_TYPE, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_SPREAD_METHOD, ATTR_TRANSFORM, Color};
|
||||||
use dyn_any::DynAny;
|
use dyn_any::DynAny;
|
||||||
use glam::DAffine2;
|
use glam::DAffine2;
|
||||||
use raster_types::{CPU, GPU, Raster};
|
use raster_types::{CPU, GPU, Raster};
|
||||||
@@ -12,6 +12,7 @@ use vector_types::GradientStops;
|
|||||||
// use vector_types::Vector;
|
// use vector_types::Vector;
|
||||||
|
|
||||||
pub use vector_types::Vector;
|
pub use vector_types::Vector;
|
||||||
|
use vector_types::vector::style::Fill;
|
||||||
|
|
||||||
/// The possible forms of graphical content that can be rendered by the Render node into either an image or SVG syntax.
|
/// The possible forms of graphical content that can be rendered by the Render node into either an image or SVG syntax.
|
||||||
#[derive(Clone, Debug, CacheHash, PartialEq, DynAny)]
|
#[derive(Clone, Debug, CacheHash, PartialEq, DynAny)]
|
||||||
@@ -169,6 +170,24 @@ fn flatten_graphic_list<T>(content: List<Graphic>, extract_variant: fn(Graphic)
|
|||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts a `Fill` enum into the `Table<Graphic>` representation used as paint storage.
|
||||||
|
/// TODO: Remove once all paint sources flow through `Table<Graphic>` directly without going through the `Fill` enum.
|
||||||
|
pub fn fill_to_paint(fill: &Fill) -> Option<Table<Graphic>> {
|
||||||
|
match fill {
|
||||||
|
Fill::None => None,
|
||||||
|
Fill::Solid(color) => Some(Table::new_from_element((*color).into())),
|
||||||
|
Fill::Gradient(gradient) => {
|
||||||
|
let gradient_row = TableRow::new_from_element(gradient.stops.clone())
|
||||||
|
.with_attribute(ATTR_TRANSFORM, gradient.to_transform())
|
||||||
|
.with_attribute(ATTR_GRADIENT_TYPE, gradient.gradient_type)
|
||||||
|
.with_attribute(ATTR_SPREAD_METHOD, gradient.spread_method);
|
||||||
|
let gradient_table = Table::new_from_row(gradient_row);
|
||||||
|
|
||||||
|
Some(Table::new_from_element(Graphic::Gradient(gradient_table)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Maps from a concrete element type to its corresponding `Graphic` enum variant,
|
/// Maps from a concrete element type to its corresponding `Graphic` enum variant,
|
||||||
/// enabling type-directed casting of typed `List`s from a `Graphic` value.
|
/// enabling type-directed casting of typed `List`s from a `Graphic` value.
|
||||||
pub trait TryFromGraphic: Clone + Sized {
|
pub trait TryFromGraphic: Clone + Sized {
|
||||||
|
|||||||
@@ -587,6 +587,12 @@ impl Gradient {
|
|||||||
|
|
||||||
Some(index)
|
Some(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Builds the affine that places the gradient endpoints at `start` and `end` when applied to canonical gradient space (0,0) -> (1,0)
|
||||||
|
pub fn to_transform(&self) -> DAffine2 {
|
||||||
|
let direction = self.end - self.start;
|
||||||
|
DAffine2::from_cols(direction, direction.perp(), self.start)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Eventually remove this migration document upgrade code
|
// TODO: Eventually remove this migration document upgrade code
|
||||||
@@ -625,3 +631,27 @@ impl core_types::bounds::BoundingBox for GradientStops {
|
|||||||
core_types::bounds::RenderBoundingBox::Rectangle([start.min(end), start.max(end)])
|
core_types::bounds::RenderBoundingBox::Rectangle([start.min(end), start.max(end)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use glam::DVec2;
|
||||||
|
|
||||||
|
fn linear_gradient(start: DVec2, end: DVec2) -> Gradient {
|
||||||
|
Gradient { start, end, ..Default::default() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_transform_roundtrip() {
|
||||||
|
let cases = [(DVec2::ZERO, DVec2::X), (DVec2::new(10., 20.), DVec2::new(50., 30.)), (DVec2::new(-5., -5.), DVec2::new(5., 3.))];
|
||||||
|
|
||||||
|
for (start, end) in cases {
|
||||||
|
let transform = linear_gradient(start, end).to_transform();
|
||||||
|
let recovered_start = transform.transform_point2(DVec2::ZERO);
|
||||||
|
let recovered_end = transform.transform_point2(DVec2::X);
|
||||||
|
|
||||||
|
assert!((recovered_start - start).length() < 1e-10);
|
||||||
|
assert!((recovered_end - end).length() < 1e-10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user