2 * Copyright © 2007 Red Hat, Inc.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Author: Carl Worth <cworth@cworth.org>
27 #define _ISOC99_SOURCE /* for INFINITY */
28 #define _GNU_SOURCE 1 /* for fedisableeexcept() et al */
30 #include "cairo-test.h"
32 #if !defined(INFINITY)
33 #define INFINITY HUGE_VAL
40 static cairo_test_status_t
41 draw (cairo_t *cr, int width, int height)
43 const cairo_test_context_t *ctx = cairo_test_get_context (cr);
44 cairo_status_t status;
45 cairo_surface_t *target;
46 cairo_font_face_t *font_face;
47 cairo_font_options_t *font_options;
48 cairo_scaled_font_t *scaled_font;
49 cairo_pattern_t *pattern;
51 cairo_matrix_t identity, bogus, inf, invalid = {
57 #define CHECK_STATUS(status, function_name) \
58 if ((status) == CAIRO_STATUS_SUCCESS) { \
59 cairo_test_log (ctx, "Error: %s with invalid matrix passed\n", \
61 return CAIRO_TEST_FAILURE; \
62 } else if ((status) != CAIRO_STATUS_INVALID_MATRIX) { \
63 cairo_test_log (ctx, "Error: %s with invalid matrix returned unexpected status " \
67 cairo_status_to_string (status)); \
68 return CAIRO_TEST_FAILURE; \
71 /* clear floating point exceptions (added by cairo_test_init()) */
72 #if HAVE_FEDISABLEEXCEPT
73 fedisableexcept (FE_INVALID);
76 /* create a bogus matrix and check results of attempted inversion */
77 bogus.x0 = bogus.xy = bogus.xx = cairo_test_NaN ();
78 bogus.y0 = bogus.yx = bogus.yy = bogus.xx;
79 status = cairo_matrix_invert (&bogus);
80 CHECK_STATUS (status, "cairo_matrix_invert(NaN)");
82 inf.x0 = inf.xy = inf.xx = INFINITY;
83 inf.y0 = inf.yx = inf.yy = inf.xx;
84 status = cairo_matrix_invert (&inf);
85 CHECK_STATUS (status, "cairo_matrix_invert(infinity)");
87 /* test cairo_matrix_invert with invalid matrix */
88 status = cairo_matrix_invert (&invalid);
89 CHECK_STATUS (status, "cairo_matrix_invert(invalid)");
92 cairo_matrix_init_identity (&identity);
94 target = cairo_get_group_target (cr);
96 /* test cairo_transform with invalid matrix */
97 cr2 = cairo_create (target);
98 cairo_transform (cr2, &invalid);
100 status = cairo_status (cr2);
102 CHECK_STATUS (status, "cairo_transform(invalid)");
104 /* test cairo_transform with bogus matrix */
105 cr2 = cairo_create (target);
106 cairo_transform (cr2, &bogus);
108 status = cairo_status (cr2);
110 CHECK_STATUS (status, "cairo_transform(NaN)");
112 /* test cairo_transform with ∞ matrix */
113 cr2 = cairo_create (target);
114 cairo_transform (cr2, &inf);
116 status = cairo_status (cr2);
118 CHECK_STATUS (status, "cairo_transform(infinity)");
121 /* test cairo_set_matrix with invalid matrix */
122 cr2 = cairo_create (target);
123 cairo_set_matrix (cr2, &invalid);
125 status = cairo_status (cr2);
127 CHECK_STATUS (status, "cairo_set_matrix(invalid)");
129 /* test cairo_set_matrix with bogus matrix */
130 cr2 = cairo_create (target);
131 cairo_set_matrix (cr2, &bogus);
133 status = cairo_status (cr2);
135 CHECK_STATUS (status, "cairo_set_matrix(NaN)");
137 /* test cairo_set_matrix with ∞ matrix */
138 cr2 = cairo_create (target);
139 cairo_set_matrix (cr2, &inf);
141 status = cairo_status (cr2);
143 CHECK_STATUS (status, "cairo_set_matrix(infinity)");
146 /* test cairo_set_font_matrix with invalid matrix */
147 cr2 = cairo_create (target);
148 cairo_set_font_matrix (cr2, &invalid);
150 /* draw some text to force the font to be resolved */
151 cairo_show_text (cr2, "hello");
153 status = cairo_status (cr2);
155 CHECK_STATUS (status, "cairo_set_font_matrix(invalid)");
157 /* test cairo_set_font_matrix with bogus matrix */
158 cr2 = cairo_create (target);
159 cairo_set_font_matrix (cr2, &bogus);
161 /* draw some text to force the font to be resolved */
162 cairo_show_text (cr2, "hello");
164 status = cairo_status (cr2);
166 CHECK_STATUS (status, "cairo_set_font_matrix(NaN)");
168 /* test cairo_set_font_matrix with ∞ matrix */
169 cr2 = cairo_create (target);
170 cairo_set_font_matrix (cr2, &inf);
172 /* draw some text to force the font to be resolved */
173 cairo_show_text (cr2, "hello");
175 status = cairo_status (cr2);
177 CHECK_STATUS (status, "cairo_set_font_matrix(infinity)");
180 /* test cairo_scaled_font_create with invalid matrix */
181 cr2 = cairo_create (target);
182 font_face = cairo_get_font_face (cr2);
183 font_options = cairo_font_options_create ();
184 cairo_get_font_options (cr, font_options);
185 scaled_font = cairo_scaled_font_create (font_face,
189 status = cairo_scaled_font_status (scaled_font);
190 CHECK_STATUS (status, "cairo_scaled_font_create(invalid)");
192 cairo_scaled_font_destroy (scaled_font);
194 scaled_font = cairo_scaled_font_create (font_face,
198 status = cairo_scaled_font_status (scaled_font);
199 CHECK_STATUS (status, "cairo_scaled_font_create(invalid)");
201 cairo_scaled_font_destroy (scaled_font);
202 cairo_font_options_destroy (font_options);
205 /* test cairo_scaled_font_create with bogus matrix */
206 cr2 = cairo_create (target);
207 font_face = cairo_get_font_face (cr2);
208 font_options = cairo_font_options_create ();
209 cairo_get_font_options (cr, font_options);
210 scaled_font = cairo_scaled_font_create (font_face,
214 status = cairo_scaled_font_status (scaled_font);
215 CHECK_STATUS (status, "cairo_scaled_font_create(NaN)");
217 cairo_scaled_font_destroy (scaled_font);
219 scaled_font = cairo_scaled_font_create (font_face,
223 status = cairo_scaled_font_status (scaled_font);
224 CHECK_STATUS (status, "cairo_scaled_font_create(NaN)");
226 cairo_scaled_font_destroy (scaled_font);
227 cairo_font_options_destroy (font_options);
230 /* test cairo_scaled_font_create with ∞ matrix */
231 cr2 = cairo_create (target);
232 font_face = cairo_get_font_face (cr2);
233 font_options = cairo_font_options_create ();
234 cairo_get_font_options (cr, font_options);
235 scaled_font = cairo_scaled_font_create (font_face,
239 status = cairo_scaled_font_status (scaled_font);
240 CHECK_STATUS (status, "cairo_scaled_font_create(infinity)");
242 cairo_scaled_font_destroy (scaled_font);
244 scaled_font = cairo_scaled_font_create (font_face,
248 status = cairo_scaled_font_status (scaled_font);
249 CHECK_STATUS (status, "cairo_scaled_font_create(infinity)");
251 cairo_scaled_font_destroy (scaled_font);
252 cairo_font_options_destroy (font_options);
256 /* test cairo_pattern_set_matrix with invalid matrix */
257 pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
258 cairo_pattern_set_matrix (pattern, &invalid);
259 status = cairo_pattern_status (pattern);
260 CHECK_STATUS (status, "cairo_pattern_set_matrix(invalid)");
261 cairo_pattern_destroy (pattern);
263 /* test cairo_pattern_set_matrix with bogus matrix */
264 pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
265 cairo_pattern_set_matrix (pattern, &bogus);
266 status = cairo_pattern_status (pattern);
267 CHECK_STATUS (status, "cairo_pattern_set_matrix(NaN)");
268 cairo_pattern_destroy (pattern);
270 /* test cairo_pattern_set_matrix with ∞ matrix */
271 pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
272 cairo_pattern_set_matrix (pattern, &inf);
273 status = cairo_pattern_status (pattern);
274 CHECK_STATUS (status, "cairo_pattern_set_matrix(infinity)");
275 cairo_pattern_destroy (pattern);
278 /* test invalid transformations */
279 cr2 = cairo_create (target);
280 cairo_translate (cr2, bogus.xx, bogus.yy);
281 CHECK_STATUS (status, "cairo_translate(NaN, NaN)");
284 cr2 = cairo_create (target);
285 cairo_translate (cr2, 0, bogus.yy);
286 CHECK_STATUS (status, "cairo_translate(0, NaN)");
289 cr2 = cairo_create (target);
290 cairo_translate (cr2, bogus.xx, 0);
291 CHECK_STATUS (status, "cairo_translate(NaN, 0)");
294 cr2 = cairo_create (target);
295 cairo_translate (cr2, inf.xx, inf.yy);
296 CHECK_STATUS (status, "cairo_translate(∞, ∞)");
299 cr2 = cairo_create (target);
300 cairo_translate (cr2, 0, inf.yy);
301 CHECK_STATUS (status, "cairo_translate(0, ∞)");
304 cr2 = cairo_create (target);
305 cairo_translate (cr2, inf.xx, 0);
306 CHECK_STATUS (status, "cairo_translate(∞, 0)");
310 cr2 = cairo_create (target);
311 cairo_scale (cr2, bogus.xx, bogus.yy);
312 CHECK_STATUS (status, "cairo_scale(NaN, NaN)");
315 cr2 = cairo_create (target);
316 cairo_scale (cr2, 1, bogus.yy);
317 CHECK_STATUS (status, "cairo_scale(1, NaN)");
320 cr2 = cairo_create (target);
321 cairo_scale (cr2, bogus.xx, 1);
322 CHECK_STATUS (status, "cairo_scale(NaN, 1)");
325 cr2 = cairo_create (target);
326 cairo_scale (cr2, inf.xx, inf.yy);
327 CHECK_STATUS (status, "cairo_scale(∞, ∞)");
330 cr2 = cairo_create (target);
331 cairo_scale (cr2, 1, inf.yy);
332 CHECK_STATUS (status, "cairo_scale(1, ∞)");
335 cr2 = cairo_create (target);
336 cairo_scale (cr2, inf.xx, 1);
337 CHECK_STATUS (status, "cairo_scale(∞, 1)");
340 cr2 = cairo_create (target);
341 cairo_scale (cr2, bogus.xx, bogus.yy);
342 CHECK_STATUS (status, "cairo_scale(0, 0)");
345 cr2 = cairo_create (target);
346 cairo_scale (cr2, 1, bogus.yy);
347 CHECK_STATUS (status, "cairo_scale(1, 0)");
350 cr2 = cairo_create (target);
351 cairo_scale (cr2, bogus.xx, 1);
352 CHECK_STATUS (status, "cairo_scale(0, 1)");
356 cr2 = cairo_create (target);
357 cairo_rotate (cr2, bogus.xx);
358 CHECK_STATUS (status, "cairo_rotate(NaN)");
361 cr2 = cairo_create (target);
362 cairo_rotate (cr2, inf.xx);
363 CHECK_STATUS (status, "cairo_rotate(∞)");
366 #if HAVE_FECLEAREXCEPT
367 feclearexcept (FE_INVALID);
370 return CAIRO_TEST_SUCCESS;
373 CAIRO_TEST (invalid_matrix,
374 "Test that all relevant public functions return CAIRO_STATUS_INVALID_MATRIX as appropriate",
375 "api, matrix", /* keywords */
376 NULL, /* requirements */