Coverage Report

Created: 2025-07-07 10:01

/work/workdir/UnpackedTarball/cairo/src/cairo-misc.c
Line
Count
Source (jump to first uncovered line)
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 <cworth@cworth.org>
38
 *      Adrian Johnson <ajohnson@redneon.com>
39
 */
40
41
#include "cairoint.h"
42
#include "cairo-error-private.h"
43
44
#include <stdio.h>
45
#include <stdlib.h>
46
#include <errno.h>
47
#include <locale.h>
48
#ifdef HAVE_XLOCALE_H
49
#include <xlocale.h>
50
#endif
51
52
COMPILE_TIME_ASSERT ((int)CAIRO_STATUS_LAST_STATUS < (int)CAIRO_INT_STATUS_UNSUPPORTED);
53
COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
54
55
/**
56
 * SECTION:cairo-status
57
 * @Title: Error handling
58
 * @Short_Description: Decoding cairo's status
59
 * @See_Also: cairo_status(), cairo_surface_status(), cairo_pattern_status(),
60
 *            cairo_font_face_status(), cairo_scaled_font_status(),
61
 *            cairo_region_status()
62
 *
63
 * Cairo uses a single status type to represent all kinds of errors.  A status
64
 * value of %CAIRO_STATUS_SUCCESS represents no error and has an integer value
65
 * of zero.  All other status values represent an error.
66
 *
67
 * Cairo's error handling is designed to be easy to use and safe.  All major
68
 * cairo objects <firstterm>retain</firstterm> an error status internally which
69
 * can be queried anytime by the users using cairo*_status() calls.  In
70
 * the mean time, it is safe to call all cairo functions normally even if the
71
 * underlying object is in an error status.  This means that no error handling
72
 * code is required before or after each individual cairo function call.
73
 **/
74
75
/* Public stuff */
76
77
/**
78
 * cairo_status_to_string:
79
 * @status: a cairo status
80
 *
81
 * Provides a human-readable description of a #cairo_status_t.
82
 *
83
 * Returns: a string representation of the status
84
 *
85
 * Since: 1.0
86
 **/
87
const char *
88
cairo_status_to_string (cairo_status_t status)
89
0
{
90
0
    switch (status) {
91
0
    case CAIRO_STATUS_SUCCESS:
92
0
  return "no error has occurred";
93
0
    case CAIRO_STATUS_NO_MEMORY:
94
0
  return "out of memory";
95
0
    case CAIRO_STATUS_INVALID_RESTORE:
96
0
  return "cairo_restore() without matching cairo_save()";
97
0
    case CAIRO_STATUS_INVALID_POP_GROUP:
98
0
  return "no saved group to pop, i.e. cairo_pop_group() without matching cairo_push_group()";
99
0
    case CAIRO_STATUS_NO_CURRENT_POINT:
100
0
  return "no current point defined";
101
0
    case CAIRO_STATUS_INVALID_MATRIX:
102
0
  return "invalid matrix (not invertible)";
103
0
    case CAIRO_STATUS_INVALID_STATUS:
104
0
  return "invalid value for an input cairo_status_t";
105
0
    case CAIRO_STATUS_NULL_POINTER:
106
0
  return "NULL pointer";
107
0
    case CAIRO_STATUS_INVALID_STRING:
108
0
  return "input string not valid UTF-8";
109
0
    case CAIRO_STATUS_INVALID_PATH_DATA:
110
0
  return "input path data not valid";
111
0
    case CAIRO_STATUS_READ_ERROR:
112
0
  return "error while reading from input stream";
113
0
    case CAIRO_STATUS_WRITE_ERROR:
114
0
  return "error while writing to output stream";
115
0
    case CAIRO_STATUS_SURFACE_FINISHED:
116
0
  return "the target surface has been finished";
117
0
    case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
118
0
  return "the surface type is not appropriate for the operation";
119
0
    case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
120
0
  return "the pattern type is not appropriate for the operation";
121
0
    case CAIRO_STATUS_INVALID_CONTENT:
122
0
  return "invalid value for an input cairo_content_t";
123
0
    case CAIRO_STATUS_INVALID_FORMAT:
124
0
  return "invalid value for an input cairo_format_t";
125
0
    case CAIRO_STATUS_INVALID_VISUAL:
126
0
  return "invalid value for an input Visual*";
127
0
    case CAIRO_STATUS_FILE_NOT_FOUND:
128
0
  return "file not found";
129
0
    case CAIRO_STATUS_INVALID_DASH:
130
0
  return "invalid value for a dash setting";
131
0
    case CAIRO_STATUS_INVALID_DSC_COMMENT:
132
0
  return "invalid value for a DSC comment";
133
0
    case CAIRO_STATUS_INVALID_INDEX:
134
0
  return "invalid index passed to getter";
135
0
    case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
136
0
        return "clip region not representable in desired format";
137
0
    case CAIRO_STATUS_TEMP_FILE_ERROR:
138
0
  return "error creating or writing to a temporary file";
139
0
    case CAIRO_STATUS_INVALID_STRIDE:
140
0
  return "invalid value for stride";
141
0
    case CAIRO_STATUS_FONT_TYPE_MISMATCH:
142
0
  return "the font type is not appropriate for the operation";
143
0
    case CAIRO_STATUS_USER_FONT_IMMUTABLE:
144
0
  return "the user-font is immutable";
145
0
    case CAIRO_STATUS_USER_FONT_ERROR:
146
0
  return "error occurred in a user-font callback function";
147
0
    case CAIRO_STATUS_NEGATIVE_COUNT:
148
0
  return "negative number used where it is not allowed";
149
0
    case CAIRO_STATUS_INVALID_CLUSTERS:
150
0
  return "input clusters do not represent the accompanying text and glyph arrays";
151
0
    case CAIRO_STATUS_INVALID_SLANT:
152
0
  return "invalid value for an input cairo_font_slant_t";
153
0
    case CAIRO_STATUS_INVALID_WEIGHT:
154
0
  return "invalid value for an input cairo_font_weight_t";
155
0
    case CAIRO_STATUS_INVALID_SIZE:
156
0
  return "invalid value (typically too big) for the size of the input (surface, pattern, etc.)";
157
0
    case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
158
0
  return "user-font method not implemented";
159
0
    case CAIRO_STATUS_DEVICE_TYPE_MISMATCH:
160
0
  return "the device type is not appropriate for the operation";
161
0
    case CAIRO_STATUS_DEVICE_ERROR:
162
0
  return "an operation to the device caused an unspecified error";
163
0
    case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
164
0
  return "invalid operation during mesh pattern construction";
165
0
    case CAIRO_STATUS_DEVICE_FINISHED:
166
0
  return "the target device has been finished";
167
0
    case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
168
0
  return "CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID used but no CAIRO_MIME_TYPE_JBIG2_GLOBAL data provided";
169
0
    case CAIRO_STATUS_PNG_ERROR:
170
0
  return "error occurred in libpng while reading from or writing to a PNG file";
171
0
    case CAIRO_STATUS_FREETYPE_ERROR:
172
0
  return "error occurred in libfreetype";
173
0
    case CAIRO_STATUS_WIN32_GDI_ERROR:
174
0
  return "error occurred in the Windows Graphics Device Interface";
175
0
    case CAIRO_STATUS_TAG_ERROR:
176
0
  return "invalid tag name, attributes, or nesting";
177
0
    case CAIRO_STATUS_DWRITE_ERROR:
178
0
  return "Window Direct Write error";
179
0
    default:
180
0
    case CAIRO_STATUS_LAST_STATUS:
181
0
  return "<unknown error status>";
182
0
    }
183
0
}
184
185
186
/**
187
 * cairo_glyph_allocate:
188
 * @num_glyphs: number of glyphs to allocate
189
 *
190
 * Allocates an array of #cairo_glyph_t's.
191
 * This function is only useful in implementations of
192
 * #cairo_user_scaled_font_text_to_glyphs_func_t where the user
193
 * needs to allocate an array of glyphs that cairo will free.
194
 * For all other uses, user can use their own allocation method
195
 * for glyphs.
196
 *
197
 * This function returns %NULL if @num_glyphs is not positive,
198
 * or if out of memory.  That means, the %NULL return value
199
 * signals out-of-memory only if @num_glyphs was positive.
200
 *
201
 * Returns: the newly allocated array of glyphs that should be
202
 *          freed using cairo_glyph_free()
203
 *
204
 * Since: 1.8
205
 **/
