[librsvg: 1/2] DrawingCtx::draw_path - clear/recalculate path only when needed
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 1/2] DrawingCtx::draw_path - clear/recalculate path only when needed
- Date: Wed, 2 Sep 2020 17:45:39 +0000 (UTC)
commit 008ddce3dc506e002a4a1ebc162860104963482f
Author: John Ledbetter <john ledbetter gmail com>
Date: Wed Sep 2 09:36:54 2020 -0400
DrawingCtx::draw_path - clear/recalculate path only when needed
In the default 'Fill, Stroke, Markers' paint order, there's no need
to regenerate the draw path in between each step, only once at the start.
We only need to re-generate the path if the paint-order specifies that the
Markers step comes between Fill and Stroke.
Adjust fill & stroke to preserve the cairo path, only creating a new one
if it has been unset to paint markers.
* Remove redundant 'if clipping' check when painting; we never get to this
match if we're clipping.
* Convert clipping if/else to an early return to help de-indent the painting
block.
rsvg_internals/src/drawing_ctx.rs | 61 ++++++++++++++++++++++++---------------
1 file changed, 38 insertions(+), 23 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index e73d134c..ead30f4b 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -1178,7 +1178,7 @@ impl DrawingCtx {
)
.map(|had_paint_server| {
if had_paint_server {
- cr.stroke();
+ cr.stroke_preserve();
}
})?;
@@ -1203,7 +1203,7 @@ impl DrawingCtx {
)
.map(|had_paint_server| {
if had_paint_server {
- cr.fill();
+ cr.fill_preserve();
}
})?;
@@ -1230,39 +1230,54 @@ impl DrawingCtx {
if clipping {
cr.set_fill_rule(cairo::FillRule::from(values.clip_rule()));
path.to_cairo(&cr, is_square_linecap)?;
- Ok(dc.empty_bbox())
- } else {
- let current_color = values.color().0;
+ return Ok(dc.empty_bbox());
+ }
- cr.set_antialias(cairo::Antialias::from(values.shape_rendering()));
- dc.setup_cr_for_stroke(&cr, values);
+ let current_color = values.color().0;
- cr.set_fill_rule(cairo::FillRule::from(values.fill_rule()));
- path.to_cairo(&cr, is_square_linecap)?;
- let bbox = compute_stroke_and_fill_box(&cr, &values);
- cr.new_path();
+ cr.set_antialias(cairo::Antialias::from(values.shape_rendering()));
+ dc.setup_cr_for_stroke(&cr, values);
- for &target in &values.paint_order().targets {
- match target {
- PaintTarget::Fill if !clipping => {
+ cr.set_fill_rule(cairo::FillRule::from(values.fill_rule()));
+
+ let mut bounding_box: Option<BoundingBox> = None;
+ let mut has_path = false;
+ cr.new_path();
+
+ for &target in &values.paint_order().targets {
+ // fill and stroke operations will preserve the path.
+ // markers operation will clear the path.
+ match target {
+ PaintTarget::Fill | PaintTarget::Stroke => {
+ if !has_path {
path.to_cairo(&cr, is_square_linecap)?;
- dc.fill(&cr, an, values, &bbox, current_color)?;
- cr.new_path();
+ has_path = true;
}
- PaintTarget::Stroke if !clipping => {
- path.to_cairo(&cr, is_square_linecap)?;
+ let bbox = bounding_box
+ .get_or_insert_with(|| compute_stroke_and_fill_box(&cr, &values));
+
+ if target == PaintTarget::Stroke {
dc.stroke(&cr, an, values, &bbox, current_color)?;
- cr.new_path();
+ } else {
+ dc.fill(&cr, an, values, &bbox, current_color)?;
}
- PaintTarget::Markers if markers == Markers::Yes => {
- marker::render_markers_for_path(path, dc, an, values, clipping)?;
+ }
+ PaintTarget::Markers if markers == Markers::Yes => {
+ if has_path {
+ cr.new_path();
+ has_path = false;
}
- _ => {}
+ marker::render_markers_for_path(path, dc, an, values, clipping)?;
}
+ _ => {}
}
+ }
- Ok(bbox)
+ if has_path {
+ cr.new_path();
}
+
+ Ok(bounding_box.unwrap())
})
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]