mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-27 15:58:12 +08:00
Add support for folder bounding boxes (#276)
This commit is contained in:
committed by
Keavon Chambers
parent
59b817301d
commit
783b7801e6
@@ -141,7 +141,7 @@ impl Document {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the layer or folder at the path. Does not return an error for root
|
/// Returns a reference to the layer or folder at the path. Does not return an error for root
|
||||||
pub fn document_layer(&mut self, path: &[LayerId]) -> Result<&Layer, DocumentError> {
|
pub fn document_layer(&self, path: &[LayerId]) -> Result<&Layer, DocumentError> {
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
return Ok(&self.root);
|
return Ok(&self.root);
|
||||||
}
|
}
|
||||||
@@ -227,13 +227,20 @@ impl Document {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layer_axis_aligned_bounding_box(&self, path: &[LayerId]) -> Result<[DVec2; 2], DocumentError> {
|
pub fn layer_axis_aligned_bounding_box(&self, path: &[LayerId]) -> Result<Option<[DVec2; 2]>, DocumentError> {
|
||||||
let layer = self.layer(path)?;
|
// TODO: Replace with functions of the transform api
|
||||||
Ok(layer.bounding_box(self.root.transform * layer.transform, layer.style))
|
if let &[] = path {
|
||||||
|
// Special case for root. Root's local is the documents global, so we avoid transforming its transform by itself.
|
||||||
|
self.layer_local_bounding_box(path)
|
||||||
|
} else {
|
||||||
|
let layer = self.document_layer(path)?;
|
||||||
|
Ok(layer.bounding_box(self.root.transform * layer.transform, layer.style))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layer_local_bounding_box(&self, path: &[LayerId]) -> Result<[DVec2; 2], DocumentError> {
|
pub fn layer_local_bounding_box(&self, path: &[LayerId]) -> Result<Option<[DVec2; 2]>, DocumentError> {
|
||||||
let layer = self.layer(path)?;
|
// TODO: Replace with functions of the transform api
|
||||||
|
let layer = self.document_layer(path)?;
|
||||||
Ok(layer.bounding_box(layer.transform, layer.style))
|
Ok(layer.bounding_box(layer.transform, layer.style))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,35 @@ impl Folder {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bounding_box(&self, transform: glam::DAffine2) -> Option<[DVec2; 2]> {
|
||||||
|
let mut layers_non_empty_bounding_boxes = self.layers.iter().filter_map(|layer| layer.bounding_box(transform * layer.transform, layer.style)).peekable();
|
||||||
|
|
||||||
|
if layers_non_empty_bounding_boxes.peek().is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut x_min = f64::MAX;
|
||||||
|
let mut y_min = f64::MAX;
|
||||||
|
let mut x_max = f64::MIN;
|
||||||
|
let mut y_max = f64::MIN;
|
||||||
|
|
||||||
|
for [bounding_box_min, bounding_box_max] in layers_non_empty_bounding_boxes {
|
||||||
|
if bounding_box_min.x < x_min {
|
||||||
|
x_min = bounding_box_min.x
|
||||||
|
}
|
||||||
|
if bounding_box_min.y < y_min {
|
||||||
|
y_min = bounding_box_min.y
|
||||||
|
}
|
||||||
|
if bounding_box_max.x > x_max {
|
||||||
|
x_max = bounding_box_max.x
|
||||||
|
}
|
||||||
|
if bounding_box_max.y > y_max {
|
||||||
|
y_max = bounding_box_max.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Some([DVec2::new(x_min, y_min), DVec2::new(x_max, y_max)]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Folder {
|
impl Default for Folder {
|
||||||
|
|||||||
@@ -175,8 +175,12 @@ impl Layer {
|
|||||||
self.data.to_kurbo_path(self.transform, self.style)
|
self.data.to_kurbo_path(self.transform, self.style)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bounding_box(&self, transform: glam::DAffine2, style: style::PathStyle) -> [DVec2; 2] {
|
pub fn bounding_box(&self, transform: glam::DAffine2, style: style::PathStyle) -> Option<[DVec2; 2]> {
|
||||||
self.data.bounding_box(transform, style)
|
if let Ok(folder) = self.as_folder() {
|
||||||
|
folder.bounding_box(transform)
|
||||||
|
} else {
|
||||||
|
Some(self.data.bounding_box(transform, style))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_folder_mut(&mut self) -> Result<&mut Folder, DocumentError> {
|
pub fn as_folder_mut(&mut self) -> Result<&mut Folder, DocumentError> {
|
||||||
|
|||||||
Reference in New Issue
Block a user