mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Serve bounding boxes through the lane source
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use crate::Color;
|
||||
use crate::lane::LaneSource;
|
||||
use glam::{DAffine2, DVec2};
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug, PartialEq)]
|
||||
@@ -51,3 +52,60 @@ impl BoundingBox for Color {
|
||||
RenderBoundingBox::Infinite
|
||||
}
|
||||
}
|
||||
|
||||
/// Combined bounding box of a lane source's elements, composing each lane's
|
||||
/// transform attribute with the given transform.
|
||||
pub fn lane_bounding_box<S: LaneSource>(source: &S, transform: DAffine2, include_stroke: bool) -> RenderBoundingBox
|
||||
where
|
||||
S::Element: BoundingBox,
|
||||
{
|
||||
let mut combined_bounds = None;
|
||||
|
||||
for lane in 0..source.lane_count() {
|
||||
let Some(element) = source.element(lane) else { continue };
|
||||
let lane_transform: DAffine2 = source.attr::<crate::attribute::Transform>(lane);
|
||||
match element.bounding_box(transform * lane_transform, include_stroke) {
|
||||
RenderBoundingBox::None => continue,
|
||||
RenderBoundingBox::Infinite => return RenderBoundingBox::Infinite,
|
||||
RenderBoundingBox::Rectangle(bounds) => match combined_bounds {
|
||||
Some(existing) => combined_bounds = Some(crate::math::quad::Quad::combine_bounds(existing, bounds)),
|
||||
None => combined_bounds = Some(bounds),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
match combined_bounds {
|
||||
Some(bounds) => RenderBoundingBox::Rectangle(bounds),
|
||||
None => RenderBoundingBox::None,
|
||||
}
|
||||
}
|
||||
|
||||
/// As [`lane_bounding_box`], but `Infinite` lanes are skipped (rather than
|
||||
/// propagating outward) so a finite sibling in a mixed group dictates the
|
||||
/// framing.
|
||||
pub fn lane_thumbnail_bounding_box<S: LaneSource>(source: &S, transform: DAffine2, include_stroke: bool) -> RenderBoundingBox
|
||||
where
|
||||
S::Element: BoundingBox,
|
||||
{
|
||||
let mut combined_bounds = None;
|
||||
let mut any_infinite = false;
|
||||
|
||||
for lane in 0..source.lane_count() {
|
||||
let Some(element) = source.element(lane) else { continue };
|
||||
let lane_transform: DAffine2 = source.attr::<crate::attribute::Transform>(lane);
|
||||
match element.thumbnail_bounding_box(transform * lane_transform, include_stroke) {
|
||||
RenderBoundingBox::None => continue,
|
||||
RenderBoundingBox::Infinite => any_infinite = true,
|
||||
RenderBoundingBox::Rectangle(bounds) => match combined_bounds {
|
||||
Some(existing) => combined_bounds = Some(crate::math::quad::Quad::combine_bounds(existing, bounds)),
|
||||
None => combined_bounds = Some(bounds),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
match (combined_bounds, any_infinite) {
|
||||
(Some(bounds), _) => RenderBoundingBox::Rectangle(bounds),
|
||||
(None, true) => RenderBoundingBox::Infinite,
|
||||
(None, false) => RenderBoundingBox::None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::attribute::Attribute as _;
|
||||
use crate::bounds::{BoundingBox, RenderBoundingBox};
|
||||
use crate::math::quad::Quad;
|
||||
use crate::transform::ApplyTransform;
|
||||
use dyn_any::{StaticType, StaticTypeSized};
|
||||
use glam::DAffine2;
|
||||
@@ -1105,48 +1104,12 @@ impl<T> List<T> {
|
||||
}
|
||||
|
||||
impl<T: BoundingBox> BoundingBox for List<T> {
|
||||
/// Computes the combined bounding box of all items, composing each item's transform attribute with the given transform.
|
||||
fn bounding_box(&self, transform: DAffine2, include_stroke: bool) -> RenderBoundingBox {
|
||||
let mut combined_bounds = None;
|
||||
|
||||
for (element, item_transform) in self.iter_element_values().zip(self.iter_attribute_values_or_default::<DAffine2>(ATTR_TRANSFORM)) {
|
||||
match element.bounding_box(transform * item_transform, include_stroke) {
|
||||
RenderBoundingBox::None => continue,
|
||||
RenderBoundingBox::Infinite => return RenderBoundingBox::Infinite,
|
||||
RenderBoundingBox::Rectangle(bounds) => match combined_bounds {
|
||||
Some(existing) => combined_bounds = Some(Quad::combine_bounds(existing, bounds)),
|
||||
None => combined_bounds = Some(bounds),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
match combined_bounds {
|
||||
Some(bounds) => RenderBoundingBox::Rectangle(bounds),
|
||||
None => RenderBoundingBox::None,
|
||||
}
|
||||
crate::bounds::lane_bounding_box(self, transform, include_stroke)
|
||||
}
|
||||
|
||||
fn thumbnail_bounding_box(&self, transform: DAffine2, include_stroke: bool) -> RenderBoundingBox {
|
||||
// `Infinite` items are skipped here (rather than propagating outward as in `bounding_box`) so a finite sibling in a mixed group dictates the framing
|
||||
let mut combined_bounds = None;
|
||||
let mut any_infinite = false;
|
||||
|
||||
for (element, item_transform) in self.iter_element_values().zip(self.iter_attribute_values_or_default::<DAffine2>(ATTR_TRANSFORM)) {
|
||||
match element.thumbnail_bounding_box(transform * item_transform, include_stroke) {
|
||||
RenderBoundingBox::None => continue,
|
||||
RenderBoundingBox::Infinite => any_infinite = true,
|
||||
RenderBoundingBox::Rectangle(bounds) => match combined_bounds {
|
||||
Some(existing) => combined_bounds = Some(Quad::combine_bounds(existing, bounds)),
|
||||
None => combined_bounds = Some(bounds),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
match (combined_bounds, any_infinite) {
|
||||
(Some(bounds), _) => RenderBoundingBox::Rectangle(bounds),
|
||||
(None, true) => RenderBoundingBox::Infinite,
|
||||
(None, false) => RenderBoundingBox::None,
|
||||
}
|
||||
crate::bounds::lane_thumbnail_bounding_box(self, transform, include_stroke)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1919,6 +1919,16 @@ impl<'a, T: 'static> crate::lane::LaneSource for RunView<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: crate::bounds::BoundingBox + 'static> crate::bounds::BoundingBox for RunView<'_, T> {
|
||||
fn bounding_box(&self, transform: glam::DAffine2, include_stroke: bool) -> crate::bounds::RenderBoundingBox {
|
||||
crate::bounds::lane_bounding_box(self, transform, include_stroke)
|
||||
}
|
||||
|
||||
fn thumbnail_bounding_box(&self, transform: glam::DAffine2, include_stroke: bool) -> crate::bounds::RenderBoundingBox {
|
||||
crate::bounds::lane_thumbnail_bounding_box(self, transform, include_stroke)
|
||||
}
|
||||
}
|
||||
|
||||
/// The records a group stores: a single homogeneous run, or a list of
|
||||
/// segments.
|
||||
#[derive(Clone, Debug)]
|
||||
|
||||
Reference in New Issue
Block a user