206
cairo_glyph_t *
207
cairo_glyph_allocate (int num_glyphs)
208
6.32k
{
209
6.32k
    if (num_glyphs <= 0)
210
0
  return NULL;
211
212
6.32k
    return _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
213
6.32k
}
214
slim_hidden_def (cairo_glyph_allocate);
215
216
/**
217
 * cairo_glyph_free:
218
 * @glyphs: array of glyphs to free, or %NULL
219
 *
220
 * Frees an array of #cairo_glyph_t's allocated using cairo_glyph_allocate().
221
 * This function is only useful to free glyph array returned
222
 * by cairo_scaled_font_text_to_glyphs() where cairo returns
223
 * an array of glyphs that the user will free.
224
 * For all other uses, user can use their own allocation method
225
 * for glyphs.
226
 *
227
 * Since: 1.8
228
 **/
229
void
230
cairo_glyph_free (cairo_glyph_t *glyphs)
231
6.32k
{
232
6.32k
    free (glyphs);
233
6.32k
}
234
slim_hidden_def (cairo_glyph_free);
235
236
/**
237
 * cairo_text_cluster_allocate:
238
 * @num_clusters: number of text_clusters to allocate
239
 *
240
 * Allocates an array of #cairo_text_cluster_t's.
241
 * This function is only useful in implementations of
242
 * #cairo_user_scaled_font_text_to_glyphs_func_t where the user
243
 * needs to allocate an array of text clusters that cairo will free.
244
 * For all other uses, user can use their own allocation method
245
 * for text clusters.
246
 *
247
 * This function returns %NULL if @num_clusters is not positive,
248
 * or if out of memory.  That means, the %NULL return value
249
 * signals out-of-memory only if @num_clusters was positive.
250
 *
251
 * Returns: the newly allocated array of text clusters that should be
252
 *          freed using cairo_text_cluster_free()
253
 *
254
 * Since: 1.8
255
 **/
256
cairo_text_cluster_t *
257
cairo_text_cluster_allocate (int num_clusters)
258
0
{
259
0
    if (num_clusters <= 0)
260
0
  return NULL;
261
262
0
    return _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t));
263
0
}
264
slim_hidden_def (cairo_text_cluster_allocate);
265
266
/**
267
 * cairo_text_cluster_free:
268
 * @clusters: array of text clusters to free, or %NULL
269
 *
270
 * Frees an array of #cairo_text_cluster's allocated using cairo_text_cluster_allocate().
271
 * This function is only useful to free text cluster array returned
272
 * by cairo_scaled_font_text_to_glyphs() where cairo returns
273
 * an array of text clusters that the user will free.
274
 * For all other uses, user can use their own allocation method
275
 * for text clusters.
276
 *
277
 * Since: 1.8
278
 **/
