mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-20 03:18:06 +08:00
Transition gradients from bbox-relative to document-absolute space (#4241)
* Use userSpaceOnUse to render gradient on SVG * Allow non-uniform transform to radial gradient on vello * Position gradients absolutely instead of by bbox * Fix SVG import by removing multiplication of bound's inverse transform * Represent sheared linear gradients via their equivalent gradient line * Migration * Fix migration for radial (elliptical) gradients * Fix boolean operation gradients --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
use core_types::list::{Item, List};
|
||||
use core_types::uuid::NodeId;
|
||||
use core_types::{ATTR_BLEND_MODE, ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_TRANSFORM, BlendMode, Color, Ctx};
|
||||
use core_types::{
|
||||
ATTR_BLEND_MODE, ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_EDITOR_MERGED_LAYERS, ATTR_GRADIENT_TYPE, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_SPREAD_METHOD, ATTR_TRANSFORM, BlendMode, Color,
|
||||
Ctx,
|
||||
};
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graphic_types::vector_types::gradient::{Gradient, GradientSpreadMethod, GradientType};
|
||||
use graphic_types::vector_types::subpath::{ManipulatorGroup, Subpath};
|
||||
use graphic_types::vector_types::vector::PointId;
|
||||
use graphic_types::vector_types::vector::algorithms::merge_by_distance::MergeByDistanceExt;
|
||||
@@ -125,13 +129,20 @@ fn boolean_operation_on_vector_list(vector: &List<Vector>, boolean_operation: Bo
|
||||
};
|
||||
let mut row = if let Some(index) = copy_from_index {
|
||||
let mut attributes = vector.clone_item_attributes(index);
|
||||
let copy_from_transform: DAffine2 = vector.attribute_cloned_or_default(ATTR_TRANSFORM, index);
|
||||
// The boolean op bakes input transforms into the output geometry, so the result item carries no transform of its own
|
||||
attributes.insert(ATTR_TRANSFORM, DAffine2::IDENTITY);
|
||||
let copy_from = vector.element(index).unwrap();
|
||||
let element = Vector {
|
||||
let mut element = Vector {
|
||||
style: copy_from.style.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
// An absolute gradient lives in the geometry's space, so bake the same transform into it to track the baked points
|
||||
if let Fill::Gradient(gradient) = element.style.fill_mut()
|
||||
&& gradient.absolute
|
||||
{
|
||||
gradient.transform = copy_from_transform * gradient.transform;
|
||||
}
|
||||
Item::from_parts(element, attributes)
|
||||
} else {
|
||||
Item::<Vector>::default()
|
||||
@@ -272,7 +283,17 @@ fn flatten_vector(graphic_list: &List<Graphic>) -> List<Vector> {
|
||||
.map(|row| {
|
||||
let (stops, attributes) = row.into_parts();
|
||||
let mut element = Vector::default();
|
||||
element.style.set_fill(Fill::Gradient(graphic_types::vector_types::gradient::Gradient { stops, ..Default::default() }));
|
||||
// Convert the gradient's transform to absolute endpoints, matching `From<List<GradientStops>> for Fill`
|
||||
let transform = attributes.get::<DAffine2>(ATTR_TRANSFORM).cloned().unwrap_or_default();
|
||||
element.style.set_fill(Fill::Gradient(Gradient {
|
||||
stops,
|
||||
gradient_type: attributes.get::<GradientType>(ATTR_GRADIENT_TYPE).cloned().unwrap_or_default(),
|
||||
spread_method: attributes.get::<GradientSpreadMethod>(ATTR_SPREAD_METHOD).cloned().unwrap_or_default(),
|
||||
start: transform.transform_point2(DVec2::ZERO),
|
||||
end: transform.transform_point2(DVec2::X),
|
||||
absolute: true,
|
||||
transform: DAffine2::IDENTITY,
|
||||
}));
|
||||
element.style.set_stroke_transform(DAffine2::IDENTITY);
|
||||
|
||||
Item::from_parts(element, attributes)
|
||||
|
||||
Reference in New Issue
Block a user