mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 23:08:05 +08:00
Add a stack-based Boolean Operation layer node (#1813)
* Multiple boolean operation node * Change boolean operation ordering * Complete layer boolean operation node * Automatically insert new boolean operation node * Remove divide operation * Fix subtract operations * Remove stack data from boolean operation properties * Fix images and custom vectors * Code cleanup * Use slice instead of iter to avoid infinite type recursion --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -57,7 +57,7 @@ impl core::hash::Hash for GraphicGroup {
|
||||
}
|
||||
|
||||
/// The possible forms of graphical content held in a Vec by the `elements` field of [`GraphicElement`].
|
||||
/// Can be another recursively nested [`GraphicGroup`], [`VectorData`], an [`ImageFrame`], text (not yet implemented), or an [`Artboard`].
|
||||
/// Can be another recursively nested [`GraphicGroup`], a [`VectorData`] shape, an [`ImageFrame`], or an [`Artboard`].
|
||||
#[derive(Clone, Debug, Hash, PartialEq, DynAny)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum GraphicElement {
|
||||
@@ -67,10 +67,6 @@ pub enum GraphicElement {
|
||||
VectorData(Box<VectorData>),
|
||||
/// A bitmap image with a finite position and extent, equivalent to the SVG <image> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image
|
||||
ImageFrame(ImageFrame<Color>),
|
||||
// TODO: Switch from `String` to a proper formatted typography type
|
||||
/// Text, equivalent to the SVG <text> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/text
|
||||
/// (Not yet implemented.)
|
||||
Text(String),
|
||||
/// The bounds for displaying a page of contained content
|
||||
Artboard(Artboard),
|
||||
}
|
||||
@@ -366,28 +362,6 @@ impl GraphicElement {
|
||||
bounding_box: None,
|
||||
}))
|
||||
}
|
||||
GraphicElement::Text(text) => usvg::Node::Text(Box::new(usvg::Text {
|
||||
id: String::new(),
|
||||
abs_transform: usvg::Transform::identity(),
|
||||
rendering_mode: usvg::TextRendering::OptimizeSpeed,
|
||||
writing_mode: usvg::WritingMode::LeftToRight,
|
||||
chunks: vec![usvg::TextChunk {
|
||||
text: text.clone(),
|
||||
x: None,
|
||||
y: None,
|
||||
anchor: usvg::TextAnchor::Start,
|
||||
spans: vec![],
|
||||
text_flow: usvg::TextFlow::Linear,
|
||||
}],
|
||||
dx: Vec::new(),
|
||||
dy: Vec::new(),
|
||||
rotate: Vec::new(),
|
||||
bounding_box: None,
|
||||
abs_bounding_box: None,
|
||||
stroke_bounding_box: None,
|
||||
abs_stroke_bounding_box: None,
|
||||
flattened: None,
|
||||
})),
|
||||
GraphicElement::GraphicGroup(group) => {
|
||||
let mut group_element = usvg::Group::default();
|
||||
|
||||
|
||||
@@ -554,7 +554,6 @@ impl GraphicElementRendered for GraphicElement {
|
||||
match self {
|
||||
GraphicElement::VectorData(vector_data) => vector_data.render_svg(render, render_params),
|
||||
GraphicElement::ImageFrame(image_frame) => image_frame.render_svg(render, render_params),
|
||||
GraphicElement::Text(_) => todo!("Render a text GraphicElement"),
|
||||
GraphicElement::GraphicGroup(graphic_group) => graphic_group.render_svg(render, render_params),
|
||||
GraphicElement::Artboard(artboard) => artboard.render_svg(render, render_params),
|
||||
}
|
||||
@@ -564,7 +563,6 @@ impl GraphicElementRendered for GraphicElement {
|
||||
match self {
|
||||
GraphicElement::VectorData(vector_data) => GraphicElementRendered::bounding_box(&**vector_data, transform),
|
||||
GraphicElement::ImageFrame(image_frame) => image_frame.bounding_box(transform),
|
||||
GraphicElement::Text(_) => todo!("Bounds of a text GraphicElement"),
|
||||
GraphicElement::GraphicGroup(graphic_group) => graphic_group.bounding_box(transform),
|
||||
GraphicElement::Artboard(artboard) => artboard.bounding_box(transform),
|
||||
}
|
||||
@@ -574,7 +572,6 @@ impl GraphicElementRendered for GraphicElement {
|
||||
match self {
|
||||
GraphicElement::VectorData(vector_data) => vector_data.add_click_targets(click_targets),
|
||||
GraphicElement::ImageFrame(image_frame) => image_frame.add_click_targets(click_targets),
|
||||
GraphicElement::Text(_) => todo!("click target for text GraphicElement"),
|
||||
GraphicElement::GraphicGroup(graphic_group) => graphic_group.add_click_targets(click_targets),
|
||||
GraphicElement::Artboard(artboard) => artboard.add_click_targets(click_targets),
|
||||
}
|
||||
@@ -584,7 +581,6 @@ impl GraphicElementRendered for GraphicElement {
|
||||
match self {
|
||||
GraphicElement::VectorData(vector_data) => vector_data.to_usvg_node(),
|
||||
GraphicElement::ImageFrame(image_frame) => image_frame.to_usvg_node(),
|
||||
GraphicElement::Text(text) => text.to_usvg_node(),
|
||||
GraphicElement::GraphicGroup(graphic_group) => graphic_group.to_usvg_node(),
|
||||
GraphicElement::Artboard(artboard) => artboard.to_usvg_node(),
|
||||
}
|
||||
@@ -594,7 +590,6 @@ impl GraphicElementRendered for GraphicElement {
|
||||
match self {
|
||||
GraphicElement::VectorData(vector_data) => vector_data.contains_artboard(),
|
||||
GraphicElement::ImageFrame(image_frame) => image_frame.contains_artboard(),
|
||||
GraphicElement::Text(text) => text.contains_artboard(),
|
||||
GraphicElement::GraphicGroup(graphic_group) => graphic_group.contains_artboard(),
|
||||
GraphicElement::Artboard(artboard) => artboard.contains_artboard(),
|
||||
}
|
||||
|
||||
@@ -75,7 +75,6 @@ impl Transform for GraphicElement {
|
||||
match self {
|
||||
GraphicElement::VectorData(vector_shape) => vector_shape.transform(),
|
||||
GraphicElement::ImageFrame(image_frame) => image_frame.transform(),
|
||||
GraphicElement::Text(_) => todo!("Transform of text"),
|
||||
GraphicElement::GraphicGroup(graphic_group) => graphic_group.transform(),
|
||||
GraphicElement::Artboard(artboard) => artboard.transform(),
|
||||
}
|
||||
@@ -84,7 +83,6 @@ impl Transform for GraphicElement {
|
||||
match self {
|
||||
GraphicElement::VectorData(vector_shape) => vector_shape.local_pivot(pivot),
|
||||
GraphicElement::ImageFrame(image_frame) => image_frame.local_pivot(pivot),
|
||||
GraphicElement::Text(_) => todo!("Transform of text"),
|
||||
GraphicElement::GraphicGroup(graphic_group) => graphic_group.local_pivot(pivot),
|
||||
GraphicElement::Artboard(artboard) => artboard.local_pivot(pivot),
|
||||
}
|
||||
@@ -93,7 +91,6 @@ impl Transform for GraphicElement {
|
||||
match self {
|
||||
GraphicElement::VectorData(vector_shape) => vector_shape.decompose_scale(),
|
||||
GraphicElement::ImageFrame(image_frame) => image_frame.decompose_scale(),
|
||||
GraphicElement::Text(_) => todo!("Transform of text"),
|
||||
GraphicElement::GraphicGroup(graphic_group) => graphic_group.decompose_scale(),
|
||||
GraphicElement::Artboard(artboard) => artboard.decompose_scale(),
|
||||
}
|
||||
@@ -104,7 +101,6 @@ impl TransformMut for GraphicElement {
|
||||
match self {
|
||||
GraphicElement::VectorData(vector_shape) => vector_shape.transform_mut(),
|
||||
GraphicElement::ImageFrame(image_frame) => image_frame.transform_mut(),
|
||||
GraphicElement::Text(_) => todo!("Transform of text"),
|
||||
GraphicElement::GraphicGroup(graphic_group) => graphic_group.transform_mut(),
|
||||
GraphicElement::Artboard(_) => todo!("Transform of artboard"),
|
||||
}
|
||||
|
||||
@@ -18,23 +18,21 @@ pub enum BooleanOperation {
|
||||
SubtractBack,
|
||||
Intersect,
|
||||
Difference,
|
||||
Divide,
|
||||
}
|
||||
|
||||
impl BooleanOperation {
|
||||
pub fn list() -> [BooleanOperation; 6] {
|
||||
pub fn list() -> [BooleanOperation; 5] {
|
||||
[
|
||||
BooleanOperation::Union,
|
||||
BooleanOperation::SubtractFront,
|
||||
BooleanOperation::SubtractBack,
|
||||
BooleanOperation::Intersect,
|
||||
BooleanOperation::Difference,
|
||||
BooleanOperation::Divide,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn icons() -> [&'static str; 6] {
|
||||
["BooleanUnion", "BooleanSubtractFront", "BooleanSubtractBack", "BooleanIntersect", "BooleanDifference", "BooleanDivide"]
|
||||
pub fn icons() -> [&'static str; 5] {
|
||||
["BooleanUnion", "BooleanSubtractFront", "BooleanSubtractBack", "BooleanIntersect", "BooleanDifference"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +44,6 @@ impl core::fmt::Display for BooleanOperation {
|
||||
BooleanOperation::SubtractBack => write!(f, "Subtract Back"),
|
||||
BooleanOperation::Intersect => write!(f, "Intersect"),
|
||||
BooleanOperation::Difference => write!(f, "Difference"),
|
||||
BooleanOperation::Divide => write!(f, "Divide"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user