[librsvg/librsvg-2.52: 3/19] Extract function to compute bounding rectangles from compute_stroke_and_fill_box
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.52: 3/19] Extract function to compute bounding rectangles from compute_stroke_and_fill_box
- Date: Thu, 17 Feb 2022 03:49:55 +0000 (UTC)
commit 17219dedb09bc31dd095b6c4cadae178e49c796b
Author: Federico Mena Quintero <federico gnome org>
Date: Fri Feb 4 12:44:56 2022 -0600
Extract function to compute bounding rectangles from compute_stroke_and_fill_box
That function now puts the rectangles in a BoundingBox, with their
coordinate system.
The test filters-composite-02-b.svg seems to have lost a pixel column...
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/660>
src/drawing_ctx.rs | 77 +++++++++++++++------
.../reftests/svg1.1/filters-composite-02-b-ref.png | Bin 17774 -> 17772 bytes
2 files changed, 57 insertions(+), 20 deletions(-)
---
diff --git a/src/drawing_ctx.rs b/src/drawing_ctx.rs
index 01cfab4d5..1b05b22af 100644
--- a/src/drawing_ctx.rs
+++ b/src/drawing_ctx.rs
@@ -1908,15 +1908,11 @@ impl CompositingAffines {
}
}
-fn compute_stroke_and_fill_box(
+fn compute_stroke_and_fill_extents(
cr: &cairo::Context,
stroke: &Stroke,
stroke_paint_source: &PaintSource,
-) -> Result<BoundingBox, RenderingError> {
- let affine = Transform::from(cr.matrix());
-
- let mut bbox = BoundingBox::new().with_transform(affine);
-
+) -> Result<PathExtents, RenderingError> {
// Dropping the precision of cairo's bezier subdivision, yielding 2x
// _rendering_ time speedups, are these rather expensive operations
// really needed here? */
@@ -1932,10 +1928,7 @@ fn compute_stroke_and_fill_box(
// rectangle's extents, even when it has no fill nor stroke.
let (x0, y0, x1, y1) = cr.fill_extents()?;
- let fb = BoundingBox::new()
- .with_transform(affine)
- .with_ink_rect(Rect::new(x0, y0, x1, y1));
- bbox.insert(&fb);
+ let fill_extents = Some(Rect::new(x0, y0, x1, y1));
// Bounding box for stroke
//
@@ -1948,26 +1941,55 @@ fn compute_stroke_and_fill_box(
// So, see if the stroke width is 0 and just not include the stroke in the
// bounding box if so.
- if !stroke.width.approx_eq_cairo(0.0) && !matches!(stroke_paint_source, PaintSource::None) {
+ let stroke_extents = if !stroke.width.approx_eq_cairo(0.0)
+ && !matches!(stroke_paint_source, PaintSource::None)
+ {
let (x0, y0, x1, y1) = cr.stroke_extents()?;
- let sb = BoundingBox::new()
- .with_transform(affine)
- .with_ink_rect(Rect::new(x0, y0, x1, y1));
- bbox.insert(&sb);
- }
+ Some(Rect::new(x0, y0, x1, y1))
+ } else {
+ None
+ };
// objectBoundingBox
let (x0, y0, x1, y1) = cr.path_extents()?;
- let ob = BoundingBox::new()
- .with_transform(affine)
- .with_rect(Rect::new(x0, y0, x1, y1));
- bbox.insert(&ob);
+ let path_extents = Some(Rect::new(x0, y0, x1, y1));
// restore tolerance
cr.set_tolerance(backup_tolerance);
+ Ok(PathExtents {
+ path_only: path_extents,
+ fill: fill_extents,
+ stroke: stroke_extents,
+ })
+}
+
+fn compute_stroke_and_fill_box(
+ cr: &cairo::Context,
+ stroke: &Stroke,
+ stroke_paint_source: &PaintSource,
+) -> Result<BoundingBox, RenderingError> {
+ let extents = compute_stroke_and_fill_extents(cr, stroke, stroke_paint_source)?;
+
+ let ink_rect = match (extents.fill, extents.stroke) {
+ (None, None) => None,
+ (Some(f), None) => Some(f),
+ (None, Some(s)) => Some(s),
+ (Some(f), Some(s)) => Some(f.union(&s)),
+ };
+
+ let mut bbox = BoundingBox::new().with_transform(Transform::from(cr.matrix()));
+
+ if let Some(rect) = extents.path_only {
+ bbox = bbox.with_rect(rect);
+ }
+
+ if let Some(ink_rect) = ink_rect {
+ bbox = bbox.with_ink_rect(ink_rect);
+ }
+
Ok(bbox)
}
@@ -2111,6 +2133,21 @@ impl From<Transform> for cairo::Matrix {
}
}
+/// Extents for a path in its current coordinate system.
+///
+/// Normally you'll want to convert this to a BoundingBox, which has knowledge about just
+/// what that coordinate system is.
+pub struct PathExtents {
+ /// Extents of the "plain", unstroked path, or `None` if the path is empty.
+ pub path_only: Option<Rect>,
+
+ /// Extents of just the fill, or `None` if the path is empty.
+ pub fill: Option<Rect>,
+
+ /// Extents for the stroked path, or `None` if the path is empty or zero-width.
+ pub stroke: Option<Rect>,
+}
+
impl Path {
pub fn to_cairo(
&self,
diff --git a/tests/fixtures/reftests/svg1.1/filters-composite-02-b-ref.png
b/tests/fixtures/reftests/svg1.1/filters-composite-02-b-ref.png
index 4cd27db84..4fcdb70e6 100644
Binary files a/tests/fixtures/reftests/svg1.1/filters-composite-02-b-ref.png and
b/tests/fixtures/reftests/svg1.1/filters-composite-02-b-ref.png differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]