1
/*
2
 * Copyright © 2006 Novell, Inc.
3
 *
4
 * Permission to use, copy, modify, distribute, and sell this software
5
 * and its documentation for any purpose is hereby granted without
6
 * fee, provided that the above copyright notice appear in all copies
7
 * and that both that copyright notice and this permission notice
8
 * appear in supporting documentation, and that the name of
9
 * Novell, Inc. not be used in advertising or publicity pertaining to
10
 * distribution of the software without specific, written prior
11
 * permission. Novell, Inc. makes no representations about the
12
 * suitability of this software for any purpose.  It is provided "as
13
 * is" without express or implied warranty.
14
 *
15
 * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17
 * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
18
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
21
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
 *
23
 * Author: Robert O'Callahan <rocallahan@novell.com>
24
 */
25

            
26
#include "cairo-test.h"
27
#include <stddef.h>
28
#include <math.h>
29

            
30
enum ExtentsType { FILL, STROKE, PATH };
31

            
32
enum Relation { EQUALS, APPROX_EQUALS, CONTAINS };
33

            
34

            
35
204
static cairo_bool_t within_tolerance(double x1, double y1,
36
				     double x2, double y2,
37
				     double expected_x1, double expected_y1,
38
				     double expected_x2, double expected_y2,
39
				     double tolerance)
40
{
41
408
    return (fabs (expected_x1 - x1) < tolerance &&
42
204
	    fabs (expected_y1 - y1) < tolerance &&
43
612
	    fabs (expected_x2 - x2) < tolerance &&
44
204
	    fabs (expected_y2 - y2) < tolerance);
45
}
46

            
47
static cairo_bool_t
48
219
check_extents (const cairo_test_context_t *ctx,
49
	       const char *message, cairo_t *cr, enum ExtentsType type,
50
               enum Relation relation,
51
               double x, double y, double width, double height)
52
{
53
    double ext_x1, ext_y1, ext_x2, ext_y2;
54
    const char *type_string;
55
    const char *relation_string;
56

            
57
219
    switch (type) {
58
72
    default:
59
    case FILL:
60
72
        type_string = "fill";
61
72
        cairo_fill_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2);
62
72
        break;
63
75
    case STROKE:
64
75
        type_string = "stroke";
65
75
        cairo_stroke_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2);
66
75
        break;
67
72
    case PATH:
68
72
        type_string = "path";
69
72
        cairo_path_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2);
70
72
        break;
71
    }
72

            
73
    /* ignore results after an error occurs */
74
219
    if (cairo_status (cr))
75
	return 1;
76

            
77
219
    switch (relation) {
78
192
    default:
79
    case EQUALS:
80
192
        relation_string = "equal";
81
192
	if (within_tolerance(x, y, x + width, y + height,
82
			     ext_x1, ext_y1, ext_x2, ext_y2,
83
			     cairo_get_tolerance(cr)))
84
192
	    return 1;
85
        break;
86
12
    case APPROX_EQUALS:
87
12
        relation_string = "approx. equal";
88
12
	if (within_tolerance(x, y, x + width, y + height,
89
			     ext_x1, ext_y1, ext_x2, ext_y2,
90
			     1.))
91
12
	    return 1;
92
        break;
93
15
    case CONTAINS:
94
15
        relation_string = "contain";
95
15
        if (width == 0 || height == 0) {
96
            /* odd test that doesn't really test anything... */
97
            return 1;
98
        }
99
15
        if (ext_x1 <= x && ext_y1 <= y && ext_x2 >= x + width && ext_y2 >= y + height)
100
15
            return 1;
101
        break;
102
    }
103

            
104
    cairo_test_log (ctx, "Error: %s; %s extents (%g, %g) x (%g, %g) should %s (%g, %g) x (%g, %g)\n",
105
                    message, type_string,
106
                    ext_x1, ext_y1, ext_x2 - ext_x1, ext_y2 - ext_y1,
107
                    relation_string,
108
                    x, y, width, height);
109
    return 0;
110
}
111

            
112
static cairo_test_status_t
113
3
draw (cairo_t *cr, int width, int height)
114
{
115
3
    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
116
    cairo_surface_t *surface;
117
    cairo_t         *cr2;
118
    const char      *phase;
119
3
    const char	     string[] = "The quick brown fox jumps over the lazy dog.";
120
    cairo_text_extents_t extents, scaled_font_extents;
121
    cairo_status_t   status;
122
3
    int              errors = 0;
123

            
124
3
    surface = cairo_surface_create_similar (cairo_get_group_target (cr),
125
                                            CAIRO_CONTENT_COLOR, 1000, 1000);
126
    /* don't use cr accidentally */
127
3
    cr = NULL;
128
3
    cr2 = cairo_create (surface);
129
3
    cairo_surface_destroy (surface);
130

            
131
3
    cairo_set_line_width (cr2, 10);
132
3
    cairo_set_line_join (cr2, CAIRO_LINE_JOIN_MITER);
133
3
    cairo_set_miter_limit (cr2, 100);
134

            
135
3
    phase = "No path";
136
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
137
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
138
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 0, 0, 0, 0);
139

            
140
3
    cairo_save (cr2);
