[librsvg: 2/6] image: inline draw_surface
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 2/6] image: inline draw_surface
- Date: Tue, 26 Jun 2018 02:03:14 +0000 (UTC)
commit 79bf3349ab1e8faa8e558f70e153915b49933477
Author: Paolo Borelli <pborelli gnome org>
Date: Sat Jun 23 11:14:53 2018 +0200
image: inline draw_surface
This is the only caller and inlining makes things shorter since
we can reuse the surface width etc
rsvg_internals/src/draw.rs | 70 ---------------------------------------------
rsvg_internals/src/image.rs | 63 ++++++++++++++++++++++++++++++++++------
2 files changed, 54 insertions(+), 79 deletions(-)
---
diff --git a/rsvg_internals/src/draw.rs b/rsvg_internals/src/draw.rs
index abd7b7cb..b91d83d1 100644
--- a/rsvg_internals/src/draw.rs
+++ b/rsvg_internals/src/draw.rs
@@ -1,5 +1,4 @@
use cairo;
-use cairo::{MatrixTrait, Pattern};
use cairo_sys;
use glib::translate::*;
use pango::{self, ContextExt, LayoutExt};
@@ -387,72 +386,3 @@ fn compute_text_bbox(
bbox
}
-
-pub fn draw_surface(
- draw_ctx: &mut DrawingCtx,
- values: &ComputedValues,
- surface: &cairo::ImageSurface,
- x: f64,
- y: f64,
- w: f64,
- h: f64,
- clipping: bool,
-) {
- if clipping {
- return;
- }
-
- let cr = draw_ctx.get_cairo_context();
-
- let affine = cr.get_matrix();
-
- let width = surface.get_width();
- let height = surface.get_height();
-
- if width == 0 || height == 0 {
- return;
- }
-
- cr.save();
-
- let width = f64::from(width);
- let height = f64::from(height);
-
- // This is the target bbox after drawing.
- let bbox = BoundingBox::new(&affine).with_rect(Some(cairo::Rectangle {
- x,
- y,
- width: w,
- height: h,
- }));
-
- draw_ctx.set_affine_on_cr(&cr);
- cr.scale(w / width, h / height);
- let x = x * width / w;
- let y = y * height / h;
-
- cr.set_operator(cairo::Operator::from(values.comp_op));
-
- // We need to set extend appropriately, so can't use cr.set_source_surface().
- //
- // If extend is left at its default value (None), then bilinear scaling uses transparency
- // outside of the image producing incorrect results. For example, in
- // svg1.1/filters-blend-01-b.svg there's a completely opaque 100×1 image of a gradient scaled
- // to 100×98 which ends up transparent almost everywhere without this fix (which it shouldn't).
- let ptn = cairo::SurfacePattern::create(&surface);
- let mut matrix = cairo::Matrix::identity();
- matrix.translate(-x, -y);
- ptn.set_matrix(matrix);
- ptn.set_extend(cairo::Extend::Pad);
- cr.set_source(&ptn);
-
- // Clip is needed due to extend being set to pad.
- cr.rectangle(x, y, width, height);
- cr.clip();
-
- cr.paint();
-
- cr.restore();
-
- draw_ctx.insert_bbox(&bbox);
-}
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index d98226bd..bb02cdf3 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -1,4 +1,5 @@
use cairo;
+use cairo::{MatrixTrait, Pattern};
use cairo_sys;
use glib;
use glib::translate::*;
@@ -9,7 +10,7 @@ use std::ptr;
use aspect_ratio::AspectRatio;
use attributes::Attribute;
-use draw::draw_surface;
+use bbox::BoundingBox;
use drawing_ctx::DrawingCtx;
use handle::RsvgHandle;
use length::*;
@@ -125,16 +126,60 @@ impl NodeTrait for NodeImage {
dc.clip(x, y, w, h);
}
- let (x, y, w, h) = aspect.compute(
- f64::from(surface.get_width()),
- f64::from(surface.get_height()),
+ let width = surface.get_width();
+ let height = surface.get_height();
+ if clipping || width == 0 || height == 0 {
+ return;
+ }
+
+ let width = f64::from(width);
+ let height = f64::from(height);
+
+ let (x, y, w, h) = aspect.compute(width, height, x, y, w, h);
+
+ let cr = dc.get_cairo_context();
+ let affine = cr.get_matrix();
+
+ // This is the target bbox after drawing.
+ let bbox = BoundingBox::new(&affine).with_rect(Some(cairo::Rectangle {
x,
y,
- w,
- h,
- );
-
- draw_surface(dc, values, surface, x, y, w, h, clipping);
+ width: w,
+ height: h,
+ }));
+
+ cr.save();
+
+ dc.set_affine_on_cr(&cr);
+ cr.scale(w / width, h / height);
+ let x = x * width / w;
+ let y = y * height / h;
+
+ cr.set_operator(cairo::Operator::from(values.comp_op));
+
+ // We need to set extend appropriately, so can't use cr.set_source_surface().
+ //
+ // If extend is left at its default value (None), then bilinear scaling uses
+ // transparency outside of the image producing incorrect results.
+ // For example, in svg1.1/filters-blend-01-b.svgthere's a completely
+ // opaque 100×1 image of a gradient scaled to 100×98 which ends up
+ // transparent almost everywhere without this fix (which it shouldn't).
+ let ptn = cairo::SurfacePattern::create(&surface);
+ let mut matrix = cairo::Matrix::identity();
+ matrix.translate(-x, -y);
+ ptn.set_matrix(matrix);
+ ptn.set_extend(cairo::Extend::Pad);
+ cr.set_source(&ptn);
+
+ // Clip is needed due to extend being set to pad.
+ cr.rectangle(x, y, width, height);
+ cr.clip();
+
+ cr.paint();
+
+ cr.restore();
+
+ dc.insert_bbox(&bbox);
});
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]