279
void
280
cairo_text_cluster_free (cairo_text_cluster_t *clusters)
281
0
{
282
0
    free (clusters);
283
0
}
284
slim_hidden_def (cairo_text_cluster_free);
285
286
287
/* Private stuff */
288
289
/**
290
 * _cairo_validate_text_clusters:
291
 * @utf8: UTF-8 text
292
 * @utf8_len: length of @utf8 in bytes
293
 * @glyphs: array of glyphs
294
 * @num_glyphs: number of glyphs
295
 * @clusters: array of cluster mapping information
296
 * @num_clusters: number of clusters in the mapping
297
 * @cluster_flags: cluster flags
298
 *
299
 * Check that clusters cover the entire glyphs and utf8 arrays,
300
 * and that cluster boundaries are UTF-8 boundaries.
301
 *
302
 * Return value: %CAIRO_STATUS_SUCCESS upon success, or
303
 *               %CAIRO_STATUS_INVALID_CLUSTERS on error.
304
 *               The error is either invalid UTF-8 input,
305
 *               or bad cluster mapping.
306
 **/
307
cairo_status_t
308
_cairo_validate_text_clusters (const char      *utf8,
309
             int          utf8_len,
310
             const cairo_glyph_t     *glyphs,
311
             int          num_glyphs,
312
             const cairo_text_cluster_t  *clusters,
313
             int          num_clusters,
314
             cairo_text_cluster_flags_t   cluster_flags)
315
0
{
316
0
    cairo_status_t status;
317
0
    unsigned int n_bytes  = 0;
318
0
    unsigned int n_glyphs = 0;
319
0
    int i;
320
321
0
    for (i = 0; i < num_clusters; i++) {
322
0
  int cluster_bytes  = clusters[i].num_bytes;
323
0
  int cluster_glyphs = clusters[i].num_glyphs;
324
325
0
  if (cluster_bytes < 0 || cluster_glyphs < 0)
326
0
      goto BAD;
327
328
  /* A cluster should cover at least one character or glyph.
329
   * I can't see any use for a 0,0 cluster.
330
   * I can't see an immediate use for a zero-text cluster
331
   * right now either, but they don't harm.
332
   * Zero-glyph clusters on the other hand are useful for
333
   * things like U+200C ZERO WIDTH NON-JOINER */
334
0
  if (cluster_bytes == 0 && cluster_glyphs == 0)
335
0
      goto BAD;
336
337
  /* Since n_bytes and n_glyphs are unsigned, but the rest of
338
   * values involved are signed, we can detect overflow easily */
339
0
  if (n_bytes+cluster_bytes > (unsigned int)utf8_len || n_glyphs+cluster_glyphs > (unsigned int)num_glyphs)
340
0
      goto BAD;
341
342
  /* Make sure we've got valid UTF-8 for the cluster */
343
0
  status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL);
344
0
  if (unlikely (status))
345
0
      return _cairo_error (CAIRO_STATUS_INVALID_CLUSTERS);
346
347
0
  n_bytes  += cluster_bytes ;
348
0
  n_glyphs += cluster_glyphs;
349
0
    }
350
351
0
    if (n_bytes != (unsigned int) utf8_len || n_glyphs != (unsigned int) num_glyphs) {
352
0
      BAD:
353
0
  return _cairo_error (CAIRO_STATUS_INVALID_CLUSTERS);
354
0
    }
355
356
0
    return CAIRO_STATUS_SUCCESS;
357
0
}
358
359
/**
360
 * _cairo_operator_bounded_by_mask:
361
 * @op: a #cairo_operator_t
362
 *
363
 * A bounded operator is one where mask pixel
364
 * of zero results in no effect on the destination image.
365
 *
366
 * Unbounded operators often require special handling; if you, for
367
 * example, draw trapezoids with an unbounded operator, the effect
368
 * extends past the bounding box of the trapezoids.
369
 *
370
 * Return value: %TRUE if the operator is bounded by the mask operand
371
 **/
372
cairo_bool_t
373
_cairo_operator_bounded_by_mask (cairo_operator_t op)
374
6.22k
{
375
6.22k
    switch (op) {
376
0
    case CAIRO_OPERATOR_CLEAR:
377
0
    case CAIRO_OPERATOR_SOURCE:
378
6.22k
    case CAIRO_OPERATOR_OVER:
379
6.22k
    case CAIRO_OPERATOR_ATOP:
380
6.22k
    case CAIRO_OPERATOR_DEST:
381
6.22k
    case CAIRO_OPERATOR_DEST_OVER:
382
6.22k
    case CAIRO_OPERATOR_DEST_OUT:
383
6.22k
    case CAIRO_OPERATOR_XOR:
384
6.22k
    case CAIRO_OPERATOR_ADD:
385
6.22k
    case CAIRO_OPERATOR_SATURATE:
386
6.22k
    case CAIRO_OPERATOR_MULTIPLY:
387
6.22k
    case CAIRO_OPERATOR_SCREEN:
388
6.22k
    case CAIRO_OPERATOR_OVERLAY:
389
6.22k
    case CAIRO_OPERATOR_DARKEN:
390
6.22k
    case CAIRO_OPERATOR_LIGHTEN:
391
6.22k
    case CAIRO_OPERATOR_COLOR_DODGE:
392
6.22k
    case CAIRO_OPERATOR_COLOR_BURN:
393
6.22k
    case CAIRO_OPERATOR_HARD_LIGHT:
394
6.22k
    case CAIRO_OPERATOR_SOFT_LIGHT:
395
6.22k
    case CAIRO_OPERATOR_DIFFERENCE:
396
6.22k
    case CAIRO_OPERATOR_EXCLUSION:
397
6.22k
    case CAIRO_OPERATOR_HSL_HUE:
398
6.22k
    case CAIRO_OPERATOR_HSL_SATURATION:
399
6.22k
    case CAIRO_OPERATOR_HSL_COLOR:
400
6.22k
    case CAIRO_OPERATOR_HSL_LUMINOSITY:
401
6.22k
  return TRUE;
402
0
    case CAIRO_OPERATOR_OUT:
403
0
    case CAIRO_OPERATOR_IN:
404
0
    case CAIRO_OPERATOR_DEST_IN:
405
0
    case CAIRO_OPERATOR_DEST_ATOP:
406
0
  return FALSE;
407
0
    default:
408
0
  ASSERT_NOT_REACHED;
409
0
  return FALSE; /* squelch warning */
410
6.22k
    }
411
6.22k
}
412
413
/**
414
 * _cairo_operator_bounded_by_source:
415
 * @op: a #cairo_operator_t
416
 *
417
 * A bounded operator is one where source pixels of zero
418
 * (in all four components, r, g, b and a) effect no change
419
 * in the resulting destination image.
420
 *
421
 * Unbounded operators often require special handling; if you, for
422
 * example, copy a surface with the SOURCE operator, the effect
423
 * extends past the bounding box of the source surface.
424
 *
425
 * Return value: %TRUE if the operator is bounded by the source operand
426
 **/