141

            
142
3
    cairo_new_path (cr2);
143
3
    cairo_move_to (cr2, 200, 400);
144
3
    cairo_close_path (cr2);
145
3
    phase = "Degenerate closed path";
146
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
147
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
148
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
149

            
150
3
    cairo_new_path (cr2);
151
3
    cairo_move_to (cr2, 200, 400);
152
3
    cairo_rel_line_to (cr2, 0., 0.);
153
3
    phase = "Degenerate line";
154
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
155
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
156
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
157

            
158
3
    cairo_new_path (cr2);
159
3
    cairo_move_to (cr2, 200, 400);
160
3
    cairo_rel_curve_to (cr2, 0., 0., 0., 0., 0., 0.);
161
3
    phase = "Degenerate curve";
162
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
163
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
164
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
165

            
166
3
    cairo_new_path (cr2);
167
3
    cairo_arc (cr2, 200, 400, 0., 0, 2 * M_PI);
168
3
    phase = "Degenerate arc (R=0)";
169
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
170
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
171
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
172

            
173
3
    cairo_new_path (cr2);
174
3
    cairo_arc_negative (cr2, 200, 400, 0., 0, 2 * M_PI);
175
3
    phase = "Degenerate negative arc (R=0)";
176
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
177
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
178
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
179

            
180
3
    cairo_new_path (cr2);
181
3
    cairo_arc (cr2, 200, 400, 10., 0, 0);
182
3
    phase = "Degenerate arc (Θ=0)";
183
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
184
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
185
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 210, 400, 0, 0);
186

            
187
3
    cairo_new_path (cr2);
188
3
    cairo_arc_negative (cr2, 200, 400, 10., 0, 0);
189
3
    phase = "Degenerate negative arc (Θ=0)";
190
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
191
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
192
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 210, 400, 0, 0);
193

            
194
3
    cairo_new_path (cr2);
195
3
    cairo_restore (cr2);
196

            
197
    /* Test that with CAIRO_LINE_CAP_ROUND, we get "dots" from
198
     * cairo_move_to; cairo_rel_line_to(0,0) */
199
3
    cairo_save (cr2);
200

            
201
3
    cairo_set_line_cap (cr2, CAIRO_LINE_CAP_ROUND);
202
3
    cairo_set_line_width (cr2, 20);
203

            
204
3
    cairo_move_to (cr2, 200, 400);
205
3
    cairo_rel_line_to (cr2, 0, 0);
206
3
    phase = "Single 'dot'";
207
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
208
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 190, 390, 20, 20);
209
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
210

            
211
    /* Add another dot without starting a new path */
212
3
    cairo_move_to (cr2, 100, 500);
213
3
    cairo_rel_line_to (cr2, 0, 0);
214
3
    phase = "Multiple 'dots'";
215
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
216
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 90, 390, 120, 120);
217
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 100, 400, 100, 100);
218

            
219
3
    cairo_new_path (cr2);
220

            
221
3
    cairo_restore (cr2);
222

            
223
    /* https://bugs.freedesktop.org/show_bug.cgi?id=7965 */
224
3
    phase = "A horizontal, open path";
225
3
    cairo_save (cr2);
226
3
    cairo_set_line_cap (cr2, CAIRO_LINE_CAP_ROUND);
227
3
    cairo_set_line_join (cr2, CAIRO_LINE_JOIN_ROUND);
228
3
    cairo_move_to (cr2, 0, 180);
229
3
    cairo_line_to (cr2, 750, 180);
230
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
231
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, -5, 175, 760, 10);
232
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 0, 180, 750, 0);
233
3
    cairo_new_path (cr2);
234
3
    cairo_restore (cr2);
235

            
236
3
    phase = "A vertical, open path";
237
3
    cairo_save (cr2);
238
3
    cairo_set_line_cap (cr2, CAIRO_LINE_CAP_ROUND);
239
3
    cairo_set_line_join (cr2, CAIRO_LINE_JOIN_ROUND);
240
3
    cairo_new_path (cr2);
241
3
    cairo_move_to (cr2, 180, 0);
242
3
    cairo_line_to (cr2, 180, 750);
