1
1
use rsvg::tests_only::{SharedImageSurface, SurfaceType};
2
use rsvg::{CairoRenderer, RenderingError};
3

            
4
use rsvg::test_utils::load_svg;
5
use rsvg::test_utils::reference_utils::{Compare, Evaluate, Reference};
6

            
7
#[test]
8
2
fn has_element_with_id_works() {
9
1
    let svg = load_svg(
10
        br#"<?xml version="1.0" encoding="UTF-8"?>
11
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
12
  <rect id="foo" x="10" y="10" width="30" height="30"/>
13
</svg>
14
"#,
15
    )
16
    .unwrap();
17

            
18
1
    assert!(svg.has_element_with_id("#foo").unwrap());
19
1
    assert!(!svg.has_element_with_id("#bar").unwrap());
20

            
21
1
    assert!(matches!(
22
1
        svg.has_element_with_id(""),
23
        Err(RenderingError::InvalidId(_))
24
    ));
25

            
26
1
    assert!(matches!(
27
1
        svg.has_element_with_id("not a fragment"),
28
        Err(RenderingError::InvalidId(_))
29
    ));
30

            
31
1
    assert!(matches!(
32
1
        svg.has_element_with_id("notfragment#fragment"),
33
        Err(RenderingError::InvalidId(_))
34
    ));
35
2
}
36

            
37
#[test]
38
2
fn render_layer() {
39
1
    let svg = load_svg(
40
        br##"<?xml version="1.0" encoding="UTF-8"?>
41
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
42
  <rect id="foo" x="10" y="10" width="30" height="30" fill="#00ff00"/>
43
  <rect id="bar" x="20" y="20" width="30" height="30" fill="#0000ff"/>
44
</svg>
45
"##,
46
    )
47
    .unwrap();
48

            
49
1
    let renderer = CairoRenderer::new(&svg);
50

            
51
1
    let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 300, 300).unwrap();
52

            
53
    let res = {
54
1
        let cr = cairo::Context::new(&output).expect("Failed to create cairo context");
55
1
        let viewport = cairo::Rectangle::new(100.0, 100.0, 100.0, 100.0);
56

            
57
1
        renderer.render_layer(&cr, Some("#bar"), &viewport)
58
1
    };
59

            
60
1
    let output_surf = res
61
2
        .map(|_| SharedImageSurface::wrap(output, SurfaceType::SRgb).unwrap())
62
        .unwrap();
63

            
64
1
    let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 300, 300).unwrap();
65

            
66
    {
67
1
        let cr = cairo::Context::new(&reference_surf).expect("Failed to create a cairo context");
68

            
69
1
        cr.translate(100.0, 100.0);
70

            
71
1
        cr.rectangle(20.0, 20.0, 30.0, 30.0);
72
1
        cr.set_source_rgba(0.0, 0.0, 1.0, 1.0);
73
1
        cr.fill().unwrap();
74
1
    }
75

            
76
1
    Reference::from_surface(reference_surf)
77
        .compare(&output_surf)
78
1
        .evaluate(&output_surf, "render_layer");
79
2
}
80

            
81
#[test]
82
2
fn untransformed_element() {
83
    // This has a rectangle inside a transformed group.  The rectangle
84
    // inherits its stroke-width from the group.
85
    //
86
    // The idea is that we'll be able to extract the geometry of the rectangle
87
    // as if it were not transformed by its ancestors, but still retain the
88
    // cascade from the ancestors.
89
1
    let svg = load_svg(
90
        br##"<?xml version="1.0" encoding="UTF-8"?>
91
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
92
  <g transform="rotate(45)" stroke-width="10" stroke="#000000">
93
    <rect id="foo" x="10" y="20" width="30" height="40" fill="#0000ff"/>
94
  </g>
95
</svg>
96
"##,
97
    )
98
    .unwrap();
99

            
100
1
    let renderer = CairoRenderer::new(&svg);
101

            
102
    /* Measuring */
103

            
104
1
    let (ink_r, logical_r) = renderer.geometry_for_element(Some("#foo")).unwrap();
105

            
106
1
    assert_eq!(ink_r, cairo::Rectangle::new(0.0, 0.0, 40.0, 50.0));
107

            
108
1
    assert_eq!(logical_r, cairo::Rectangle::new(5.0, 5.0, 30.0, 40.0));
109

            
110
    /* Rendering */
111

            
112
1
    let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 300, 300).unwrap();