427
cairo_bool_t
428
_cairo_operator_bounded_by_source (cairo_operator_t op)
429
0
{
430
0
    switch (op) {
431
0
    case CAIRO_OPERATOR_OVER:
432
0
    case CAIRO_OPERATOR_ATOP:
433
0
    case CAIRO_OPERATOR_DEST:
434
0
    case CAIRO_OPERATOR_DEST_OVER:
435
0
    case CAIRO_OPERATOR_DEST_OUT:
436
0
    case CAIRO_OPERATOR_XOR:
437
0
    case CAIRO_OPERATOR_ADD:
438
0
    case CAIRO_OPERATOR_SATURATE:
439
0
    case CAIRO_OPERATOR_MULTIPLY:
440
0
    case CAIRO_OPERATOR_SCREEN:
441
0
    case CAIRO_OPERATOR_OVERLAY:
442
0
    case CAIRO_OPERATOR_DARKEN:
443
0
    case CAIRO_OPERATOR_LIGHTEN:
444
0
    case CAIRO_OPERATOR_COLOR_DODGE:
445
0
    case CAIRO_OPERATOR_COLOR_BURN:
446
0
    case CAIRO_OPERATOR_HARD_LIGHT:
447
0
    case CAIRO_OPERATOR_SOFT_LIGHT:
448
0
    case CAIRO_OPERATOR_DIFFERENCE:
449
0
    case CAIRO_OPERATOR_EXCLUSION:
450
0
    case CAIRO_OPERATOR_HSL_HUE:
451
0
    case CAIRO_OPERATOR_HSL_SATURATION:
452
0
    case CAIRO_OPERATOR_HSL_COLOR:
453
0
    case CAIRO_OPERATOR_HSL_LUMINOSITY:
454
0
  return TRUE;
455
0
    case CAIRO_OPERATOR_CLEAR:
456
0
    case CAIRO_OPERATOR_SOURCE:
457
0
    case CAIRO_OPERATOR_OUT:
458
0
    case CAIRO_OPERATOR_IN:
459
0
    case CAIRO_OPERATOR_DEST_IN:
460
0
    case CAIRO_OPERATOR_DEST_ATOP:
461
0
  return FALSE;
462
0
    default:
463
0
  ASSERT_NOT_REACHED;
464
0
  return FALSE; /* squelch warning */
465
0
    }
466
0
}
467
468
uint32_t
469
_cairo_operator_bounded_by_either (cairo_operator_t op)
470
8.49M
{
471
8.49M
    switch (op) {
472
8.47M
    case CAIRO_OPERATOR_OVER:
473
8.47M
    case CAIRO_OPERATOR_ATOP:
474
8.47M
    case CAIRO_OPERATOR_DEST:
475
8.47M
    case CAIRO_OPERATOR_DEST_OVER:
476
8.47M
    case CAIRO_OPERATOR_DEST_OUT:
477
8.47M
    case CAIRO_OPERATOR_XOR:
478
8.47M
    case CAIRO_OPERATOR_ADD:
479
8.47M
    case CAIRO_OPERATOR_SATURATE:
480
8.47M
    case CAIRO_OPERATOR_MULTIPLY:
481
8.47M
    case CAIRO_OPERATOR_SCREEN:
482
8.47M
    case CAIRO_OPERATOR_OVERLAY:
483
8.47M
    case CAIRO_OPERATOR_DARKEN:
484
8.47M
    case CAIRO_OPERATOR_LIGHTEN:
485
8.47M
    case CAIRO_OPERATOR_COLOR_DODGE:
486
8.47M
    case CAIRO_OPERATOR_COLOR_BURN:
487
8.47M
    case CAIRO_OPERATOR_HARD_LIGHT:
488
8.47M
    case CAIRO_OPERATOR_SOFT_LIGHT:
489
8.47M
    case CAIRO_OPERATOR_DIFFERENCE:
490
8.47M
    case CAIRO_OPERATOR_EXCLUSION:
491
8.47M
    case CAIRO_OPERATOR_HSL_HUE:
492
8.47M
    case CAIRO_OPERATOR_HSL_SATURATION:
493
8.47M
    case CAIRO_OPERATOR_HSL_COLOR:
494
8.47M
    case CAIRO_OPERATOR_HSL_LUMINOSITY:
495
8.47M
  return CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE;
496
0
    case CAIRO_OPERATOR_CLEAR:
497
17.3k
    case CAIRO_OPERATOR_SOURCE:
498
17.3k
  return CAIRO_OPERATOR_BOUND_BY_MASK;
499
0
    case CAIRO_OPERATOR_OUT:
500
0
    case CAIRO_OPERATOR_IN:
501
0
    case CAIRO_OPERATOR_DEST_IN:
502
0
    case CAIRO_OPERATOR_DEST_ATOP:
503
0
  return 0;
504
0
    default:
505
0
  ASSERT_NOT_REACHED;
506
0
  return FALSE; /* squelch warning */
507
8.49M
    }
508
509
8.49M
}
510
511
#if DISABLE_SOME_FLOATING_POINT
512
/* This function is identical to the C99 function lround(), except that it
513
 * performs arithmetic rounding (floor(d + .5) instead of away-from-zero rounding) and
514
 * has a valid input range of (INT_MIN, INT_MAX] instead of
515
 * [INT_MIN, INT_MAX]. It is much faster on both x86 and FPU-less systems
516
 * than other commonly used methods for rounding (lround, round, rint, lrint
517
 * or float (d + 0.5)).
518
 *
519
 * The reason why this function is much faster on x86 than other
520
 * methods is due to the fact that it avoids the fldcw instruction.
521
 * This instruction incurs a large performance penalty on modern Intel
522
 * processors due to how it prevents efficient instruction pipelining.
523
 *
524
 * The reason why this function is much faster on FPU-less systems is for
525
 * an entirely different reason. All common rounding methods involve multiple
526
 * floating-point operations. Each one of these operations has to be
527
 * emulated in software, which adds up to be a large performance penalty.
528
 * This function doesn't perform any floating-point calculations, and thus
529
 * avoids this penalty.
530
  */