243
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
244
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 175, -5, 10, 760);
245
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 180, 0, 0, 750);
246
3
    cairo_new_path (cr2);
247
3
    cairo_restore (cr2);
248

            
249
3
    phase = "A degenerate open path";
250
3
    cairo_save (cr2);
251
3
    cairo_set_line_cap (cr2, CAIRO_LINE_CAP_ROUND);
252
3
    cairo_set_line_join (cr2, CAIRO_LINE_JOIN_ROUND);
253
3
    cairo_new_path (cr2);
254
3
    cairo_move_to (cr2, 180, 0);
255
3
    cairo_line_to (cr2, 180, 0);
256
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
257
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 175, -5, 10, 10);
258
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 180, 0, 0, 0);
259
3
    cairo_new_path (cr2);
260
3
    cairo_restore (cr2);
261

            
262
3
    phase = "Simple rect";
263
3
    cairo_save (cr2);
264
3
    cairo_rectangle (cr2, 10, 10, 80, 80);
265
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
266
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 5, 5, 90, 90);
267
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 80, 80);
268
3
    cairo_new_path (cr2);
269
3
    cairo_restore (cr2);
270

            
271
3
    phase = "Two rects";
272
3
    cairo_save (cr2);
273
3
    cairo_rectangle (cr2, 10, 10, 10, 10);
274
3
    cairo_rectangle (cr2, 20, 20, 10, 10);
275
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 20, 20);
276
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 5, 5, 30, 30);
277
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 20, 20);
278
3
    cairo_new_path (cr2);
279
3
    cairo_restore (cr2);
280

            
281
3
    phase = "Triangle";
282
3
    cairo_save (cr2);
283
3
    cairo_move_to (cr2, 10, 10);
284
3
    cairo_line_to (cr2, 90, 90);
285
3
    cairo_line_to (cr2, 90, 10);
286
3
    cairo_close_path (cr2);
287
    /* miter joins protrude 5*(1+sqrt(2)) above the top-left corner and to
288
       the right of the bottom-right corner */
289
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
290
3
    errors += !check_extents (ctx, phase, cr2, STROKE, CONTAINS, 0, 5, 95, 95);
291
3
    errors += !check_extents (ctx, phase, cr2, PATH, CONTAINS, 10, 10, 80, 80);
292
3
    cairo_new_path (cr2);
293
3
    cairo_restore (cr2);
294

            
295
3
    cairo_save (cr2);
296

            
297
3
    cairo_set_line_width (cr2, 4);
298

            
299
3
    cairo_rectangle (cr2, 10, 10, 30, 30);
300
3
    cairo_rectangle (cr2, 25, 10, 15, 30);
301

            
302
3
    cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_EVEN_ODD);
303
3
    phase = "EVEN_ODD overlapping rectangles";
304
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
305
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
306
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
307

            
308
    /* Test other fill rule with the same path. */
309

            
310
3
    cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_WINDING);
311
3
    phase = "WINDING overlapping rectangles";
312
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 30, 30);
313
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
314
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
315

            
316
    /* Now, change the direction of the second rectangle and test both
317
     * fill rules again. */
318
3
    cairo_new_path (cr2);
319
3
    cairo_rectangle (cr2, 10, 10, 30, 30);
320
3
    cairo_rectangle (cr2, 25, 40, 15, -30);
321

            
322
3
    cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_EVEN_ODD);
323
3
    phase = "EVEN_ODD overlapping rectangles";
324
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
325
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
326
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
327

            
328
    /* Test other fill rule with the same path. */
329

            
330
3
    cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_WINDING);
331
3
    phase = "WINDING overlapping rectangles";
332
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
333
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
334
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
335

            
336
3
    cairo_new_path (cr2);
337

            
338
3
    cairo_restore (cr2);
339

            
340
    /* https://bugs.freedesktop.org/show_bug.cgi?id=7245 */
341
3
    phase = "Arc";
342
3
    cairo_save (cr2);
343
3
    cairo_arc (cr2, 250.0, 250.0, 157.0, 5.147, 3.432);
344
3
    cairo_set_line_width (cr2, 154.0);
345
3
    errors += !check_extents (ctx, phase, cr2, STROKE, APPROX_EQUALS, 16, 38, 468, 446);
346
3
    cairo_new_path (cr2);
347
3
    cairo_restore (cr2);
348

            
349
3
    phase = "Text";
350
3
    cairo_save (cr2);
351
3
    cairo_select_font_face (cr2, CAIRO_TEST_FONT_FAMILY " Sans",
352
			    CAIRO_FONT_SLANT_NORMAL,
353
			    CAIRO_FONT_WEIGHT_NORMAL);
354
3
    cairo_set_font_size (cr2, 12);
