mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 05:18:19 +00:00
Fix how transforms work with footprints and remove a redundant transforms field (#1484)
* Prune unused thumbnails in node graph executor * Fix transform downcasting failure for GraphicElementData * Remove more warnings * Revert upstream transform calculation change * Use footprint to calculate layer transforms * Fix artboards * Move artwork with artboard * Remove Keavon's warnings * Prevent misordered FrontendMessages failing to reach JS handlers --------- Co-authored-by: 0hypercube <0hypercube@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
1093aabc88
commit
b7fe38cf31
14 changed files with 116 additions and 112 deletions
|
@ -1,4 +1,5 @@
|
|||
use crate::raster::{BlendMode, ImageFrame};
|
||||
use crate::transform::Footprint;
|
||||
use crate::vector::VectorData;
|
||||
use crate::{Color, Node};
|
||||
|
||||
|
@ -136,7 +137,8 @@ fn to_graphic_element_data<Data: Into<GraphicElementData>>(graphic_element_data:
|
|||
graphic_element_data.into()
|
||||
}
|
||||
|
||||
pub struct ConstructArtboardNode<Location, Dimensions, Background, Clip> {
|
||||
pub struct ConstructArtboardNode<Contents, Location, Dimensions, Background, Clip> {
|
||||
contents: Contents,
|
||||
location: Location,
|
||||
dimensions: Dimensions,
|
||||
background: Background,
|
||||
|
@ -144,7 +146,16 @@ pub struct ConstructArtboardNode<Location, Dimensions, Background, Clip> {
|
|||
}
|
||||
|
||||
#[node_fn(ConstructArtboardNode)]
|
||||
fn construct_artboard(graphic_group: GraphicGroup, location: IVec2, dimensions: IVec2, background: Color, clip: bool) -> Artboard {
|
||||
async fn construct_artboard<Fut: Future<Output = GraphicGroup>>(
|
||||
mut footprint: Footprint,
|
||||
contents: impl Node<Footprint, Output = Fut>,
|
||||
location: IVec2,
|
||||
dimensions: IVec2,
|
||||
background: Color,
|
||||
clip: bool,
|
||||
) -> Artboard {
|
||||
footprint.transform = footprint.transform * DAffine2::from_translation(location.as_dvec2());
|
||||
let graphic_group = self.contents.eval(footprint).await;
|
||||
Artboard {
|
||||
graphic_group,
|
||||
location: location.min(location + dimensions),
|
||||
|
|
|
@ -284,15 +284,20 @@ impl GraphicElementRendered for Artboard {
|
|||
"g",
|
||||
|attributes| {
|
||||
attributes.push("class", "artboard");
|
||||
attributes.push("transform", format_transform_matrix(self.graphic_group.transform));
|
||||
attributes.push(
|
||||
"transform",
|
||||
format_transform_matrix(DAffine2::from_translation(self.location.as_dvec2()) * self.graphic_group.transform),
|
||||
);
|
||||
if self.clip {
|
||||
let id = format!("artboard-{}", generate_uuid());
|
||||
let selector = format!("url(#{id})");
|
||||
use std::fmt::Write;
|
||||
write!(
|
||||
&mut attributes.0.svg_defs,
|
||||
r##"<clipPath id="{id}"><rect x="{}" y="{}" width="{}" height="{}"/></clipPath>"##,
|
||||
self.location.x, self.location.y, self.dimensions.x, self.dimensions.y
|
||||
r##"<clipPath id="{id}"><rect x="0" y="0" width="{}" height="{}" transform="{}"/></clipPath>"##,
|
||||
self.dimensions.x,
|
||||
self.dimensions.y,
|
||||
format_transform_matrix(self.graphic_group.transform.inverse())
|
||||
)
|
||||
.unwrap();
|
||||
attributes.push("clip-path", selector);
|
||||
|
|
|
@ -54,6 +54,10 @@ pub trait Node<'i, Input: 'i>: 'i {
|
|||
fn eval(&'i self, input: Input) -> Self::Output;
|
||||
/// Resets the node, e.g. the LetNode's cache is set to None.
|
||||
fn reset(&self) {}
|
||||
/// Returns the name of the node for diagnostic purposes.
|
||||
fn node_name(&self) -> &'static str {
|
||||
core::any::type_name::<Self>()
|
||||
}
|
||||
/// Serialize the node which is used for the `introspect` function which can retrieve values from monitor nodes.
|
||||
#[cfg(feature = "std")]
|
||||
fn serialize(&self) -> Option<std::sync::Arc<dyn core::any::Any>> {
|
||||
|
@ -98,10 +102,6 @@ where
|
|||
Self::Output: 'i + StaticTypeSized,
|
||||
Input: 'i + StaticTypeSized,
|
||||
{
|
||||
fn node_name(&self) -> &'static str {
|
||||
core::any::type_name::<Self>()
|
||||
}
|
||||
|
||||
fn input_type(&self) -> TypeId {
|
||||
TypeId::of::<Input::Static>()
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::raster::bbox::AxisAlignedBbox;
|
|||
use crate::raster::ImageFrame;
|
||||
use crate::raster::Pixel;
|
||||
use crate::vector::VectorData;
|
||||
use crate::Artboard;
|
||||
use crate::GraphicElementData;
|
||||
use crate::GraphicGroup;
|
||||
use crate::Node;
|
||||
|
@ -76,7 +77,7 @@ impl Transform for GraphicElementData {
|
|||
GraphicElementData::ImageFrame(image_frame) => image_frame.transform(),
|
||||
GraphicElementData::Text(_) => todo!("Transform of text"),
|
||||
GraphicElementData::GraphicGroup(graphic_group) => graphic_group.transform(),
|
||||
GraphicElementData::Artboard(artboard) => artboard.graphic_group.transform(),
|
||||
GraphicElementData::Artboard(artboard) => artboard.transform(),
|
||||
}
|
||||
}
|
||||
fn local_pivot(&self, pivot: DVec2) -> DVec2 {
|
||||
|
@ -85,7 +86,7 @@ impl Transform for GraphicElementData {
|
|||
GraphicElementData::ImageFrame(image_frame) => image_frame.local_pivot(pivot),
|
||||
GraphicElementData::Text(_) => todo!("Transform of text"),
|
||||
GraphicElementData::GraphicGroup(graphic_group) => graphic_group.local_pivot(pivot),
|
||||
GraphicElementData::Artboard(artboard) => artboard.graphic_group.local_pivot(pivot),
|
||||
GraphicElementData::Artboard(artboard) => artboard.local_pivot(pivot),
|
||||
}
|
||||
}
|
||||
fn decompose_scale(&self) -> DVec2 {
|
||||
|
@ -94,7 +95,7 @@ impl Transform for GraphicElementData {
|
|||
GraphicElementData::ImageFrame(image_frame) => image_frame.decompose_scale(),
|
||||
GraphicElementData::Text(_) => todo!("Transform of text"),
|
||||
GraphicElementData::GraphicGroup(graphic_group) => graphic_group.decompose_scale(),
|
||||
GraphicElementData::Artboard(artboard) => artboard.graphic_group.decompose_scale(),
|
||||
GraphicElementData::Artboard(artboard) => artboard.decompose_scale(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +106,7 @@ impl TransformMut for GraphicElementData {
|
|||
GraphicElementData::ImageFrame(image_frame) => image_frame.transform_mut(),
|
||||
GraphicElementData::Text(_) => todo!("Transform of text"),
|
||||
GraphicElementData::GraphicGroup(graphic_group) => graphic_group.transform_mut(),
|
||||
GraphicElementData::Artboard(artboard) => artboard.graphic_group.transform_mut(),
|
||||
GraphicElementData::Artboard(_) => todo!("Transform of artboard"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +125,15 @@ impl TransformMut for VectorData {
|
|||
}
|
||||
}
|
||||
|
||||
impl Transform for Artboard {
|
||||
fn transform(&self) -> DAffine2 {
|
||||
DAffine2::IDENTITY
|
||||
}
|
||||
fn local_pivot(&self, pivot: DVec2) -> DVec2 {
|
||||
self.location.as_dvec2() + self.dimensions.as_dvec2() * pivot
|
||||
}
|
||||
}
|
||||
|
||||
impl Transform for DAffine2 {
|
||||
fn transform(&self) -> DAffine2 {
|
||||
*self
|
||||
|
|
|
@ -844,7 +844,7 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||
register_node!(graphene_core::ToGraphicElementData, input: ImageFrame<Color>, params: []),
|
||||
register_node!(graphene_core::ToGraphicElementData, input: GraphicGroup, params: []),
|
||||
register_node!(graphene_core::ToGraphicElementData, input: Artboard, params: []),
|
||||
register_node!(graphene_core::ConstructArtboardNode<_, _, _, _>, input: GraphicGroup, params: [glam::IVec2, glam::IVec2, Color, bool]),
|
||||
async_node!(graphene_core::ConstructArtboardNode<_, _, _, _, _>, input: Footprint, output: Artboard, fn_params: [Footprint => GraphicGroup, () => glam::IVec2, () => glam::IVec2, () => Color, () => bool]),
|
||||
];
|
||||
let mut map: HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstructor>> = HashMap::new();
|
||||
for (id, c, types) in node_types.into_iter().flatten() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue