Rev 1892 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1892 | serge | 1 | /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ |
2 | /* cairo - a vector graphics library with display and print output |
||
3 | * |
||
4 | * Copyright © 2002 University of Southern California |
||
5 | * Copyright © 2005 Red Hat, Inc. |
||
6 | * Copyright © 2007 Adrian Johnson |
||
7 | * |
||
8 | * This library is free software; you can redistribute it and/or |
||
9 | * modify it either under the terms of the GNU Lesser General Public |
||
10 | * License version 2.1 as published by the Free Software Foundation |
||
11 | * (the "LGPL") or, at your option, under the terms of the Mozilla |
||
12 | * Public License Version 1.1 (the "MPL"). If you do not alter this |
||
13 | * notice, a recipient may use your version of this file under either |
||
14 | * the MPL or the LGPL. |
||
15 | * |
||
16 | * You should have received a copy of the LGPL along with this library |
||
17 | * in the file COPYING-LGPL-2.1; if not, write to the Free Software |
||
18 | * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA |
||
19 | * You should have received a copy of the MPL along with this library |
||
20 | * in the file COPYING-MPL-1.1 |
||
21 | * |
||
22 | * The contents of this file are subject to the Mozilla Public License |
||
23 | * Version 1.1 (the "License"); you may not use this file except in |
||
24 | * compliance with the License. You may obtain a copy of the License at |
||
25 | * http://www.mozilla.org/MPL/ |
||
26 | * |
||
27 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY |
||
28 | * OF ANY KIND, either express or implied. See the LGPL or the MPL for |
||
29 | * the specific language governing rights and limitations. |
||
30 | * |
||
31 | * The Original Code is the cairo graphics library. |
||
32 | * |
||
33 | * The Initial Developer of the Original Code is University of Southern |
||
34 | * California. |
||
35 | * |
||
36 | * Contributor(s): |
||
37 | * Carl D. Worth |
||
38 | * Adrian Johnson |
||
39 | */ |
||
40 | |||
41 | #include "cairoint.h" |
||
42 | #include "cairo-error-private.h" |
||
43 | |||
3959 | Serge | 44 | COMPILE_TIME_ASSERT ((int)CAIRO_STATUS_LAST_STATUS < (int)CAIRO_INT_STATUS_UNSUPPORTED); |
1892 | serge | 45 | COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127); |
46 | |||
47 | /** |
||
48 | * SECTION:cairo-status |
||
49 | * @Title: Error handling |
||
50 | * @Short_Description: Decoding cairo's status |
||
51 | * @See_Also: cairo_status(), cairo_surface_status(), cairo_pattern_status(), |
||
3959 | Serge | 52 | * cairo_font_face_status(), cairo_scaled_font_status(), |
1892 | serge | 53 | * cairo_region_status() |
54 | * |
||
55 | * Cairo uses a single status type to represent all kinds of errors. A status |
||
56 | * value of %CAIRO_STATUS_SUCCESS represents no error and has an integer value |
||
57 | * of zero. All other status values represent an error. |
||
58 | * |
||
59 | * Cairo's error handling is designed to be easy to use and safe. All major |
||
60 | * cairo objects |
||
61 | * can be queried anytime by the users using cairo*_status() calls. In |
||
62 | * the mean time, it is safe to call all cairo functions normally even if the |
||
63 | * underlying object is in an error status. This means that no error handling |
||
64 | * code is required before or after each individual cairo function call. |
||
3959 | Serge | 65 | **/ |
1892 | serge | 66 | |
67 | /* Public stuff */ |
||
68 | |||
69 | /** |
||
70 | * cairo_status_to_string: |
||
71 | * @status: a cairo status |
||
72 | * |
||
73 | * Provides a human-readable description of a #cairo_status_t. |
||
74 | * |
||
75 | * Returns: a string representation of the status |
||
3959 | Serge | 76 | * |
77 | * Since: 1.0 |
||
78 | **/ |
||
1892 | serge | 79 | const char * |
80 | cairo_status_to_string (cairo_status_t status) |
||
81 | { |
||
82 | switch (status) { |
||
83 | case CAIRO_STATUS_SUCCESS: |
||
84 | return "no error has occurred"; |
||
85 | case CAIRO_STATUS_NO_MEMORY: |
||
86 | return "out of memory"; |
||
87 | case CAIRO_STATUS_INVALID_RESTORE: |
||
88 | return "cairo_restore() without matching cairo_save()"; |
||
89 | case CAIRO_STATUS_INVALID_POP_GROUP: |
||
90 | return "no saved group to pop, i.e. cairo_pop_group() without matching cairo_push_group()"; |
||
91 | case CAIRO_STATUS_NO_CURRENT_POINT: |
||
92 | return "no current point defined"; |
||
93 | case CAIRO_STATUS_INVALID_MATRIX: |
||
94 | return "invalid matrix (not invertible)"; |
||
95 | case CAIRO_STATUS_INVALID_STATUS: |
||
96 | return "invalid value for an input cairo_status_t"; |
||
97 | case CAIRO_STATUS_NULL_POINTER: |
||
98 | return "NULL pointer"; |
||
99 | case CAIRO_STATUS_INVALID_STRING: |
||
100 | return "input string not valid UTF-8"; |
||
101 | case CAIRO_STATUS_INVALID_PATH_DATA: |
||
102 | return "input path data not valid"; |
||
103 | case CAIRO_STATUS_READ_ERROR: |
||
104 | return "error while reading from input stream"; |
||
105 | case CAIRO_STATUS_WRITE_ERROR: |
||
106 | return "error while writing to output stream"; |
||
107 | case CAIRO_STATUS_SURFACE_FINISHED: |
||
108 | return "the target surface has been finished"; |
||
109 | case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: |
||
110 | return "the surface type is not appropriate for the operation"; |
||
111 | case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: |
||
112 | return "the pattern type is not appropriate for the operation"; |
||
113 | case CAIRO_STATUS_INVALID_CONTENT: |
||
114 | return "invalid value for an input cairo_content_t"; |
||
115 | case CAIRO_STATUS_INVALID_FORMAT: |
||
116 | return "invalid value for an input cairo_format_t"; |
||
117 | case CAIRO_STATUS_INVALID_VISUAL: |
||
118 | return "invalid value for an input Visual*"; |
||
119 | case CAIRO_STATUS_FILE_NOT_FOUND: |
||
120 | return "file not found"; |
||
121 | case CAIRO_STATUS_INVALID_DASH: |
||
122 | return "invalid value for a dash setting"; |
||
123 | case CAIRO_STATUS_INVALID_DSC_COMMENT: |
||
124 | return "invalid value for a DSC comment"; |
||
125 | case CAIRO_STATUS_INVALID_INDEX: |
||
126 | return "invalid index passed to getter"; |
||
127 | case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: |
||
128 | return "clip region not representable in desired format"; |
||
129 | case CAIRO_STATUS_TEMP_FILE_ERROR: |
||
130 | return "error creating or writing to a temporary file"; |
||
131 | case CAIRO_STATUS_INVALID_STRIDE: |
||
132 | return "invalid value for stride"; |
||
133 | case CAIRO_STATUS_FONT_TYPE_MISMATCH: |
||
134 | return "the font type is not appropriate for the operation"; |
||
135 | case CAIRO_STATUS_USER_FONT_IMMUTABLE: |
||
136 | return "the user-font is immutable"; |
||
137 | case CAIRO_STATUS_USER_FONT_ERROR: |
||
138 | return "error occurred in a user-font callback function"; |
||
139 | case CAIRO_STATUS_NEGATIVE_COUNT: |
||
140 | return "negative number used where it is not allowed"; |
||
141 | case CAIRO_STATUS_INVALID_CLUSTERS: |
||
142 | return "input clusters do not represent the accompanying text and glyph arrays"; |
||
143 | case CAIRO_STATUS_INVALID_SLANT: |
||
144 | return "invalid value for an input cairo_font_slant_t"; |
||
145 | case CAIRO_STATUS_INVALID_WEIGHT: |
||
146 | return "invalid value for an input cairo_font_weight_t"; |
||
147 | case CAIRO_STATUS_INVALID_SIZE: |
||
148 | return "invalid value (typically too big) for the size of the input (surface, pattern, etc.)"; |
||
149 | case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: |
||
150 | return "user-font method not implemented"; |
||
151 | case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: |
||
152 | return "the device type is not appropriate for the operation"; |
||
153 | case CAIRO_STATUS_DEVICE_ERROR: |
||
154 | return "an operation to the device caused an unspecified error"; |
||
3959 | Serge | 155 | case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: |
156 | return "invalid operation during mesh pattern construction"; |
||
157 | case CAIRO_STATUS_DEVICE_FINISHED: |
||
158 | return "the target device has been finished"; |
||
1892 | serge | 159 | default: |
160 | case CAIRO_STATUS_LAST_STATUS: |
||
161 | return " |
||
162 | } |
||
163 | } |
||
164 | |||
165 | |||
166 | /** |
||
167 | * cairo_glyph_allocate: |
||
168 | * @num_glyphs: number of glyphs to allocate |
||
169 | * |
||
170 | * Allocates an array of #cairo_glyph_t's. |
||
171 | * This function is only useful in implementations of |
||
172 | * #cairo_user_scaled_font_text_to_glyphs_func_t where the user |
||
173 | * needs to allocate an array of glyphs that cairo will free. |
||
174 | * For all other uses, user can use their own allocation method |
||
175 | * for glyphs. |
||
176 | * |
||
177 | * This function returns %NULL if @num_glyphs is not positive, |
||
178 | * or if out of memory. That means, the %NULL return value |
||
179 | * signals out-of-memory only if @num_glyphs was positive. |
||
180 | * |
||
181 | * Returns: the newly allocated array of glyphs that should be |
||
182 | * freed using cairo_glyph_free() |
||
183 | * |
||
184 | * Since: 1.8 |
||
3959 | Serge | 185 | **/ |
1892 | serge | 186 | cairo_glyph_t * |
187 | cairo_glyph_allocate (int num_glyphs) |
||
188 | { |
||
189 | if (num_glyphs <= 0) |
||
190 | return NULL; |
||
191 | |||
192 | return _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); |
||
193 | } |
||
194 | slim_hidden_def (cairo_glyph_allocate); |
||
195 | |||
196 | /** |
||
197 | * cairo_glyph_free: |
||
198 | * @glyphs: array of glyphs to free, or %NULL |
||
199 | * |
||
200 | * Frees an array of #cairo_glyph_t's allocated using cairo_glyph_allocate(). |
||
201 | * This function is only useful to free glyph array returned |
||
202 | * by cairo_scaled_font_text_to_glyphs() where cairo returns |
||
203 | * an array of glyphs that the user will free. |
||
204 | * For all other uses, user can use their own allocation method |
||
205 | * for glyphs. |
||
206 | * |
||
207 | * Since: 1.8 |
||
3959 | Serge | 208 | **/ |
1892 | serge | 209 | void |
210 | cairo_glyph_free (cairo_glyph_t *glyphs) |
||
211 | { |
||
3959 | Serge | 212 | free (glyphs); |
1892 | serge | 213 | } |
214 | slim_hidden_def (cairo_glyph_free); |
||
215 | |||
216 | /** |
||
217 | * cairo_text_cluster_allocate: |
||
218 | * @num_clusters: number of text_clusters to allocate |
||
219 | * |
||
220 | * Allocates an array of #cairo_text_cluster_t's. |
||
221 | * This function is only useful in implementations of |
||
222 | * #cairo_user_scaled_font_text_to_glyphs_func_t where the user |
||
223 | * needs to allocate an array of text clusters that cairo will free. |
||
224 | * For all other uses, user can use their own allocation method |
||
225 | * for text clusters. |
||
226 | * |
||
227 | * This function returns %NULL if @num_clusters is not positive, |
||
228 | * or if out of memory. That means, the %NULL return value |
||
229 | * signals out-of-memory only if @num_clusters was positive. |
||
230 | * |
||
231 | * Returns: the newly allocated array of text clusters that should be |
||
232 | * freed using cairo_text_cluster_free() |
||
233 | * |
||
234 | * Since: 1.8 |
||
3959 | Serge | 235 | **/ |
1892 | serge | 236 | cairo_text_cluster_t * |
237 | cairo_text_cluster_allocate (int num_clusters) |
||
238 | { |
||
239 | if (num_clusters <= 0) |
||
240 | return NULL; |
||
241 | |||
242 | return _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t)); |
||
243 | } |
||
244 | slim_hidden_def (cairo_text_cluster_allocate); |
||
245 | |||
246 | /** |
||
247 | * cairo_text_cluster_free: |
||
248 | * @clusters: array of text clusters to free, or %NULL |
||
249 | * |
||
250 | * Frees an array of #cairo_text_cluster's allocated using cairo_text_cluster_allocate(). |
||
251 | * This function is only useful to free text cluster array returned |
||
252 | * by cairo_scaled_font_text_to_glyphs() where cairo returns |
||
253 | * an array of text clusters that the user will free. |
||
254 | * For all other uses, user can use their own allocation method |
||
255 | * for text clusters. |
||
256 | * |
||
257 | * Since: 1.8 |
||
3959 | Serge | 258 | **/ |
1892 | serge | 259 | void |
260 | cairo_text_cluster_free (cairo_text_cluster_t *clusters) |
||
261 | { |
||
3959 | Serge | 262 | free (clusters); |
1892 | serge | 263 | } |
264 | slim_hidden_def (cairo_text_cluster_free); |
||
265 | |||
266 | |||
267 | /* Private stuff */ |
||
268 | |||
269 | /** |
||
270 | * _cairo_validate_text_clusters: |
||
271 | * @utf8: UTF-8 text |
||
272 | * @utf8_len: length of @utf8 in bytes |
||
273 | * @glyphs: array of glyphs |
||
274 | * @num_glyphs: number of glyphs |
||
275 | * @clusters: array of cluster mapping information |
||
276 | * @num_clusters: number of clusters in the mapping |
||
277 | * @cluster_flags: cluster flags |
||
278 | * |
||
279 | * Check that clusters cover the entire glyphs and utf8 arrays, |
||
280 | * and that cluster boundaries are UTF-8 boundaries. |
||
281 | * |
||
282 | * Return value: %CAIRO_STATUS_SUCCESS upon success, or |
||
283 | * %CAIRO_STATUS_INVALID_CLUSTERS on error. |
||
284 | * The error is either invalid UTF-8 input, |
||
285 | * or bad cluster mapping. |
||
3959 | Serge | 286 | **/ |
1892 | serge | 287 | cairo_status_t |
288 | _cairo_validate_text_clusters (const char *utf8, |
||
289 | int utf8_len, |
||
290 | const cairo_glyph_t *glyphs, |
||
291 | int num_glyphs, |
||
292 | const cairo_text_cluster_t *clusters, |
||
293 | int num_clusters, |
||
294 | cairo_text_cluster_flags_t cluster_flags) |
||
295 | { |
||
296 | cairo_status_t status; |
||
297 | unsigned int n_bytes = 0; |
||
298 | unsigned int n_glyphs = 0; |
||
299 | int i; |
||
300 | |||
301 | for (i = 0; i < num_clusters; i++) { |
||
302 | int cluster_bytes = clusters[i].num_bytes; |
||
303 | int cluster_glyphs = clusters[i].num_glyphs; |
||
304 | |||
305 | if (cluster_bytes < 0 || cluster_glyphs < 0) |
||
306 | goto BAD; |
||
307 | |||
308 | /* A cluster should cover at least one character or glyph. |
||
309 | * I can't see any use for a 0,0 cluster. |
||
310 | * I can't see an immediate use for a zero-text cluster |
||
311 | * right now either, but they don't harm. |
||
312 | * Zero-glyph clusters on the other hand are useful for |
||
313 | * things like U+200C ZERO WIDTH NON-JOINER */ |
||
314 | if (cluster_bytes == 0 && cluster_glyphs == 0) |
||
315 | goto BAD; |
||
316 | |||
317 | /* Since n_bytes and n_glyphs are unsigned, but the rest of |
||
318 | * values involved are signed, we can detect overflow easily */ |
||
319 | if (n_bytes+cluster_bytes > (unsigned int)utf8_len || n_glyphs+cluster_glyphs > (unsigned int)num_glyphs) |
||
320 | goto BAD; |
||
321 | |||
322 | /* Make sure we've got valid UTF-8 for the cluster */ |
||
323 | status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL); |
||
324 | if (unlikely (status)) |
||
325 | return _cairo_error (CAIRO_STATUS_INVALID_CLUSTERS); |
||
326 | |||
327 | n_bytes += cluster_bytes ; |
||
328 | n_glyphs += cluster_glyphs; |
||
329 | } |
||
330 | |||
331 | if (n_bytes != (unsigned int) utf8_len || n_glyphs != (unsigned int) num_glyphs) { |
||
332 | BAD: |
||
333 | return _cairo_error (CAIRO_STATUS_INVALID_CLUSTERS); |
||
334 | } |
||
335 | |||
336 | return CAIRO_STATUS_SUCCESS; |
||
337 | } |
||
338 | |||
339 | /** |
||
340 | * _cairo_operator_bounded_by_mask: |
||
341 | * @op: a #cairo_operator_t |
||
342 | * |
||
343 | * A bounded operator is one where mask pixel |
||
344 | * of zero results in no effect on the destination image. |
||
345 | * |
||
346 | * Unbounded operators often require special handling; if you, for |
||
347 | * example, draw trapezoids with an unbounded operator, the effect |
||
348 | * extends past the bounding box of the trapezoids. |
||
349 | * |
||
350 | * Return value: %TRUE if the operator is bounded by the mask operand |
||
351 | **/ |
||
352 | cairo_bool_t |
||
353 | _cairo_operator_bounded_by_mask (cairo_operator_t op) |
||
354 | { |
||
355 | switch (op) { |
||
356 | case CAIRO_OPERATOR_CLEAR: |
||
357 | case CAIRO_OPERATOR_SOURCE: |
||
358 | case CAIRO_OPERATOR_OVER: |
||
359 | case CAIRO_OPERATOR_ATOP: |
||
360 | case CAIRO_OPERATOR_DEST: |
||
361 | case CAIRO_OPERATOR_DEST_OVER: |
||
362 | case CAIRO_OPERATOR_DEST_OUT: |
||
363 | case CAIRO_OPERATOR_XOR: |
||
364 | case CAIRO_OPERATOR_ADD: |
||
365 | case CAIRO_OPERATOR_SATURATE: |
||
366 | case CAIRO_OPERATOR_MULTIPLY: |
||
367 | case CAIRO_OPERATOR_SCREEN: |
||
368 | case CAIRO_OPERATOR_OVERLAY: |
||
369 | case CAIRO_OPERATOR_DARKEN: |
||
370 | case CAIRO_OPERATOR_LIGHTEN: |
||
371 | case CAIRO_OPERATOR_COLOR_DODGE: |
||
372 | case CAIRO_OPERATOR_COLOR_BURN: |
||
373 | case CAIRO_OPERATOR_HARD_LIGHT: |
||
374 | case CAIRO_OPERATOR_SOFT_LIGHT: |
||
375 | case CAIRO_OPERATOR_DIFFERENCE: |
||
376 | case CAIRO_OPERATOR_EXCLUSION: |
||
377 | case CAIRO_OPERATOR_HSL_HUE: |
||
378 | case CAIRO_OPERATOR_HSL_SATURATION: |
||
379 | case CAIRO_OPERATOR_HSL_COLOR: |
||
380 | case CAIRO_OPERATOR_HSL_LUMINOSITY: |
||
381 | return TRUE; |
||
382 | case CAIRO_OPERATOR_OUT: |
||
383 | case CAIRO_OPERATOR_IN: |
||
384 | case CAIRO_OPERATOR_DEST_IN: |
||
385 | case CAIRO_OPERATOR_DEST_ATOP: |
||
386 | return FALSE; |
||
387 | } |
||
388 | |||
389 | ASSERT_NOT_REACHED; |
||
390 | return FALSE; |
||
391 | } |
||
392 | |||
393 | /** |
||
394 | * _cairo_operator_bounded_by_source: |
||
395 | * @op: a #cairo_operator_t |
||
396 | * |
||
397 | * A bounded operator is one where source pixels of zero |
||
398 | * (in all four components, r, g, b and a) effect no change |
||
399 | * in the resulting destination image. |
||
400 | * |
||
401 | * Unbounded operators often require special handling; if you, for |
||
402 | * example, copy a surface with the SOURCE operator, the effect |
||
403 | * extends past the bounding box of the source surface. |
||
404 | * |
||
405 | * Return value: %TRUE if the operator is bounded by the source operand |
||
406 | **/ |
||
407 | cairo_bool_t |
||
408 | _cairo_operator_bounded_by_source (cairo_operator_t op) |
||
409 | { |
||
410 | switch (op) { |
||
411 | case CAIRO_OPERATOR_OVER: |
||
412 | case CAIRO_OPERATOR_ATOP: |
||
413 | case CAIRO_OPERATOR_DEST: |
||
414 | case CAIRO_OPERATOR_DEST_OVER: |
||
415 | case CAIRO_OPERATOR_DEST_OUT: |
||
416 | case CAIRO_OPERATOR_XOR: |
||
417 | case CAIRO_OPERATOR_ADD: |
||
418 | case CAIRO_OPERATOR_SATURATE: |
||
419 | case CAIRO_OPERATOR_MULTIPLY: |
||
420 | case CAIRO_OPERATOR_SCREEN: |
||
421 | case CAIRO_OPERATOR_OVERLAY: |
||
422 | case CAIRO_OPERATOR_DARKEN: |
||
423 | case CAIRO_OPERATOR_LIGHTEN: |
||
424 | case CAIRO_OPERATOR_COLOR_DODGE: |
||
425 | case CAIRO_OPERATOR_COLOR_BURN: |
||
426 | case CAIRO_OPERATOR_HARD_LIGHT: |
||
427 | case CAIRO_OPERATOR_SOFT_LIGHT: |
||
428 | case CAIRO_OPERATOR_DIFFERENCE: |
||
429 | case CAIRO_OPERATOR_EXCLUSION: |
||
430 | case CAIRO_OPERATOR_HSL_HUE: |
||
431 | case CAIRO_OPERATOR_HSL_SATURATION: |
||
432 | case CAIRO_OPERATOR_HSL_COLOR: |
||
433 | case CAIRO_OPERATOR_HSL_LUMINOSITY: |
||
434 | return TRUE; |
||
435 | case CAIRO_OPERATOR_CLEAR: |
||
436 | case CAIRO_OPERATOR_SOURCE: |
||
437 | case CAIRO_OPERATOR_OUT: |
||
438 | case CAIRO_OPERATOR_IN: |
||
439 | case CAIRO_OPERATOR_DEST_IN: |
||
440 | case CAIRO_OPERATOR_DEST_ATOP: |
||
441 | return FALSE; |
||
442 | } |
||
443 | |||
444 | ASSERT_NOT_REACHED; |
||
445 | return FALSE; |
||
446 | } |
||
447 | |||
448 | uint32_t |
||
449 | _cairo_operator_bounded_by_either (cairo_operator_t op) |
||
450 | { |
||
451 | switch (op) { |
||
452 | default: |
||
453 | ASSERT_NOT_REACHED; |
||
454 | case CAIRO_OPERATOR_OVER: |
||
455 | case CAIRO_OPERATOR_ATOP: |
||
456 | case CAIRO_OPERATOR_DEST: |
||
457 | case CAIRO_OPERATOR_DEST_OVER: |
||
458 | case CAIRO_OPERATOR_DEST_OUT: |
||
459 | case CAIRO_OPERATOR_XOR: |
||
460 | case CAIRO_OPERATOR_ADD: |
||
461 | case CAIRO_OPERATOR_SATURATE: |
||
462 | case CAIRO_OPERATOR_MULTIPLY: |
||
463 | case CAIRO_OPERATOR_SCREEN: |
||
464 | case CAIRO_OPERATOR_OVERLAY: |
||
465 | case CAIRO_OPERATOR_DARKEN: |
||
466 | case CAIRO_OPERATOR_LIGHTEN: |
||
467 | case CAIRO_OPERATOR_COLOR_DODGE: |
||
468 | case CAIRO_OPERATOR_COLOR_BURN: |
||
469 | case CAIRO_OPERATOR_HARD_LIGHT: |
||
470 | case CAIRO_OPERATOR_SOFT_LIGHT: |
||
471 | case CAIRO_OPERATOR_DIFFERENCE: |
||
472 | case CAIRO_OPERATOR_EXCLUSION: |
||
473 | case CAIRO_OPERATOR_HSL_HUE: |
||
474 | case CAIRO_OPERATOR_HSL_SATURATION: |
||
475 | case CAIRO_OPERATOR_HSL_COLOR: |
||
476 | case CAIRO_OPERATOR_HSL_LUMINOSITY: |
||
477 | return CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE; |
||
478 | case CAIRO_OPERATOR_CLEAR: |
||
479 | case CAIRO_OPERATOR_SOURCE: |
||
480 | return CAIRO_OPERATOR_BOUND_BY_MASK; |
||
481 | case CAIRO_OPERATOR_OUT: |
||
482 | case CAIRO_OPERATOR_IN: |
||
483 | case CAIRO_OPERATOR_DEST_IN: |
||
484 | case CAIRO_OPERATOR_DEST_ATOP: |
||
485 | return 0; |
||
486 | } |
||
487 | |||
488 | } |
||
489 | |||
490 | #if DISABLE_SOME_FLOATING_POINT |
||
491 | /* This function is identical to the C99 function lround(), except that it |
||
492 | * performs arithmetic rounding (floor(d + .5) instead of away-from-zero rounding) and |
||
493 | * has a valid input range of (INT_MIN, INT_MAX] instead of |
||
494 | * [INT_MIN, INT_MAX]. It is much faster on both x86 and FPU-less systems |
||
495 | * than other commonly used methods for rounding (lround, round, rint, lrint |
||
496 | * or float (d + 0.5)). |
||
497 | * |
||
498 | * The reason why this function is much faster on x86 than other |
||
499 | * methods is due to the fact that it avoids the fldcw instruction. |
||
500 | * This instruction incurs a large performance penalty on modern Intel |
||
501 | * processors due to how it prevents efficient instruction pipelining. |
||
502 | * |
||
503 | * The reason why this function is much faster on FPU-less systems is for |
||
504 | * an entirely different reason. All common rounding methods involve multiple |
||
505 | * floating-point operations. Each one of these operations has to be |
||
506 | * emulated in software, which adds up to be a large performance penalty. |
||
507 | * This function doesn't perform any floating-point calculations, and thus |
||
508 | * avoids this penalty. |
||
509 | */ |
||
510 | int |
||
511 | _cairo_lround (double d) |
||
512 | { |
||
513 | uint32_t top, shift_amount, output; |
||
514 | union { |
||
515 | double d; |
||
516 | uint64_t ui64; |
||
517 | uint32_t ui32[2]; |
||
518 | } u; |
||
519 | |||
520 | u.d = d; |
||
521 | |||
522 | /* If the integer word order doesn't match the float word order, we swap |
||
523 | * the words of the input double. This is needed because we will be |
||
524 | * treating the whole double as a 64-bit unsigned integer. Notice that we |
||
525 | * use WORDS_BIGENDIAN to detect the integer word order, which isn't |
||
526 | * exactly correct because WORDS_BIGENDIAN refers to byte order, not word |
||
527 | * order. Thus, we are making the assumption that the byte order is the |
||
528 | * same as the integer word order which, on the modern machines that we |
||
529 | * care about, is OK. |
||
530 | */ |
||
531 | #if ( defined(FLOAT_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)) || \ |
||
532 | (!defined(FLOAT_WORDS_BIGENDIAN) && defined(WORDS_BIGENDIAN)) |
||
533 | { |
||
534 | uint32_t temp = u.ui32[0]; |
||
535 | u.ui32[0] = u.ui32[1]; |
||
536 | u.ui32[1] = temp; |
||
537 | } |
||
538 | #endif |
||
539 | |||
540 | #ifdef WORDS_BIGENDIAN |
||
541 | #define MSW (0) /* Most Significant Word */ |
||
542 | #define LSW (1) /* Least Significant Word */ |
||
543 | #else |
||
544 | #define MSW (1) |
||
545 | #define LSW (0) |
||
546 | #endif |
||
547 | |||
548 | /* By shifting the most significant word of the input double to the |
||
549 | * right 20 places, we get the very "top" of the double where the exponent |
||
550 | * and sign bit lie. |
||
551 | */ |
||
552 | top = u.ui32[MSW] >> 20; |
||
553 | |||
554 | /* Here, we calculate how much we have to shift the mantissa to normalize |
||
555 | * it to an integer value. We extract the exponent "top" by masking out the |
||
556 | * sign bit, then we calculate the shift amount by subtracting the exponent |
||
557 | * from the bias. Notice that the correct bias for 64-bit doubles is |
||
558 | * actually 1075, but we use 1053 instead for two reasons: |
||
559 | * |
||
560 | * 1) To perform rounding later on, we will first need the target |
||
561 | * value in a 31.1 fixed-point format. Thus, the bias needs to be one |
||
562 | * less: (1075 - 1: 1074). |
||
563 | * |
||
564 | * 2) To avoid shifting the mantissa as a full 64-bit integer (which is |
||
565 | * costly on certain architectures), we break the shift into two parts. |
||
566 | * First, the upper and lower parts of the mantissa are shifted |
||
567 | * individually by a constant amount that all valid inputs will require |
||
568 | * at the very least. This amount is chosen to be 21, because this will |
||
569 | * allow the two parts of the mantissa to later be combined into a |
||
570 | * single 32-bit representation, on which the remainder of the shift |
||
571 | * will be performed. Thus, we decrease the bias by an additional 21: |
||
572 | * (1074 - 21: 1053). |
||
573 | */ |
||
574 | shift_amount = 1053 - (top & 0x7FF); |
||
575 | |||
576 | /* We are done with the exponent portion in "top", so here we shift it off |
||
577 | * the end. |
||
578 | */ |
||
579 | top >>= 11; |
||
580 | |||
581 | /* Before we perform any operations on the mantissa, we need to OR in |
||
582 | * the implicit 1 at the top (see the IEEE-754 spec). We needn't mask |
||
583 | * off the sign bit nor the exponent bits because these higher bits won't |
||
584 | * make a bit of difference in the rest of our calculations. |
||
585 | */ |
||
586 | u.ui32[MSW] |= 0x100000; |
||
587 | |||
588 | /* If the input double is negative, we have to decrease the mantissa |
||
589 | * by a hair. This is an important part of performing arithmetic rounding, |
||
590 | * as negative numbers must round towards positive infinity in the |
||
591 | * halfwase case of -x.5. Since "top" contains only the sign bit at this |
||
592 | * point, we can just decrease the mantissa by the value of "top". |
||
593 | */ |
||
594 | u.ui64 -= top; |
||
595 | |||
596 | /* By decrementing "top", we create a bitmask with a value of either |
||
597 | * 0x0 (if the input was negative) or 0xFFFFFFFF (if the input was positive |
||
598 | * and thus the unsigned subtraction underflowed) that we'll use later. |
||
599 | */ |
||
600 | top--; |
||
601 | |||
602 | /* Here, we shift the mantissa by the constant value as described above. |
||
603 | * We can emulate a 64-bit shift right by 21 through shifting the top 32 |
||
604 | * bits left 11 places and ORing in the bottom 32 bits shifted 21 places |
||
605 | * to the right. Both parts of the mantissa are now packed into a single |
||
606 | * 32-bit integer. Although we severely truncate the lower part in the |
||
607 | * process, we still have enough significant bits to perform the conversion |
||
608 | * without error (for all valid inputs). |
||
609 | */ |
||
610 | output = (u.ui32[MSW] << 11) | (u.ui32[LSW] >> 21); |
||
611 | |||
612 | /* Next, we perform the shift that converts the X.Y fixed-point number |
||
613 | * currently found in "output" to the desired 31.1 fixed-point format |
||
614 | * needed for the following rounding step. It is important to consider |
||
615 | * all possible values for "shift_amount" at this point: |
||
616 | * |
||
617 | * - {shift_amount < 0} Since shift_amount is an unsigned integer, it |
||
618 | * really can't have a value less than zero. But, if the shift_amount |
||
619 | * calculation above caused underflow (which would happen with |
||
620 | * input > INT_MAX or input <= INT_MIN) then shift_amount will now be |
||
621 | * a very large number, and so this shift will result in complete |
||
622 | * garbage. But that's OK, as the input was out of our range, so our |
||
623 | * output is undefined. |
||
624 | * |
||
625 | * - {shift_amount > 31} If the magnitude of the input was very small |
||
626 | * (i.e. |input| << 1.0), shift_amount will have a value greater than |
||
627 | * 31. Thus, this shift will also result in garbage. After performing |
||
628 | * the shift, we will zero-out "output" if this is the case. |
||
629 | * |
||
630 | * - {0 <= shift_amount < 32} In this case, the shift will properly convert |
||
631 | * the mantissa into a 31.1 fixed-point number. |
||
632 | */ |
||
633 | output >>= shift_amount; |
||
634 | |||
635 | /* This is where we perform rounding with the 31.1 fixed-point number. |
||
636 | * Since what we're after is arithmetic rounding, we simply add the single |
||
637 | * fractional bit into the integer part of "output", and just keep the |
||
638 | * integer part. |
||
639 | */ |
||
640 | output = (output >> 1) + (output & 1); |
||
641 | |||
642 | /* Here, we zero-out the result if the magnitude if the input was very small |
||
643 | * (as explained in the section above). Notice that all input out of the |
||
644 | * valid range is also caught by this condition, which means we produce 0 |
||
645 | * for all invalid input, which is a nice side effect. |
||
646 | * |
||
647 | * The most straightforward way to do this would be: |
||
648 | * |
||
649 | * if (shift_amount > 31) |
||
650 | * output = 0; |
||
651 | * |
||
652 | * But we can use a little trick to avoid the potential branch. The |
||
653 | * expression (shift_amount > 31) will be either 1 or 0, which when |
||
654 | * decremented will be either 0x0 or 0xFFFFFFFF (unsigned underflow), |
||
655 | * which can be used to conditionally mask away all the bits in "output" |
||
656 | * (in the 0x0 case), effectively zeroing it out. Certain, compilers would |
||
657 | * have done this for us automatically. |
||
658 | */ |
||
659 | output &= ((shift_amount > 31) - 1); |
||
660 | |||
661 | /* If the input double was a negative number, then we have to negate our |
||
662 | * output. The most straightforward way to do this would be: |
||
663 | * |
||
664 | * if (!top) |
||
665 | * output = -output; |
||
666 | * |
||
667 | * as "top" at this point is either 0x0 (if the input was negative) or |
||
668 | * 0xFFFFFFFF (if the input was positive). But, we can use a trick to |
||
669 | * avoid the branch. Observe that the following snippet of code has the |
||
670 | * same effect as the reference snippet above: |
||
671 | * |
||
672 | * if (!top) |
||
673 | * output = 0 - output; |
||
674 | * else |
||
675 | * output = output - 0; |
||
676 | * |
||
677 | * Armed with the bitmask found in "top", we can condense the two statements |
||
678 | * into the following: |
||
679 | * |
||
680 | * output = (output & top) - (output & ~top); |
||
681 | * |
||
682 | * where, in the case that the input double was negative, "top" will be 0, |
||
683 | * and the statement will be equivalent to: |
||
684 | * |
||
685 | * output = (0) - (output); |
||
686 | * |
||
687 | * and if the input double was positive, "top" will be 0xFFFFFFFF, and the |
||
688 | * statement will be equivalent to: |
||
689 | * |
||
690 | * output = (output) - (0); |
||
691 | * |
||
692 | * Which, as pointed out earlier, is equivalent to the original reference |
||
693 | * snippet. |
||
694 | */ |
||
695 | output = (output & top) - (output & ~top); |
||
696 | |||
697 | return output; |
||
698 | #undef MSW |
||
699 | #undef LSW |
||
700 | } |
||
701 | #endif |
||
702 | |||
703 | /* Convert a 32-bit IEEE single precision floating point number to a |
||
704 | * 'half' representation (s10.5) |
||
705 | */ |
||
706 | uint16_t |
||
707 | _cairo_half_from_float (float f) |
||
708 | { |
||
709 | union { |
||
710 | uint32_t ui; |
||
711 | float f; |
||
712 | } u; |
||
713 | int s, e, m; |
||
714 | |||
715 | u.f = f; |
||
716 | s = (u.ui >> 16) & 0x00008000; |
||
717 | e = ((u.ui >> 23) & 0x000000ff) - (127 - 15); |
||
718 | m = u.ui & 0x007fffff; |
||
719 | if (e <= 0) { |
||
720 | if (e < -10) { |
||
721 | /* underflow */ |
||
722 | return 0; |
||
723 | } |
||
724 | |||
725 | m = (m | 0x00800000) >> (1 - e); |
||
726 | |||
727 | /* round to nearest, round 0.5 up. */ |
||
728 | if (m & 0x00001000) |
||
729 | m += 0x00002000; |
||
730 | return s | (m >> 13); |
||
731 | } else if (e == 0xff - (127 - 15)) { |
||
732 | if (m == 0) { |
||
733 | /* infinity */ |
||
734 | return s | 0x7c00; |
||
735 | } else { |
||
736 | /* nan */ |
||
737 | m >>= 13; |
||
738 | return s | 0x7c00 | m | (m == 0); |
||
739 | } |
||
740 | } else { |
||
741 | /* round to nearest, round 0.5 up. */ |
||
742 | if (m & 0x00001000) { |
||
743 | m += 0x00002000; |
||
744 | |||
745 | if (m & 0x00800000) { |
||
746 | m = 0; |
||
747 | e += 1; |
||
748 | } |
||
749 | } |
||
750 | |||
751 | if (e > 30) { |
||
752 | /* overflow -> infinity */ |
||
753 | return s | 0x7c00; |
||
754 | } |
||
755 | |||
756 | return s | (e << 10) | (m >> 13); |
||
757 | } |
||
758 | } |
||
759 | |||
760 | |||
761 | #ifdef _WIN32 |
||
762 | |||
763 | #define WIN32_LEAN_AND_MEAN |
||
764 | /* We require Windows 2000 features such as ETO_PDY */ |
||
765 | #if !defined(WINVER) || (WINVER < 0x0500) |
||
766 | # define WINVER 0x0500 |
||
767 | #endif |
||
768 | #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) |
||
769 | # define _WIN32_WINNT 0x0500 |
||
770 | #endif |
||
771 | |||
772 | #include |
||
773 | #include |
||
774 | |||
775 | #if !_WIN32_WCE |
||
776 | /* tmpfile() replacement for Windows. |
||
777 | * |
||
778 | * On Windows tmpfile() creates the file in the root directory. This |
||
779 | * may fail due to unsufficient privileges. However, this isn't a |
||
780 | * problem on Windows CE so we don't use it there. |
||
781 | */ |
||
782 | FILE * |
||
783 | _cairo_win32_tmpfile (void) |
||
784 | { |
||
785 | DWORD path_len; |
||
786 | WCHAR path_name[MAX_PATH + 1]; |
||
787 | WCHAR file_name[MAX_PATH + 1]; |
||
788 | HANDLE handle; |
||
789 | int fd; |
||
790 | FILE *fp; |
||
791 | |||
792 | path_len = GetTempPathW (MAX_PATH, path_name); |
||
793 | if (path_len <= 0 || path_len >= MAX_PATH) |
||
794 | return NULL; |
||
795 | |||
796 | if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0) |
||
797 | return NULL; |
||
798 | |||
799 | handle = CreateFileW (file_name, |
||
800 | GENERIC_READ | GENERIC_WRITE, |
||
801 | 0, |
||
802 | NULL, |
||
803 | CREATE_ALWAYS, |
||
804 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, |
||
805 | NULL); |
||
806 | if (handle == INVALID_HANDLE_VALUE) { |
||
807 | DeleteFileW (file_name); |
||
808 | return NULL; |
||
809 | } |
||
810 | |||
811 | fd = _open_osfhandle((intptr_t) handle, 0); |
||
812 | if (fd < 0) { |
||
813 | CloseHandle (handle); |
||
814 | return NULL; |
||
815 | } |
||
816 | |||
817 | fp = fdopen(fd, "w+b"); |
||
818 | if (fp == NULL) { |
||
819 | _close(fd); |
||
820 | return NULL; |
||
821 | } |
||
822 | |||
823 | return fp; |
||
824 | } |
||
825 | #endif /* !_WIN32_WCE */ |
||
826 | |||
827 | #endif /* _WIN32 */ |
||
828 | |||
829 | typedef struct _cairo_intern_string { |
||
830 | cairo_hash_entry_t hash_entry; |
||
831 | int len; |
||
832 | char *string; |
||
833 | } cairo_intern_string_t; |
||
834 | |||
835 | static cairo_hash_table_t *_cairo_intern_string_ht; |
||
836 | |||
837 | static unsigned long |
||
838 | _intern_string_hash (const char *str, int len) |
||
839 | { |
||
840 | const signed char *p = (const signed char *) str; |
||
841 | unsigned int h = *p; |
||
842 | |||
843 | for (p += 1; --len; p++) |
||
844 | h = (h << 5) - h + *p; |
||
845 | |||
846 | return h; |
||
847 | } |
||
848 | |||
849 | static cairo_bool_t |
||
850 | _intern_string_equal (const void *_a, const void *_b) |
||
851 | { |
||
852 | const cairo_intern_string_t *a = _a; |
||
853 | const cairo_intern_string_t *b = _b; |
||
854 | |||
855 | if (a->len != b->len) |
||
856 | return FALSE; |
||
857 | |||
858 | return memcmp (a->string, b->string, a->len) == 0; |
||
859 | } |
||
860 | |||
861 | cairo_status_t |
||
862 | _cairo_intern_string (const char **str_inout, int len) |
||
863 | { |
||
864 | char *str = (char *) *str_inout; |
||
865 | cairo_intern_string_t tmpl, *istring; |
||
866 | cairo_status_t status = CAIRO_STATUS_SUCCESS; |
||
867 | |||
868 | if (CAIRO_INJECT_FAULT ()) |
||
869 | return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
||
870 | |||
871 | if (len < 0) |
||
872 | len = strlen (str); |
||
873 | tmpl.hash_entry.hash = _intern_string_hash (str, len); |
||
874 | tmpl.len = len; |
||
875 | tmpl.string = (char *) str; |
||
876 | |||
877 | CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex); |
||
878 | if (_cairo_intern_string_ht == NULL) { |
||
879 | _cairo_intern_string_ht = _cairo_hash_table_create (_intern_string_equal); |
||
880 | if (unlikely (_cairo_intern_string_ht == NULL)) { |
||
881 | status = _cairo_error (CAIRO_STATUS_NO_MEMORY); |
||
882 | goto BAIL; |
||
883 | } |
||
884 | } |
||
885 | |||
886 | istring = _cairo_hash_table_lookup (_cairo_intern_string_ht, |
||
887 | &tmpl.hash_entry); |
||
888 | if (istring == NULL) { |
||
889 | istring = malloc (sizeof (cairo_intern_string_t) + len + 1); |
||
890 | if (likely (istring != NULL)) { |
||
891 | istring->hash_entry.hash = tmpl.hash_entry.hash; |
||
892 | istring->len = tmpl.len; |
||
893 | istring->string = (char *) (istring + 1); |
||
894 | memcpy (istring->string, str, len); |
||
895 | istring->string[len] = '\0'; |
||
896 | |||
897 | status = _cairo_hash_table_insert (_cairo_intern_string_ht, |
||
898 | &istring->hash_entry); |
||
899 | if (unlikely (status)) { |
||
900 | free (istring); |
||
901 | goto BAIL; |
||
902 | } |
||
903 | } else { |
||
904 | status = _cairo_error (CAIRO_STATUS_NO_MEMORY); |
||
905 | goto BAIL; |
||
906 | } |
||
907 | } |
||
908 | |||
909 | *str_inout = istring->string; |
||
910 | |||
911 | BAIL: |
||
912 | CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex); |
||
913 | return status; |
||
914 | } |
||
915 | |||
916 | static void |
||
917 | _intern_string_pluck (void *entry, void *closure) |
||
918 | { |
||
919 | _cairo_hash_table_remove (closure, entry); |
||
920 | free (entry); |
||
921 | } |
||
922 | |||
923 | void |
||
924 | _cairo_intern_string_reset_static_data (void) |
||
925 | { |
||
926 | CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex); |
||
927 | if (_cairo_intern_string_ht != NULL) { |
||
928 | _cairo_hash_table_foreach (_cairo_intern_string_ht, |
||
929 | _intern_string_pluck, |
||
930 | _cairo_intern_string_ht); |
||
931 | _cairo_hash_table_destroy(_cairo_intern_string_ht); |
||
932 | _cairo_intern_string_ht = NULL; |
||
933 | } |
||
934 | CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex); |
||
935 | }>><>>=>>>><>>=>>=>><>=>>><>>>>=>=>=>> |