[librsvg: 57/90] New test for clipping to a viewport offsetted by a transformation



commit ff217e75b8ac54cb9bf3ec8826cb229eefa8125f
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Mar 20 09:59:10 2019 -0600

    New test for clipping to a viewport offsetted by a transformation
    
    The bbox for the contents of the temporary surface was being created
    with the wrong affine.

 .../clip-on-transformed-viewport-200x200.png       | Bin 0 -> 1117 bytes
 librsvg_crate/tests/render_to_viewport.rs          |  67 ++++++++++++++++++++-
 rsvg_internals/src/drawing_ctx.rs                  |  11 ++--
 3 files changed, 70 insertions(+), 8 deletions(-)
---
diff --git a/librsvg_crate/tests/fixtures/clip-on-transformed-viewport-200x200.png 
b/librsvg_crate/tests/fixtures/clip-on-transformed-viewport-200x200.png
new file mode 100644
index 00000000..2aa259d7
Binary files /dev/null and b/librsvg_crate/tests/fixtures/clip-on-transformed-viewport-200x200.png differ
diff --git a/librsvg_crate/tests/render_to_viewport.rs b/librsvg_crate/tests/render_to_viewport.rs
index 36e22e23..9092508a 100644
--- a/librsvg_crate/tests/render_to_viewport.rs
+++ b/librsvg_crate/tests/render_to_viewport.rs
@@ -129,7 +129,6 @@ fn render_to_offsetted_viewport() {
             surf.write_to_png(&mut output_file).unwrap();
 
             assert_eq!(diff.num_pixels_changed, 0);
-            
         }
     }
 }
@@ -189,7 +188,71 @@ fn render_to_viewport_with_transform() {
             surf.write_to_png(&mut output_file).unwrap();
 
             assert_eq!(diff.num_pixels_changed, 0);
-            
+        }
+    }
+}
+
+#[test]
+fn clip_on_transformed_viewport() {
+    let svg = load_svg(
+        br##"<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="100" height="100">
+  <defs>
+    <clipPath id="one" clipPathUnits="objectBoundingBox">
+      <circle cx="0.5" cy="0.5" r="0.5"/>
+    </clipPath>
+  </defs>
+  <g clip-path="url(#one)">
+    <rect x="10" y="10" width="40" height="40" fill="blue"/>
+    <rect x="50" y="50" width="40" height="40" fill="limegreen"/>
+  </g>
+</svg>
+"##,
+    );
+
+    let renderer = CairoRenderer::new(&svg);
+
+    let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 200, 200).unwrap();
+
+    {
+        let cr = cairo::Context::new(&output);
+        cr.translate(50.0, 50.0);
+        renderer
+            .render_element_to_viewport(
+                &cr,
+                None,
+                &cairo::Rectangle {
+                    x: 0.0,
+                    y: 0.0,
+                    width: 100.0,
+                    height: 100.0,
+                },
+            )
+            .unwrap();
+    }
+
+    let mut output_file = File::create(Path::new("output.png")).unwrap();
+    output.write_to_png(&mut output_file).unwrap();
+
+    let output_surf = SharedImageSurface::new(output, SurfaceType::SRgb).unwrap();
+
+    let fixture_path = Path::new("tests/fixtures/clip-on-transformed-viewport-200x200.png");
+    let mut fixture_file = BufReader::new(File::open(fixture_path).unwrap());
+
+    let expected = cairo::ImageSurface::create_from_png(&mut fixture_file).unwrap();
+    let expected_surf = SharedImageSurface::new(expected, SurfaceType::SRgb).unwrap();
+
+    let diff = compare_surfaces(&output_surf, &expected_surf).unwrap();
+
+    match diff {
+        BufferDiff::DifferentSizes => unreachable!("surfaces should be of the same size"),
+
+        BufferDiff::Diff(diff) => {
+            let surf = diff.surface.into_image_surface().unwrap();
+            let mut output_file = File::create(Path::new("diff.png")).unwrap();
+            surf.write_to_png(&mut output_file).unwrap();
+
+            assert_eq!(diff.num_pixels_changed, 0);
         }
     }
 }
diff --git a/rsvg_internals/src/drawing_ctx.rs b/rsvg_internals/src/drawing_ctx.rs
index 4a947aff..2e9824ba 100644
--- a/rsvg_internals/src/drawing_ctx.rs
+++ b/rsvg_internals/src/drawing_ctx.rs
@@ -473,14 +473,13 @@ impl DrawingCtx {
 
                     let initial_inverse = dc.initial_affine.try_invert().unwrap();
                     let untransformed = cairo::Matrix::multiply(&affine, &initial_inverse);
-                    println!("untransformed: {:?}", untransformed);
                     cr.set_matrix(untransformed);
 
                     dc.cr_stack.push(dc.cr.clone());
                     dc.cr = cr;
 
                     let prev_bbox = dc.bbox;
-                    dc.bbox = BoundingBox::new(&affine);
+                    dc.bbox = BoundingBox::new(&untransformed);
 
                     let mut res = draw_fn(dc);
 
@@ -497,12 +496,8 @@ impl DrawingCtx {
 
                     dc.cr = dc.cr_stack.pop().unwrap();
 
-                    dc.cr.set_matrix(dc.initial_affine);
                     dc.cr.set_source_surface(&source_surface, 0.0, 0.0);
 
-                    dc.cr.set_matrix(untransformed);
-//                    dc.cr.set_matrix(affine);
-                    dc.clip_to_node(clip_in_object_space)?;
                     dc.clip_to_node(&clip_in_object_space)?;
 
                     if let Some(mask) = mask {
@@ -525,6 +520,8 @@ impl DrawingCtx {
                             );
                         }
                     } else {
+                        dc.cr.set_matrix(dc.initial_affine);
+
                         if opacity < 1.0 {
                             dc.cr.paint_with_alpha(opacity);
                         } else {
@@ -532,6 +529,8 @@ impl DrawingCtx {
                         }
                     }
 
+                    dc.cr.set_matrix(affine);
+
                     let bbox = dc.bbox;
                     dc.bbox = prev_bbox;
                     dc.bbox.insert(&bbox);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]