355
3
    cairo_text_extents (cr2, string, &extents);
356
    /* double check that the two methods of measuring the text agree... */
357
3
    cairo_scaled_font_text_extents (cairo_get_scaled_font (cr2),
358
				    string,
359
				    &scaled_font_extents);
360
3
    if (memcmp (&extents, &scaled_font_extents, sizeof (extents))) {
361
	cairo_test_log (ctx, "Error: cairo_text_extents() does not match cairo_scaled_font_text_extents() - font extents (%f, %f) x (%f, %f) should be (%f, %f) x (%f, %f)\n",
362
		        scaled_font_extents.x_bearing,
363
			scaled_font_extents.y_bearing,
364
			scaled_font_extents.width,
365
			scaled_font_extents.height,
366
			extents.x_bearing,
367
			extents.y_bearing,
368
			extents.width,
369
			extents.height);
370
	errors++;
371
    }
372

            
373
3
    cairo_move_to (cr2, -extents.x_bearing, -extents.y_bearing);
374
3
    cairo_text_path (cr2, string);
375
3
    cairo_set_line_width (cr2, 2.0);
376
    /* XXX: We'd like to be able to use EQUALS here, but currently
377
     * when hinting is enabled freetype returns integer extents. See
378
     * https://cairographics.org/todo */
379
3
    errors += !check_extents (ctx, phase, cr2, FILL, APPROX_EQUALS,
380
			      0, 0, extents.width, extents.height);
381
6
    errors += !check_extents (ctx, phase, cr2, STROKE, APPROX_EQUALS,
382
3
			      -1, -1, extents.width+2, extents.height+2);
383
3
    errors += !check_extents (ctx, phase, cr2, PATH, APPROX_EQUALS,
384
			      0, 0, extents.width, extents.height);
385
3
    cairo_new_path (cr2);
386
3
    cairo_restore (cr2);
387

            
388
3
    phase = "User space, simple scale, getting extents with same transform";
389
3
    cairo_save (cr2);
390
3
    cairo_scale (cr2, 2, 2);
391
3
    cairo_rectangle (cr2, 5, 5, 40, 40);
392
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 5, 5, 40, 40);
393
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 50, 50);
394
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 5, 5, 40, 40);
395
3
    cairo_new_path (cr2);
396
3
    cairo_restore (cr2);
397

            
398
3
    phase = "User space, simple scale, getting extents with no transform";
399
3
    cairo_save (cr2);
400
3
    cairo_save (cr2);
401
3
    cairo_scale (cr2, 2, 2);
402
3
    cairo_rectangle (cr2, 5, 5, 40, 40);
403
3
    cairo_restore (cr2);
404
3
    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
405
3
    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 5, 5, 90, 90);
406
3
    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 80, 80);
407
3
    cairo_new_path (cr2);
408
3
    cairo_restore (cr2);
409

            
410
3
    phase = "User space, rotation, getting extents with transform";
411
3
    cairo_save (cr2);
412
3
    cairo_rectangle (cr2, -50, -50, 50, 50);
413
3
    cairo_rotate (cr2, -M_PI/4);
414
    /* the path in user space is now (nearly) the square rotated by
415
       45 degrees about the origin. Thus its x1 and x2 are both nearly 0.
416
       This should show any bugs where we just transform device-space
417
       x1,y1 and x2,y2 to get the extents. */
418
    /* The largest axis-aligned square inside the rotated path has
419
       side lengths 50*sqrt(2), so a bit over 35 on either side of
420
       the axes. With the stroke width added to the rotated path,
421
       the largest axis-aligned square is a bit over 38 on either side of
422
       the axes. */
423
3
    errors += !check_extents (ctx, phase, cr2, FILL, CONTAINS, -35, -35, 35, 35);
424
3
    errors += !check_extents (ctx, phase, cr2, STROKE, CONTAINS, -38, -38, 38, 38);
425
3
    errors += !check_extents (ctx, phase, cr2, PATH, CONTAINS, -35, -35, 35, 35);
426
3
    cairo_new_path (cr2);
427
3
    cairo_restore (cr2);
428

            
429
3
    status = cairo_status (cr2);
430
3
    cairo_destroy (cr2);
431

            
432
3
    if (status)
433
	return cairo_test_status_from_status (ctx, status);
434

            
435
3
    return errors == 0 ? CAIRO_TEST_SUCCESS : CAIRO_TEST_FAILURE;
436
}
437

            
438
1
CAIRO_TEST (get_path_extents,
439
	    "Test cairo_fill_extents and cairo_stroke_extents",
440
	    "extents, path", /* keywords */
441
	    NULL, /* requirements */
442
	    0, 0,
443
	    NULL, draw)