531
int
532
_cairo_lround (double d)
533
{
534
    uint32_t top, shift_amount, output;
535
    union {
536
        double d;
537
        uint64_t ui64;
538
        uint32_t ui32[2];
539
    } u;
540
541
    u.d = d;
542
543
    /* If the integer word order doesn't match the float word order, we swap
544
     * the words of the input double. This is needed because we will be
545
     * treating the whole double as a 64-bit unsigned integer. Notice that we
546
     * use WORDS_BIGENDIAN to detect the integer word order, which isn't
547
     * exactly correct because WORDS_BIGENDIAN refers to byte order, not word
548
     * order. Thus, we are making the assumption that the byte order is the
549
     * same as the integer word order which, on the modern machines that we
550
     * care about, is OK.
551
     */
552
#if ( defined(FLOAT_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)) || \
553
    (!defined(FLOAT_WORDS_BIGENDIAN) &&  defined(WORDS_BIGENDIAN))
554
    {
555
        uint32_t temp = u.ui32[0];
556
        u.ui32[0] = u.ui32[1];
557
        u.ui32[1] = temp;
558
    }
559
#endif
560
561
#ifdef WORDS_BIGENDIAN
562
    #define MSW (0) /* Most Significant Word */
563
    #define LSW (1) /* Least Significant Word */
564
#else
565
    #define MSW (1)
566
    #define LSW (0)
567
#endif
568
569
    /* By shifting the most significant word of the input double to the
570
     * right 20 places, we get the very "top" of the double where the exponent
571
     * and sign bit lie.
572
     */
573
    top = u.ui32[MSW] >> 20;
574
575
    /* Here, we calculate how much we have to shift the mantissa to normalize
576
     * it to an integer value. We extract the exponent "top" by masking out the
577
     * sign bit, then we calculate the shift amount by subtracting the exponent
578
     * from the bias. Notice that the correct bias for 64-bit doubles is
579
     * actually 1075, but we use 1053 instead for two reasons:
580
     *
581
     *  1) To perform rounding later on, we will first need the target
582
     *     value in a 31.1 fixed-point format. Thus, the bias needs to be one
583
     *     less: (1075 - 1: 1074).
584
     *
585
     *  2) To avoid shifting the mantissa as a full 64-bit integer (which is
586
     *     costly on certain architectures), we break the shift into two parts.
587
     *     First, the upper and lower parts of the mantissa are shifted
588
     *     individually by a constant amount that all valid inputs will require
589
     *     at the very least. This amount is chosen to be 21, because this will
590
     *     allow the two parts of the mantissa to later be combined into a
591
     *     single 32-bit representation, on which the remainder of the shift
592
     *     will be performed. Thus, we decrease the bias by an additional 21:
593
     *     (1074 - 21: 1053).
594
     */
595
    shift_amount = 1053 - (top & 0x7FF);
596
597
    /* We are done with the exponent portion in "top", so here we shift it off
598
     * the end.
599
     */
600
    top >>= 11;
601
602
    /* Before we perform any operations on the mantissa, we need to OR in
603
     * the implicit 1 at the top (see the IEEE-754 spec). We needn't mask
604
     * off the sign bit nor the exponent bits because these higher bits won't
605
     * make a bit of difference in the rest of our calculations.
606
     */
607
    u.ui32[MSW] |= 0x100000;
608
609
    /* If the input double is negative, we have to decrease the mantissa
610
     * by a hair. This is an important part of performing arithmetic rounding,
611
     * as negative numbers must round towards positive infinity in the
612
     * halfwase case of -x.5. Since "top" contains only the sign bit at this
613
     * point, we can just decrease the mantissa by the value of "top".
614
     */
615
    u.ui64 -= top;
616
617
    /* By decrementing "top", we create a bitmask with a value of either
618
     * 0x0 (if the input was negative) or 0xFFFFFFFF (if the input was positive
619
     * and thus the unsigned subtraction underflowed) that we'll use later.
620
     */
621
    top--;
622
623
    /* Here, we shift the mantissa by the constant value as described above.
624
     * We can emulate a 64-bit shift right by 21 through shifting the top 32
625
     * bits left 11 places and ORing in the bottom 32 bits shifted 21 places
626
     * to the right. Both parts of the mantissa are now packed into a single
627
     * 32-bit integer. Although we severely truncate the lower part in the
628
     * process, we still have enough significant bits to perform the conversion
629
     * without error (for all valid inputs).
630
     */
631
    output = (u.ui32[MSW] << 11) | (u.ui32[LSW] >> 21);
632
633
    /* Next, we perform the shift that converts the X.Y fixed-point number
634
     * currently found in "output" to the desired 31.1 fixed-point format
635
     * needed for the following rounding step. It is important to consider
636
     * all possible values for "shift_amount" at this point:
637
     *
638
     * - {shift_amount < 0} Since shift_amount is an unsigned integer, it
639
     *   really can't have a value less than zero. But, if the shift_amount
640
     *   calculation above caused underflow (which would happen with
641
     *   input > INT_MAX or input <= INT_MIN) then shift_amount will now be
642
     *   a very large number, and so this shift will result in complete
643
     *   garbage. But that's OK, as the input was out of our range, so our
644
     *   output is undefined.
645
     *
646
     * - {shift_amount > 31} If the magnitude of the input was very small
647
     *   (i.e. |input| << 1.0), shift_amount will have a value greater than
648
     *   31. Thus, this shift will also result in garbage. After performing
649
     *   the shift, we will zero-out "output" if this is the case.
650
     *
651
     * - {0 <= shift_amount < 32} In this case, the shift will properly convert
652
     *   the mantissa into a 31.1 fixed-point number.
653
     */
654
    output >>= shift_amount;
655
656
    /* This is where we perform rounding with the 31.1 fixed-point number.
657
     * Since what we're after is arithmetic rounding, we simply add the single
658
     * fractional bit into the integer part of "output", and just keep the
659
     * integer part.
660
     */
661
    output = (output >> 1) + (output & 1);
662
663
    /* Here, we zero-out the result if the magnitude if the input was very small
664
     * (as explained in the section above). Notice that all input out of the
665
     * valid range is also caught by this condition, which means we produce 0
666
     * for all invalid input, which is a nice side effect.
667
     *
668
     * The most straightforward way to do this would be:
669
     *
670
     *      if (shift_amount > 31)
671
     *          output = 0;
672
     *
673
     * But we can use a little trick to avoid the potential branch. The
674
     * expression (shift_amount > 31) will be either 1 or 0, which when
675
     * decremented will be either 0x0 or 0xFFFFFFFF (unsigned underflow),
676
     * which can be used to conditionally mask away all the bits in "output"
677
     * (in the 0x0 case), effectively zeroing it out. Certain, compilers would
678
     * have done this for us automatically.
679
     */
680
    output &= ((shift_amount > 31) - 1);
681
682
    /* If the input double was a negative number, then we have to negate our
683
     * output. The most straightforward way to do this would be:
684
     *
685
     *      if (!top)
686
     *          output = -output;
687
     *
688
     * as "top" at this point is either 0x0 (if the input was negative) or
689
     * 0xFFFFFFFF (if the input was positive). But, we can use a trick to
690
     * avoid the branch. Observe that the following snippet of code has the
691
     * same effect as the reference snippet above:
692
     *
693
     *      if (!top)
694
     *          output = 0 - output;
695
     *      else
696
     *          output = output - 0;
697
     *
698
     * Armed with the bitmask found in "top", we can condense the two statements
699
     * into the following:
700
     *
701
     *      output = (output & top) - (output & ~top);
702
     *
703
     * where, in the case that the input double was negative, "top" will be 0,
704
     * and the statement will be equivalent to:
705
     *
706
     *      output = (0) - (output);
707
     *
708
     * and if the input double was positive, "top" will be 0xFFFFFFFF, and the
709
     * statement will be equivalent to:
710
     *
711
     *      output = (output) - (0);
712
     *
713
     * Which, as pointed out earlier, is equivalent to the original reference
714
     * snippet.
715
     */
716
    output = (output & top) - (output & ~top);
717
718
    return output;
719
#undef MSW
720
#undef LSW
721
}
722
#endif
723
724
/* Convert a 32-bit IEEE single precision floating point number to a
725
 * 'half' representation (s10.5)
726
 */
