Coverage Report

Created: 2025-09-27 07:50

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