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
36 static cairo_test_status_t
37 draw (cairo_t *cr, int width, int height)
39 const cairo_test_context_t *ctx = cairo_test_get_context (cr);
40 cairo_status_t status;
41 cairo_surface_t *target;
42 cairo_font_face_t *font_face;
43 cairo_font_options_t *font_options;
44 cairo_scaled_font_t *scaled_font;
45 cairo_pattern_t *pattern;
47 cairo_matrix_t identity, bogus, inf, invalid = {
53 #define CHECK_STATUS(status, function_name) \
54 if ((status) == CAIRO_STATUS_SUCCESS) { \
55 cairo_test_log (ctx, "Error: %s with invalid matrix passed\n", \
57 return CAIRO_TEST_FAILURE; \
58 } else if ((status) != CAIRO_STATUS_INVALID_MATRIX) { \
59 cairo_test_log (ctx, "Error: %s with invalid matrix returned unexpected status " \
63 cairo_status_to_string (status)); \
64 return CAIRO_TEST_FAILURE; \
67 /* clear floating point exceptions (added by cairo_test_init()) */
68 #if HAVE_FEDISABLEEXCEPT
69 fedisableexcept (FE_INVALID);
72 /* create a bogus matrix and check results of attempted inversion */
73 bogus.x0 = bogus.xy = bogus.xx = cairo_test_NaN ();
74 bogus.y0 = bogus.yx = bogus.yy = bogus.xx;
75 status = cairo_matrix_invert (&bogus);
76 CHECK_STATUS (status, "cairo_matrix_invert(NaN)");
78 inf.x0 = inf.xy = inf.xx = INFINITY;
79 inf.y0 = inf.yx = inf.yy = inf.xx;
80 status = cairo_matrix_invert (&inf);
81 CHECK_STATUS (status, "cairo_matrix_invert(infinity)");
83 /* test cairo_matrix_invert with invalid matrix */
84 status = cairo_matrix_invert (&invalid);
85 CHECK_STATUS (status, "cairo_matrix_invert(invalid)");
88 cairo_matrix_init_identity (&identity);
90 target = cairo_get_group_target (cr);
92 /* test cairo_transform with invalid matrix */
93 cr2 = cairo_create (target);
94 cairo_transform (cr2, &invalid);
96 status = cairo_status (cr2);
98 CHECK_STATUS (status, "cairo_transform(invalid)");
100 /* test cairo_transform with bogus matrix */
101 cr2 = cairo_create (target);
102 cairo_transform (cr2, &bogus);
104 status = cairo_status (cr2);
106 CHECK_STATUS (status, "cairo_transform(NaN)");
108 /* test cairo_transform with ∞ matrix */
109 cr2 = cairo_create (target);
110 cairo_transform (cr2, &inf);
112 status = cairo_status (cr2);
114 CHECK_STATUS (status, "cairo_transform(infinity)");
117 /* test cairo_set_matrix with invalid matrix */
118 cr2 = cairo_create (target);
119 cairo_set_matrix (cr2, &invalid);
121 status = cairo_status (cr2);
123 CHECK_STATUS (status, "cairo_set_matrix(invalid)");
125 /* test cairo_set_matrix with bogus matrix */
126 cr2 = cairo_create (target);
127 cairo_set_matrix (cr2, &bogus);
129 status = cairo_status (cr2);
131 CHECK_STATUS (status, "cairo_set_matrix(NaN)");
133 /* test cairo_set_matrix with ∞ matrix */
134 cr2 = cairo_create (target);
135 cairo_set_matrix (cr2, &inf);
137 status = cairo_status (cr2);
139 CHECK_STATUS (status, "cairo_set_matrix(infinity)");
142 /* test cairo_set_font_matrix with invalid matrix */
143 cr2 = cairo_create (target);
144 cairo_set_font_matrix (cr2, &invalid);
146 /* draw some text to force the font to be resolved */
147 cairo_show_text (cr2, "hello");
149 status = cairo_status (cr2);
151 CHECK_STATUS (status, "cairo_set_font_matrix(invalid)");
153 /* test cairo_set_font_matrix with bogus matrix */
154 cr2 = cairo_create (target);
155 cairo_set_font_matrix (cr2, &bogus);
157 /* draw some text to force the font to be resolved */
158 cairo_show_text (cr2, "hello");
160 status = cairo_status (cr2);
162 CHECK_STATUS (status, "cairo_set_font_matrix(NaN)");
164 /* test cairo_set_font_matrix with ∞ matrix */
165 cr2 = cairo_create (target);
166 cairo_set_font_matrix (cr2, &inf);
168 /* draw some text to force the font to be resolved */
169 cairo_show_text (cr2, "hello");
171 status = cairo_status (cr2);
173 CHECK_STATUS (status, "cairo_set_font_matrix(infinity)");
176 /* test cairo_scaled_font_create with invalid matrix */
177 cr2 = cairo_create (target);
178 font_face = cairo_get_font_face (cr2);
179 font_options = cairo_font_options_create ();
180 cairo_get_font_options (cr, font_options);
181 scaled_font = cairo_scaled_font_create (font_face,
185 status = cairo_scaled_font_status (scaled_font);
186 CHECK_STATUS (status, "cairo_scaled_font_create(invalid)");
188 cairo_scaled_font_destroy (scaled_font);
190 scaled_font = cairo_scaled_font_create (font_face,
194 status = cairo_scaled_font_status (scaled_font);
195 CHECK_STATUS (status, "cairo_scaled_font_create(invalid)");
197 cairo_scaled_font_destroy (scaled_font);
198 cairo_font_options_destroy (font_options);
201 /* test cairo_scaled_font_create with bogus matrix */
202 cr2 = cairo_create (target);
203 font_face = cairo_get_font_face (cr2);
204 font_options = cairo_font_options_create ();
205 cairo_get_font_options (cr, font_options);
206 scaled_font = cairo_scaled_font_create (font_face,
210 status = cairo_scaled_font_status (scaled_font);
211 CHECK_STATUS (status, "cairo_scaled_font_create(NaN)");
213 cairo_scaled_font_destroy (scaled_font);
215 scaled_font = cairo_scaled_font_create (font_face,
219 status = cairo_scaled_font_status (scaled_font);
220 CHECK_STATUS (status, "cairo_scaled_font_create(NaN)");
222 cairo_scaled_font_destroy (scaled_font);
223 cairo_font_options_destroy (font_options);
226 /* test cairo_scaled_font_create with ∞ matrix */
227 cr2 = cairo_create (target);
228 font_face = cairo_get_font_face (cr2);
229 font_options = cairo_font_options_create ();
230 cairo_get_font_options (cr, font_options);
231 scaled_font = cairo_scaled_font_create (font_face,
235 status = cairo_scaled_font_status (scaled_font);
236 CHECK_STATUS (status, "cairo_scaled_font_create(infinity)");
238 cairo_scaled_font_destroy (scaled_font);
240 scaled_font = cairo_scaled_font_create (font_face,
244 status = cairo_scaled_font_status (scaled_font);
245 CHECK_STATUS (status, "cairo_scaled_font_create(infinity)");
247 cairo_scaled_font_destroy (scaled_font);
248 cairo_font_options_destroy (font_options);
252 /* test cairo_pattern_set_matrix with invalid matrix */
253 pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
254 cairo_pattern_set_matrix (pattern, &invalid);
255 status = cairo_pattern_status (pattern);
256 CHECK_STATUS (status, "cairo_pattern_set_matrix(invalid)");
257 cairo_pattern_destroy (pattern);
259 /* test cairo_pattern_set_matrix with bogus matrix */
260 pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
261 cairo_pattern_set_matrix (pattern, &bogus);
262 status = cairo_pattern_status (pattern);
263 CHECK_STATUS (status, "cairo_pattern_set_matrix(NaN)");
264 cairo_pattern_destroy (pattern);
266 /* test cairo_pattern_set_matrix with ∞ matrix */
267 pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
268 cairo_pattern_set_matrix (pattern, &inf);
269 status = cairo_pattern_status (pattern);
270 CHECK_STATUS (status, "cairo_pattern_set_matrix(infinity)");
271 cairo_pattern_destroy (pattern);
274 /* test invalid transformations */
275 cr2 = cairo_create (target);
276 cairo_translate (cr2, bogus.xx, bogus.yy);
277 CHECK_STATUS (status, "cairo_translate(NaN, NaN)");
280 cr2 = cairo_create (target);
281 cairo_translate (cr2, 0, bogus.yy);
282 CHECK_STATUS (status, "cairo_translate(0, NaN)");
285 cr2 = cairo_create (target);
286 cairo_translate (cr2, bogus.xx, 0);
287 CHECK_STATUS (status, "cairo_translate(NaN, 0)");
290 cr2 = cairo_create (target);
291 cairo_translate (cr2, inf.xx, inf.yy);
292 CHECK_STATUS (status, "cairo_translate(∞, ∞)");
295 cr2 = cairo_create (target);
296 cairo_translate (cr2, 0, inf.yy);
297 CHECK_STATUS (status, "cairo_translate(0, ∞)");
300 cr2 = cairo_create (target);
301 cairo_translate (cr2, inf.xx, 0);
302 CHECK_STATUS (status, "cairo_translate(∞, 0)");
306 cr2 = cairo_create (target);
307 cairo_scale (cr2, bogus.xx, bogus.yy);
308 CHECK_STATUS (status, "cairo_scale(NaN, NaN)");
311 cr2 = cairo_create (target);
312 cairo_scale (cr2, 1, bogus.yy);
313 CHECK_STATUS (status, "cairo_scale(1, NaN)");
316 cr2 = cairo_create (target);
317 cairo_scale (cr2, bogus.xx, 1);
318 CHECK_STATUS (status, "cairo_scale(NaN, 1)");
321 cr2 = cairo_create (target);
322 cairo_scale (cr2, inf.xx, inf.yy);
323 CHECK_STATUS (status, "cairo_scale(∞, ∞)");
326 cr2 = cairo_create (target);
327 cairo_scale (cr2, 1, inf.yy);
328 CHECK_STATUS (status, "cairo_scale(1, ∞)");
331 cr2 = cairo_create (target);
332 cairo_scale (cr2, inf.xx, 1);
333 CHECK_STATUS (status, "cairo_scale(∞, 1)");
336 cr2 = cairo_create (target);
337 cairo_scale (cr2, bogus.xx, bogus.yy);
338 CHECK_STATUS (status, "cairo_scale(0, 0)");
341 cr2 = cairo_create (target);
342 cairo_scale (cr2, 1, bogus.yy);
343 CHECK_STATUS (status, "cairo_scale(1, 0)");
346 cr2 = cairo_create (target);
347 cairo_scale (cr2, bogus.xx, 1);
348 CHECK_STATUS (status, "cairo_scale(0, 1)");
352 cr2 = cairo_create (target);
353 cairo_rotate (cr2, bogus.xx);
354 CHECK_STATUS (status, "cairo_rotate(NaN)");
357 cr2 = cairo_create (target);
358 cairo_rotate (cr2, inf.xx);
359 CHECK_STATUS (status, "cairo_rotate(∞)");
362 #if HAVE_FECLEAREXCEPT
363 feclearexcept (FE_INVALID);
366 return CAIRO_TEST_SUCCESS;
369 CAIRO_TEST (invalid_matrix,
370 "Test that all relevant public functions return CAIRO_STATUS_INVALID_MATRIX as appropriate",
371 "api, matrix", /* keywords */
372 NULL, /* requirements */