727
uint16_t
728
_cairo_half_from_float (float f)
729
0
{
730
0
    union {
731
0
  uint32_t ui;
732
0
  float f;
733
0
    } u;
734
0
    int s, e, m;
735
736
0
    u.f = f;
737
0
    s =  (u.ui >> 16) & 0x00008000;
738
0
    e = ((u.ui >> 23) & 0x000000ff) - (127 - 15);
739
0
    m =   u.ui        & 0x007fffff;
740
0
    if (e <= 0) {
741
0
  if (e < -10) {
742
      /* underflow */
743
0
      return 0;
744
0
  }
745
746
0
  m = (m | 0x00800000) >> (1 - e);
747
748
  /* round to nearest, round 0.5 up. */
749
0
  if (m &  0x00001000)
750
0
      m += 0x00002000;
751
0
  return s | (m >> 13);
752
0
    } else if (e == 0xff - (127 - 15)) {
753
0
  if (m == 0) {
754
      /* infinity */
755
0
      return s | 0x7c00;
756
0
  } else {
757
      /* nan */
758
0
      m >>= 13;
759
0
      return s | 0x7c00 | m | (m == 0);
760
0
  }
761
0
    } else {
762
  /* round to nearest, round 0.5 up. */
763
0
  if (m &  0x00001000) {
764
0
      m += 0x00002000;
765
766
0
      if (m & 0x00800000) {
767
0
    m =  0;
768
0
    e += 1;
769
0
      }
770
0
  }
771
772
0
  if (e > 30) {
773
      /* overflow -> infinity */
774
0
      return s | 0x7c00;
775
0
  }
776
777
0
  return s | (e << 10) | (m >> 13);
778
0
    }
779
0
}
780
781
#ifndef __BIONIC__
782
# include <locale.h>
783
784
const char *
785
_cairo_get_locale_decimal_point (void)
786
6
{
787
6
    struct lconv *locale_data = localeconv ();
788
6
    return locale_data->decimal_point;
789
6
}
790
791
#else
792
/* Android's Bionic libc doesn't provide decimal_point */
793
const char *
794
_cairo_get_locale_decimal_point (void)
795
{
796
    return ".";
797
}
798
#endif
799
800
#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
801
802
static locale_t C_locale;
803
804
static locale_t
805
get_C_locale (void)
806
0
{
807
0
    locale_t C;
808
809
0
retry:
810
0
    C = (locale_t) _cairo_atomic_ptr_get ((void **) &C_locale);
811
812
0
    if (unlikely (!C)) {
813
0
        C = newlocale (LC_ALL_MASK, "C", NULL);
814
815
0
        if (!_cairo_atomic_ptr_cmpxchg ((void **) &C_locale, NULL, C)) {
816
0
            freelocale (C_locale);
817
0
            goto retry;
818
0
        }
819
0
    }
820
821
0
    return C;
822
0
}
823
824
double
825
_cairo_strtod (const char *nptr, char **endptr)
826
0
{
827
0
    return strtod_l (nptr, endptr, get_C_locale ());
828
0
}
829
830
#else
831
832
/* strtod replacement that ignores locale and only accepts decimal points */
833
double
834
_cairo_strtod (const char *nptr, char **endptr)
835
{
836
    const char *decimal_point;
837
    int decimal_point_len;
838
    const char *p;
839
    char buf[100];
840
    char *bufptr;
841
    char *bufend = buf + sizeof(buf) - 1;
842
    double value;
843
    char *end;
844
    int delta;
845
    cairo_bool_t have_dp;
846
847
    decimal_point = _cairo_get_locale_decimal_point ();
848
    decimal_point_len = strlen (decimal_point);
849
    assert (decimal_point_len != 0);
850
851
    p = nptr;
852
    bufptr = buf;
853
    delta = 0;
854
    have_dp = FALSE;
855
    while (*p && _cairo_isspace (*p)) {
856
  p++;
857
  delta++;
858
    }
859
860
    while (*p && (bufptr + decimal_point_len < bufend)) {
861
  if (_cairo_isdigit (*p)) {
862
      *bufptr++ = *p;
863
  } else if (*p == '.') {
864
      if (have_dp)
865
    break;
866
      strncpy (bufptr, decimal_point, decimal_point_len);
867
      bufptr += decimal_point_len;
868
      delta -= decimal_point_len - 1;
869
      have_dp = TRUE;
870
  } else if (bufptr == buf && (*p == '-' || *p == '+')) {
871
      *bufptr++ = *p;
872
  } else {
873
      break;
874
  }
875
  p++;
876
    }
877
    *bufptr = 0;
878
879
    value = strtod (buf, &end);
880
    if (endptr) {
881
  if (end == buf)
882
      *endptr = (char*)(nptr);
883
  else
884
      *endptr = (char*)(nptr + (end - buf) + delta);
885
    }
886
887
    return value;
888
}
889
#endif
890
891
/**
892
 * _cairo_fopen:
893
 * @filename: filename to open
894
 * @mode: mode string with which to open the file
895
 * @file_out: reference to file handle
896
 *
897
 * Exactly like the C library function, but possibly doing encoding
898
 * conversion on the filename. On all platforms, the filename is
899
 * passed directly to the system, but on Windows, the filename is
900
 * interpreted as UTF-8, rather than in a codepage that would depend
901
 * on system settings.
902
 *
903
 * Return value: CAIRO_STATUS_SUCCESS when the filename was converted
904
 * successfully to the native encoding, or the error reported by
905
 * _cairo_utf8_to_utf16 otherwise. To check if the file handle could
906
 * be obtained, dereference file_out and compare its value against
907
 * NULL
908
 **/
