Bug Summary

File:root/firefox-clang/gfx/cairo/cairo/src/cairo-default-context.c
Warning:line 165, column 6
Value stored to 'is_empty' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_c_gfx_cairo_cairo_src1.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/cairo/src -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/cairo/src -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D HAVE_FT_LOAD_SFNT_TABLE -D PACKAGE_VERSION="moz" -D PACKAGE_BUGREPORT="http://bugzilla.mozilla.org/" -D CAIRO_HAS_PTHREAD -D _GNU_SOURCE -D MOZ_TREE_PIXMAN -D SIZEOF_VOID_P=__SIZEOF_POINTER__ -D SIZEOF_INT=__SIZEOF_INT__ -D SIZEOF_LONG=__SIZEOF_LONG__ -D SIZEOF_LONG_LONG=__SIZEOF_LONG_LONG__ -D HAVE_UINT64_T -D HAVE_CXX11_ATOMIC_PRIMITIVES -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/gfx/cairo/cairo/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/cairo/cairo/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/libpng16 -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-enum-compare -Wno-int-to-pointer-cast -Wno-int-conversion -Wno-incompatible-pointer-types -Wno-sign-compare -Wno-type-limits -Wno-missing-field-initializers -Wno-conversion -Wno-narrowing -Wno-switch -Wno-unused -Wno-unused-variable -Wno-error=uninitialized -Wno-absolute-value -Wno-deprecated-register -Wno-incompatible-pointer-types -Wno-macro-redefined -Wno-shift-negative-value -Wno-tautological-compare -Wno-tautological-constant-out-of-range-compare -Wno-unreachable-code -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-26-231904-1820671-1 -x c Unified_c_gfx_cairo_cairo_src1.c
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 © 2011 Intel Corporation
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 * Chris Wilson <chris@chris-wilson.co.uk>
39 */
40
41#include "cairoint.h"
42
43#include "cairo-private.h"
44#include "cairo-arc-private.h"
45#include "cairo-backend-private.h"
46#include "cairo-clip-inline.h"
47#include "cairo-default-context-private.h"
48#include "cairo-error-private.h"
49#include "cairo-freed-pool-private.h"
50#include "cairo-path-private.h"
51#include "cairo-pattern-private.h"
52
53#define CAIRO_TOLERANCE_MINIMUM_cairo_fixed_to_double(1) _cairo_fixed_to_double(1)
54
55#if !defined(INFINITY(__builtin_inff ()))
56#define INFINITY(__builtin_inff ()) HUGE_VAL(__builtin_huge_val ())
57#endif
58
59static freed_pool_t context_pool;
60
61void
62_cairo_default_context_reset_static_data (void)
63{
64 _freed_pool_reset (&context_pool);
65}
66
67void
68_cairo_default_context_fini (cairo_default_context_t *cr)
69{
70 while (cr->gstate != &cr->gstate_tail[0]) {
71 if (_cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist))
72 break;
73 }
74
75 _cairo_gstate_fini (cr->gstate);
76 cr->gstate_freelist = cr->gstate_freelist->next; /* skip over tail[1] */
77 while (cr->gstate_freelist != NULL((void*)0)) {
78 cairo_gstate_t *gstate = cr->gstate_freelist;
79 cr->gstate_freelist = gstate->next;
80 free (gstate);
81 }
82
83 _cairo_path_fixed_fini (cr->path);
84
85 _cairo_fini (&cr->base);
86}
87
88static void
89_cairo_default_context_destroy (void *abstract_cr)
90{
91 cairo_default_context_t *cr = abstract_cr;
92
93 _cairo_default_context_fini (cr);
94
95 /* mark the context as invalid to protect against misuse */
96 cr->base.status = CAIRO_STATUS_NULL_POINTER;
97 _freed_pool_put (&context_pool, cr);
98}
99
100static cairo_surface_t *
101_cairo_default_context_get_original_target (void *abstract_cr)
102{
103 cairo_default_context_t *cr = abstract_cr;
104
105 return _cairo_gstate_get_original_target (cr->gstate);
106}
107
108static cairo_surface_t *
109_cairo_default_context_get_current_target (void *abstract_cr)
110{
111 cairo_default_context_t *cr = abstract_cr;
112
113 return _cairo_gstate_get_target (cr->gstate);
114}
115
116static cairo_status_t
117_cairo_default_context_save (void *abstract_cr)
118{
119 cairo_default_context_t *cr = abstract_cr;
120
121 return _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
122}
123
124static cairo_status_t
125_cairo_default_context_restore (void *abstract_cr)
126{
127 cairo_default_context_t *cr = abstract_cr;
128
129 if (unlikely (_cairo_gstate_is_group (cr->gstate))(__builtin_expect (!!(_cairo_gstate_is_group (cr->gstate))
, 0))
)
130 return _cairo_error (CAIRO_STATUS_INVALID_RESTORE);
131
132 return _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
133}
134
135static cairo_status_t
136_cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
137{
138 cairo_default_context_t *cr = abstract_cr;
139 cairo_surface_t *group_surface;
140 cairo_clip_t *clip;
141 cairo_status_t status;
142
143 clip = _cairo_gstate_get_clip (cr->gstate);
144 if (_cairo_clip_is_all_clipped (clip)) {
145 group_surface = cairo_image_surface_create_moz_cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
146 status = group_surface->status;
147 if (unlikely (status)(__builtin_expect (!!(status), 0)))
148 goto bail;
149 } else {
150 cairo_surface_t *parent_surface;
151 cairo_rectangle_int_t extents;
152 cairo_bool_t bounded, is_empty;
153
154 parent_surface = _cairo_gstate_get_target (cr->gstate);
155
156 if (unlikely (parent_surface->status)(__builtin_expect (!!(parent_surface->status), 0)))
157 return parent_surface->status;
158 if (unlikely (parent_surface->finished)(__builtin_expect (!!(parent_surface->finished), 0)))
159 return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
160
161 /* Get the extents that we'll use in creating our new group surface */
162 bounded = _cairo_surface_get_extents (parent_surface, &extents);
163 if (clip)
164 /* XXX: This assignment just fixes a compiler warning? */
165 is_empty = _cairo_rectangle_intersect (&extents,
Value stored to 'is_empty' is never read
166 _cairo_clip_get_extents (clip));
167
168 if (!bounded) {
169 /* XXX: Generic solution? */
170 group_surface = cairo_recording_surface_create_moz_cairo_recording_surface_create (content, NULL((void*)0));
171 extents.x = extents.y = 0;
172 } else {
173 group_surface = _cairo_surface_create_scratch (parent_surface,
174 content,
175 extents.width,
176 extents.height,
177 CAIRO_COLOR_TRANSPARENT_cairo_stock_color (CAIRO_STOCK_TRANSPARENT));
178 }
179 status = group_surface->status;
180 if (unlikely (status)(__builtin_expect (!!(status), 0)))
181 goto bail;
182
183 /* Set device offsets on the new surface so that logically it appears at
184 * the same location on the parent surface -- when we pop_group this,
185 * the source pattern will get fixed up for the appropriate target surface
186 * device offsets, so we want to set our own surface offsets from /that/,
187 * and not from the device origin. */
188 cairo_surface_set_device_offset_moz_cairo_surface_set_device_offset (group_surface,
189 parent_surface->device_transform.x0 - extents.x,
190 parent_surface->device_transform.y0 - extents.y);
191
192 cairo_surface_set_device_scale (group_surface,
193 parent_surface->device_transform.xx,
194 parent_surface->device_transform.yy);
195
196 /* If we have a current path, we need to adjust it to compensate for
197 * the device offset just applied. */
198 _cairo_path_fixed_translate (cr->path,
199 _cairo_fixed_from_int (-extents.x),
200 _cairo_fixed_from_int (-extents.y));
201 }
202
203 /* create a new gstate for the redirect */
204 status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
205 if (unlikely (status)(__builtin_expect (!!(status), 0)))
206 goto bail;
207
208 status = _cairo_gstate_redirect_target (cr->gstate, group_surface);
209
210bail:
211 cairo_surface_destroy_moz_cairo_surface_destroy (group_surface);
212 return status;
213}
214
215static cairo_pattern_t *
216_cairo_default_context_pop_group (void *abstract_cr)
217{
218 cairo_default_context_t *cr = abstract_cr;
219 cairo_surface_t *group_surface;
220 cairo_pattern_t *group_pattern;
221 cairo_surface_t *parent_surface;
222 cairo_matrix_t group_matrix;
223 cairo_status_t status;
224
225 /* Verify that we are at the right nesting level */
226 if (unlikely (! _cairo_gstate_is_group (cr->gstate))(__builtin_expect (!!(! _cairo_gstate_is_group (cr->gstate
)), 0))
)
227 return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP);
228
229 /* Get a reference to the active surface before restoring */
230 group_surface = _cairo_gstate_get_target (cr->gstate);
231 group_surface = cairo_surface_reference_moz_cairo_surface_reference (group_surface);
232
233 status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
234 assert (status == CAIRO_STATUS_SUCCESS)((void) sizeof ((status == CAIRO_STATUS_SUCCESS) ? 1 : 0), __extension__
({ if (status == CAIRO_STATUS_SUCCESS) ; else __assert_fail (
"status == CAIRO_STATUS_SUCCESS", "/root/firefox-clang/gfx/cairo/cairo/src/cairo-default-context.c"
, 234, __extension__ __PRETTY_FUNCTION__); }))
;
235
236 parent_surface = _cairo_gstate_get_target (cr->gstate);
237
238 group_pattern = cairo_pattern_create_for_surface_moz_cairo_pattern_create_for_surface (group_surface);
239 status = group_pattern->status;
240 if (unlikely (status)(__builtin_expect (!!(status), 0)))
241 goto done;
242
243 _cairo_gstate_get_matrix (cr->gstate, &group_matrix);
244 cairo_pattern_set_matrix_moz_cairo_pattern_set_matrix (group_pattern, &group_matrix);
245
246 /* If we have a current path, we need to adjust it to compensate for
247 * the device offset just removed. */
248 _cairo_path_fixed_translate (cr->path,
249 _cairo_fixed_from_int (parent_surface->device_transform.x0 - group_surface->device_transform.x0),
250 _cairo_fixed_from_int (parent_surface->device_transform.y0 - group_surface->device_transform.y0));
251
252done:
253 cairo_surface_destroy_moz_cairo_surface_destroy (group_surface);
254
255 return group_pattern;
256}
257
258static cairo_status_t
259_cairo_default_context_set_source (void *abstract_cr,
260 cairo_pattern_t *source)
261{
262 cairo_default_context_t *cr = abstract_cr;
263
264 return _cairo_gstate_set_source (cr->gstate, source);
265}
266
267static cairo_bool_t
268_current_source_matches_solid (const cairo_pattern_t *pattern,
269 double red,
270 double green,
271 double blue,
272 double alpha)
273{
274 cairo_color_t color;
275
276 if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
277 return FALSE0;
278
279 red = _cairo_restrict_value (red, 0.0, 1.0);
280 green = _cairo_restrict_value (green, 0.0, 1.0);
281 blue = _cairo_restrict_value (blue, 0.0, 1.0);
282 alpha = _cairo_restrict_value (alpha, 0.0, 1.0);
283
284 _cairo_color_init_rgba (&color, red, green, blue, alpha);
285 return _cairo_color_equal (&color,
286 &((cairo_solid_pattern_t *) pattern)->color);
287}
288
289static cairo_status_t
290_cairo_default_context_set_source_rgba (void *abstract_cr, double red, double green, double blue, double alpha)
291{
292 cairo_default_context_t *cr = abstract_cr;
293 cairo_pattern_t *pattern;
294 cairo_status_t status;
295
296 if (_current_source_matches_solid (cr->gstate->source,
297 red, green, blue, alpha))
298 return CAIRO_STATUS_SUCCESS;
299
300 /* push the current pattern to the freed lists */
301 _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
302
303 pattern = cairo_pattern_create_rgba_moz_cairo_pattern_create_rgba (red, green, blue, alpha);
304 if (unlikely (pattern->status)(__builtin_expect (!!(pattern->status), 0)))
305 return pattern->status;
306
307 status = _cairo_default_context_set_source (cr, pattern);
308 cairo_pattern_destroy_moz_cairo_pattern_destroy (pattern);
309
310 return status;
311}
312
313static cairo_status_t
314_cairo_default_context_set_source_surface (void *abstract_cr,
315 cairo_surface_t *surface,
316 double x,
317 double y)
318{
319 cairo_default_context_t *cr = abstract_cr;
320 cairo_pattern_t *pattern;
321 cairo_matrix_t matrix;
322 cairo_status_t status;
323
324 /* push the current pattern to the freed lists */
325 _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
326
327 pattern = cairo_pattern_create_for_surface_moz_cairo_pattern_create_for_surface (surface);
328 if (unlikely (pattern->status)(__builtin_expect (!!(pattern->status), 0))) {
329 status = pattern->status;
330 cairo_pattern_destroy_moz_cairo_pattern_destroy (pattern);
331 return status;
332 }
333
334 cairo_matrix_init_translate_moz_cairo_matrix_init_translate (&matrix, -x, -y);
335 cairo_pattern_set_matrix_moz_cairo_pattern_set_matrix (pattern, &matrix);
336
337 status = _cairo_default_context_set_source (cr, pattern);
338 cairo_pattern_destroy_moz_cairo_pattern_destroy (pattern);
339
340 return status;
341}
342
343static cairo_pattern_t *
344_cairo_default_context_get_source (void *abstract_cr)
345{
346 cairo_default_context_t *cr = abstract_cr;
347
348 return _cairo_gstate_get_source (cr->gstate);
349}
350
351static cairo_status_t
352_cairo_default_context_set_tolerance (void *abstract_cr,
353 double tolerance)
354{
355 cairo_default_context_t *cr = abstract_cr;
356
357 if (tolerance < CAIRO_TOLERANCE_MINIMUM_cairo_fixed_to_double(1))
358 tolerance = CAIRO_TOLERANCE_MINIMUM_cairo_fixed_to_double(1);
359
360 return _cairo_gstate_set_tolerance (cr->gstate, tolerance);
361}
362
363static cairo_status_t
364_cairo_default_context_set_operator (void *abstract_cr, cairo_operator_t op)
365{
366 cairo_default_context_t *cr = abstract_cr;
367
368 return _cairo_gstate_set_operator (cr->gstate, op);
369}
370
371static cairo_status_t
372_cairo_default_context_set_opacity (void *abstract_cr, double opacity)
373{
374 cairo_default_context_t *cr = abstract_cr;
375
376 return _cairo_gstate_set_opacity (cr->gstate, opacity);
377}
378
379static cairo_status_t
380_cairo_default_context_set_antialias (void *abstract_cr,
381 cairo_antialias_t antialias)
382{
383 cairo_default_context_t *cr = abstract_cr;
384
385 return _cairo_gstate_set_antialias (cr->gstate, antialias);
386}
387
388static cairo_status_t
389_cairo_default_context_set_fill_rule (void *abstract_cr,
390 cairo_fill_rule_t fill_rule)
391{
392 cairo_default_context_t *cr = abstract_cr;
393
394 return _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
395}
396
397static cairo_status_t
398_cairo_default_context_set_line_width (void *abstract_cr,
399 double line_width)
400{
401 cairo_default_context_t *cr = abstract_cr;
402
403 return _cairo_gstate_set_line_width (cr->gstate, line_width);
404}
405
406static cairo_status_t
407_cairo_default_context_set_hairline (void *abstract_cr, cairo_bool_t set_hairline)
408{
409 cairo_default_context_t *cr = abstract_cr;
410
411 return _cairo_gstate_set_hairline (cr->gstate, set_hairline);
412}
413
414static cairo_status_t
415_cairo_default_context_set_line_cap (void *abstract_cr,
416 cairo_line_cap_t line_cap)
417{
418 cairo_default_context_t *cr = abstract_cr;
419
420 return _cairo_gstate_set_line_cap (cr->gstate, line_cap);
421}
422
423static cairo_status_t
424_cairo_default_context_set_line_join (void *abstract_cr,
425 cairo_line_join_t line_join)
426{
427 cairo_default_context_t *cr = abstract_cr;
428
429 return _cairo_gstate_set_line_join (cr->gstate, line_join);
430}
431
432static cairo_status_t
433_cairo_default_context_set_dash (void *abstract_cr,
434 const double *dashes,
435 int num_dashes,
436 double offset)
437{
438 cairo_default_context_t *cr = abstract_cr;
439
440 return _cairo_gstate_set_dash (cr->gstate,
441 dashes, num_dashes, offset);
442}
443
444static cairo_status_t
445_cairo_default_context_set_miter_limit (void *abstract_cr,
446 double limit)
447{
448 cairo_default_context_t *cr = abstract_cr;
449
450 return _cairo_gstate_set_miter_limit (cr->gstate, limit);
451}
452
453static cairo_antialias_t
454_cairo_default_context_get_antialias (void *abstract_cr)
455{
456 cairo_default_context_t *cr = abstract_cr;
457
458 return _cairo_gstate_get_antialias (cr->gstate);
459}
460
461static void
462_cairo_default_context_get_dash (void *abstract_cr,
463 double *dashes,
464 int *num_dashes,
465 double *offset)
466{
467 cairo_default_context_t *cr = abstract_cr;
468
469 _cairo_gstate_get_dash (cr->gstate, dashes, num_dashes, offset);
470}
471
472static cairo_fill_rule_t
473_cairo_default_context_get_fill_rule (void *abstract_cr)
474{
475 cairo_default_context_t *cr = abstract_cr;
476
477 return _cairo_gstate_get_fill_rule (cr->gstate);
478}
479
480static double
481_cairo_default_context_get_line_width (void *abstract_cr)
482{
483 cairo_default_context_t *cr = abstract_cr;
484
485 return _cairo_gstate_get_line_width (cr->gstate);
486}
487
488static cairo_bool_t
489_cairo_default_context_get_hairline (void *abstract_cr)
490{
491 cairo_default_context_t *cr = abstract_cr;
492
493 return _cairo_gstate_get_hairline (cr->gstate);
494}
495
496static cairo_line_cap_t
497_cairo_default_context_get_line_cap (void *abstract_cr)
498{
499 cairo_default_context_t *cr = abstract_cr;
500
501 return _cairo_gstate_get_line_cap (cr->gstate);
502}
503
504static cairo_line_join_t
505_cairo_default_context_get_line_join (void *abstract_cr)
506{
507 cairo_default_context_t *cr = abstract_cr;
508
509 return _cairo_gstate_get_line_join (cr->gstate);
510}
511
512static double
513_cairo_default_context_get_miter_limit (void *abstract_cr)
514{
515 cairo_default_context_t *cr = abstract_cr;
516
517 return _cairo_gstate_get_miter_limit (cr->gstate);
518}
519
520static cairo_operator_t
521_cairo_default_context_get_operator (void *abstract_cr)
522{
523 cairo_default_context_t *cr = abstract_cr;
524
525 return _cairo_gstate_get_operator (cr->gstate);
526}
527
528static double
529_cairo_default_context_get_opacity (void *abstract_cr)
530{
531 cairo_default_context_t *cr = abstract_cr;
532
533 return _cairo_gstate_get_opacity (cr->gstate);
534}
535
536static double
537_cairo_default_context_get_tolerance (void *abstract_cr)
538{
539 cairo_default_context_t *cr = abstract_cr;
540
541 return _cairo_gstate_get_tolerance (cr->gstate);
542}
543
544
545/* Current transformation matrix */
546
547static cairo_status_t
548_cairo_default_context_translate (void *abstract_cr,
549 double tx,
550 double ty)
551{
552 cairo_default_context_t *cr = abstract_cr;
553
554 return _cairo_gstate_translate (cr->gstate, tx, ty);
555}
556
557static cairo_status_t
558_cairo_default_context_scale (void *abstract_cr,
559 double sx,
560 double sy)
561{
562 cairo_default_context_t *cr = abstract_cr;
563
564 return _cairo_gstate_scale (cr->gstate, sx, sy);
565}
566
567static cairo_status_t
568_cairo_default_context_rotate (void *abstract_cr,
569 double theta)
570{
571 cairo_default_context_t *cr = abstract_cr;
572
573 return _cairo_gstate_rotate (cr->gstate, theta);
574}
575
576static cairo_status_t
577_cairo_default_context_transform (void *abstract_cr,
578 const cairo_matrix_t *matrix)
579{
580 cairo_default_context_t *cr = abstract_cr;
581
582 return _cairo_gstate_transform (cr->gstate, matrix);
583}
584
585static cairo_status_t
586_cairo_default_context_set_matrix (void *abstract_cr,
587 const cairo_matrix_t *matrix)
588{
589 cairo_default_context_t *cr = abstract_cr;
590
591 return _cairo_gstate_set_matrix (cr->gstate, matrix);
592}
593
594static cairo_status_t
595_cairo_default_context_set_identity_matrix (void *abstract_cr)
596{
597 cairo_default_context_t *cr = abstract_cr;
598
599 _cairo_gstate_identity_matrix (cr->gstate);
600 return CAIRO_STATUS_SUCCESS;
601}
602
603static void
604_cairo_default_context_get_matrix (void *abstract_cr,
605 cairo_matrix_t *matrix)
606{
607 cairo_default_context_t *cr = abstract_cr;
608
609 _cairo_gstate_get_matrix (cr->gstate, matrix);
610}
611
612static void
613_cairo_default_context_user_to_device (void *abstract_cr,
614 double *x,
615 double *y)
616{
617 cairo_default_context_t *cr = abstract_cr;
618
619 _cairo_gstate_user_to_device (cr->gstate, x, y);
620}
621
622static void
623_cairo_default_context_user_to_device_distance (void *abstract_cr, double *dx, double *dy)
624{
625 cairo_default_context_t *cr = abstract_cr;
626
627 _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
628}
629
630static void
631_cairo_default_context_device_to_user (void *abstract_cr,
632 double *x,
633 double *y)
634{
635 cairo_default_context_t *cr = abstract_cr;
636
637 _cairo_gstate_device_to_user (cr->gstate, x, y);
638}
639
640static void
641_cairo_default_context_device_to_user_distance (void *abstract_cr,
642 double *dx,
643 double *dy)
644{
645 cairo_default_context_t *cr = abstract_cr;
646
647 _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
648}
649
650static void
651_cairo_default_context_backend_to_user (void *abstract_cr,
652 double *x,
653 double *y)
654{
655 cairo_default_context_t *cr = abstract_cr;
656
657 _cairo_gstate_backend_to_user (cr->gstate, x, y);
658}
659
660static void
661_cairo_default_context_backend_to_user_distance (void *abstract_cr, double *dx, double *dy)
662{
663 cairo_default_context_t *cr = abstract_cr;
664
665 _cairo_gstate_backend_to_user_distance (cr->gstate, dx, dy);
666}
667
668static void
669_cairo_default_context_user_to_backend (void *abstract_cr,
670 double *x,
671 double *y)
672{
673 cairo_default_context_t *cr = abstract_cr;
674
675 _cairo_gstate_user_to_backend (cr->gstate, x, y);
676}
677
678static void
679_cairo_default_context_user_to_backend_distance (void *abstract_cr,
680 double *dx,
681 double *dy)
682{
683 cairo_default_context_t *cr = abstract_cr;
684
685 _cairo_gstate_user_to_backend_distance (cr->gstate, dx, dy);
686}
687
688/* Path constructor */
689
690static cairo_status_t
691_cairo_default_context_new_path (void *abstract_cr)
692{
693 cairo_default_context_t *cr = abstract_cr;
694
695 _cairo_path_fixed_fini (cr->path);
696 _cairo_path_fixed_init (cr->path);
697
698 return CAIRO_STATUS_SUCCESS;
699}
700
701static cairo_status_t
702_cairo_default_context_new_sub_path (void *abstract_cr)
703{
704 cairo_default_context_t *cr = abstract_cr;
705
706 _cairo_path_fixed_new_sub_path (cr->path);
707
708 return CAIRO_STATUS_SUCCESS;
709}
710
711static cairo_status_t
712_cairo_default_context_move_to (void *abstract_cr, double x, double y)
713{
714 cairo_default_context_t *cr = abstract_cr;
715 cairo_fixed_t x_fixed, y_fixed;
716 double width;
717
718 _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
719 width = _cairo_gstate_get_line_width (cr->gstate);
720 x_fixed = _cairo_fixed_from_double_clamped (x, width);
721 y_fixed = _cairo_fixed_from_double_clamped (y, width);
722
723 return _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed);
724}
725
726static cairo_status_t
727_cairo_default_context_line_to (void *abstract_cr, double x, double y)
728{
729 cairo_default_context_t *cr = abstract_cr;
730 cairo_fixed_t x_fixed, y_fixed;
731 double width;
732
733 _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
734 width = _cairo_gstate_get_line_width (cr->gstate);
735 x_fixed = _cairo_fixed_from_double_clamped (x, width);
736 y_fixed = _cairo_fixed_from_double_clamped (y, width);
737
738 return _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
739}
740
741static cairo_status_t
742_cairo_default_context_curve_to (void *abstract_cr,
743 double x1, double y1,
744 double x2, double y2,
745 double x3, double y3)
746{
747 cairo_default_context_t *cr = abstract_cr;
748 cairo_fixed_t x1_fixed, y1_fixed;
749 cairo_fixed_t x2_fixed, y2_fixed;
750 cairo_fixed_t x3_fixed, y3_fixed;
751 double width;
752
753 _cairo_gstate_user_to_backend (cr->gstate, &x1, &y1);
754 _cairo_gstate_user_to_backend (cr->gstate, &x2, &y2);
755 _cairo_gstate_user_to_backend (cr->gstate, &x3, &y3);
756 width = _cairo_gstate_get_line_width (cr->gstate);
757
758 x1_fixed = _cairo_fixed_from_double_clamped (x1, width);
759 y1_fixed = _cairo_fixed_from_double_clamped (y1, width);
760
761 x2_fixed = _cairo_fixed_from_double_clamped (x2, width);
762 y2_fixed = _cairo_fixed_from_double_clamped (y2, width);
763
764 x3_fixed = _cairo_fixed_from_double_clamped (x3, width);
765 y3_fixed = _cairo_fixed_from_double_clamped (y3, width);
766
767 return _cairo_path_fixed_curve_to (cr->path,
768 x1_fixed, y1_fixed,
769 x2_fixed, y2_fixed,
770 x3_fixed, y3_fixed);
771}
772
773static cairo_status_t
774_cairo_default_context_arc (void *abstract_cr,
775 double xc, double yc, double radius,
776 double angle1, double angle2,
777 cairo_bool_t forward)
778{
779 cairo_default_context_t *cr = abstract_cr;
780 cairo_status_t status;
781
782 /* Do nothing, successfully, if radius is <= 0 */
783 if (radius <= 0.0) {
784 cairo_fixed_t x_fixed, y_fixed;
785
786 _cairo_gstate_user_to_backend (cr->gstate, &xc, &yc);
787 x_fixed = _cairo_fixed_from_double (xc);
788 y_fixed = _cairo_fixed_from_double (yc);
789 status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
790 if (unlikely (status)(__builtin_expect (!!(status), 0)))
791 return status;
792
793 status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
794 if (unlikely (status)(__builtin_expect (!!(status), 0)))
795 return status;
796
797 return CAIRO_STATUS_SUCCESS;
798 }
799
800 status = _cairo_default_context_line_to (cr,
801 xc + radius * cos (angle1),
802 yc + radius * sin (angle1));
803
804 if (unlikely (status)(__builtin_expect (!!(status), 0)))
805 return status;
806
807 if (forward)
808 _cairo_arc_path (&cr->base, xc, yc, radius, angle1, angle2);
809 else
810 _cairo_arc_path_negative (&cr->base, xc, yc, radius, angle1, angle2);
811
812 return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */
813}
814
815static cairo_status_t
816_cairo_default_context_rel_move_to (void *abstract_cr, double dx, double dy)
817{
818 cairo_default_context_t *cr = abstract_cr;
819 cairo_fixed_t dx_fixed, dy_fixed;
820
821 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy);
822
823 dx_fixed = _cairo_fixed_from_double (dx);
824 dy_fixed = _cairo_fixed_from_double (dy);
825
826 return _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
827}
828
829static cairo_status_t
830_cairo_default_context_rel_line_to (void *abstract_cr, double dx, double dy)
831{
832 cairo_default_context_t *cr = abstract_cr;
833 cairo_fixed_t dx_fixed, dy_fixed;
834
835 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy);
836
837 dx_fixed = _cairo_fixed_from_double (dx);
838 dy_fixed = _cairo_fixed_from_double (dy);
839
840 return _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
841}
842
843
844static cairo_status_t
845_cairo_default_context_rel_curve_to (void *abstract_cr,
846 double dx1, double dy1,
847 double dx2, double dy2,
848 double dx3, double dy3)
849{
850 cairo_default_context_t *cr = abstract_cr;
851 cairo_fixed_t dx1_fixed, dy1_fixed;
852 cairo_fixed_t dx2_fixed, dy2_fixed;
853 cairo_fixed_t dx3_fixed, dy3_fixed;
854
855 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx1, &dy1);
856 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx2, &dy2);
857 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx3, &dy3);
858
859 dx1_fixed = _cairo_fixed_from_double (dx1);
860 dy1_fixed = _cairo_fixed_from_double (dy1);
861
862 dx2_fixed = _cairo_fixed_from_double (dx2);
863 dy2_fixed = _cairo_fixed_from_double (dy2);
864
865 dx3_fixed = _cairo_fixed_from_double (dx3);
866 dy3_fixed = _cairo_fixed_from_double (dy3);
867
868 return _cairo_path_fixed_rel_curve_to (cr->path,
869 dx1_fixed, dy1_fixed,
870 dx2_fixed, dy2_fixed,
871 dx3_fixed, dy3_fixed);
872}
873
874static cairo_status_t
875_cairo_default_context_close_path (void *abstract_cr)
876{
877 cairo_default_context_t *cr = abstract_cr;
878
879 return _cairo_path_fixed_close_path (cr->path);
880}
881
882static cairo_status_t
883_cairo_default_context_rectangle (void *abstract_cr,
884 double x, double y,
885 double width, double height)
886{
887 cairo_default_context_t *cr = abstract_cr;
888 cairo_status_t status;
889
890 status = _cairo_default_context_move_to (cr, x, y);
891 if (unlikely (status)(__builtin_expect (!!(status), 0)))
892 return status;
893
894 status = _cairo_default_context_rel_line_to (cr, width, 0);
895 if (unlikely (status)(__builtin_expect (!!(status), 0)))
896 return status;
897
898 status = _cairo_default_context_rel_line_to (cr, 0, height);
899 if (unlikely (status)(__builtin_expect (!!(status), 0)))
900 return status;
901
902 status = _cairo_default_context_rel_line_to (cr, -width, 0);
903 if (unlikely (status)(__builtin_expect (!!(status), 0)))
904 return status;
905
906 return _cairo_default_context_close_path (cr);
907}
908
909static void
910_cairo_default_context_path_extents (void *abstract_cr,
911 double *x1,
912 double *y1,
913 double *x2,
914 double *y2)
915{
916 cairo_default_context_t *cr = abstract_cr;
917
918 _cairo_gstate_path_extents (cr->gstate,
919 cr->path,
920 x1, y1, x2, y2);
921}
922
923static cairo_bool_t
924_cairo_default_context_has_current_point (void *abstract_cr)
925{
926 cairo_default_context_t *cr = abstract_cr;
927
928 return cr->path->has_current_point;
929}
930
931static cairo_bool_t
932_cairo_default_context_get_current_point (void *abstract_cr,
933 double *x,
934 double *y)
935{
936 cairo_default_context_t *cr = abstract_cr;
937 cairo_fixed_t x_fixed, y_fixed;
938
939 if (_cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed))
940 {
941 *x = _cairo_fixed_to_double (x_fixed);
942 *y = _cairo_fixed_to_double (y_fixed);
943 _cairo_gstate_backend_to_user (cr->gstate, x, y);
944
945 return TRUE1;
946 }
947 else
948 {
949 return FALSE0;
950 }
951}
952
953static cairo_path_t *
954_cairo_default_context_copy_path (void *abstract_cr)
955{
956 cairo_default_context_t *cr = abstract_cr;
957
958 return _cairo_path_create (cr->path, &cr->base);
959}
960
961static cairo_path_t *
962_cairo_default_context_copy_path_flat (void *abstract_cr)
963{
964 cairo_default_context_t *cr = abstract_cr;
965
966 return _cairo_path_create_flat (cr->path, &cr->base);
967}
968
969static cairo_status_t
970_cairo_default_context_append_path (void *abstract_cr,
971 const cairo_path_t *path)
972{
973 cairo_default_context_t *cr = abstract_cr;
974
975 return _cairo_path_append_to_context (path, &cr->base);
976}
977
978static cairo_status_t
979_cairo_default_context_paint (void *abstract_cr)
980{
981 cairo_default_context_t *cr = abstract_cr;
982
983 return _cairo_gstate_paint (cr->gstate);
984}
985
986static cairo_status_t
987_cairo_default_context_paint_with_alpha (void *abstract_cr,
988 double alpha)
989{
990 cairo_default_context_t *cr = abstract_cr;
991 cairo_solid_pattern_t pattern;
992 cairo_status_t status;
993 cairo_color_t color;
994
995 if (CAIRO_ALPHA_IS_OPAQUE (alpha)((alpha) >= ((double)0xff00 / (double)0xffff)))
996 return _cairo_gstate_paint (cr->gstate);
997
998 if (CAIRO_ALPHA_IS_ZERO (alpha)((alpha) <= 0.0) &&
999 _cairo_operator_bounded_by_mask (cr->gstate->op)) {
1000 return CAIRO_STATUS_SUCCESS;
1001 }
1002
1003 _cairo_color_init_rgba (&color, 0., 0., 0., alpha);
1004 _cairo_pattern_init_solid (&pattern, &color);
1005
1006 status = _cairo_gstate_mask (cr->gstate, &pattern.base);
1007 _cairo_pattern_fini (&pattern.base);
1008
1009 return status;
1010}
1011
1012static cairo_status_t
1013_cairo_default_context_mask (void *abstract_cr,
1014 cairo_pattern_t *mask)
1015{
1016 cairo_default_context_t *cr = abstract_cr;
1017
1018 return _cairo_gstate_mask (cr->gstate, mask);
1019}
1020
1021static cairo_status_t
1022_cairo_default_context_stroke_preserve (void *abstract_cr)
1023{
1024 cairo_default_context_t *cr = abstract_cr;
1025
1026 return _cairo_gstate_stroke (cr->gstate, cr->path);
1027}
1028
1029static cairo_status_t
1030_cairo_default_context_stroke (void *abstract_cr)
1031{
1032 cairo_default_context_t *cr = abstract_cr;
1033 cairo_status_t status;
1034
1035 status = _cairo_gstate_stroke (cr->gstate, cr->path);
1036 if (unlikely (status)(__builtin_expect (!!(status), 0)))
1037 return status;
1038
1039 return _cairo_default_context_new_path (cr);
1040}
1041
1042static cairo_status_t
1043_cairo_default_context_in_stroke (void *abstract_cr,
1044 double x, double y,
1045 cairo_bool_t *inside)
1046{
1047 cairo_default_context_t *cr = abstract_cr;
1048
1049 return _cairo_gstate_in_stroke (cr->gstate,
1050 cr->path,
1051 x, y,
1052 inside);
1053}
1054
1055static cairo_status_t
1056_cairo_default_context_stroke_extents (void *abstract_cr,
1057 double *x1, double *y1, double *x2, double *y2)
1058{
1059 cairo_default_context_t *cr = abstract_cr;
1060
1061 return _cairo_gstate_stroke_extents (cr->gstate,
1062 cr->path,
1063 x1, y1, x2, y2);
1064}
1065
1066static cairo_status_t
1067_cairo_default_context_fill_preserve (void *abstract_cr)
1068{
1069 cairo_default_context_t *cr = abstract_cr;
1070
1071 return _cairo_gstate_fill (cr->gstate, cr->path);
1072}
1073
1074static cairo_status_t
1075_cairo_default_context_fill (void *abstract_cr)
1076{
1077 cairo_default_context_t *cr = abstract_cr;
1078 cairo_status_t status;
1079
1080 status = _cairo_gstate_fill (cr->gstate, cr->path);
1081 if (unlikely (status)(__builtin_expect (!!(status), 0)))
1082 return status;
1083
1084 return _cairo_default_context_new_path (cr);
1085}
1086
1087static cairo_status_t
1088_cairo_default_context_in_fill (void *abstract_cr,
1089 double x, double y,
1090 cairo_bool_t *inside)
1091{
1092 cairo_default_context_t *cr = abstract_cr;
1093
1094 *inside = _cairo_gstate_in_fill (cr->gstate,
1095 cr->path,
1096 x, y);
1097 return CAIRO_STATUS_SUCCESS;
1098}
1099
1100static cairo_status_t
1101_cairo_default_context_fill_extents (void *abstract_cr,
1102 double *x1, double *y1, double *x2, double *y2)
1103{
1104 cairo_default_context_t *cr = abstract_cr;
1105
1106 return _cairo_gstate_fill_extents (cr->gstate,
1107 cr->path,
1108 x1, y1, x2, y2);
1109}
1110
1111static cairo_status_t
1112_cairo_default_context_clip_preserve (void *abstract_cr)
1113{
1114 cairo_default_context_t *cr = abstract_cr;
1115
1116 return _cairo_gstate_clip (cr->gstate, cr->path);
1117}
1118
1119static cairo_status_t
1120_cairo_default_context_clip (void *abstract_cr)
1121{
1122 cairo_default_context_t *cr = abstract_cr;
1123 cairo_status_t status;
1124
1125 status = _cairo_gstate_clip (cr->gstate, cr->path);
1126 if (unlikely (status)(__builtin_expect (!!(status), 0)))
1127 return status;
1128
1129 return _cairo_default_context_new_path (cr);
1130}
1131
1132static cairo_status_t
1133_cairo_default_context_in_clip (void *abstract_cr,
1134 double x, double y,
1135 cairo_bool_t *inside)
1136{
1137 cairo_default_context_t *cr = abstract_cr;
1138
1139 *inside = _cairo_gstate_in_clip (cr->gstate, x, y);
1140 return CAIRO_STATUS_SUCCESS;
1141}
1142
1143static cairo_status_t
1144_cairo_default_context_reset_clip (void *abstract_cr)
1145{
1146 cairo_default_context_t *cr = abstract_cr;
1147
1148 return _cairo_gstate_reset_clip (cr->gstate);
1149}
1150
1151static cairo_status_t
1152_cairo_default_context_clip_extents (void *abstract_cr,
1153 double *x1, double *y1, double *x2, double *y2)
1154{
1155 cairo_default_context_t *cr = abstract_cr;
1156
1157 if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) {
1158 *x1 = -INFINITY(__builtin_inff ());
1159 *y1 = -INFINITY(__builtin_inff ());
1160 *x2 = +INFINITY(__builtin_inff ());
1161 *y2 = +INFINITY(__builtin_inff ());
1162 }
1163
1164 return CAIRO_STATUS_SUCCESS;
1165}
1166
1167static cairo_rectangle_list_t *
1168_cairo_default_context_copy_clip_rectangle_list (void *abstract_cr)
1169{
1170 cairo_default_context_t *cr = abstract_cr;
1171
1172 return _cairo_gstate_copy_clip_rectangle_list (cr->gstate);
1173}
1174
1175static cairo_status_t
1176_cairo_default_context_copy_page (void *abstract_cr)
1177{
1178 cairo_default_context_t *cr = abstract_cr;
1179
1180 return _cairo_gstate_copy_page (cr->gstate);
1181}
1182
1183static cairo_status_t
1184_cairo_default_context_tag_begin (void *abstract_cr,
1185 const char *tag_name, const char *attributes)
1186{
1187 cairo_default_context_t *cr = abstract_cr;
1188
1189 return _cairo_gstate_tag_begin (cr->gstate, tag_name, attributes);
1190}
1191
1192static cairo_status_t
1193_cairo_default_context_tag_end (void *abstract_cr,
1194 const char *tag_name)
1195{
1196 cairo_default_context_t *cr = abstract_cr;
1197
1198 return _cairo_gstate_tag_end (cr->gstate, tag_name);
1199}
1200
1201static cairo_status_t
1202_cairo_default_context_show_page (void *abstract_cr)
1203{
1204 cairo_default_context_t *cr = abstract_cr;
1205
1206 return _cairo_gstate_show_page (cr->gstate);
1207}
1208
1209static cairo_status_t
1210_cairo_default_context_set_font_face (void *abstract_cr,
1211 cairo_font_face_t *font_face)
1212{
1213 cairo_default_context_t *cr = abstract_cr;
1214
1215 return _cairo_gstate_set_font_face (cr->gstate, font_face);
1216}
1217
1218static cairo_font_face_t *
1219_cairo_default_context_get_font_face (void *abstract_cr)
1220{
1221 cairo_default_context_t *cr = abstract_cr;
1222 cairo_font_face_t *font_face;
1223 cairo_status_t status;
1224
1225 status = _cairo_gstate_get_font_face (cr->gstate, &font_face);
1226 if (unlikely (status)(__builtin_expect (!!(status), 0))) {
1227 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY)do { cairo_status_t status__ = _cairo_error (CAIRO_STATUS_NO_MEMORY
); (void) status__; } while (0)
;
1228 return (cairo_font_face_t *) &_cairo_font_face_nil;
1229 }
1230
1231 return font_face;
1232}
1233
1234static cairo_status_t
1235_cairo_default_context_font_extents (void *abstract_cr,
1236 cairo_font_extents_t *extents)
1237{
1238 cairo_default_context_t *cr = abstract_cr;
1239
1240 return _cairo_gstate_get_font_extents (cr->gstate, extents);
1241}
1242
1243static cairo_status_t
1244_cairo_default_context_set_font_size (void *abstract_cr,
1245 double size)
1246{
1247 cairo_default_context_t *cr = abstract_cr;
1248
1249 return _cairo_gstate_set_font_size (cr->gstate, size);
1250}
1251
1252static cairo_status_t
1253_cairo_default_context_set_font_matrix (void *abstract_cr,
1254 const cairo_matrix_t *matrix)
1255{
1256 cairo_default_context_t *cr = abstract_cr;
1257
1258 return _cairo_gstate_set_font_matrix (cr->gstate, matrix);
1259}
1260
1261static void
1262_cairo_default_context_get_font_matrix (void *abstract_cr,
1263 cairo_matrix_t *matrix)
1264{
1265 cairo_default_context_t *cr = abstract_cr;
1266
1267 _cairo_gstate_get_font_matrix (cr->gstate, matrix);
1268}
1269
1270static cairo_status_t
1271_cairo_default_context_set_font_options (void *abstract_cr,
1272 const cairo_font_options_t *options)
1273{
1274 cairo_default_context_t *cr = abstract_cr;
1275
1276 _cairo_gstate_set_font_options (cr->gstate, options);
1277 return CAIRO_STATUS_SUCCESS;
1278}
1279
1280static void
1281_cairo_default_context_get_font_options (void *abstract_cr,
1282 cairo_font_options_t *options)
1283{
1284 cairo_default_context_t *cr = abstract_cr;
1285
1286 _cairo_gstate_get_font_options (cr->gstate, options);
1287}
1288
1289static cairo_status_t
1290_cairo_default_context_set_scaled_font (void *abstract_cr,
1291 cairo_scaled_font_t *scaled_font)
1292{
1293 cairo_default_context_t *cr = abstract_cr;
1294 cairo_bool_t was_previous;
1295 cairo_status_t status;
1296
1297 if (scaled_font == cr->gstate->scaled_font)
1298 return CAIRO_STATUS_SUCCESS;
1299
1300 was_previous = scaled_font == cr->gstate->previous_scaled_font;
1301
1302 status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
1303 if (unlikely (status)(__builtin_expect (!!(status), 0)))
1304 return status;
1305
1306 status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
1307 if (unlikely (status)(__builtin_expect (!!(status), 0)))
1308 return status;
1309
1310 _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
1311
1312 if (was_previous)
1313 cr->gstate->scaled_font = cairo_scaled_font_reference_moz_cairo_scaled_font_reference (scaled_font);
1314
1315 return CAIRO_STATUS_SUCCESS;
1316}
1317
1318static cairo_scaled_font_t *
1319_cairo_default_context_get_scaled_font (void *abstract_cr)
1320{
1321 cairo_default_context_t *cr = abstract_cr;
1322 cairo_scaled_font_t *scaled_font;
1323 cairo_status_t status;
1324
1325 status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font);
1326 if (unlikely (status)(__builtin_expect (!!(status), 0)))
1327 return _cairo_scaled_font_create_in_error (status);
1328
1329 return scaled_font;
1330}
1331
1332static cairo_status_t
1333_cairo_default_context_glyphs (void *abstract_cr,
1334 const cairo_glyph_t *glyphs,
1335 int num_glyphs,
1336 cairo_glyph_text_info_t *info)
1337{
1338 cairo_default_context_t *cr = abstract_cr;
1339
1340 return _cairo_gstate_show_text_glyphs (cr->gstate, glyphs, num_glyphs, info);
1341}
1342
1343static cairo_status_t
1344_cairo_default_context_glyph_path (void *abstract_cr,
1345 const cairo_glyph_t *glyphs,
1346 int num_glyphs)
1347{
1348 cairo_default_context_t *cr = abstract_cr;
1349
1350 return _cairo_gstate_glyph_path (cr->gstate,
1351 glyphs, num_glyphs,
1352 cr->path);
1353}
1354
1355static cairo_status_t
1356_cairo_default_context_glyph_extents (void *abstract_cr,
1357 const cairo_glyph_t *glyphs,
1358 int num_glyphs,
1359 cairo_text_extents_t *extents)
1360{
1361 cairo_default_context_t *cr = abstract_cr;
1362
1363 return _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
1364}
1365
1366static const cairo_backend_t _cairo_default_context_backend = {
1367 CAIRO_TYPE_DEFAULT,
1368 _cairo_default_context_destroy,
1369
1370 _cairo_default_context_get_original_target,
1371 _cairo_default_context_get_current_target,
1372
1373 _cairo_default_context_save,
1374 _cairo_default_context_restore,
1375
1376 _cairo_default_context_push_group,
1377 _cairo_default_context_pop_group,
1378
1379 _cairo_default_context_set_source_rgba,
1380 _cairo_default_context_set_source_surface,
1381 _cairo_default_context_set_source,
1382 _cairo_default_context_get_source,
1383
1384 _cairo_default_context_set_antialias,
1385 _cairo_default_context_set_dash,
1386 _cairo_default_context_set_fill_rule,
1387 _cairo_default_context_set_line_cap,
1388 _cairo_default_context_set_line_join,
1389 _cairo_default_context_set_line_width,
1390 _cairo_default_context_set_hairline,
1391 _cairo_default_context_set_miter_limit,
1392 _cairo_default_context_set_opacity,
1393 _cairo_default_context_set_operator,
1394 _cairo_default_context_set_tolerance,
1395 _cairo_default_context_get_antialias,
1396 _cairo_default_context_get_dash,
1397 _cairo_default_context_get_fill_rule,
1398 _cairo_default_context_get_line_cap,
1399 _cairo_default_context_get_line_join,
1400 _cairo_default_context_get_line_width,
1401 _cairo_default_context_get_hairline,
1402 _cairo_default_context_get_miter_limit,
1403 _cairo_default_context_get_opacity,
1404 _cairo_default_context_get_operator,
1405 _cairo_default_context_get_tolerance,
1406
1407 _cairo_default_context_translate,
1408 _cairo_default_context_scale,
1409 _cairo_default_context_rotate,
1410 _cairo_default_context_transform,
1411 _cairo_default_context_set_matrix,
1412 _cairo_default_context_set_identity_matrix,
1413 _cairo_default_context_get_matrix,
1414
1415 _cairo_default_context_user_to_device,
1416 _cairo_default_context_user_to_device_distance,
1417 _cairo_default_context_device_to_user,
1418 _cairo_default_context_device_to_user_distance,
1419
1420 _cairo_default_context_user_to_backend,
1421 _cairo_default_context_user_to_backend_distance,
1422 _cairo_default_context_backend_to_user,
1423 _cairo_default_context_backend_to_user_distance,
1424
1425 _cairo_default_context_new_path,
1426 _cairo_default_context_new_sub_path,
1427 _cairo_default_context_move_to,
1428 _cairo_default_context_rel_move_to,
1429 _cairo_default_context_line_to,
1430 _cairo_default_context_rel_line_to,
1431 _cairo_default_context_curve_to,
1432 _cairo_default_context_rel_curve_to,
1433 NULL((void*)0), /* arc-to */
1434 NULL((void*)0), /* rel-arc-to */
1435 _cairo_default_context_close_path,
1436 _cairo_default_context_arc,
1437 _cairo_default_context_rectangle,
1438 _cairo_default_context_path_extents,
1439 _cairo_default_context_has_current_point,
1440 _cairo_default_context_get_current_point,
1441 _cairo_default_context_copy_path,
1442 _cairo_default_context_copy_path_flat,
1443 _cairo_default_context_append_path,
1444
1445 NULL((void*)0), /* stroke-to-path */
1446
1447 _cairo_default_context_clip,
1448 _cairo_default_context_clip_preserve,
1449 _cairo_default_context_in_clip,
1450 _cairo_default_context_clip_extents,
1451 _cairo_default_context_reset_clip,
1452 _cairo_default_context_copy_clip_rectangle_list,
1453
1454 _cairo_default_context_paint,
1455 _cairo_default_context_paint_with_alpha,
1456 _cairo_default_context_mask,
1457
1458 _cairo_default_context_stroke,
1459 _cairo_default_context_stroke_preserve,
1460 _cairo_default_context_in_stroke,
1461 _cairo_default_context_stroke_extents,
1462
1463 _cairo_default_context_fill,
1464 _cairo_default_context_fill_preserve,
1465 _cairo_default_context_in_fill,
1466 _cairo_default_context_fill_extents,
1467
1468 _cairo_default_context_set_font_face,
1469 _cairo_default_context_get_font_face,
1470 _cairo_default_context_set_font_size,
1471 _cairo_default_context_set_font_matrix,
1472 _cairo_default_context_get_font_matrix,
1473 _cairo_default_context_set_font_options,
1474 _cairo_default_context_get_font_options,
1475 _cairo_default_context_set_scaled_font,
1476 _cairo_default_context_get_scaled_font,
1477 _cairo_default_context_font_extents,
1478
1479 _cairo_default_context_glyphs,
1480 _cairo_default_context_glyph_path,
1481 _cairo_default_context_glyph_extents,
1482
1483 _cairo_default_context_copy_page,
1484 _cairo_default_context_show_page,
1485
1486 _cairo_default_context_tag_begin,
1487 _cairo_default_context_tag_end,
1488};
1489
1490cairo_status_t
1491_cairo_default_context_init (cairo_default_context_t *cr, void *target)
1492{
1493 _cairo_init (&cr->base, &_cairo_default_context_backend);
1494 _cairo_path_fixed_init (cr->path);
1495
1496 cr->gstate = &cr->gstate_tail[0];
1497 cr->gstate_freelist = &cr->gstate_tail[1];
1498 cr->gstate_tail[1].next = NULL((void*)0);
1499
1500 return _cairo_gstate_init (cr->gstate, target);
1501}
1502
1503cairo_t *
1504_cairo_default_context_create (void *target)
1505{
1506 cairo_default_context_t *cr;
1507 cairo_status_t status;
1508
1509 cr = _freed_pool_get (&context_pool);
1510 if (unlikely (cr == NULL)(__builtin_expect (!!(cr == ((void*)0)), 0))) {
1511 cr = _cairo_malloc (sizeof (cairo_default_context_t))((sizeof (cairo_default_context_t)) != 0 ? malloc(sizeof (cairo_default_context_t
)) : ((void*)0))
;
1512 if (unlikely (cr == NULL)(__builtin_expect (!!(cr == ((void*)0)), 0)))
1513 return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
1514 }
1515
1516 status = _cairo_default_context_init (cr, target);
1517 if (unlikely (status)(__builtin_expect (!!(status), 0))) {
1518 _freed_pool_put (&context_pool, cr);
1519 return _cairo_create_in_error (status);
1520 }
1521
1522 return &cr->base;
1523}