mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 23:08:05 +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::render_complexity::RenderComplexity;
|
||||
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 glam::DAffine2;
|
||||
use raster_types::{CPU, GPU, Raster};
|
||||
@@ -12,6 +12,7 @@ use vector_types::GradientStops;
|
||||
// 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.
|
||||
#[derive(Clone, Debug, CacheHash, PartialEq, DynAny)]
|
||||
@@ -169,6 +170,24 @@ fn flatten_graphic_list<T>(content: List<Graphic>, extract_variant: fn(Graphic)
|
||||
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,
|
||||
/// enabling type-directed casting of typed `List`s from a `Graphic` value.
|
||||
pub trait TryFromGraphic: Clone + Sized {
|
||||
|
||||
@@ -587,6 +587,12 @@ impl Gradient {
|
||||
|
||||
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
|
||||
@@ -625,3 +631,27 @@ impl core_types::bounds::BoundingBox for GradientStops {
|
||||
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