[librsvg: 67/90] Nested temporary surfaces should not be offset with respect to each other
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 67/90] Nested temporary surfaces should not be offset with respect to each other
- Date: Tue, 26 Mar 2019 19:17:42 +0000 (UTC)
commit 7b07dd55b23c6ce4cb73a951b04beacf5e43b40c
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Mar 21 12:41:57 2019 -0600
Nested temporary surfaces should not be offset with respect to each other
This has a new test, compound_opacity, which captures the failing
parts of masking-opacity-01-b.svg.
760 pass, 6 fail
librsvg_crate/tests/primitives.rs | 61 +++++++++++++++++++++++++++++++++++++++
rsvg_internals/src/drawing_ctx.rs | 22 +++++++++-----
2 files changed, 76 insertions(+), 7 deletions(-)
---
diff --git a/librsvg_crate/tests/primitives.rs b/librsvg_crate/tests/primitives.rs
index e5c01699..21fc65c0 100644
--- a/librsvg_crate/tests/primitives.rs
+++ b/librsvg_crate/tests/primitives.rs
@@ -10,6 +10,8 @@ use rsvg_internals::surface_utils::shared_surface::{SharedImageSurface, SurfaceT
use self::utils::{load_svg, render_to_viewport, compare_to_surface, SurfaceSize};
+use std::fs::File;
+
#[test]
fn simple_opacity_with_transform() {
let svg = load_svg(
@@ -132,3 +134,62 @@ fn opacity_inside_transformed_group() {
compare_to_surface(&output_surf, &reference_surf, "opacity_inside_transformed_group");
}
+
+#[test]
+fn compound_opacity() {
+ let svg = load_svg(
+ br##"<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" baseProfile="basic" id="svg-root"
+ width="100%" height="100%" viewBox="0 0 480 360"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <g>
+ <g opacity="0.5">
+ <rect x="60" y="230" width="80" height="40" fill="#0000ff" opacity=".5"/>
+ <rect x="70" y="240" width="80" height="40" fill="#00ff00" opacity=".5"/>
+ </g>
+ </g>
+</svg>
+"##,
+ );
+
+ let output_surf = render_to_viewport(
+ &svg,
+ SurfaceSize(500, 380),
+ |cr| cr.translate(10.0, 10.0),
+ cairo::Rectangle {
+ x: 0.0,
+ y: 0.0,
+ width: 480.0,
+ height: 360.0,
+ },
+ )
+ .unwrap();
+
+ let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 500, 380).unwrap();
+
+ {
+ let cr = cairo::Context::new(&reference_surf);
+
+ cr.translate(10.0, 10.0);
+
+ cr.push_group();
+
+ cr.rectangle(60.0, 230.0, 80.0, 40.0);
+ cr.set_source_rgba(0.0, 0.0, 1.0, 0.5);
+ cr.fill();
+
+ cr.rectangle(70.0, 240.0, 80.0, 40.0);
+ cr.set_source_rgba(0.0, 1.0, 0.0, 0.5);
+ cr.fill();
+
+ cr.pop_group_to_source();
+ cr.paint_with_alpha(0.5);
+ }
+
+ let mut file = File::create("/tmp/reference.png").unwrap();
+ reference_surf.write_to_png(&mut file).unwrap();
+
+ let reference_surf = SharedImageSurface::new(reference_surf, SurfaceType::SRgb).unwrap();
+
+ compare_to_surface(&output_surf, &reference_surf, "compound_opacity");
+}
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 236697fe..e59b9210 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -463,6 +463,15 @@ impl DrawingCtx {
&& enable_background == EnableBackground::Accumulate);
if needs_temporary_surface {
+ let stack_was_empty = dc.cr_stack.len() == 0;
+
+ let affine = if stack_was_empty {
+ affine
+ } else {
+ let initial_inverse = dc.initial_affine_with_offset().try_invert().unwrap();
+ cairo::Matrix::multiply(&affine, &initial_inverse)
+ };
+
let cr = if filter.is_some() {
cairo::Context::new(&dc.create_surface_for_toplevel_viewport()?)
} else {
@@ -471,8 +480,6 @@ impl DrawingCtx {
)
};
- let stack_was_empty = dc.cr_stack.len() == 0;
-
let temporary_affine = if stack_was_empty {
let initial_inverse = dc.initial_affine_with_offset().try_invert().unwrap();
let untransformed = cairo::Matrix::multiply(&affine, &initial_inverse);
@@ -505,13 +512,15 @@ impl DrawingCtx {
dc.cr = dc.cr_stack.pop().unwrap();
- let save_matrix = dc.cr.get_matrix();
+ let paint_affine = if stack_was_empty {
+ dc.initial_affine_with_offset()
+ } else {
+ cairo::Matrix::identity()
+ };
- dc.cr.set_matrix(dc.initial_affine_with_offset());
+ dc.cr.set_matrix(paint_affine);
dc.cr.set_source_surface(&source_surface, 0.0, 0.0);
- assert!(affine == save_matrix);
-
dc.cr.set_matrix(affine);
dc.clip_to_node(&clip_in_object_space)?;
@@ -535,7 +544,6 @@ impl DrawingCtx {
);
}
} else {
- let paint_affine = dc.initial_affine_with_offset();
dc.cr.set_matrix(paint_affine);
if opacity < 1.0 {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]