909
cairo_status_t
910
_cairo_fopen (const char *filename, const char *mode, FILE **file_out)
911
0
{
912
0
    FILE *result;
913
#ifdef _WIN32 /* also defined on x86_64 */
914
    uint16_t *filename_w;
915
    uint16_t *mode_w;
916
    cairo_status_t status;
917
918
    *file_out = NULL;
919
920
    if (filename == NULL || mode == NULL) {
921
  errno = EINVAL;
922
  return CAIRO_STATUS_SUCCESS;
923
    }
924
925
    if ((status = _cairo_utf8_to_utf16 (filename, -1, &filename_w, NULL)) != CAIRO_STATUS_SUCCESS) {
926
  errno = EINVAL;
927
  return status;
928
    }
929
930
    if ((status = _cairo_utf8_to_utf16 (mode, -1, &mode_w, NULL)) != CAIRO_STATUS_SUCCESS) {
931
  free (filename_w);
932
  errno = EINVAL;
933
  return status;
934
    }
935
936
    result = _wfopen(filename_w, mode_w);
937
938
    free (filename_w);
939
    free (mode_w);
940
941
#else /* Use fopen directly */
942
0
    result = fopen (filename, mode);
943
0
#endif
944
945
0
    *file_out = result;
946
947
0
    return CAIRO_STATUS_SUCCESS;
948
0
}
949
950
#ifdef _WIN32
951
952
#define WIN32_LEAN_AND_MEAN
953
/* We require Windows 2000 features such as ETO_PDY */
954
#if !defined(WINVER) || (WINVER < 0x0500)
955
# define WINVER 0x0500
956
#endif
957
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
958
# define _WIN32_WINNT 0x0500
959
#endif
960
961
#include <windows.h>
962
#include <io.h>
963
964
#if !_WIN32_WCE
965
/* tmpfile() replacement for Windows.
966
 *
967
 * On Windows tmpfile() creates the file in the root directory. This
968
 * may fail due to insufficient privileges. However, this isn't a
969
 * problem on Windows CE so we don't use it there.
970
 */