113

            
114
    let res = {
115
1
        let cr = cairo::Context::new(&output).expect("Failed to create cairo context");
116
1
        let viewport = cairo::Rectangle::new(100.0, 100.0, 100.0, 100.0);
117

            
118
1
        renderer.render_element(&cr, Some("#foo"), &viewport)
119
1
    };
120

            
121
1
    let output_surf = res
122
2
        .map(|_| SharedImageSurface::wrap(output, SurfaceType::SRgb).unwrap())
123
        .unwrap();
124

            
125
1
    let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 300, 300).unwrap();
126

            
127
    {
128
1
        let cr = cairo::Context::new(&reference_surf).expect("Failed to create a cairo context");
129

            
130
1
        cr.translate(100.0, 100.0);
131

            
132
1
        cr.rectangle(10.0, 10.0, 60.0, 80.0);
133
1
        cr.set_source_rgba(0.0, 0.0, 1.0, 1.0);
134
1
        cr.fill_preserve().unwrap();
135

            
136
1
        cr.set_line_width(20.0);
137
1
        cr.set_source_rgba(0.0, 0.0, 0.0, 1.0);
138
1
        cr.stroke().unwrap();
139
1
    }
140

            
141
1
    Reference::from_surface(reference_surf)
142
        .compare(&output_surf)
143
1
        .evaluate(&output_surf, "untransformed_element");
144
2
}
145

            
146
#[test]
147
2
fn set_stylesheet() {
148
    // This has a rectangle which we style from a user-supplied stylesheet.
149
1
    let mut svg = load_svg(
150
        br##"<?xml version="1.0" encoding="UTF-8"?>
151
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
152
  <rect id="foo" x="10" y="20" width="30" height="40" fill="black"/>
153
</svg>
154
"##,
155
    )
156
    .unwrap();
157

            
158
1
    svg.set_stylesheet("rect { fill: #00ff00; }")
159
        .expect("should be a valid stylesheet");
160

            
161
1
    let renderer = CairoRenderer::new(&svg);
162

            
163
1
    let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 100, 100).unwrap();
164

            
165
    let res = {
166
1
        let cr = cairo::Context::new(&output).expect("Failed to create cairo context");
167
1
        let viewport = cairo::Rectangle::new(0.0, 0.0, 100.0, 100.0);
168

            
169
1
        renderer.render_document(&cr, &viewport)
170
1
    };
171

            
172
1
    let output_surf = res
173
2
        .map(|_| SharedImageSurface::wrap(output, SurfaceType::SRgb).unwrap())
174
        .unwrap();
175

            
176
1
    let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 100, 100).unwrap();
177

            
178
    {
179
1
        let cr = cairo::Context::new(&reference_surf).expect("Failed to create a cairo context");
180

            
181
1
        cr.rectangle(10.0, 20.0, 30.0, 40.0);
182
1
        cr.set_source_rgba(0.0, 1.0, 0.0, 1.0);
183
1
        cr.fill().unwrap();
184
1
    }
185

            
186
1
    Reference::from_surface(reference_surf)
187
        .compare(&output_surf)
188
1
        .evaluate(&output_surf, "set_stylesheet");
189
2
}
190

            
191
// https://gitlab.gnome.org/GNOME/librsvg/-/issues/799
192
#[test]
193
2
fn text_doesnt_leave_points_in_current_path() {
194
1
    let svg = load_svg(
195
        br##"<?xml version="1.0" encoding="UTF-8"?>
196
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
197
  <text>Hello world!</text>
198
</svg>
199
"##,
200
    )
201
    .unwrap();
202

            
203
1
    let renderer = CairoRenderer::new(&svg);
204

            
205
1
    let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 100, 100).unwrap();
206
1
    let cr = cairo::Context::new(&output).unwrap();
207

            
208
1
    assert!(!cr.has_current_point().unwrap());
209

            
210
1
    let viewport = cairo::Rectangle::new(0.0, 0.0, 100.0, 100.0);
211

            
212
1
    renderer.render_document(&cr, &viewport).unwrap();
213

            
214
1
    assert!(!cr.has_current_point().unwrap());
215
2
}