[librsvg/librsvg-2.50] Introduce helper object to clean up path handling
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.50] Introduce helper object to clean up path handling
- Date: Fri, 2 Oct 2020 19:24:34 +0000 (UTC)
commit 897989f8dd4fbd8a30f7565cc3d641352d4ae522
Author: Sven Neumann <sven svenfoo org>
Date: Mon Sep 7 19:37:19 2020 +0200
Introduce helper object to clean up path handling
Add a helper object to keep track of whether the path has already
been set on the cairo context.
rsvg_internals/src/drawing_ctx.rs | 63 +++++++++++++++++++++++++++++----------
1 file changed, 47 insertions(+), 16 deletions(-)
---
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index b77efb72..4485bf0b 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -86,6 +86,47 @@ pub enum ClipMode {
ClipToVbox,
}
+/// Set path on the cairo context, or clear it.
+/// This helper object keeps track whether the path has been set already,
+/// so that it isn't recalculated every so often.
+struct PathHelper<'a> {
+ cr: &'a cairo::Context,
+ path: &'a Path,
+ is_square_linecap: bool,
+ has_path: Option<bool>,
+}
+
+impl<'a> PathHelper<'a> {
+ pub fn new(cr: &'a cairo::Context, path: &'a Path, values: &ComputedValues) -> Self {
+ PathHelper {
+ cr,
+ path,
+ is_square_linecap: values.stroke_line_cap() == StrokeLinecap::Square,
+ has_path: None,
+ }
+ }
+
+ pub fn set(&mut self) -> Result<(), cairo::Status> {
+ match self.has_path {
+ Some(false) | None => {
+ self.has_path = Some(true);
+ self.path.to_cairo(self.cr, self.is_square_linecap)
+ }
+ Some(true) => Ok(()),
+ }
+ }
+
+ pub fn unset(&mut self) {
+ match self.has_path {
+ Some(true) | None => {
+ self.has_path = Some(false);
+ self.cr.new_path();
+ }
+ Some(false) => {}
+ }
+ }
+}
+
pub struct DrawingCtx {
initial_transform: Transform,
@@ -1225,11 +1266,11 @@ impl DrawingCtx {
self.with_discrete_layer(node, acquired_nodes, values, clipping, &mut |an, dc| {
let cr = dc.cr.clone();
- let is_square_linecap = values.stroke_line_cap() == StrokeLinecap::Square;
+ let mut path_helper = PathHelper::new(&cr, path, values);
if clipping {
cr.set_fill_rule(cairo::FillRule::from(values.clip_rule()));
- path.to_cairo(&cr, is_square_linecap)?;
+ path_helper.set()?;
return Ok(dc.empty_bbox());
}
@@ -1241,18 +1282,14 @@ impl DrawingCtx {
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();
+ path_helper.unset();
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)?;
- has_path = true;
- }
+ path_helper.set()?;
let bbox = bounding_box
.get_or_insert_with(|| compute_stroke_and_fill_box(&cr, &values));
@@ -1263,20 +1300,14 @@ impl DrawingCtx {
}
}
PaintTarget::Markers if markers == Markers::Yes => {
- if has_path {
- cr.new_path();
- has_path = false;
- }
+ path_helper.unset();
marker::render_markers_for_path(path, dc, an, values, clipping)?;
}
_ => {}
}
}
- if has_path {
- cr.new_path();
- }
-
+ path_helper.unset();
Ok(bounding_box.unwrap())
})
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]