971
FILE *
972
_cairo_win32_tmpfile (void)
973
{
974
    DWORD path_len;
975
    WCHAR path_name[MAX_PATH + 1];
976
    WCHAR file_name[MAX_PATH + 1];
977
    HANDLE handle;
978
    int fd;
979
    FILE *fp;
980
981
    path_len = GetTempPathW (MAX_PATH, path_name);
982
    if (path_len <= 0 || path_len >= MAX_PATH)
983
  return NULL;
984
985
    if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0)
986
  return NULL;
987
988
    handle = CreateFileW (file_name,
989
       GENERIC_READ | GENERIC_WRITE,
990
       0,
991
       NULL,
992
       CREATE_ALWAYS,
993
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
994
       NULL);
995
    if (handle == INVALID_HANDLE_VALUE) {
996
  DeleteFileW (file_name);
997
  return NULL;
998
    }
999
1000
    fd = _open_osfhandle((intptr_t) handle, 0);
1001
    if (fd < 0) {
1002
  CloseHandle (handle);
1003
  return NULL;
1004
    }
1005
1006
    fp = fdopen(fd, "w+b");
1007
    if (fp == NULL) {
1008
  _close(fd);
1009
  return NULL;
1010
    }
1011
1012
    return fp;
1013
}
1014
#endif /* !_WIN32_WCE */
1015
1016
#endif /* _WIN32 */
1017
1018
typedef struct _cairo_intern_string {
1019
    cairo_hash_entry_t hash_entry;
1020
    int len;
1021
    char *string;
1022
} cairo_intern_string_t;
1023
1024
static cairo_hash_table_t *_cairo_intern_string_ht;
1025
1026
unsigned long
1027
_cairo_string_hash (const char *str, int len)
1028
0
{
1029
0
    const signed char *p = (const signed char *) str;
1030
0
    unsigned int h = *p;
1031
1032
0
    for (p += 1; len > 0; len--, p++)
1033
0
  h = (h << 5) - h + *p;
1034
1035
0
    return h;
1036
0
}
1037
1038
static cairo_bool_t
1039
_intern_string_equal (const void *_a, const void *_b)
1040
0
{
1041
0
    const cairo_intern_string_t *a = _a;
1042
0
    const cairo_intern_string_t *b = _b;
1043
1044
0
    if (a->len != b->len)
1045
0
  return FALSE;
1046
1047
0
    return memcmp (a->string, b->string, a->len) == 0;
1048
0
}
1049
1050
cairo_status_t
1051
_cairo_intern_string (const char **str_inout, int len)
1052
0
{
1053
0
    char *str = (char *) *str_inout;
1054
0
    cairo_intern_string_t tmpl, *istring;
1055
0
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
1056
1057
0
    if (CAIRO_INJECT_FAULT ())
1058
0
  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1059
1060
0
    if (len < 0)
1061
0
  len = strlen (str);
1062
0
    tmpl.hash_entry.hash = _cairo_string_hash (str, len);
1063
0
    tmpl.len = len;
1064
0
    tmpl.string = (char *) str;
1065
1066
0
    CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex);
1067
0
    if (_cairo_intern_string_ht == NULL) {
1068
0
  _cairo_intern_string_ht = _cairo_hash_table_create (_intern_string_equal);
1069
0
  if (unlikely (_cairo_intern_string_ht == NULL)) {
1070
0
      status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1071
0
      goto BAIL;
1072
0
  }
1073
0
    }
1074
1075
0
    istring = _cairo_hash_table_lookup (_cairo_intern_string_ht,
1076
0
          &tmpl.hash_entry);
1077
0
    if (istring == NULL) {
1078
0
  istring = _cairo_malloc (sizeof (cairo_intern_string_t) + len + 1);
1079
0
  if (likely (istring != NULL)) {
1080
0
      istring->hash_entry.hash = tmpl.hash_entry.hash;
1081
0
      istring->len = tmpl.len;
1082
0
      istring->string = (char *) (istring + 1);
1083
0
      memcpy (istring->string, str, len);
1084
0
      istring->string[len] = '\0';
1085
1086
0
      status = _cairo_hash_table_insert (_cairo_intern_string_ht,
1087
0
                 &istring->hash_entry);
1088
0
      if (unlikely (status)) {
1089
0
    free (istring);
1090
0
    goto BAIL;
1091
0
      }
1092
0
  } else {
1093
0
      status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1094
0
      goto BAIL;
1095
0
  }
1096
0
    }
1097
1098
0
    *str_inout = istring->string;
1099
1100
0
  BAIL:
1101
0
    CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex);
1102
0
    return status;
1103
0
}
1104
1105
static void
1106
_intern_string_pluck (void *entry, void *closure)
1107
0
{
1108
0
    _cairo_hash_table_remove (closure, entry);
1109
0
    free (entry);
1110
0
}
1111
1112
void
1113
_cairo_intern_string_reset_static_data (void)
1114
0
{
1115
0
    CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex);
1116
0
    if (_cairo_intern_string_ht != NULL) {
1117
0
  _cairo_hash_table_foreach (_cairo_intern_string_ht,
1118
0
           _intern_string_pluck,
1119
0
           _cairo_intern_string_ht);
1120
0
  _cairo_hash_table_destroy(_cairo_intern_string_ht);
1121
0
  _cairo_intern_string_ht = NULL;
1122
0
    }
1123
0
    CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex);
1124
0
}