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 : *
7 : * This library is free software; you can redistribute it and/or
8 : * modify it either under the terms of the GNU Lesser General Public
9 : * License version 2.1 as published by the Free Software Foundation
10 : * (the "LGPL") or, at your option, under the terms of the Mozilla
11 : * Public License Version 1.1 (the "MPL"). If you do not alter this
12 : * notice, a recipient may use your version of this file under either
13 : * the MPL or the LGPL.
14 : *
15 : * You should have received a copy of the LGPL along with this library
16 : * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 : * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18 : * You should have received a copy of the MPL along with this library
19 : * in the file COPYING-MPL-1.1
20 : *
21 : * The contents of this file are subject to the Mozilla Public License
22 : * Version 1.1 (the "License"); you may not use this file except in
23 : * compliance with the License. You may obtain a copy of the License at
24 : * http://www.mozilla.org/MPL/
25 : *
26 : * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 : * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 : * the specific language governing rights and limitations.
29 : *
30 : * The Original Code is the cairo graphics library.
31 : *
32 : * The Initial Developer of the Original Code is University of Southern
33 : * California.
34 : *
35 : * Contributor(s):
36 : * Carl D. Worth <cworth@cworth.org>
37 : */
38 :
39 : #include "cairoint.h"
40 : #include "cairo-private.h"
41 :
42 : #include "cairo-arc-private.h"
43 : #include "cairo-error-private.h"
44 : #include "cairo-path-private.h"
45 :
46 : /**
47 : * SECTION:cairo
48 : * @Title: cairo_t
49 : * @Short_Description: The cairo drawing context
50 : * @See_Also: #cairo_surface_t
51 : *
52 : * #cairo_t is the main object used when drawing with cairo. To
53 : * draw with cairo, you create a #cairo_t, set the target surface,
54 : * and drawing options for the #cairo_t, create shapes with
55 : * functions like cairo_move_to() and cairo_line_to(), and then
56 : * draw shapes with cairo_stroke() or cairo_fill().
57 : *
58 : * #cairo_t<!-- -->'s can be pushed to a stack via cairo_save().
59 : * They may then safely be changed, without loosing the current state.
60 : * Use cairo_restore() to restore to the saved state.
61 : */
62 :
63 : /**
64 : * SECTION:cairo-text
65 : * @Title: text
66 : * @Short_Description: Rendering text and glyphs
67 : * @See_Also: #cairo_font_face_t, #cairo_scaled_font_t, cairo_text_path(),
68 : * cairo_glyph_path()
69 : *
70 : * The functions with <emphasis>text</emphasis> in their name form cairo's
71 : * <firstterm>toy</firstterm> text API. The toy API takes UTF-8 encoded
72 : * text and is limited in its functionality to rendering simple
73 : * left-to-right text with no advanced features. That means for example
74 : * that most complex scripts like Hebrew, Arabic, and Indic scripts are
75 : * out of question. No kerning or correct positioning of diacritical marks
76 : * either. The font selection is pretty limited too and doesn't handle the
77 : * case that the selected font does not cover the characters in the text.
78 : * This set of functions are really that, a toy text API, for testing and
79 : * demonstration purposes. Any serious application should avoid them.
80 : *
81 : * The functions with <emphasis>glyphs</emphasis> in their name form cairo's
82 : * <firstterm>low-level</firstterm> text API. The low-level API relies on
83 : * the user to convert text to a set of glyph indexes and positions. This
84 : * is a very hard problem and is best handled by external libraries, like
85 : * the pangocairo that is part of the Pango text layout and rendering library.
86 : * Pango is available from <ulink
87 : * url="http://www.pango.org/">http://www.pango.org/</ulink>.
88 : */
89 :
90 : /**
91 : * SECTION:cairo-transforms
92 : * @Title: Transformations
93 : * @Short_Description: Manipulating the current transformation matrix
94 : * @See_Also: #cairo_matrix_t
95 : *
96 : * The current transformation matrix, <firstterm>ctm</firstterm>, is a
97 : * two-dimensional affine transformation that maps all coordinates and other
98 : * drawing instruments from the <firstterm>user space</firstterm> into the
99 : * surface's canonical coordinate system, also known as the <firstterm>device
100 : * space</firstterm>.
101 : */
102 :
103 : #define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1)
104 :
105 : #if !defined(INFINITY)
106 : #define INFINITY HUGE_VAL
107 : #endif
108 :
109 : static const cairo_t _cairo_nil = {
110 : CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
111 : CAIRO_STATUS_NO_MEMORY, /* status */
112 : { 0, 0, 0, NULL }, /* user_data */
113 : NULL, /* gstate */
114 : {{ 0 }, { 0 }}, /* gstate_tail */
115 : NULL, /* gstate_freelist */
116 : {{ /* path */
117 : { 0, 0 }, /* last_move_point */
118 : { 0, 0 }, /* current point */
119 : FALSE, /* has_current_point */
120 : FALSE, /* has_last_move_point */
121 : FALSE, /* has_curve_to */
122 : FALSE, /* is_box */
123 : FALSE, /* maybe_fill_region */
124 : TRUE, /* is_empty_fill */
125 : { {0, 0}, {0, 0}}, /* extents */
126 : {{{NULL,NULL}}} /* link */
127 : }}
128 : };
129 :
130 : static const cairo_t _cairo_nil__null_pointer = {
131 : CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
132 : CAIRO_STATUS_NULL_POINTER, /* status */
133 : { 0, 0, 0, NULL }, /* user_data */
134 : NULL, /* gstate */
135 : {{ 0 }, { 0 }}, /* gstate_tail */
136 : NULL, /* gstate_freelist */
137 : {{ /* path */
138 : { 0, 0 }, /* last_move_point */
139 : { 0, 0 }, /* current point */
140 : FALSE, /* has_current_point */
141 : FALSE, /* has_last_move_point */
142 : FALSE, /* has_curve_to */
143 : FALSE, /* is_box */
144 : FALSE, /* maybe_fill_region */
145 : TRUE, /* is_empty_fill */
146 : { {0, 0}, {0, 0}}, /* extents */
147 : {{{NULL,NULL}}} /* link */
148 : }}
149 : };
150 : #include <assert.h>
151 :
152 : /**
153 : * _cairo_error:
154 : * @status: a status value indicating an error, (eg. not
155 : * %CAIRO_STATUS_SUCCESS)
156 : *
157 : * Checks that status is an error status, but does nothing else.
158 : *
159 : * All assignments of an error status to any user-visible object
160 : * within the cairo application should result in a call to
161 : * _cairo_error().
162 : *
163 : * The purpose of this function is to allow the user to set a
164 : * breakpoint in _cairo_error() to generate a stack trace for when the
165 : * user causes cairo to detect an error.
166 : *
167 : * Return value: the error status.
168 : **/
169 : cairo_status_t
170 0 : _cairo_error (cairo_status_t status)
171 : {
172 : CAIRO_ENSURE_UNIQUE;
173 0 : assert (_cairo_status_is_error (status));
174 :
175 0 : return status;
176 : }
177 :
178 : /**
179 : * _cairo_set_error:
180 : * @cr: a cairo context
181 : * @status: a status value indicating an error
182 : *
183 : * Atomically sets cr->status to @status and calls _cairo_error;
184 : * Does nothing if status is %CAIRO_STATUS_SUCCESS.
185 : *
186 : * All assignments of an error status to cr->status should happen
187 : * through _cairo_set_error(). Note that due to the nature of the atomic
188 : * operation, it is not safe to call this function on the nil objects.
189 : *
190 : * The purpose of this function is to allow the user to set a
191 : * breakpoint in _cairo_error() to generate a stack trace for when the
192 : * user causes cairo to detect an error.
193 : **/
194 : static void
195 0 : _cairo_set_error (cairo_t *cr, cairo_status_t status)
196 : {
197 : /* Don't overwrite an existing error. This preserves the first
198 : * error, which is the most significant. */
199 0 : _cairo_status_set_error (&cr->status, _cairo_error (status));
200 0 : }
201 :
202 : /* We keep a small stash of contexts to reduce malloc pressure */
203 : #define CAIRO_STASH_SIZE 4
204 : #if CAIRO_NO_MUTEX
205 : static struct {
206 : cairo_t pool[CAIRO_STASH_SIZE];
207 : int occupied;
208 : } _context_stash;
209 :
210 : static cairo_t *
211 64 : _context_get (void)
212 : {
213 : int avail;
214 :
215 64 : avail = ffs (~_context_stash.occupied) - 1;
216 64 : if (avail >= CAIRO_STASH_SIZE)
217 0 : return malloc (sizeof (cairo_t));
218 :
219 64 : _context_stash.occupied |= 1 << avail;
220 64 : return &_context_stash.pool[avail];
221 : }
222 :
223 : static void
224 64 : _context_put (cairo_t *cr)
225 : {
226 128 : if (cr < &_context_stash.pool[0] ||
227 64 : cr >= &_context_stash.pool[CAIRO_STASH_SIZE])
228 : {
229 0 : free (cr);
230 0 : return;
231 : }
232 :
233 64 : _context_stash.occupied &= ~(1 << (cr - &_context_stash.pool[0]));
234 : }
235 : #elif HAS_ATOMIC_OPS
236 : static struct {
237 : cairo_t pool[CAIRO_STASH_SIZE];
238 : cairo_atomic_int_t occupied;
239 : } _context_stash;
240 :
241 : static cairo_t *
242 : _context_get (void)
243 : {
244 : cairo_atomic_int_t avail, old, new;
245 :
246 : do {
247 : old = _cairo_atomic_int_get (&_context_stash.occupied);
248 : avail = ffs (~old) - 1;
249 : if (avail >= CAIRO_STASH_SIZE)
250 : return malloc (sizeof (cairo_t));
251 :
252 : new = old | (1 << avail);
253 : } while (! _cairo_atomic_int_cmpxchg (&_context_stash.occupied, old, new));
254 :
255 : return &_context_stash.pool[avail];
256 : }
257 :
258 : static void
259 : _context_put (cairo_t *cr)
260 : {
261 : cairo_atomic_int_t old, new, avail;
262 :
263 : if (cr < &_context_stash.pool[0] ||
264 : cr >= &_context_stash.pool[CAIRO_STASH_SIZE])
265 : {
266 : free (cr);
267 : return;
268 : }
269 :
270 : avail = ~(1 << (cr - &_context_stash.pool[0]));
271 : do {
272 : old = _cairo_atomic_int_get (&_context_stash.occupied);
273 : new = old & avail;
274 : } while (! _cairo_atomic_int_cmpxchg (&_context_stash.occupied, old, new));
275 : }
276 : #else
277 : #define _context_get() malloc (sizeof (cairo_t))
278 : #define _context_put(cr) free (cr)
279 : #endif
280 :
281 : /* XXX This should disappear in favour of a common pool of error objects. */
282 : static cairo_t *_cairo_nil__objects[CAIRO_STATUS_LAST_STATUS + 1];
283 :
284 : static cairo_t *
285 0 : _cairo_create_in_error (cairo_status_t status)
286 : {
287 : cairo_t *cr;
288 :
289 0 : assert (status != CAIRO_STATUS_SUCCESS);
290 :
291 : /* special case OOM in order to avoid another allocation */
292 0 : switch ((int) status) {
293 : case CAIRO_STATUS_NO_MEMORY:
294 0 : return (cairo_t *) &_cairo_nil;
295 : case CAIRO_STATUS_NULL_POINTER:
296 0 : return (cairo_t *) &_cairo_nil__null_pointer;
297 : }
298 :
299 : CAIRO_MUTEX_LOCK (_cairo_error_mutex);
300 0 : cr = _cairo_nil__objects[status];
301 0 : if (cr == NULL) {
302 0 : cr = malloc (sizeof (cairo_t));
303 0 : if (unlikely (cr == NULL)) {
304 : CAIRO_MUTEX_UNLOCK (_cairo_error_mutex);
305 0 : _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
306 0 : return (cairo_t *) &_cairo_nil;
307 : }
308 :
309 0 : *cr = _cairo_nil;
310 0 : cr->status = status;
311 0 : _cairo_nil__objects[status] = cr;
312 : }
313 : CAIRO_MUTEX_UNLOCK (_cairo_error_mutex);
314 :
315 0 : return cr;
316 : }
317 :
318 : void
319 3 : _cairo_reset_static_data (void)
320 : {
321 : int status;
322 :
323 : CAIRO_MUTEX_LOCK (_cairo_error_mutex);
324 120 : for (status = CAIRO_STATUS_SUCCESS;
325 : status <= CAIRO_STATUS_LAST_STATUS;
326 114 : status++)
327 : {
328 114 : if (_cairo_nil__objects[status] != NULL) {
329 0 : free (_cairo_nil__objects[status]);
330 0 : _cairo_nil__objects[status] = NULL;
331 : }
332 : }
333 : CAIRO_MUTEX_UNLOCK (_cairo_error_mutex);
334 3 : }
335 :
336 : /**
337 : * cairo_create:
338 : * @target: target surface for the context
339 : *
340 : * Creates a new #cairo_t with all graphics state parameters set to
341 : * default values and with @target as a target surface. The target
342 : * surface should be constructed with a backend-specific function such
343 : * as cairo_image_surface_create() (or any other
344 : * cairo_<emphasis>backend</emphasis>_surface_create() variant).
345 : *
346 : * This function references @target, so you can immediately
347 : * call cairo_surface_destroy() on it if you don't need to
348 : * maintain a separate reference to it.
349 : *
350 : * Return value: a newly allocated #cairo_t with a reference
351 : * count of 1. The initial reference count should be released
352 : * with cairo_destroy() when you are done using the #cairo_t.
353 : * This function never returns %NULL. If memory cannot be
354 : * allocated, a special #cairo_t object will be returned on
355 : * which cairo_status() returns %CAIRO_STATUS_NO_MEMORY.
356 : * You can use this object normally, but no drawing will
357 : * be done.
358 : **/
359 : cairo_t *
360 64 : cairo_create (cairo_surface_t *target)
361 : {
362 : cairo_t *cr;
363 : cairo_status_t status;
364 :
365 64 : if (unlikely (target == NULL))
366 0 : return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
367 64 : if (unlikely (target->status))
368 0 : return _cairo_create_in_error (target->status);
369 :
370 64 : cr = _context_get ();
371 64 : if (unlikely (cr == NULL))
372 0 : return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
373 :
374 64 : CAIRO_REFERENCE_COUNT_INIT (&cr->ref_count, 1);
375 :
376 64 : cr->status = CAIRO_STATUS_SUCCESS;
377 :
378 64 : _cairo_user_data_array_init (&cr->user_data);
379 64 : _cairo_path_fixed_init (cr->path);
380 :
381 64 : cr->gstate = &cr->gstate_tail[0];
382 64 : cr->gstate_freelist = &cr->gstate_tail[1];
383 64 : cr->gstate_tail[1].next = NULL;
384 :
385 64 : status = _cairo_gstate_init (cr->gstate, target);
386 64 : if (unlikely (status)) {
387 0 : _context_put (cr);
388 0 : cr = _cairo_create_in_error (status);
389 : }
390 :
391 64 : return cr;
392 : }
393 : slim_hidden_def (cairo_create);
394 :
395 : /**
396 : * cairo_reference:
397 : * @cr: a #cairo_t
398 : *
399 : * Increases the reference count on @cr by one. This prevents
400 : * @cr from being destroyed until a matching call to cairo_destroy()
401 : * is made.
402 : *
403 : * The number of references to a #cairo_t can be get using
404 : * cairo_get_reference_count().
405 : *
406 : * Return value: the referenced #cairo_t.
407 : **/
408 : cairo_t *
409 0 : cairo_reference (cairo_t *cr)
410 : {
411 0 : if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
412 0 : return cr;
413 :
414 0 : assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&cr->ref_count));
415 :
416 0 : _cairo_reference_count_inc (&cr->ref_count);
417 :
418 0 : return cr;
419 : }
420 :
421 : /**
422 : * cairo_destroy:
423 : * @cr: a #cairo_t
424 : *
425 : * Decreases the reference count on @cr by one. If the result
426 : * is zero, then @cr and all associated resources are freed.
427 : * See cairo_reference().
428 : **/
429 : void
430 64 : cairo_destroy (cairo_t *cr)
431 : {
432 : cairo_surface_t *surface;
433 :
434 64 : if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
435 0 : return;
436 :
437 64 : assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&cr->ref_count));
438 :
439 64 : if (! _cairo_reference_count_dec_and_test (&cr->ref_count))
440 0 : return;
441 :
442 128 : while (cr->gstate != &cr->gstate_tail[0]) {
443 0 : if (_cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist))
444 0 : break;
445 : }
446 :
447 : /* The context is expected (>99% of all use cases) to be held for the
448 : * duration of a single expose event/sequence of graphic operations.
449 : * Therefore, on destroy we explicitly flush the Cairo pipeline of any
450 : * pending operations.
451 : */
452 64 : surface = _cairo_gstate_get_original_target (cr->gstate);
453 64 : if (surface != NULL)
454 64 : cairo_surface_flush (surface);
455 :
456 64 : _cairo_gstate_fini (cr->gstate);
457 64 : cr->gstate_freelist = cr->gstate_freelist->next; /* skip over tail[1] */
458 128 : while (cr->gstate_freelist != NULL) {
459 0 : cairo_gstate_t *gstate = cr->gstate_freelist;
460 0 : cr->gstate_freelist = gstate->next;
461 0 : free (gstate);
462 : }
463 :
464 64 : _cairo_path_fixed_fini (cr->path);
465 :
466 64 : _cairo_user_data_array_fini (&cr->user_data);
467 :
468 : /* mark the context as invalid to protect against misuse */
469 64 : cr->status = CAIRO_STATUS_NULL_POINTER;
470 :
471 64 : _context_put (cr);
472 : }
473 : slim_hidden_def (cairo_destroy);
474 :
475 : /**
476 : * cairo_get_user_data:
477 : * @cr: a #cairo_t
478 : * @key: the address of the #cairo_user_data_key_t the user data was
479 : * attached to
480 : *
481 : * Return user data previously attached to @cr using the specified
482 : * key. If no user data has been attached with the given key this
483 : * function returns %NULL.
484 : *
485 : * Return value: the user data previously attached or %NULL.
486 : *
487 : * Since: 1.4
488 : **/
489 : void *
490 0 : cairo_get_user_data (cairo_t *cr,
491 : const cairo_user_data_key_t *key)
492 : {
493 0 : return _cairo_user_data_array_get_data (&cr->user_data,
494 : key);
495 : }
496 :
497 : /**
498 : * cairo_set_user_data:
499 : * @cr: a #cairo_t
500 : * @key: the address of a #cairo_user_data_key_t to attach the user data to
501 : * @user_data: the user data to attach to the #cairo_t
502 : * @destroy: a #cairo_destroy_func_t which will be called when the
503 : * #cairo_t is destroyed or when new user data is attached using the
504 : * same key.
505 : *
506 : * Attach user data to @cr. To remove user data from a surface,
507 : * call this function with the key that was used to set it and %NULL
508 : * for @data.
509 : *
510 : * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
511 : * slot could not be allocated for the user data.
512 : *
513 : * Since: 1.4
514 : **/
515 : cairo_status_t
516 0 : cairo_set_user_data (cairo_t *cr,
517 : const cairo_user_data_key_t *key,
518 : void *user_data,
519 : cairo_destroy_func_t destroy)
520 : {
521 0 : if (CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
522 0 : return cr->status;
523 :
524 0 : return _cairo_user_data_array_set_data (&cr->user_data,
525 : key, user_data, destroy);
526 : }
527 :
528 : /**
529 : * cairo_get_reference_count:
530 : * @cr: a #cairo_t
531 : *
532 : * Returns the current reference count of @cr.
533 : *
534 : * Return value: the current reference count of @cr. If the
535 : * object is a nil object, 0 will be returned.
536 : *
537 : * Since: 1.4
538 : **/
539 : unsigned int
540 0 : cairo_get_reference_count (cairo_t *cr)
541 : {
542 0 : if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
543 0 : return 0;
544 :
545 0 : return CAIRO_REFERENCE_COUNT_GET_VALUE (&cr->ref_count);
546 : }
547 :
548 : /**
549 : * cairo_save:
550 : * @cr: a #cairo_t
551 : *
552 : * Makes a copy of the current state of @cr and saves it
553 : * on an internal stack of saved states for @cr. When
554 : * cairo_restore() is called, @cr will be restored to
555 : * the saved state. Multiple calls to cairo_save() and
556 : * cairo_restore() can be nested; each call to cairo_restore()
557 : * restores the state from the matching paired cairo_save().
558 : *
559 : * It isn't necessary to clear all saved states before
560 : * a #cairo_t is freed. If the reference count of a #cairo_t
561 : * drops to zero in response to a call to cairo_destroy(),
562 : * any saved states will be freed along with the #cairo_t.
563 : **/
564 : void
565 0 : cairo_save (cairo_t *cr)
566 : {
567 : cairo_status_t status;
568 :
569 0 : if (unlikely (cr->status))
570 0 : return;
571 :
572 0 : status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
573 0 : if (unlikely (status))
574 0 : _cairo_set_error (cr, status);
575 : }
576 : slim_hidden_def(cairo_save);
577 :
578 : /**
579 : * cairo_restore:
580 : * @cr: a #cairo_t
581 : *
582 : * Restores @cr to the state saved by a preceding call to
583 : * cairo_save() and removes that state from the stack of
584 : * saved states.
585 : **/
586 : void
587 0 : cairo_restore (cairo_t *cr)
588 : {
589 : cairo_status_t status;
590 :
591 0 : if (unlikely (cr->status))
592 0 : return;
593 :
594 0 : status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
595 0 : if (unlikely (status))
596 0 : _cairo_set_error (cr, status);
597 : }
598 : slim_hidden_def(cairo_restore);
599 :
600 : /**
601 : * cairo_push_group:
602 : * @cr: a cairo context
603 : *
604 : * Temporarily redirects drawing to an intermediate surface known as a
605 : * group. The redirection lasts until the group is completed by a call
606 : * to cairo_pop_group() or cairo_pop_group_to_source(). These calls
607 : * provide the result of any drawing to the group as a pattern,
608 : * (either as an explicit object, or set as the source pattern).
609 : *
610 : * This group functionality can be convenient for performing
611 : * intermediate compositing. One common use of a group is to render
612 : * objects as opaque within the group, (so that they occlude each
613 : * other), and then blend the result with translucence onto the
614 : * destination.
615 : *
616 : * Groups can be nested arbitrarily deep by making balanced calls to
617 : * cairo_push_group()/cairo_pop_group(). Each call pushes/pops the new
618 : * target group onto/from a stack.
619 : *
620 : * The cairo_push_group() function calls cairo_save() so that any
621 : * changes to the graphics state will not be visible outside the
622 : * group, (the pop_group functions call cairo_restore()).
623 : *
624 : * By default the intermediate group will have a content type of
625 : * %CAIRO_CONTENT_COLOR_ALPHA. Other content types can be chosen for
626 : * the group by using cairo_push_group_with_content() instead.
627 : *
628 : * As an example, here is how one might fill and stroke a path with
629 : * translucence, but without any portion of the fill being visible
630 : * under the stroke:
631 : *
632 : * <informalexample><programlisting>
633 : * cairo_push_group (cr);
634 : * cairo_set_source (cr, fill_pattern);
635 : * cairo_fill_preserve (cr);
636 : * cairo_set_source (cr, stroke_pattern);
637 : * cairo_stroke (cr);
638 : * cairo_pop_group_to_source (cr);
639 : * cairo_paint_with_alpha (cr, alpha);
640 : * </programlisting></informalexample>
641 : *
642 : * Since: 1.2
643 : */
644 : void
645 0 : cairo_push_group (cairo_t *cr)
646 : {
647 0 : cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
648 0 : }
649 :
650 : /**
651 : * cairo_push_group_with_content:
652 : * @cr: a cairo context
653 : * @content: a #cairo_content_t indicating the type of group that
654 : * will be created
655 : *
656 : * Temporarily redirects drawing to an intermediate surface known as a
657 : * group. The redirection lasts until the group is completed by a call
658 : * to cairo_pop_group() or cairo_pop_group_to_source(). These calls
659 : * provide the result of any drawing to the group as a pattern,
660 : * (either as an explicit object, or set as the source pattern).
661 : *
662 : * The group will have a content type of @content. The ability to
663 : * control this content type is the only distinction between this
664 : * function and cairo_push_group() which you should see for a more
665 : * detailed description of group rendering.
666 : *
667 : * Since: 1.2
668 : */
669 : void
670 0 : cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
671 : {
672 : cairo_surface_t *group_surface;
673 : cairo_clip_t *clip;
674 : cairo_status_t status;
675 :
676 0 : if (unlikely (cr->status))
677 0 : return;
678 :
679 0 : clip = _cairo_gstate_get_clip (cr->gstate);
680 0 : if (clip->all_clipped) {
681 0 : group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
682 0 : status = group_surface->status;
683 0 : if (unlikely (status))
684 0 : goto bail;
685 : } else {
686 : cairo_surface_t *parent_surface;
687 : const cairo_rectangle_int_t *clip_extents;
688 : cairo_rectangle_int_t extents;
689 : cairo_matrix_t matrix;
690 : cairo_bool_t is_empty;
691 :
692 0 : parent_surface = _cairo_gstate_get_target (cr->gstate);
693 :
694 : /* Get the extents that we'll use in creating our new group surface */
695 0 : is_empty = _cairo_surface_get_extents (parent_surface, &extents);
696 0 : clip_extents = _cairo_clip_get_extents (_cairo_gstate_get_clip (cr->gstate));
697 0 : if (clip_extents != NULL)
698 0 : is_empty = _cairo_rectangle_intersect (&extents, clip_extents);
699 :
700 0 : group_surface = _cairo_surface_create_similar_solid (parent_surface,
701 : content,
702 : extents.width,
703 : extents.height,
704 : CAIRO_COLOR_TRANSPARENT,
705 : TRUE);
706 0 : status = group_surface->status;
707 0 : if (unlikely (status))
708 0 : goto bail;
709 :
710 : /* Set device offsets on the new surface so that logically it appears at
711 : * the same location on the parent surface -- when we pop_group this,
712 : * the source pattern will get fixed up for the appropriate target surface
713 : * device offsets, so we want to set our own surface offsets from /that/,
714 : * and not from the device origin. */
715 0 : cairo_surface_set_device_offset (group_surface,
716 0 : parent_surface->device_transform.x0 - extents.x,
717 0 : parent_surface->device_transform.y0 - extents.y);
718 :
719 : /* If we have a current path, we need to adjust it to compensate for
720 : * the device offset just applied. */
721 0 : cairo_matrix_init_translate (&matrix, -extents.x, -extents.y);
722 0 : _cairo_path_fixed_transform (cr->path, &matrix);
723 : }
724 :
725 : /* create a new gstate for the redirect */
726 0 : cairo_save (cr);
727 0 : if (unlikely (cr->status))
728 0 : goto bail;
729 :
730 0 : status = _cairo_gstate_redirect_target (cr->gstate, group_surface);
731 :
732 : bail:
733 0 : cairo_surface_destroy (group_surface);
734 0 : if (unlikely (status))
735 0 : _cairo_set_error (cr, status);
736 : }
737 : slim_hidden_def(cairo_push_group_with_content);
738 :
739 : /**
740 : * cairo_pop_group:
741 : * @cr: a cairo context
742 : *
743 : * Terminates the redirection begun by a call to cairo_push_group() or
744 : * cairo_push_group_with_content() and returns a new pattern
745 : * containing the results of all drawing operations performed to the
746 : * group.
747 : *
748 : * The cairo_pop_group() function calls cairo_restore(), (balancing a
749 : * call to cairo_save() by the push_group function), so that any
750 : * changes to the graphics state will not be visible outside the
751 : * group.
752 : *
753 : * Return value: a newly created (surface) pattern containing the
754 : * results of all drawing operations performed to the group. The
755 : * caller owns the returned object and should call
756 : * cairo_pattern_destroy() when finished with it.
757 : *
758 : * Since: 1.2
759 : **/
760 : cairo_pattern_t *
761 0 : cairo_pop_group (cairo_t *cr)
762 : {
763 : cairo_surface_t *group_surface, *parent_target;
764 : cairo_pattern_t *group_pattern;
765 : cairo_matrix_t group_matrix, device_transform_matrix;
766 : cairo_status_t status;
767 :
768 0 : if (unlikely (cr->status))
769 0 : return _cairo_pattern_create_in_error (cr->status);
770 :
771 : /* Grab the active surfaces */
772 0 : group_surface = _cairo_gstate_get_target (cr->gstate);
773 0 : parent_target = _cairo_gstate_get_parent_target (cr->gstate);
774 :
775 : /* Verify that we are at the right nesting level */
776 0 : if (parent_target == NULL) {
777 0 : _cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP);
778 0 : return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP);
779 : }
780 :
781 : /* We need to save group_surface before we restore; we don't need
782 : * to reference parent_target and original_target, since the
783 : * gstate will still hold refs to them once we restore. */
784 0 : group_surface = cairo_surface_reference (group_surface);
785 :
786 0 : cairo_restore (cr);
787 :
788 0 : if (unlikely (cr->status)) {
789 0 : group_pattern = _cairo_pattern_create_in_error (cr->status);
790 0 : goto done;
791 : }
792 :
793 0 : group_pattern = cairo_pattern_create_for_surface (group_surface);
794 0 : status = group_pattern->status;
795 0 : if (unlikely (status)) {
796 0 : _cairo_set_error (cr, status);
797 0 : goto done;
798 : }
799 :
800 0 : _cairo_gstate_get_matrix (cr->gstate, &group_matrix);
801 : /* Transform by group_matrix centered around device_transform so that when
802 : * we call _cairo_gstate_copy_transformed_pattern the result is a pattern
803 : * with a matrix equivalent to the device_transform of group_surface. */
804 0 : if (_cairo_surface_has_device_transform (group_surface)) {
805 0 : cairo_pattern_set_matrix (group_pattern, &group_surface->device_transform);
806 0 : _cairo_pattern_transform (group_pattern, &group_matrix);
807 0 : _cairo_pattern_transform (group_pattern, &group_surface->device_transform_inverse);
808 : } else {
809 0 : cairo_pattern_set_matrix (group_pattern, &group_matrix);
810 : }
811 :
812 : /* If we have a current path, we need to adjust it to compensate for
813 : * the device offset just removed. */
814 0 : cairo_matrix_multiply (&device_transform_matrix,
815 0 : &_cairo_gstate_get_target (cr->gstate)->device_transform,
816 0 : &group_surface->device_transform_inverse);
817 0 : _cairo_path_fixed_transform (cr->path, &device_transform_matrix);
818 :
819 : done:
820 0 : cairo_surface_destroy (group_surface);
821 :
822 0 : return group_pattern;
823 : }
824 : slim_hidden_def(cairo_pop_group);
825 :
826 : /**
827 : * cairo_pop_group_to_source:
828 : * @cr: a cairo context
829 : *
830 : * Terminates the redirection begun by a call to cairo_push_group() or
831 : * cairo_push_group_with_content() and installs the resulting pattern
832 : * as the source pattern in the given cairo context.
833 : *
834 : * The behavior of this function is equivalent to the sequence of
835 : * operations:
836 : *
837 : * <informalexample><programlisting>
838 : * #cairo_pattern_t *group = cairo_pop_group (cr);
839 : * cairo_set_source (cr, group);
840 : * cairo_pattern_destroy (group);
841 : * </programlisting></informalexample>
842 : *
843 : * but is more convenient as their is no need for a variable to store
844 : * the short-lived pointer to the pattern.
845 : *
846 : * The cairo_pop_group() function calls cairo_restore(), (balancing a
847 : * call to cairo_save() by the push_group function), so that any
848 : * changes to the graphics state will not be visible outside the
849 : * group.
850 : *
851 : * Since: 1.2
852 : **/
853 : void
854 0 : cairo_pop_group_to_source (cairo_t *cr)
855 : {
856 : cairo_pattern_t *group_pattern;
857 :
858 0 : group_pattern = cairo_pop_group (cr);
859 0 : cairo_set_source (cr, group_pattern);
860 0 : cairo_pattern_destroy (group_pattern);
861 0 : }
862 :
863 : /**
864 : * cairo_set_operator:
865 : * @cr: a #cairo_t
866 : * @op: a compositing operator, specified as a #cairo_operator_t
867 : *
868 : * Sets the compositing operator to be used for all drawing
869 : * operations. See #cairo_operator_t for details on the semantics of
870 : * each available compositing operator.
871 : *
872 : * The default operator is %CAIRO_OPERATOR_OVER.
873 : **/
874 : void
875 64 : cairo_set_operator (cairo_t *cr, cairo_operator_t op)
876 : {
877 : cairo_status_t status;
878 :
879 64 : if (unlikely (cr->status))
880 0 : return;
881 :
882 64 : status = _cairo_gstate_set_operator (cr->gstate, op);
883 64 : if (unlikely (status))
884 0 : _cairo_set_error (cr, status);
885 : }
886 : slim_hidden_def (cairo_set_operator);
887 :
888 :
889 : static cairo_bool_t
890 0 : _current_source_matches_solid (cairo_t *cr,
891 : double red,
892 : double green,
893 : double blue,
894 : double alpha)
895 : {
896 : const cairo_pattern_t *current;
897 : cairo_color_t color;
898 :
899 0 : current = cr->gstate->source;
900 0 : if (current->type != CAIRO_PATTERN_TYPE_SOLID)
901 0 : return FALSE;
902 :
903 0 : red = _cairo_restrict_value (red, 0.0, 1.0);
904 0 : green = _cairo_restrict_value (green, 0.0, 1.0);
905 0 : blue = _cairo_restrict_value (blue, 0.0, 1.0);
906 0 : alpha = _cairo_restrict_value (alpha, 0.0, 1.0);
907 :
908 0 : _cairo_color_init_rgba (&color, red, green, blue, alpha);
909 0 : return _cairo_color_equal (&color,
910 0 : &((cairo_solid_pattern_t *) current)->color);
911 : }
912 : /**
913 : * cairo_set_source_rgb
914 : * @cr: a cairo context
915 : * @red: red component of color
916 : * @green: green component of color
917 : * @blue: blue component of color
918 : *
919 : * Sets the source pattern within @cr to an opaque color. This opaque
920 : * color will then be used for any subsequent drawing operation until
921 : * a new source pattern is set.
922 : *
923 : * The color components are floating point numbers in the range 0 to
924 : * 1. If the values passed in are outside that range, they will be
925 : * clamped.
926 : *
927 : * The default source pattern is opaque black, (that is, it is
928 : * equivalent to cairo_set_source_rgb(cr, 0.0, 0.0, 0.0)).
929 : **/
930 : void
931 0 : cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue)
932 : {
933 : cairo_pattern_t *pattern;
934 :
935 0 : if (unlikely (cr->status))
936 0 : return;
937 :
938 0 : if (_current_source_matches_solid (cr, red, green, blue, 1.))
939 0 : return;
940 :
941 : /* push the current pattern to the freed lists */
942 0 : cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
943 :
944 0 : pattern = cairo_pattern_create_rgb (red, green, blue);
945 0 : cairo_set_source (cr, pattern);
946 0 : cairo_pattern_destroy (pattern);
947 : }
948 : slim_hidden_def (cairo_set_source_rgb);
949 :
950 : /**
951 : * cairo_set_source_rgba:
952 : * @cr: a cairo context
953 : * @red: red component of color
954 : * @green: green component of color
955 : * @blue: blue component of color
956 : * @alpha: alpha component of color
957 : *
958 : * Sets the source pattern within @cr to a translucent color. This
959 : * color will then be used for any subsequent drawing operation until
960 : * a new source pattern is set.
961 : *
962 : * The color and alpha components are floating point numbers in the
963 : * range 0 to 1. If the values passed in are outside that range, they
964 : * will be clamped.
965 : *
966 : * The default source pattern is opaque black, (that is, it is
967 : * equivalent to cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0)).
968 : **/
969 : void
970 0 : cairo_set_source_rgba (cairo_t *cr,
971 : double red, double green, double blue,
972 : double alpha)
973 : {
974 : cairo_pattern_t *pattern;
975 :
976 0 : if (unlikely (cr->status))
977 0 : return;
978 :
979 0 : if (_current_source_matches_solid (cr, red, green, blue, alpha))
980 0 : return;
981 :
982 : /* push the current pattern to the freed lists */
983 0 : cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
984 :
985 0 : pattern = cairo_pattern_create_rgba (red, green, blue, alpha);
986 0 : cairo_set_source (cr, pattern);
987 0 : cairo_pattern_destroy (pattern);
988 : }
989 :
990 : /**
991 : * cairo_set_source_surface:
992 : * @cr: a cairo context
993 : * @surface: a surface to be used to set the source pattern
994 : * @x: User-space X coordinate for surface origin
995 : * @y: User-space Y coordinate for surface origin
996 : *
997 : * This is a convenience function for creating a pattern from @surface
998 : * and setting it as the source in @cr with cairo_set_source().
999 : *
1000 : * The @x and @y parameters give the user-space coordinate at which
1001 : * the surface origin should appear. (The surface origin is its
1002 : * upper-left corner before any transformation has been applied.) The
1003 : * @x and @y parameters are negated and then set as translation values
1004 : * in the pattern matrix.
1005 : *
1006 : * Other than the initial translation pattern matrix, as described
1007 : * above, all other pattern attributes, (such as its extend mode), are
1008 : * set to the default values as in cairo_pattern_create_for_surface().
1009 : * The resulting pattern can be queried with cairo_get_source() so
1010 : * that these attributes can be modified if desired, (eg. to create a
1011 : * repeating pattern with cairo_pattern_set_extend()).
1012 : **/
1013 : void
1014 28 : cairo_set_source_surface (cairo_t *cr,
1015 : cairo_surface_t *surface,
1016 : double x,
1017 : double y)
1018 : {
1019 : cairo_pattern_t *pattern;
1020 : cairo_matrix_t matrix;
1021 :
1022 28 : if (unlikely (cr->status))
1023 0 : return;
1024 :
1025 : /* push the current pattern to the freed lists */
1026 28 : cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
1027 :
1028 28 : pattern = cairo_pattern_create_for_surface (surface);
1029 :
1030 28 : cairo_matrix_init_translate (&matrix, -x, -y);
1031 28 : cairo_pattern_set_matrix (pattern, &matrix);
1032 :
1033 28 : cairo_set_source (cr, pattern);
1034 28 : cairo_pattern_destroy (pattern);
1035 : }
1036 : slim_hidden_def (cairo_set_source_surface);
1037 :
1038 : /**
1039 : * cairo_set_source
1040 : * @cr: a cairo context
1041 : * @source: a #cairo_pattern_t to be used as the source for
1042 : * subsequent drawing operations.
1043 : *
1044 : * Sets the source pattern within @cr to @source. This pattern
1045 : * will then be used for any subsequent drawing operation until a new
1046 : * source pattern is set.
1047 : *
1048 : * Note: The pattern's transformation matrix will be locked to the
1049 : * user space in effect at the time of cairo_set_source(). This means
1050 : * that further modifications of the current transformation matrix
1051 : * will not affect the source pattern. See cairo_pattern_set_matrix().
1052 : *
1053 : * The default source pattern is a solid pattern that is opaque black,
1054 : * (that is, it is equivalent to cairo_set_source_rgb(cr, 0.0, 0.0,
1055 : * 0.0)).
1056 : **/
1057 : void
1058 75 : cairo_set_source (cairo_t *cr, cairo_pattern_t *source)
1059 : {
1060 : cairo_status_t status;
1061 :
1062 75 : if (unlikely (cr->status))
1063 0 : return;
1064 :
1065 75 : if (source == NULL) {
1066 0 : _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
1067 0 : return;
1068 : }
1069 :
1070 75 : if (source->status) {
1071 0 : _cairo_set_error (cr, source->status);
1072 0 : return;
1073 : }
1074 :
1075 75 : status = _cairo_gstate_set_source (cr->gstate, source);
1076 75 : if (unlikely (status))
1077 0 : _cairo_set_error (cr, status);
1078 : }
1079 : slim_hidden_def (cairo_set_source);
1080 :
1081 : /**
1082 : * cairo_get_source:
1083 : * @cr: a cairo context
1084 : *
1085 : * Gets the current source pattern for @cr.
1086 : *
1087 : * Return value: the current source pattern. This object is owned by
1088 : * cairo. To keep a reference to it, you must call
1089 : * cairo_pattern_reference().
1090 : **/
1091 : cairo_pattern_t *
1092 0 : cairo_get_source (cairo_t *cr)
1093 : {
1094 0 : if (unlikely (cr->status))
1095 0 : return _cairo_pattern_create_in_error (cr->status);
1096 :
1097 0 : return _cairo_gstate_get_source (cr->gstate);
1098 : }
1099 :
1100 : /**
1101 : * cairo_set_tolerance:
1102 : * @cr: a #cairo_t
1103 : * @tolerance: the tolerance, in device units (typically pixels)
1104 : *
1105 : * Sets the tolerance used when converting paths into trapezoids.
1106 : * Curved segments of the path will be subdivided until the maximum
1107 : * deviation between the original path and the polygonal approximation
1108 : * is less than @tolerance. The default value is 0.1. A larger
1109 : * value will give better performance, a smaller value, better
1110 : * appearance. (Reducing the value from the default value of 0.1
1111 : * is unlikely to improve appearance significantly.) The accuracy of paths
1112 : * within Cairo is limited by the precision of its internal arithmetic, and
1113 : * the prescribed @tolerance is restricted to the smallest
1114 : * representable internal value.
1115 : **/
1116 : void
1117 0 : cairo_set_tolerance (cairo_t *cr, double tolerance)
1118 : {
1119 : cairo_status_t status;
1120 :
1121 0 : if (unlikely (cr->status))
1122 0 : return;
1123 :
1124 0 : if (tolerance < CAIRO_TOLERANCE_MINIMUM)
1125 0 : tolerance = CAIRO_TOLERANCE_MINIMUM;
1126 :
1127 0 : status = _cairo_gstate_set_tolerance (cr->gstate, tolerance);
1128 0 : if (unlikely (status))
1129 0 : _cairo_set_error (cr, status);
1130 : }
1131 : slim_hidden_def (cairo_set_tolerance);
1132 :
1133 : /**
1134 : * cairo_set_antialias:
1135 : * @cr: a #cairo_t
1136 : * @antialias: the new antialiasing mode
1137 : *
1138 : * Set the antialiasing mode of the rasterizer used for drawing shapes.
1139 : * This value is a hint, and a particular backend may or may not support
1140 : * a particular value. At the current time, no backend supports
1141 : * %CAIRO_ANTIALIAS_SUBPIXEL when drawing shapes.
1142 : *
1143 : * Note that this option does not affect text rendering, instead see
1144 : * cairo_font_options_set_antialias().
1145 : **/
1146 : void
1147 0 : cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias)
1148 : {
1149 : cairo_status_t status;
1150 :
1151 0 : if (unlikely (cr->status))
1152 0 : return;
1153 :
1154 0 : status = _cairo_gstate_set_antialias (cr->gstate, antialias);
1155 0 : if (unlikely (status))
1156 0 : _cairo_set_error (cr, status);
1157 : }
1158 :
1159 : /**
1160 : * cairo_set_fill_rule:
1161 : * @cr: a #cairo_t
1162 : * @fill_rule: a fill rule, specified as a #cairo_fill_rule_t
1163 : *
1164 : * Set the current fill rule within the cairo context. The fill rule
1165 : * is used to determine which regions are inside or outside a complex
1166 : * (potentially self-intersecting) path. The current fill rule affects
1167 : * both cairo_fill() and cairo_clip(). See #cairo_fill_rule_t for details
1168 : * on the semantics of each available fill rule.
1169 : *
1170 : * The default fill rule is %CAIRO_FILL_RULE_WINDING.
1171 : **/
1172 : void
1173 0 : cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule)
1174 : {
1175 : cairo_status_t status;
1176 :
1177 0 : if (unlikely (cr->status))
1178 0 : return;
1179 :
1180 0 : status = _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
1181 0 : if (unlikely (status))
1182 0 : _cairo_set_error (cr, status);
1183 : }
1184 :
1185 : /**
1186 : * cairo_set_line_width:
1187 : * @cr: a #cairo_t
1188 : * @width: a line width
1189 : *
1190 : * Sets the current line width within the cairo context. The line
1191 : * width value specifies the diameter of a pen that is circular in
1192 : * user space, (though device-space pen may be an ellipse in general
1193 : * due to scaling/shear/rotation of the CTM).
1194 : *
1195 : * Note: When the description above refers to user space and CTM it
1196 : * refers to the user space and CTM in effect at the time of the
1197 : * stroking operation, not the user space and CTM in effect at the
1198 : * time of the call to cairo_set_line_width(). The simplest usage
1199 : * makes both of these spaces identical. That is, if there is no
1200 : * change to the CTM between a call to cairo_set_line_width() and the
1201 : * stroking operation, then one can just pass user-space values to
1202 : * cairo_set_line_width() and ignore this note.
1203 : *
1204 : * As with the other stroke parameters, the current line width is
1205 : * examined by cairo_stroke(), cairo_stroke_extents(), and
1206 : * cairo_stroke_to_path(), but does not have any effect during path
1207 : * construction.
1208 : *
1209 : * The default line width value is 2.0.
1210 : **/
1211 : void
1212 0 : cairo_set_line_width (cairo_t *cr, double width)
1213 : {
1214 : cairo_status_t status;
1215 :
1216 0 : if (unlikely (cr->status))
1217 0 : return;
1218 :
1219 0 : if (width < 0.)
1220 0 : width = 0.;
1221 :
1222 0 : status = _cairo_gstate_set_line_width (cr->gstate, width);
1223 0 : if (unlikely (status))
1224 0 : _cairo_set_error (cr, status);
1225 : }
1226 : slim_hidden_def (cairo_set_line_width);
1227 :
1228 : /**
1229 : * cairo_set_line_cap:
1230 : * @cr: a cairo context
1231 : * @line_cap: a line cap style
1232 : *
1233 : * Sets the current line cap style within the cairo context. See
1234 : * #cairo_line_cap_t for details about how the available line cap
1235 : * styles are drawn.
1236 : *
1237 : * As with the other stroke parameters, the current line cap style is
1238 : * examined by cairo_stroke(), cairo_stroke_extents(), and
1239 : * cairo_stroke_to_path(), but does not have any effect during path
1240 : * construction.
1241 : *
1242 : * The default line cap style is %CAIRO_LINE_CAP_BUTT.
1243 : **/
1244 : void
1245 0 : cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
1246 : {
1247 : cairo_status_t status;
1248 :
1249 0 : if (unlikely (cr->status))
1250 0 : return;
1251 :
1252 0 : status = _cairo_gstate_set_line_cap (cr->gstate, line_cap);
1253 0 : if (unlikely (status))
1254 0 : _cairo_set_error (cr, status);
1255 : }
1256 : slim_hidden_def (cairo_set_line_cap);
1257 :
1258 : /**
1259 : * cairo_set_line_join:
1260 : * @cr: a cairo context
1261 : * @line_join: a line join style
1262 : *
1263 : * Sets the current line join style within the cairo context. See
1264 : * #cairo_line_join_t for details about how the available line join
1265 : * styles are drawn.
1266 : *
1267 : * As with the other stroke parameters, the current line join style is
1268 : * examined by cairo_stroke(), cairo_stroke_extents(), and
1269 : * cairo_stroke_to_path(), but does not have any effect during path
1270 : * construction.
1271 : *
1272 : * The default line join style is %CAIRO_LINE_JOIN_MITER.
1273 : **/
1274 : void
1275 0 : cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
1276 : {
1277 : cairo_status_t status;
1278 :
1279 0 : if (unlikely (cr->status))
1280 0 : return;
1281 :
1282 0 : status = _cairo_gstate_set_line_join (cr->gstate, line_join);
1283 0 : if (unlikely (status))
1284 0 : _cairo_set_error (cr, status);
1285 : }
1286 : slim_hidden_def (cairo_set_line_join);
1287 :
1288 : /**
1289 : * cairo_set_dash:
1290 : * @cr: a cairo context
1291 : * @dashes: an array specifying alternate lengths of on and off stroke portions
1292 : * @num_dashes: the length of the dashes array
1293 : * @offset: an offset into the dash pattern at which the stroke should start
1294 : *
1295 : * Sets the dash pattern to be used by cairo_stroke(). A dash pattern
1296 : * is specified by @dashes, an array of positive values. Each value
1297 : * provides the length of alternate "on" and "off" portions of the
1298 : * stroke. The @offset specifies an offset into the pattern at which
1299 : * the stroke begins.
1300 : *
1301 : * Each "on" segment will have caps applied as if the segment were a
1302 : * separate sub-path. In particular, it is valid to use an "on" length
1303 : * of 0.0 with %CAIRO_LINE_CAP_ROUND or %CAIRO_LINE_CAP_SQUARE in order
1304 : * to distributed dots or squares along a path.
1305 : *
1306 : * Note: The length values are in user-space units as evaluated at the
1307 : * time of stroking. This is not necessarily the same as the user
1308 : * space at the time of cairo_set_dash().
1309 : *
1310 : * If @num_dashes is 0 dashing is disabled.
1311 : *
1312 : * If @num_dashes is 1 a symmetric pattern is assumed with alternating
1313 : * on and off portions of the size specified by the single value in
1314 : * @dashes.
1315 : *
1316 : * If any value in @dashes is negative, or if all values are 0, then
1317 : * @cr will be put into an error state with a status of
1318 : * %CAIRO_STATUS_INVALID_DASH.
1319 : **/
1320 : void
1321 0 : cairo_set_dash (cairo_t *cr,
1322 : const double *dashes,
1323 : int num_dashes,
1324 : double offset)
1325 : {
1326 : cairo_status_t status;
1327 :
1328 0 : if (unlikely (cr->status))
1329 0 : return;
1330 :
1331 0 : status = _cairo_gstate_set_dash (cr->gstate,
1332 : dashes, num_dashes, offset);
1333 0 : if (unlikely (status))
1334 0 : _cairo_set_error (cr, status);
1335 : }
1336 :
1337 : /**
1338 : * cairo_get_dash_count:
1339 : * @cr: a #cairo_t
1340 : *
1341 : * This function returns the length of the dash array in @cr (0 if dashing
1342 : * is not currently in effect).
1343 : *
1344 : * See also cairo_set_dash() and cairo_get_dash().
1345 : *
1346 : * Return value: the length of the dash array, or 0 if no dash array set.
1347 : *
1348 : * Since: 1.4
1349 : */
1350 : int
1351 0 : cairo_get_dash_count (cairo_t *cr)
1352 : {
1353 : int num_dashes;
1354 :
1355 0 : if (unlikely (cr->status))
1356 0 : return 0;
1357 :
1358 0 : _cairo_gstate_get_dash (cr->gstate, NULL, &num_dashes, NULL);
1359 :
1360 0 : return num_dashes;
1361 : }
1362 :
1363 : /**
1364 : * cairo_get_dash:
1365 : * @cr: a #cairo_t
1366 : * @dashes: return value for the dash array, or %NULL
1367 : * @offset: return value for the current dash offset, or %NULL
1368 : *
1369 : * Gets the current dash array. If not %NULL, @dashes should be big
1370 : * enough to hold at least the number of values returned by
1371 : * cairo_get_dash_count().
1372 : *
1373 : * Since: 1.4
1374 : **/
1375 : void
1376 0 : cairo_get_dash (cairo_t *cr,
1377 : double *dashes,
1378 : double *offset)
1379 : {
1380 0 : if (unlikely (cr->status))
1381 0 : return;
1382 :
1383 0 : _cairo_gstate_get_dash (cr->gstate, dashes, NULL, offset);
1384 : }
1385 :
1386 : /**
1387 : * cairo_set_miter_limit:
1388 : * @cr: a cairo context
1389 : * @limit: miter limit to set
1390 : *
1391 : * Sets the current miter limit within the cairo context.
1392 : *
1393 : * If the current line join style is set to %CAIRO_LINE_JOIN_MITER
1394 : * (see cairo_set_line_join()), the miter limit is used to determine
1395 : * whether the lines should be joined with a bevel instead of a miter.
1396 : * Cairo divides the length of the miter by the line width.
1397 : * If the result is greater than the miter limit, the style is
1398 : * converted to a bevel.
1399 : *
1400 : * As with the other stroke parameters, the current line miter limit is
1401 : * examined by cairo_stroke(), cairo_stroke_extents(), and
1402 : * cairo_stroke_to_path(), but does not have any effect during path
1403 : * construction.
1404 : *
1405 : * The default miter limit value is 10.0, which will convert joins
1406 : * with interior angles less than 11 degrees to bevels instead of
1407 : * miters. For reference, a miter limit of 2.0 makes the miter cutoff
1408 : * at 60 degrees, and a miter limit of 1.414 makes the cutoff at 90
1409 : * degrees.
1410 : *
1411 : * A miter limit for a desired angle can be computed as: miter limit =
1412 : * 1/sin(angle/2)
1413 : **/
1414 : void
1415 0 : cairo_set_miter_limit (cairo_t *cr, double limit)
1416 : {
1417 : cairo_status_t status;
1418 :
1419 0 : if (unlikely (cr->status))
1420 0 : return;
1421 :
1422 0 : status = _cairo_gstate_set_miter_limit (cr->gstate, limit);
1423 0 : if (unlikely (status))
1424 0 : _cairo_set_error (cr, status);
1425 : }
1426 :
1427 : /**
1428 : * cairo_translate:
1429 : * @cr: a cairo context
1430 : * @tx: amount to translate in the X direction
1431 : * @ty: amount to translate in the Y direction
1432 : *
1433 : * Modifies the current transformation matrix (CTM) by translating the
1434 : * user-space origin by (@tx, @ty). This offset is interpreted as a
1435 : * user-space coordinate according to the CTM in place before the new
1436 : * call to cairo_translate(). In other words, the translation of the
1437 : * user-space origin takes place after any existing transformation.
1438 : **/
1439 : void
1440 19 : cairo_translate (cairo_t *cr, double tx, double ty)
1441 : {
1442 : cairo_status_t status;
1443 :
1444 19 : if (unlikely (cr->status))
1445 0 : return;
1446 :
1447 19 : status = _cairo_gstate_translate (cr->gstate, tx, ty);
1448 19 : if (unlikely (status))
1449 0 : _cairo_set_error (cr, status);
1450 : }
1451 : slim_hidden_def (cairo_translate);
1452 :
1453 : /**
1454 : * cairo_scale:
1455 : * @cr: a cairo context
1456 : * @sx: scale factor for the X dimension
1457 : * @sy: scale factor for the Y dimension
1458 : *
1459 : * Modifies the current transformation matrix (CTM) by scaling the X
1460 : * and Y user-space axes by @sx and @sy respectively. The scaling of
1461 : * the axes takes place after any existing transformation of user
1462 : * space.
1463 : **/
1464 : void
1465 12 : cairo_scale (cairo_t *cr, double sx, double sy)
1466 : {
1467 : cairo_status_t status;
1468 :
1469 12 : if (unlikely (cr->status))
1470 0 : return;
1471 :
1472 12 : status = _cairo_gstate_scale (cr->gstate, sx, sy);
1473 12 : if (unlikely (status))
1474 0 : _cairo_set_error (cr, status);
1475 : }
1476 : slim_hidden_def (cairo_scale);
1477 :
1478 : /**
1479 : * cairo_rotate:
1480 : * @cr: a cairo context
1481 : * @angle: angle (in radians) by which the user-space axes will be
1482 : * rotated
1483 : *
1484 : * Modifies the current transformation matrix (CTM) by rotating the
1485 : * user-space axes by @angle radians. The rotation of the axes takes
1486 : * places after any existing transformation of user space. The
1487 : * rotation direction for positive angles is from the positive X axis
1488 : * toward the positive Y axis.
1489 : **/
1490 : void
1491 0 : cairo_rotate (cairo_t *cr, double angle)
1492 : {
1493 : cairo_status_t status;
1494 :
1495 0 : if (unlikely (cr->status))
1496 0 : return;
1497 :
1498 0 : status = _cairo_gstate_rotate (cr->gstate, angle);
1499 0 : if (unlikely (status))
1500 0 : _cairo_set_error (cr, status);
1501 : }
1502 :
1503 : /**
1504 : * cairo_transform:
1505 : * @cr: a cairo context
1506 : * @matrix: a transformation to be applied to the user-space axes
1507 : *
1508 : * Modifies the current transformation matrix (CTM) by applying
1509 : * @matrix as an additional transformation. The new transformation of
1510 : * user space takes place after any existing transformation.
1511 : **/
1512 : void
1513 0 : cairo_transform (cairo_t *cr,
1514 : const cairo_matrix_t *matrix)
1515 : {
1516 : cairo_status_t status;
1517 :
1518 0 : if (unlikely (cr->status))
1519 0 : return;
1520 :
1521 0 : status = _cairo_gstate_transform (cr->gstate, matrix);
1522 0 : if (unlikely (status))
1523 0 : _cairo_set_error (cr, status);
1524 : }
1525 : slim_hidden_def (cairo_transform);
1526 :
1527 : /**
1528 : * cairo_set_matrix:
1529 : * @cr: a cairo context
1530 : * @matrix: a transformation matrix from user space to device space
1531 : *
1532 : * Modifies the current transformation matrix (CTM) by setting it
1533 : * equal to @matrix.
1534 : **/
1535 : void
1536 0 : cairo_set_matrix (cairo_t *cr,
1537 : const cairo_matrix_t *matrix)
1538 : {
1539 : cairo_status_t status;
1540 :
1541 0 : if (unlikely (cr->status))
1542 0 : return;
1543 :
1544 0 : status = _cairo_gstate_set_matrix (cr->gstate, matrix);
1545 0 : if (unlikely (status))
1546 0 : _cairo_set_error (cr, status);
1547 : }
1548 : slim_hidden_def (cairo_set_matrix);
1549 :
1550 : /**
1551 : * cairo_identity_matrix:
1552 : * @cr: a cairo context
1553 : *
1554 : * Resets the current transformation matrix (CTM) by setting it equal
1555 : * to the identity matrix. That is, the user-space and device-space
1556 : * axes will be aligned and one user-space unit will transform to one
1557 : * device-space unit.
1558 : **/
1559 : void
1560 0 : cairo_identity_matrix (cairo_t *cr)
1561 : {
1562 0 : if (unlikely (cr->status))
1563 0 : return;
1564 :
1565 0 : _cairo_gstate_identity_matrix (cr->gstate);
1566 : }
1567 :
1568 : /**
1569 : * cairo_user_to_device:
1570 : * @cr: a cairo context
1571 : * @x: X value of coordinate (in/out parameter)
1572 : * @y: Y value of coordinate (in/out parameter)
1573 : *
1574 : * Transform a coordinate from user space to device space by
1575 : * multiplying the given point by the current transformation matrix
1576 : * (CTM).
1577 : **/
1578 : void
1579 0 : cairo_user_to_device (cairo_t *cr, double *x, double *y)
1580 : {
1581 0 : if (unlikely (cr->status))
1582 0 : return;
1583 :
1584 0 : _cairo_gstate_user_to_device (cr->gstate, x, y);
1585 : }
1586 : slim_hidden_def (cairo_user_to_device);
1587 :
1588 : /**
1589 : * cairo_user_to_device_distance:
1590 : * @cr: a cairo context
1591 : * @dx: X component of a distance vector (in/out parameter)
1592 : * @dy: Y component of a distance vector (in/out parameter)
1593 : *
1594 : * Transform a distance vector from user space to device space. This
1595 : * function is similar to cairo_user_to_device() except that the
1596 : * translation components of the CTM will be ignored when transforming
1597 : * (@dx,@dy).
1598 : **/
1599 : void
1600 0 : cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy)
1601 : {
1602 0 : if (unlikely (cr->status))
1603 0 : return;
1604 :
1605 0 : _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
1606 : }
1607 : slim_hidden_def (cairo_user_to_device_distance);
1608 :
1609 : /**
1610 : * cairo_device_to_user:
1611 : * @cr: a cairo
1612 : * @x: X value of coordinate (in/out parameter)
1613 : * @y: Y value of coordinate (in/out parameter)
1614 : *
1615 : * Transform a coordinate from device space to user space by
1616 : * multiplying the given point by the inverse of the current
1617 : * transformation matrix (CTM).
1618 : **/
1619 : void
1620 0 : cairo_device_to_user (cairo_t *cr, double *x, double *y)
1621 : {
1622 0 : if (unlikely (cr->status))
1623 0 : return;
1624 :
1625 0 : _cairo_gstate_device_to_user (cr->gstate, x, y);
1626 : }
1627 :
1628 : /**
1629 : * cairo_device_to_user_distance:
1630 : * @cr: a cairo context
1631 : * @dx: X component of a distance vector (in/out parameter)
1632 : * @dy: Y component of a distance vector (in/out parameter)
1633 : *
1634 : * Transform a distance vector from device space to user space. This
1635 : * function is similar to cairo_device_to_user() except that the
1636 : * translation components of the inverse CTM will be ignored when
1637 : * transforming (@dx,@dy).
1638 : **/
1639 : void
1640 0 : cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy)
1641 : {
1642 0 : if (unlikely (cr->status))
1643 0 : return;
1644 :
1645 0 : _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
1646 : }
1647 :
1648 : /**
1649 : * cairo_new_path:
1650 : * @cr: a cairo context
1651 : *
1652 : * Clears the current path. After this call there will be no path and
1653 : * no current point.
1654 : **/
1655 : void
1656 0 : cairo_new_path (cairo_t *cr)
1657 : {
1658 0 : if (unlikely (cr->status))
1659 0 : return;
1660 :
1661 0 : _cairo_path_fixed_fini (cr->path);
1662 0 : _cairo_path_fixed_init (cr->path);
1663 : }
1664 : slim_hidden_def(cairo_new_path);
1665 :
1666 : /**
1667 : * cairo_move_to:
1668 : * @cr: a cairo context
1669 : * @x: the X coordinate of the new position
1670 : * @y: the Y coordinate of the new position
1671 : *
1672 : * Begin a new sub-path. After this call the current point will be (@x,
1673 : * @y).
1674 : **/
1675 : void
1676 21 : cairo_move_to (cairo_t *cr, double x, double y)
1677 : {
1678 : cairo_status_t status;
1679 : cairo_fixed_t x_fixed, y_fixed;
1680 :
1681 21 : if (unlikely (cr->status))
1682 0 : return;
1683 :
1684 21 : _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
1685 21 : x_fixed = _cairo_fixed_from_double (x);
1686 21 : y_fixed = _cairo_fixed_from_double (y);
1687 :
1688 21 : status = _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed);
1689 21 : if (unlikely (status))
1690 0 : _cairo_set_error (cr, status);
1691 : }
1692 : slim_hidden_def(cairo_move_to);
1693 :
1694 : /**
1695 : * cairo_new_sub_path:
1696 : * @cr: a cairo context
1697 : *
1698 : * Begin a new sub-path. Note that the existing path is not
1699 : * affected. After this call there will be no current point.
1700 : *
1701 : * In many cases, this call is not needed since new sub-paths are
1702 : * frequently started with cairo_move_to().
1703 : *
1704 : * A call to cairo_new_sub_path() is particularly useful when
1705 : * beginning a new sub-path with one of the cairo_arc() calls. This
1706 : * makes things easier as it is no longer necessary to manually
1707 : * compute the arc's initial coordinates for a call to
1708 : * cairo_move_to().
1709 : *
1710 : * Since: 1.2
1711 : **/
1712 : void
1713 0 : cairo_new_sub_path (cairo_t *cr)
1714 : {
1715 0 : if (unlikely (cr->status))
1716 0 : return;
1717 :
1718 0 : _cairo_path_fixed_new_sub_path (cr->path);
1719 : }
1720 :
1721 : /**
1722 : * cairo_line_to:
1723 : * @cr: a cairo context
1724 : * @x: the X coordinate of the end of the new line
1725 : * @y: the Y coordinate of the end of the new line
1726 : *
1727 : * Adds a line to the path from the current point to position (@x, @y)
1728 : * in user-space coordinates. After this call the current point
1729 : * will be (@x, @y).
1730 : *
1731 : * If there is no current point before the call to cairo_line_to()
1732 : * this function will behave as cairo_move_to(@cr, @x, @y).
1733 : **/
1734 : void
1735 0 : cairo_line_to (cairo_t *cr, double x, double y)
1736 : {
1737 : cairo_status_t status;
1738 : cairo_fixed_t x_fixed, y_fixed;
1739 :
1740 0 : if (unlikely (cr->status))
1741 0 : return;
1742 :
1743 0 : _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
1744 0 : x_fixed = _cairo_fixed_from_double (x);
1745 0 : y_fixed = _cairo_fixed_from_double (y);
1746 :
1747 0 : status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
1748 0 : if (unlikely (status))
1749 0 : _cairo_set_error (cr, status);
1750 : }
1751 : slim_hidden_def (cairo_line_to);
1752 :
1753 : /**
1754 : * cairo_curve_to:
1755 : * @cr: a cairo context
1756 : * @x1: the X coordinate of the first control point
1757 : * @y1: the Y coordinate of the first control point
1758 : * @x2: the X coordinate of the second control point
1759 : * @y2: the Y coordinate of the second control point
1760 : * @x3: the X coordinate of the end of the curve
1761 : * @y3: the Y coordinate of the end of the curve
1762 : *
1763 : * Adds a cubic Bézier spline to the path from the current point to
1764 : * position (@x3, @y3) in user-space coordinates, using (@x1, @y1) and
1765 : * (@x2, @y2) as the control points. After this call the current point
1766 : * will be (@x3, @y3).
1767 : *
1768 : * If there is no current point before the call to cairo_curve_to()
1769 : * this function will behave as if preceded by a call to
1770 : * cairo_move_to(@cr, @x1, @y1).
1771 : **/
1772 : void
1773 0 : cairo_curve_to (cairo_t *cr,
1774 : double x1, double y1,
1775 : double x2, double y2,
1776 : double x3, double y3)
1777 : {
1778 : cairo_status_t status;
1779 : cairo_fixed_t x1_fixed, y1_fixed;
1780 : cairo_fixed_t x2_fixed, y2_fixed;
1781 : cairo_fixed_t x3_fixed, y3_fixed;
1782 :
1783 0 : if (unlikely (cr->status))
1784 0 : return;
1785 :
1786 0 : _cairo_gstate_user_to_backend (cr->gstate, &x1, &y1);
1787 0 : _cairo_gstate_user_to_backend (cr->gstate, &x2, &y2);
1788 0 : _cairo_gstate_user_to_backend (cr->gstate, &x3, &y3);
1789 :
1790 0 : x1_fixed = _cairo_fixed_from_double (x1);
1791 0 : y1_fixed = _cairo_fixed_from_double (y1);
1792 :
1793 0 : x2_fixed = _cairo_fixed_from_double (x2);
1794 0 : y2_fixed = _cairo_fixed_from_double (y2);
1795 :
1796 0 : x3_fixed = _cairo_fixed_from_double (x3);
1797 0 : y3_fixed = _cairo_fixed_from_double (y3);
1798 :
1799 0 : status = _cairo_path_fixed_curve_to (cr->path,
1800 : x1_fixed, y1_fixed,
1801 : x2_fixed, y2_fixed,
1802 : x3_fixed, y3_fixed);
1803 0 : if (unlikely (status))
1804 0 : _cairo_set_error (cr, status);
1805 : }
1806 : slim_hidden_def (cairo_curve_to);
1807 :
1808 : /**
1809 : * cairo_arc:
1810 : * @cr: a cairo context
1811 : * @xc: X position of the center of the arc
1812 : * @yc: Y position of the center of the arc
1813 : * @radius: the radius of the arc
1814 : * @angle1: the start angle, in radians
1815 : * @angle2: the end angle, in radians
1816 : *
1817 : * Adds a circular arc of the given @radius to the current path. The
1818 : * arc is centered at (@xc, @yc), begins at @angle1 and proceeds in
1819 : * the direction of increasing angles to end at @angle2. If @angle2 is
1820 : * less than @angle1 it will be progressively increased by 2*M_PI
1821 : * until it is greater than @angle1.
1822 : *
1823 : * If there is a current point, an initial line segment will be added
1824 : * to the path to connect the current point to the beginning of the
1825 : * arc. If this initial line is undesired, it can be avoided by
1826 : * calling cairo_new_sub_path() before calling cairo_arc().
1827 : *
1828 : * Angles are measured in radians. An angle of 0.0 is in the direction
1829 : * of the positive X axis (in user space). An angle of %M_PI/2.0 radians
1830 : * (90 degrees) is in the direction of the positive Y axis (in
1831 : * user space). Angles increase in the direction from the positive X
1832 : * axis toward the positive Y axis. So with the default transformation
1833 : * matrix, angles increase in a clockwise direction.
1834 : *
1835 : * (To convert from degrees to radians, use <literal>degrees * (M_PI /
1836 : * 180.)</literal>.)
1837 : *
1838 : * This function gives the arc in the direction of increasing angles;
1839 : * see cairo_arc_negative() to get the arc in the direction of
1840 : * decreasing angles.
1841 : *
1842 : * The arc is circular in user space. To achieve an elliptical arc,
1843 : * you can scale the current transformation matrix by different
1844 : * amounts in the X and Y directions. For example, to draw an ellipse
1845 : * in the box given by @x, @y, @width, @height:
1846 : *
1847 : * <informalexample><programlisting>
1848 : * cairo_save (cr);
1849 : * cairo_translate (cr, x + width / 2., y + height / 2.);
1850 : * cairo_scale (cr, width / 2., height / 2.);
1851 : * cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI);
1852 : * cairo_restore (cr);
1853 : * </programlisting></informalexample>
1854 : **/
1855 : void
1856 0 : cairo_arc (cairo_t *cr,
1857 : double xc, double yc,
1858 : double radius,
1859 : double angle1, double angle2)
1860 : {
1861 0 : if (unlikely (cr->status))
1862 0 : return;
1863 :
1864 : /* Do nothing, successfully, if radius is <= 0 */
1865 0 : if (radius <= 0.0) {
1866 0 : cairo_line_to (cr, xc, yc);
1867 0 : return;
1868 : }
1869 :
1870 0 : while (angle2 < angle1)
1871 0 : angle2 += 2 * M_PI;
1872 :
1873 0 : cairo_line_to (cr,
1874 0 : xc + radius * cos (angle1),
1875 0 : yc + radius * sin (angle1));
1876 :
1877 0 : _cairo_arc_path (cr, xc, yc, radius,
1878 : angle1, angle2);
1879 : }
1880 :
1881 : /**
1882 : * cairo_arc_negative:
1883 : * @cr: a cairo context
1884 : * @xc: X position of the center of the arc
1885 : * @yc: Y position of the center of the arc
1886 : * @radius: the radius of the arc
1887 : * @angle1: the start angle, in radians
1888 : * @angle2: the end angle, in radians
1889 : *
1890 : * Adds a circular arc of the given @radius to the current path. The
1891 : * arc is centered at (@xc, @yc), begins at @angle1 and proceeds in
1892 : * the direction of decreasing angles to end at @angle2. If @angle2 is
1893 : * greater than @angle1 it will be progressively decreased by 2*M_PI
1894 : * until it is less than @angle1.
1895 : *
1896 : * See cairo_arc() for more details. This function differs only in the
1897 : * direction of the arc between the two angles.
1898 : **/
1899 : void
1900 0 : cairo_arc_negative (cairo_t *cr,
1901 : double xc, double yc,
1902 : double radius,
1903 : double angle1, double angle2)
1904 : {
1905 0 : if (unlikely (cr->status))
1906 0 : return;
1907 :
1908 : /* Do nothing, successfully, if radius is <= 0 */
1909 0 : if (radius <= 0.0)
1910 0 : return;
1911 :
1912 0 : while (angle2 > angle1)
1913 0 : angle2 -= 2 * M_PI;
1914 :
1915 0 : cairo_line_to (cr,
1916 0 : xc + radius * cos (angle1),
1917 0 : yc + radius * sin (angle1));
1918 :
1919 0 : _cairo_arc_path_negative (cr, xc, yc, radius,
1920 : angle1, angle2);
1921 : }
1922 :
1923 : /* XXX: NYI
1924 : void
1925 : cairo_arc_to (cairo_t *cr,
1926 : double x1, double y1,
1927 : double x2, double y2,
1928 : double radius)
1929 : {
1930 : cairo_status_t status;
1931 :
1932 : if (unlikely (cr->status))
1933 : return;
1934 :
1935 : status = _cairo_gstate_arc_to (cr->gstate,
1936 : x1, y1,
1937 : x2, y2,
1938 : radius);
1939 : if (unlikely (status))
1940 : _cairo_set_error (cr, status);
1941 : }
1942 : */
1943 :
1944 : /**
1945 : * cairo_rel_move_to:
1946 : * @cr: a cairo context
1947 : * @dx: the X offset
1948 : * @dy: the Y offset
1949 : *
1950 : * Begin a new sub-path. After this call the current point will offset
1951 : * by (@x, @y).
1952 : *
1953 : * Given a current point of (x, y), cairo_rel_move_to(@cr, @dx, @dy)
1954 : * is logically equivalent to cairo_move_to(@cr, x + @dx, y + @dy).
1955 : *
1956 : * It is an error to call this function with no current point. Doing
1957 : * so will cause @cr to shutdown with a status of
1958 : * %CAIRO_STATUS_NO_CURRENT_POINT.
1959 : **/
1960 : void
1961 0 : cairo_rel_move_to (cairo_t *cr, double dx, double dy)
1962 : {
1963 : cairo_fixed_t dx_fixed, dy_fixed;
1964 : cairo_status_t status;
1965 :
1966 0 : if (unlikely (cr->status))
1967 0 : return;
1968 :
1969 0 : _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
1970 :
1971 0 : dx_fixed = _cairo_fixed_from_double (dx);
1972 0 : dy_fixed = _cairo_fixed_from_double (dy);
1973 :
1974 0 : status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
1975 0 : if (unlikely (status))
1976 0 : _cairo_set_error (cr, status);
1977 : }
1978 :
1979 : /**
1980 : * cairo_rel_line_to:
1981 : * @cr: a cairo context
1982 : * @dx: the X offset to the end of the new line
1983 : * @dy: the Y offset to the end of the new line
1984 : *
1985 : * Relative-coordinate version of cairo_line_to(). Adds a line to the
1986 : * path from the current point to a point that is offset from the
1987 : * current point by (@dx, @dy) in user space. After this call the
1988 : * current point will be offset by (@dx, @dy).
1989 : *
1990 : * Given a current point of (x, y), cairo_rel_line_to(@cr, @dx, @dy)
1991 : * is logically equivalent to cairo_line_to(@cr, x + @dx, y + @dy).
1992 : *
1993 : * It is an error to call this function with no current point. Doing
1994 : * so will cause @cr to shutdown with a status of
1995 : * %CAIRO_STATUS_NO_CURRENT_POINT.
1996 : **/
1997 : void
1998 63 : cairo_rel_line_to (cairo_t *cr, double dx, double dy)
1999 : {
2000 : cairo_fixed_t dx_fixed, dy_fixed;
2001 : cairo_status_t status;
2002 :
2003 63 : if (unlikely (cr->status))
2004 0 : return;
2005 :
2006 63 : _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
2007 :
2008 63 : dx_fixed = _cairo_fixed_from_double (dx);
2009 63 : dy_fixed = _cairo_fixed_from_double (dy);
2010 :
2011 63 : status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
2012 63 : if (unlikely (status))
2013 0 : _cairo_set_error (cr, status);
2014 : }
2015 : slim_hidden_def(cairo_rel_line_to);
2016 :
2017 : /**
2018 : * cairo_rel_curve_to:
2019 : * @cr: a cairo context
2020 : * @dx1: the X offset to the first control point
2021 : * @dy1: the Y offset to the first control point
2022 : * @dx2: the X offset to the second control point
2023 : * @dy2: the Y offset to the second control point
2024 : * @dx3: the X offset to the end of the curve
2025 : * @dy3: the Y offset to the end of the curve
2026 : *
2027 : * Relative-coordinate version of cairo_curve_to(). All offsets are
2028 : * relative to the current point. Adds a cubic Bézier spline to the
2029 : * path from the current point to a point offset from the current
2030 : * point by (@dx3, @dy3), using points offset by (@dx1, @dy1) and
2031 : * (@dx2, @dy2) as the control points. After this call the current
2032 : * point will be offset by (@dx3, @dy3).
2033 : *
2034 : * Given a current point of (x, y), cairo_rel_curve_to(@cr, @dx1,
2035 : * @dy1, @dx2, @dy2, @dx3, @dy3) is logically equivalent to
2036 : * cairo_curve_to(@cr, x+@dx1, y+@dy1, x+@dx2, y+@dy2, x+@dx3, y+@dy3).
2037 : *
2038 : * It is an error to call this function with no current point. Doing
2039 : * so will cause @cr to shutdown with a status of
2040 : * %CAIRO_STATUS_NO_CURRENT_POINT.
2041 : **/
2042 : void
2043 0 : cairo_rel_curve_to (cairo_t *cr,
2044 : double dx1, double dy1,
2045 : double dx2, double dy2,
2046 : double dx3, double dy3)
2047 : {
2048 : cairo_fixed_t dx1_fixed, dy1_fixed;
2049 : cairo_fixed_t dx2_fixed, dy2_fixed;
2050 : cairo_fixed_t dx3_fixed, dy3_fixed;
2051 : cairo_status_t status;
2052 :
2053 0 : if (unlikely (cr->status))
2054 0 : return;
2055 :
2056 0 : _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1);
2057 0 : _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2);
2058 0 : _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3);
2059 :
2060 0 : dx1_fixed = _cairo_fixed_from_double (dx1);
2061 0 : dy1_fixed = _cairo_fixed_from_double (dy1);
2062 :
2063 0 : dx2_fixed = _cairo_fixed_from_double (dx2);
2064 0 : dy2_fixed = _cairo_fixed_from_double (dy2);
2065 :
2066 0 : dx3_fixed = _cairo_fixed_from_double (dx3);
2067 0 : dy3_fixed = _cairo_fixed_from_double (dy3);
2068 :
2069 0 : status = _cairo_path_fixed_rel_curve_to (cr->path,
2070 : dx1_fixed, dy1_fixed,
2071 : dx2_fixed, dy2_fixed,
2072 : dx3_fixed, dy3_fixed);
2073 0 : if (unlikely (status))
2074 0 : _cairo_set_error (cr, status);
2075 : }
2076 :
2077 : /**
2078 : * cairo_rectangle:
2079 : * @cr: a cairo context
2080 : * @x: the X coordinate of the top left corner of the rectangle
2081 : * @y: the Y coordinate to the top left corner of the rectangle
2082 : * @width: the width of the rectangle
2083 : * @height: the height of the rectangle
2084 : *
2085 : * Adds a closed sub-path rectangle of the given size to the current
2086 : * path at position (@x, @y) in user-space coordinates.
2087 : *
2088 : * This function is logically equivalent to:
2089 : * <informalexample><programlisting>
2090 : * cairo_move_to (cr, x, y);
2091 : * cairo_rel_line_to (cr, width, 0);
2092 : * cairo_rel_line_to (cr, 0, height);
2093 : * cairo_rel_line_to (cr, -width, 0);
2094 : * cairo_close_path (cr);
2095 : * </programlisting></informalexample>
2096 : **/
2097 : void
2098 21 : cairo_rectangle (cairo_t *cr,
2099 : double x, double y,
2100 : double width, double height)
2101 : {
2102 21 : if (unlikely (cr->status))
2103 0 : return;
2104 :
2105 21 : cairo_move_to (cr, x, y);
2106 21 : cairo_rel_line_to (cr, width, 0);
2107 21 : cairo_rel_line_to (cr, 0, height);
2108 21 : cairo_rel_line_to (cr, -width, 0);
2109 21 : cairo_close_path (cr);
2110 : }
2111 :
2112 : #if 0
2113 : /* XXX: NYI */
2114 : void
2115 : cairo_stroke_to_path (cairo_t *cr)
2116 : {
2117 : cairo_status_t status;
2118 :
2119 : if (unlikely (cr->status))
2120 : return;
2121 :
2122 : /* The code in _cairo_recording_surface_get_path has a poorman's stroke_to_path */
2123 :
2124 : status = _cairo_gstate_stroke_path (cr->gstate);
2125 : if (unlikely (status))
2126 : _cairo_set_error (cr, status);
2127 : }
2128 : #endif
2129 :
2130 : /**
2131 : * cairo_close_path:
2132 : * @cr: a cairo context
2133 : *
2134 : * Adds a line segment to the path from the current point to the
2135 : * beginning of the current sub-path, (the most recent point passed to
2136 : * cairo_move_to()), and closes this sub-path. After this call the
2137 : * current point will be at the joined endpoint of the sub-path.
2138 : *
2139 : * The behavior of cairo_close_path() is distinct from simply calling
2140 : * cairo_line_to() with the equivalent coordinate in the case of
2141 : * stroking. When a closed sub-path is stroked, there are no caps on
2142 : * the ends of the sub-path. Instead, there is a line join connecting
2143 : * the final and initial segments of the sub-path.
2144 : *
2145 : * If there is no current point before the call to cairo_close_path(),
2146 : * this function will have no effect.
2147 : *
2148 : * Note: As of cairo version 1.2.4 any call to cairo_close_path() will
2149 : * place an explicit MOVE_TO element into the path immediately after
2150 : * the CLOSE_PATH element, (which can be seen in cairo_copy_path() for
2151 : * example). This can simplify path processing in some cases as it may
2152 : * not be necessary to save the "last move_to point" during processing
2153 : * as the MOVE_TO immediately after the CLOSE_PATH will provide that
2154 : * point.
2155 : **/
2156 : void
2157 21 : cairo_close_path (cairo_t *cr)
2158 : {
2159 : cairo_status_t status;
2160 :
2161 21 : if (unlikely (cr->status))
2162 0 : return;
2163 :
2164 21 : status = _cairo_path_fixed_close_path (cr->path);
2165 21 : if (unlikely (status))
2166 0 : _cairo_set_error (cr, status);
2167 : }
2168 : slim_hidden_def(cairo_close_path);
2169 :
2170 : /**
2171 : * cairo_path_extents:
2172 : * @cr: a cairo context
2173 : * @x1: left of the resulting extents
2174 : * @y1: top of the resulting extents
2175 : * @x2: right of the resulting extents
2176 : * @y2: bottom of the resulting extents
2177 : *
2178 : * Computes a bounding box in user-space coordinates covering the
2179 : * points on the current path. If the current path is empty, returns
2180 : * an empty rectangle ((0,0), (0,0)). Stroke parameters, fill rule,
2181 : * surface dimensions and clipping are not taken into account.
2182 : *
2183 : * Contrast with cairo_fill_extents() and cairo_stroke_extents() which
2184 : * return the extents of only the area that would be "inked" by
2185 : * the corresponding drawing operations.
2186 : *
2187 : * The result of cairo_path_extents() is defined as equivalent to the
2188 : * limit of cairo_stroke_extents() with %CAIRO_LINE_CAP_ROUND as the
2189 : * line width approaches 0.0, (but never reaching the empty-rectangle
2190 : * returned by cairo_stroke_extents() for a line width of 0.0).
2191 : *
2192 : * Specifically, this means that zero-area sub-paths such as
2193 : * cairo_move_to();cairo_line_to() segments, (even degenerate cases
2194 : * where the coordinates to both calls are identical), will be
2195 : * considered as contributing to the extents. However, a lone
2196 : * cairo_move_to() will not contribute to the results of
2197 : * cairo_path_extents().
2198 : *
2199 : * Since: 1.6
2200 : **/
2201 : void
2202 0 : cairo_path_extents (cairo_t *cr,
2203 : double *x1, double *y1, double *x2, double *y2)
2204 : {
2205 0 : if (unlikely (cr->status)) {
2206 0 : if (x1)
2207 0 : *x1 = 0.0;
2208 0 : if (y1)
2209 0 : *y1 = 0.0;
2210 0 : if (x2)
2211 0 : *x2 = 0.0;
2212 0 : if (y2)
2213 0 : *y2 = 0.0;
2214 :
2215 0 : return;
2216 : }
2217 :
2218 0 : _cairo_gstate_path_extents (cr->gstate,
2219 : cr->path,
2220 : x1, y1, x2, y2);
2221 : }
2222 :
2223 : /**
2224 : * cairo_paint:
2225 : * @cr: a cairo context
2226 : *
2227 : * A drawing operator that paints the current source everywhere within
2228 : * the current clip region.
2229 : **/
2230 : void
2231 43 : cairo_paint (cairo_t *cr)
2232 : {
2233 : cairo_status_t status;
2234 :
2235 43 : if (unlikely (cr->status))
2236 0 : return;
2237 :
2238 43 : status = _cairo_gstate_paint (cr->gstate);
2239 43 : if (unlikely (status))
2240 0 : _cairo_set_error (cr, status);
2241 : }
2242 : slim_hidden_def (cairo_paint);
2243 :
2244 : /**
2245 : * cairo_paint_with_alpha:
2246 : * @cr: a cairo context
2247 : * @alpha: alpha value, between 0 (transparent) and 1 (opaque)
2248 : *
2249 : * A drawing operator that paints the current source everywhere within
2250 : * the current clip region using a mask of constant alpha value
2251 : * @alpha. The effect is similar to cairo_paint(), but the drawing
2252 : * is faded out using the alpha value.
2253 : **/
2254 : void
2255 43 : cairo_paint_with_alpha (cairo_t *cr,
2256 : double alpha)
2257 : {
2258 : cairo_status_t status;
2259 : cairo_color_t color;
2260 : cairo_solid_pattern_t pattern;
2261 :
2262 43 : if (unlikely (cr->status))
2263 0 : return;
2264 :
2265 43 : if (CAIRO_ALPHA_IS_OPAQUE (alpha)) {
2266 43 : cairo_paint (cr);
2267 43 : return;
2268 : }
2269 :
2270 0 : if (CAIRO_ALPHA_IS_ZERO (alpha) &&
2271 0 : _cairo_operator_bounded_by_mask (cr->gstate->op)) {
2272 0 : return;
2273 : }
2274 :
2275 0 : _cairo_color_init_rgba (&color, 0., 0., 0., alpha);
2276 0 : _cairo_pattern_init_solid (&pattern, &color);
2277 :
2278 0 : status = _cairo_gstate_mask (cr->gstate, &pattern.base);
2279 0 : if (unlikely (status))
2280 0 : _cairo_set_error (cr, status);
2281 :
2282 0 : _cairo_pattern_fini (&pattern.base);
2283 : }
2284 :
2285 : /**
2286 : * cairo_mask:
2287 : * @cr: a cairo context
2288 : * @pattern: a #cairo_pattern_t
2289 : *
2290 : * A drawing operator that paints the current source
2291 : * using the alpha channel of @pattern as a mask. (Opaque
2292 : * areas of @pattern are painted with the source, transparent
2293 : * areas are not painted.)
2294 : */
2295 : void
2296 0 : cairo_mask (cairo_t *cr,
2297 : cairo_pattern_t *pattern)
2298 : {
2299 : cairo_status_t status;
2300 :
2301 0 : if (unlikely (cr->status))
2302 0 : return;
2303 :
2304 0 : if (pattern == NULL) {
2305 0 : _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
2306 0 : return;
2307 : }
2308 :
2309 0 : if (pattern->status) {
2310 0 : _cairo_set_error (cr, pattern->status);
2311 0 : return;
2312 : }
2313 :
2314 0 : status = _cairo_gstate_mask (cr->gstate, pattern);
2315 0 : if (unlikely (status))
2316 0 : _cairo_set_error (cr, status);
2317 : }
2318 : slim_hidden_def (cairo_mask);
2319 :
2320 : /**
2321 : * cairo_mask_surface:
2322 : * @cr: a cairo context
2323 : * @surface: a #cairo_surface_t
2324 : * @surface_x: X coordinate at which to place the origin of @surface
2325 : * @surface_y: Y coordinate at which to place the origin of @surface
2326 : *
2327 : * A drawing operator that paints the current source
2328 : * using the alpha channel of @surface as a mask. (Opaque
2329 : * areas of @surface are painted with the source, transparent
2330 : * areas are not painted.)
2331 : */
2332 : void
2333 0 : cairo_mask_surface (cairo_t *cr,
2334 : cairo_surface_t *surface,
2335 : double surface_x,
2336 : double surface_y)
2337 : {
2338 : cairo_pattern_t *pattern;
2339 : cairo_matrix_t matrix;
2340 :
2341 0 : if (unlikely (cr->status))
2342 0 : return;
2343 :
2344 0 : pattern = cairo_pattern_create_for_surface (surface);
2345 :
2346 0 : cairo_matrix_init_translate (&matrix, - surface_x, - surface_y);
2347 0 : cairo_pattern_set_matrix (pattern, &matrix);
2348 :
2349 0 : cairo_mask (cr, pattern);
2350 :
2351 0 : cairo_pattern_destroy (pattern);
2352 : }
2353 :
2354 : /**
2355 : * cairo_stroke:
2356 : * @cr: a cairo context
2357 : *
2358 : * A drawing operator that strokes the current path according to the
2359 : * current line width, line join, line cap, and dash settings. After
2360 : * cairo_stroke(), the current path will be cleared from the cairo
2361 : * context. See cairo_set_line_width(), cairo_set_line_join(),
2362 : * cairo_set_line_cap(), cairo_set_dash(), and
2363 : * cairo_stroke_preserve().
2364 : *
2365 : * Note: Degenerate segments and sub-paths are treated specially and
2366 : * provide a useful result. These can result in two different
2367 : * situations:
2368 : *
2369 : * 1. Zero-length "on" segments set in cairo_set_dash(). If the cap
2370 : * style is %CAIRO_LINE_CAP_ROUND or %CAIRO_LINE_CAP_SQUARE then these
2371 : * segments will be drawn as circular dots or squares respectively. In
2372 : * the case of %CAIRO_LINE_CAP_SQUARE, the orientation of the squares
2373 : * is determined by the direction of the underlying path.
2374 : *
2375 : * 2. A sub-path created by cairo_move_to() followed by either a
2376 : * cairo_close_path() or one or more calls to cairo_line_to() to the
2377 : * same coordinate as the cairo_move_to(). If the cap style is
2378 : * %CAIRO_LINE_CAP_ROUND then these sub-paths will be drawn as circular
2379 : * dots. Note that in the case of %CAIRO_LINE_CAP_SQUARE a degenerate
2380 : * sub-path will not be drawn at all, (since the correct orientation
2381 : * is indeterminate).
2382 : *
2383 : * In no case will a cap style of %CAIRO_LINE_CAP_BUTT cause anything
2384 : * to be drawn in the case of either degenerate segments or sub-paths.
2385 : **/
2386 : void
2387 0 : cairo_stroke (cairo_t *cr)
2388 : {
2389 0 : cairo_stroke_preserve (cr);
2390 :
2391 0 : cairo_new_path (cr);
2392 0 : }
2393 : slim_hidden_def(cairo_stroke);
2394 :
2395 : /**
2396 : * cairo_stroke_preserve:
2397 : * @cr: a cairo context
2398 : *
2399 : * A drawing operator that strokes the current path according to the
2400 : * current line width, line join, line cap, and dash settings. Unlike
2401 : * cairo_stroke(), cairo_stroke_preserve() preserves the path within the
2402 : * cairo context.
2403 : *
2404 : * See cairo_set_line_width(), cairo_set_line_join(),
2405 : * cairo_set_line_cap(), cairo_set_dash(), and
2406 : * cairo_stroke_preserve().
2407 : **/
2408 : void
2409 0 : cairo_stroke_preserve (cairo_t *cr)
2410 : {
2411 : cairo_status_t status;
2412 :
2413 0 : if (unlikely (cr->status))
2414 0 : return;
2415 :
2416 0 : status = _cairo_gstate_stroke (cr->gstate, cr->path);
2417 0 : if (unlikely (status))
2418 0 : _cairo_set_error (cr, status);
2419 : }
2420 : slim_hidden_def(cairo_stroke_preserve);
2421 :
2422 : /**
2423 : * cairo_fill:
2424 : * @cr: a cairo context
2425 : *
2426 : * A drawing operator that fills the current path according to the
2427 : * current fill rule, (each sub-path is implicitly closed before being
2428 : * filled). After cairo_fill(), the current path will be cleared from
2429 : * the cairo context. See cairo_set_fill_rule() and
2430 : * cairo_fill_preserve().
2431 : **/
2432 : void
2433 0 : cairo_fill (cairo_t *cr)
2434 : {
2435 0 : cairo_fill_preserve (cr);
2436 :
2437 0 : cairo_new_path (cr);
2438 0 : }
2439 :
2440 : /**
2441 : * cairo_fill_preserve:
2442 : * @cr: a cairo context
2443 : *
2444 : * A drawing operator that fills the current path according to the
2445 : * current fill rule, (each sub-path is implicitly closed before being
2446 : * filled). Unlike cairo_fill(), cairo_fill_preserve() preserves the
2447 : * path within the cairo context.
2448 : *
2449 : * See cairo_set_fill_rule() and cairo_fill().
2450 : **/
2451 : void
2452 21 : cairo_fill_preserve (cairo_t *cr)
2453 : {
2454 : cairo_status_t status;
2455 :
2456 21 : if (unlikely (cr->status))
2457 0 : return;
2458 :
2459 21 : status = _cairo_gstate_fill (cr->gstate, cr->path);
2460 21 : if (unlikely (status))
2461 0 : _cairo_set_error (cr, status);
2462 : }
2463 : slim_hidden_def(cairo_fill_preserve);
2464 :
2465 : /**
2466 : * cairo_copy_page:
2467 : * @cr: a cairo context
2468 : *
2469 : * Emits the current page for backends that support multiple pages, but
2470 : * doesn't clear it, so, the contents of the current page will be retained
2471 : * for the next page too. Use cairo_show_page() if you want to get an
2472 : * empty page after the emission.
2473 : *
2474 : * This is a convenience function that simply calls
2475 : * cairo_surface_copy_page() on @cr's target.
2476 : **/
2477 : void
2478 0 : cairo_copy_page (cairo_t *cr)
2479 : {
2480 : cairo_status_t status;
2481 :
2482 0 : if (unlikely (cr->status))
2483 0 : return;
2484 :
2485 0 : status = _cairo_gstate_copy_page (cr->gstate);
2486 0 : if (unlikely (status))
2487 0 : _cairo_set_error (cr, status);
2488 : }
2489 :
2490 : /**
2491 : * cairo_show_page:
2492 : * @cr: a cairo context
2493 : *
2494 : * Emits and clears the current page for backends that support multiple
2495 : * pages. Use cairo_copy_page() if you don't want to clear the page.
2496 : *
2497 : * This is a convenience function that simply calls
2498 : * cairo_surface_show_page() on @cr's target.
2499 : **/
2500 : void
2501 0 : cairo_show_page (cairo_t *cr)
2502 : {
2503 : cairo_status_t status;
2504 :
2505 0 : if (unlikely (cr->status))
2506 0 : return;
2507 :
2508 0 : status = _cairo_gstate_show_page (cr->gstate);
2509 0 : if (unlikely (status))
2510 0 : _cairo_set_error (cr, status);
2511 : }
2512 :
2513 : /**
2514 : * cairo_in_stroke:
2515 : * @cr: a cairo context
2516 : * @x: X coordinate of the point to test
2517 : * @y: Y coordinate of the point to test
2518 : *
2519 : * Tests whether the given point is inside the area that would be
2520 : * affected by a cairo_stroke() operation given the current path and
2521 : * stroking parameters. Surface dimensions and clipping are not taken
2522 : * into account.
2523 : *
2524 : * See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(),
2525 : * cairo_set_line_cap(), cairo_set_dash(), and
2526 : * cairo_stroke_preserve().
2527 : *
2528 : * Return value: A non-zero value if the point is inside, or zero if
2529 : * outside.
2530 : **/
2531 : cairo_bool_t
2532 0 : cairo_in_stroke (cairo_t *cr, double x, double y)
2533 : {
2534 : cairo_status_t status;
2535 0 : cairo_bool_t inside = FALSE;
2536 :
2537 0 : if (unlikely (cr->status))
2538 0 : return FALSE;
2539 :
2540 0 : status = _cairo_gstate_in_stroke (cr->gstate,
2541 : cr->path,
2542 : x, y, &inside);
2543 0 : if (unlikely (status))
2544 0 : _cairo_set_error (cr, status);
2545 :
2546 0 : return inside;
2547 : }
2548 :
2549 : /**
2550 : * cairo_in_fill:
2551 : * @cr: a cairo context
2552 : * @x: X coordinate of the point to test
2553 : * @y: Y coordinate of the point to test
2554 : *
2555 : * Tests whether the given point is inside the area that would be
2556 : * affected by a cairo_fill() operation given the current path and
2557 : * filling parameters. Surface dimensions and clipping are not taken
2558 : * into account.
2559 : *
2560 : * See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve().
2561 : *
2562 : * Return value: A non-zero value if the point is inside, or zero if
2563 : * outside.
2564 : **/
2565 : cairo_bool_t
2566 0 : cairo_in_fill (cairo_t *cr, double x, double y)
2567 : {
2568 0 : if (unlikely (cr->status))
2569 0 : return FALSE;
2570 :
2571 0 : return _cairo_gstate_in_fill (cr->gstate, cr->path, x, y);
2572 : }
2573 :
2574 : /**
2575 : * cairo_stroke_extents:
2576 : * @cr: a cairo context
2577 : * @x1: left of the resulting extents
2578 : * @y1: top of the resulting extents
2579 : * @x2: right of the resulting extents
2580 : * @y2: bottom of the resulting extents
2581 : *
2582 : * Computes a bounding box in user coordinates covering the area that
2583 : * would be affected, (the "inked" area), by a cairo_stroke()
2584 : * operation given the current path and stroke parameters.
2585 : * If the current path is empty, returns an empty rectangle ((0,0), (0,0)).
2586 : * Surface dimensions and clipping are not taken into account.
2587 : *
2588 : * Note that if the line width is set to exactly zero, then
2589 : * cairo_stroke_extents() will return an empty rectangle. Contrast with
2590 : * cairo_path_extents() which can be used to compute the non-empty
2591 : * bounds as the line width approaches zero.
2592 : *
2593 : * Note that cairo_stroke_extents() must necessarily do more work to
2594 : * compute the precise inked areas in light of the stroke parameters,
2595 : * so cairo_path_extents() may be more desirable for sake of
2596 : * performance if non-inked path extents are desired.
2597 : *
2598 : * See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(),
2599 : * cairo_set_line_cap(), cairo_set_dash(), and
2600 : * cairo_stroke_preserve().
2601 : **/
2602 : void
2603 0 : cairo_stroke_extents (cairo_t *cr,
2604 : double *x1, double *y1, double *x2, double *y2)
2605 : {
2606 : cairo_status_t status;
2607 :
2608 0 : if (unlikely (cr->status)) {
2609 0 : if (x1)
2610 0 : *x1 = 0.0;
2611 0 : if (y1)
2612 0 : *y1 = 0.0;
2613 0 : if (x2)
2614 0 : *x2 = 0.0;
2615 0 : if (y2)
2616 0 : *y2 = 0.0;
2617 :
2618 0 : return;
2619 : }
2620 :
2621 0 : status = _cairo_gstate_stroke_extents (cr->gstate,
2622 : cr->path,
2623 : x1, y1, x2, y2);
2624 0 : if (unlikely (status))
2625 0 : _cairo_set_error (cr, status);
2626 : }
2627 :
2628 : /**
2629 : * cairo_fill_extents:
2630 : * @cr: a cairo context
2631 : * @x1: left of the resulting extents
2632 : * @y1: top of the resulting extents
2633 : * @x2: right of the resulting extents
2634 : * @y2: bottom of the resulting extents
2635 : *
2636 : * Computes a bounding box in user coordinates covering the area that
2637 : * would be affected, (the "inked" area), by a cairo_fill() operation
2638 : * given the current path and fill parameters. If the current path is
2639 : * empty, returns an empty rectangle ((0,0), (0,0)). Surface
2640 : * dimensions and clipping are not taken into account.
2641 : *
2642 : * Contrast with cairo_path_extents(), which is similar, but returns
2643 : * non-zero extents for some paths with no inked area, (such as a
2644 : * simple line segment).
2645 : *
2646 : * Note that cairo_fill_extents() must necessarily do more work to
2647 : * compute the precise inked areas in light of the fill rule, so
2648 : * cairo_path_extents() may be more desirable for sake of performance
2649 : * if the non-inked path extents are desired.
2650 : *
2651 : * See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve().
2652 : **/
2653 : void
2654 0 : cairo_fill_extents (cairo_t *cr,
2655 : double *x1, double *y1, double *x2, double *y2)
2656 : {
2657 : cairo_status_t status;
2658 :
2659 0 : if (unlikely (cr->status)) {
2660 0 : if (x1)
2661 0 : *x1 = 0.0;
2662 0 : if (y1)
2663 0 : *y1 = 0.0;
2664 0 : if (x2)
2665 0 : *x2 = 0.0;
2666 0 : if (y2)
2667 0 : *y2 = 0.0;
2668 :
2669 0 : return;
2670 : }
2671 :
2672 0 : status = _cairo_gstate_fill_extents (cr->gstate,
2673 : cr->path,
2674 : x1, y1, x2, y2);
2675 0 : if (unlikely (status))
2676 0 : _cairo_set_error (cr, status);
2677 : }
2678 :
2679 : /**
2680 : * cairo_clip:
2681 : * @cr: a cairo context
2682 : *
2683 : * Establishes a new clip region by intersecting the current clip
2684 : * region with the current path as it would be filled by cairo_fill()
2685 : * and according to the current fill rule (see cairo_set_fill_rule()).
2686 : *
2687 : * After cairo_clip(), the current path will be cleared from the cairo
2688 : * context.
2689 : *
2690 : * The current clip region affects all drawing operations by
2691 : * effectively masking out any changes to the surface that are outside
2692 : * the current clip region.
2693 : *
2694 : * Calling cairo_clip() can only make the clip region smaller, never
2695 : * larger. But the current clip is part of the graphics state, so a
2696 : * temporary restriction of the clip region can be achieved by
2697 : * calling cairo_clip() within a cairo_save()/cairo_restore()
2698 : * pair. The only other means of increasing the size of the clip
2699 : * region is cairo_reset_clip().
2700 : **/
2701 : void
2702 0 : cairo_clip (cairo_t *cr)
2703 : {
2704 0 : cairo_clip_preserve (cr);
2705 :
2706 0 : cairo_new_path (cr);
2707 0 : }
2708 :
2709 : /**
2710 : * cairo_clip_preserve:
2711 : * @cr: a cairo context
2712 : *
2713 : * Establishes a new clip region by intersecting the current clip
2714 : * region with the current path as it would be filled by cairo_fill()
2715 : * and according to the current fill rule (see cairo_set_fill_rule()).
2716 : *
2717 : * Unlike cairo_clip(), cairo_clip_preserve() preserves the path within
2718 : * the cairo context.
2719 : *
2720 : * The current clip region affects all drawing operations by
2721 : * effectively masking out any changes to the surface that are outside
2722 : * the current clip region.
2723 : *
2724 : * Calling cairo_clip_preserve() can only make the clip region smaller, never
2725 : * larger. But the current clip is part of the graphics state, so a
2726 : * temporary restriction of the clip region can be achieved by
2727 : * calling cairo_clip_preserve() within a cairo_save()/cairo_restore()
2728 : * pair. The only other means of increasing the size of the clip
2729 : * region is cairo_reset_clip().
2730 : **/
2731 : void
2732 0 : cairo_clip_preserve (cairo_t *cr)
2733 : {
2734 : cairo_status_t status;
2735 :
2736 0 : if (unlikely (cr->status))
2737 0 : return;
2738 :
2739 0 : status = _cairo_gstate_clip (cr->gstate, cr->path);
2740 0 : if (unlikely (status))
2741 0 : _cairo_set_error (cr, status);
2742 : }
2743 : slim_hidden_def(cairo_clip_preserve);
2744 :
2745 : /**
2746 : * cairo_reset_clip:
2747 : * @cr: a cairo context
2748 : *
2749 : * Reset the current clip region to its original, unrestricted
2750 : * state. That is, set the clip region to an infinitely large shape
2751 : * containing the target surface. Equivalently, if infinity is too
2752 : * hard to grasp, one can imagine the clip region being reset to the
2753 : * exact bounds of the target surface.
2754 : *
2755 : * Note that code meant to be reusable should not call
2756 : * cairo_reset_clip() as it will cause results unexpected by
2757 : * higher-level code which calls cairo_clip(). Consider using
2758 : * cairo_save() and cairo_restore() around cairo_clip() as a more
2759 : * robust means of temporarily restricting the clip region.
2760 : **/
2761 : void
2762 0 : cairo_reset_clip (cairo_t *cr)
2763 : {
2764 : cairo_status_t status;
2765 :
2766 0 : if (unlikely (cr->status))
2767 0 : return;
2768 :
2769 0 : status = _cairo_gstate_reset_clip (cr->gstate);
2770 0 : if (unlikely (status))
2771 0 : _cairo_set_error (cr, status);
2772 : }
2773 :
2774 : /**
2775 : * cairo_clip_extents:
2776 : * @cr: a cairo context
2777 : * @x1: left of the resulting extents
2778 : * @y1: top of the resulting extents
2779 : * @x2: right of the resulting extents
2780 : * @y2: bottom of the resulting extents
2781 : *
2782 : * Computes a bounding box in user coordinates covering the area inside the
2783 : * current clip.
2784 : *
2785 : * Since: 1.4
2786 : **/
2787 : void
2788 0 : cairo_clip_extents (cairo_t *cr,
2789 : double *x1, double *y1,
2790 : double *x2, double *y2)
2791 : {
2792 0 : if (unlikely (cr->status)) {
2793 0 : if (x1)
2794 0 : *x1 = 0.0;
2795 0 : if (y1)
2796 0 : *y1 = 0.0;
2797 0 : if (x2)
2798 0 : *x2 = 0.0;
2799 0 : if (y2)
2800 0 : *y2 = 0.0;
2801 :
2802 0 : return;
2803 : }
2804 :
2805 0 : if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) {
2806 0 : *x1 = -INFINITY;
2807 0 : *y1 = -INFINITY;
2808 0 : *x2 = +INFINITY;
2809 0 : *y2 = +INFINITY;
2810 : }
2811 : }
2812 :
2813 : /**
2814 : * cairo_in_clip:
2815 : * @cr: a cairo context
2816 : * @x: X coordinate of the point to test
2817 : * @y: Y coordinate of the point to test
2818 : *
2819 : * Tests whether the given point is inside the area that would be
2820 : * visible through the current clip, i.e. the area that would be filled by
2821 : * a cairo_paint() operation.
2822 : *
2823 : * See cairo_clip(), and cairo_clip_preserve().
2824 : *
2825 : * Return value: A non-zero value if the point is inside, or zero if
2826 : * outside.
2827 : *
2828 : * Since: 1.10
2829 : **/
2830 : cairo_bool_t
2831 0 : cairo_in_clip (cairo_t *cr, double x, double y)
2832 : {
2833 0 : if (unlikely (cr->status))
2834 0 : return FALSE;
2835 :
2836 0 : return _cairo_gstate_in_clip (cr->gstate, x, y);
2837 : }
2838 :
2839 : static cairo_rectangle_list_t *
2840 0 : _cairo_rectangle_list_create_in_error (cairo_status_t status)
2841 : {
2842 : cairo_rectangle_list_t *list;
2843 :
2844 0 : if (status == CAIRO_STATUS_NO_MEMORY)
2845 0 : return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
2846 :
2847 0 : list = malloc (sizeof (cairo_rectangle_list_t));
2848 0 : if (unlikely (list == NULL)) {
2849 0 : status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2850 0 : return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
2851 : }
2852 :
2853 0 : list->status = status;
2854 0 : list->rectangles = NULL;
2855 0 : list->num_rectangles = 0;
2856 0 : return list;
2857 : }
2858 :
2859 : /**
2860 : * cairo_copy_clip_rectangle_list:
2861 : * @cr: a cairo context
2862 : *
2863 : * Gets the current clip region as a list of rectangles in user coordinates.
2864 : * Never returns %NULL.
2865 : *
2866 : * The status in the list may be %CAIRO_STATUS_CLIP_NOT_REPRESENTABLE to
2867 : * indicate that the clip region cannot be represented as a list of
2868 : * user-space rectangles. The status may have other values to indicate
2869 : * other errors.
2870 : *
2871 : * Returns: the current clip region as a list of rectangles in user coordinates,
2872 : * which should be destroyed using cairo_rectangle_list_destroy().
2873 : *
2874 : * Since: 1.4
2875 : **/
2876 : cairo_rectangle_list_t *
2877 0 : cairo_copy_clip_rectangle_list (cairo_t *cr)
2878 : {
2879 0 : if (unlikely (cr->status))
2880 0 : return _cairo_rectangle_list_create_in_error (cr->status);
2881 :
2882 0 : return _cairo_gstate_copy_clip_rectangle_list (cr->gstate);
2883 : }
2884 :
2885 : /**
2886 : * cairo_select_font_face:
2887 : * @cr: a #cairo_t
2888 : * @family: a font family name, encoded in UTF-8
2889 : * @slant: the slant for the font
2890 : * @weight: the weight for the font
2891 : *
2892 : * Note: The cairo_select_font_face() function call is part of what
2893 : * the cairo designers call the "toy" text API. It is convenient for
2894 : * short demos and simple programs, but it is not expected to be
2895 : * adequate for serious text-using applications.
2896 : *
2897 : * Selects a family and style of font from a simplified description as
2898 : * a family name, slant and weight. Cairo provides no operation to
2899 : * list available family names on the system (this is a "toy",
2900 : * remember), but the standard CSS2 generic family names, ("serif",
2901 : * "sans-serif", "cursive", "fantasy", "monospace"), are likely to
2902 : * work as expected.
2903 : *
2904 : * If @family starts with the string "@cairo:", or if no native font
2905 : * backends are compiled in, cairo will use an internal font family.
2906 : * The internal font family recognizes many modifiers in the @family
2907 : * string, most notably, it recognizes the string "monospace". That is,
2908 : * the family name "@cairo:monospace" will use the monospace version of
2909 : * the internal font family.
2910 : *
2911 : * For "real" font selection, see the font-backend-specific
2912 : * font_face_create functions for the font backend you are using. (For
2913 : * example, if you are using the freetype-based cairo-ft font backend,
2914 : * see cairo_ft_font_face_create_for_ft_face() or
2915 : * cairo_ft_font_face_create_for_pattern().) The resulting font face
2916 : * could then be used with cairo_scaled_font_create() and
2917 : * cairo_set_scaled_font().
2918 : *
2919 : * Similarly, when using the "real" font support, you can call
2920 : * directly into the underlying font system, (such as fontconfig or
2921 : * freetype), for operations such as listing available fonts, etc.
2922 : *
2923 : * It is expected that most applications will need to use a more
2924 : * comprehensive font handling and text layout library, (for example,
2925 : * pango), in conjunction with cairo.
2926 : *
2927 : * If text is drawn without a call to cairo_select_font_face(), (nor
2928 : * cairo_set_font_face() nor cairo_set_scaled_font()), the default
2929 : * family is platform-specific, but is essentially "sans-serif".
2930 : * Default slant is %CAIRO_FONT_SLANT_NORMAL, and default weight is
2931 : * %CAIRO_FONT_WEIGHT_NORMAL.
2932 : *
2933 : * This function is equivalent to a call to cairo_toy_font_face_create()
2934 : * followed by cairo_set_font_face().
2935 : **/
2936 : void
2937 0 : cairo_select_font_face (cairo_t *cr,
2938 : const char *family,
2939 : cairo_font_slant_t slant,
2940 : cairo_font_weight_t weight)
2941 : {
2942 : cairo_status_t status;
2943 :
2944 0 : if (unlikely (cr->status))
2945 0 : return;
2946 :
2947 0 : status = _cairo_gstate_select_font_face (cr->gstate, family, slant, weight);
2948 0 : if (unlikely (status))
2949 0 : _cairo_set_error (cr, status);
2950 : }
2951 :
2952 : /**
2953 : * cairo_font_extents:
2954 : * @cr: a #cairo_t
2955 : * @extents: a #cairo_font_extents_t object into which the results
2956 : * will be stored.
2957 : *
2958 : * Gets the font extents for the currently selected font.
2959 : **/
2960 : void
2961 0 : cairo_font_extents (cairo_t *cr,
2962 : cairo_font_extents_t *extents)
2963 : {
2964 : cairo_status_t status;
2965 :
2966 0 : extents->ascent = 0.0;
2967 0 : extents->descent = 0.0;
2968 0 : extents->height = 0.0;
2969 0 : extents->max_x_advance = 0.0;
2970 0 : extents->max_y_advance = 0.0;
2971 :
2972 0 : if (unlikely (cr->status))
2973 0 : return;
2974 :
2975 0 : status = _cairo_gstate_get_font_extents (cr->gstate, extents);
2976 0 : if (unlikely (status))
2977 0 : _cairo_set_error (cr, status);
2978 : }
2979 :
2980 : /**
2981 : * cairo_set_font_face:
2982 : * @cr: a #cairo_t
2983 : * @font_face: a #cairo_font_face_t, or %NULL to restore to the default font
2984 : *
2985 : * Replaces the current #cairo_font_face_t object in the #cairo_t with
2986 : * @font_face. The replaced font face in the #cairo_t will be
2987 : * destroyed if there are no other references to it.
2988 : **/
2989 : void
2990 0 : cairo_set_font_face (cairo_t *cr,
2991 : cairo_font_face_t *font_face)
2992 : {
2993 : cairo_status_t status;
2994 :
2995 0 : if (unlikely (cr->status))
2996 0 : return;
2997 :
2998 0 : status = _cairo_gstate_set_font_face (cr->gstate, font_face);
2999 0 : if (unlikely (status))
3000 0 : _cairo_set_error (cr, status);
3001 : }
3002 :
3003 : /**
3004 : * cairo_get_font_face:
3005 : * @cr: a #cairo_t
3006 : *
3007 : * Gets the current font face for a #cairo_t.
3008 : *
3009 : * Return value: the current font face. This object is owned by
3010 : * cairo. To keep a reference to it, you must call
3011 : * cairo_font_face_reference().
3012 : *
3013 : * This function never returns %NULL. If memory cannot be allocated, a
3014 : * special "nil" #cairo_font_face_t object will be returned on which
3015 : * cairo_font_face_status() returns %CAIRO_STATUS_NO_MEMORY. Using
3016 : * this nil object will cause its error state to propagate to other
3017 : * objects it is passed to, (for example, calling
3018 : * cairo_set_font_face() with a nil font will trigger an error that
3019 : * will shutdown the #cairo_t object).
3020 : **/
3021 : cairo_font_face_t *
3022 0 : cairo_get_font_face (cairo_t *cr)
3023 : {
3024 : cairo_status_t status;
3025 : cairo_font_face_t *font_face;
3026 :
3027 0 : if (unlikely (cr->status))
3028 0 : return (cairo_font_face_t*) &_cairo_font_face_nil;
3029 :
3030 0 : status = _cairo_gstate_get_font_face (cr->gstate, &font_face);
3031 0 : if (unlikely (status)) {
3032 0 : _cairo_set_error (cr, status);
3033 0 : return (cairo_font_face_t*) &_cairo_font_face_nil;
3034 : }
3035 :
3036 0 : return font_face;
3037 : }
3038 :
3039 : /**
3040 : * cairo_set_font_size:
3041 : * @cr: a #cairo_t
3042 : * @size: the new font size, in user space units
3043 : *
3044 : * Sets the current font matrix to a scale by a factor of @size, replacing
3045 : * any font matrix previously set with cairo_set_font_size() or
3046 : * cairo_set_font_matrix(). This results in a font size of @size user space
3047 : * units. (More precisely, this matrix will result in the font's
3048 : * em-square being a @size by @size square in user space.)
3049 : *
3050 : * If text is drawn without a call to cairo_set_font_size(), (nor
3051 : * cairo_set_font_matrix() nor cairo_set_scaled_font()), the default
3052 : * font size is 10.0.
3053 : **/
3054 : void
3055 0 : cairo_set_font_size (cairo_t *cr, double size)
3056 : {
3057 : cairo_status_t status;
3058 :
3059 0 : if (unlikely (cr->status))
3060 0 : return;
3061 :
3062 0 : status = _cairo_gstate_set_font_size (cr->gstate, size);
3063 0 : if (unlikely (status))
3064 0 : _cairo_set_error (cr, status);
3065 : }
3066 : slim_hidden_def (cairo_set_font_size);
3067 :
3068 : /**
3069 : * cairo_set_font_matrix
3070 : * @cr: a #cairo_t
3071 : * @matrix: a #cairo_matrix_t describing a transform to be applied to
3072 : * the current font.
3073 : *
3074 : * Sets the current font matrix to @matrix. The font matrix gives a
3075 : * transformation from the design space of the font (in this space,
3076 : * the em-square is 1 unit by 1 unit) to user space. Normally, a
3077 : * simple scale is used (see cairo_set_font_size()), but a more
3078 : * complex font matrix can be used to shear the font
3079 : * or stretch it unequally along the two axes
3080 : **/
3081 : void
3082 0 : cairo_set_font_matrix (cairo_t *cr,
3083 : const cairo_matrix_t *matrix)
3084 : {
3085 : cairo_status_t status;
3086 :
3087 0 : if (unlikely (cr->status))
3088 0 : return;
3089 :
3090 0 : status = _cairo_gstate_set_font_matrix (cr->gstate, matrix);
3091 0 : if (unlikely (status))
3092 0 : _cairo_set_error (cr, status);
3093 : }
3094 :
3095 : /**
3096 : * cairo_get_font_matrix
3097 : * @cr: a #cairo_t
3098 : * @matrix: return value for the matrix
3099 : *
3100 : * Stores the current font matrix into @matrix. See
3101 : * cairo_set_font_matrix().
3102 : **/
3103 : void
3104 0 : cairo_get_font_matrix (cairo_t *cr, cairo_matrix_t *matrix)
3105 : {
3106 0 : if (unlikely (cr->status)) {
3107 0 : cairo_matrix_init_identity (matrix);
3108 0 : return;
3109 : }
3110 :
3111 0 : _cairo_gstate_get_font_matrix (cr->gstate, matrix);
3112 : }
3113 :
3114 : /**
3115 : * cairo_set_font_options:
3116 : * @cr: a #cairo_t
3117 : * @options: font options to use
3118 : *
3119 : * Sets a set of custom font rendering options for the #cairo_t.
3120 : * Rendering options are derived by merging these options with the
3121 : * options derived from underlying surface; if the value in @options
3122 : * has a default value (like %CAIRO_ANTIALIAS_DEFAULT), then the value
3123 : * from the surface is used.
3124 : **/
3125 : void
3126 0 : cairo_set_font_options (cairo_t *cr,
3127 : const cairo_font_options_t *options)
3128 : {
3129 : cairo_status_t status;
3130 :
3131 0 : if (unlikely (cr->status))
3132 0 : return;
3133 :
3134 0 : status = cairo_font_options_status ((cairo_font_options_t *) options);
3135 0 : if (unlikely (status)) {
3136 0 : _cairo_set_error (cr, status);
3137 0 : return;
3138 : }
3139 :
3140 0 : _cairo_gstate_set_font_options (cr->gstate, options);
3141 : }
3142 : slim_hidden_def (cairo_set_font_options);
3143 :
3144 : /**
3145 : * cairo_get_font_options:
3146 : * @cr: a #cairo_t
3147 : * @options: a #cairo_font_options_t object into which to store
3148 : * the retrieved options. All existing values are overwritten
3149 : *
3150 : * Retrieves font rendering options set via #cairo_set_font_options.
3151 : * Note that the returned options do not include any options derived
3152 : * from the underlying surface; they are literally the options
3153 : * passed to cairo_set_font_options().
3154 : **/
3155 : void
3156 0 : cairo_get_font_options (cairo_t *cr,
3157 : cairo_font_options_t *options)
3158 : {
3159 : /* check that we aren't trying to overwrite the nil object */
3160 0 : if (cairo_font_options_status (options))
3161 0 : return;
3162 :
3163 0 : if (unlikely (cr->status)) {
3164 0 : _cairo_font_options_init_default (options);
3165 0 : return;
3166 : }
3167 :
3168 0 : _cairo_gstate_get_font_options (cr->gstate, options);
3169 : }
3170 :
3171 : /**
3172 : * cairo_set_scaled_font:
3173 : * @cr: a #cairo_t
3174 : * @scaled_font: a #cairo_scaled_font_t
3175 : *
3176 : * Replaces the current font face, font matrix, and font options in
3177 : * the #cairo_t with those of the #cairo_scaled_font_t. Except for
3178 : * some translation, the current CTM of the #cairo_t should be the
3179 : * same as that of the #cairo_scaled_font_t, which can be accessed
3180 : * using cairo_scaled_font_get_ctm().
3181 : *
3182 : * Since: 1.2
3183 : **/
3184 : void
3185 0 : cairo_set_scaled_font (cairo_t *cr,
3186 : const cairo_scaled_font_t *scaled_font)
3187 : {
3188 : cairo_status_t status;
3189 : cairo_bool_t was_previous;
3190 :
3191 0 : if (unlikely (cr->status))
3192 0 : return;
3193 :
3194 0 : if (scaled_font == NULL) {
3195 0 : status = _cairo_error (CAIRO_STATUS_NULL_POINTER);
3196 0 : goto BAIL;
3197 : }
3198 :
3199 0 : status = scaled_font->status;
3200 0 : if (unlikely (status))
3201 0 : goto BAIL;
3202 :
3203 0 : if (scaled_font == cr->gstate->scaled_font)
3204 0 : return;
3205 :
3206 0 : was_previous = scaled_font == cr->gstate->previous_scaled_font;
3207 :
3208 0 : status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
3209 0 : if (unlikely (status))
3210 0 : goto BAIL;
3211 :
3212 0 : status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
3213 0 : if (unlikely (status))
3214 0 : goto BAIL;
3215 :
3216 0 : _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
3217 :
3218 : /* XXX: Mozilla code assumes that the ctm of a scaled font doesn't need to
3219 : * match the context ctm. This assumption breaks the previous_scaled_font
3220 : * cache. So we avoid using the cache for now.
3221 : if (was_previous)
3222 : cr->gstate->scaled_font = cairo_scaled_font_reference ((cairo_scaled_font_t *) scaled_font);
3223 : */
3224 :
3225 0 : return;
3226 :
3227 : BAIL:
3228 0 : _cairo_set_error (cr, status);
3229 : }
3230 :
3231 : /**
3232 : * cairo_get_scaled_font:
3233 : * @cr: a #cairo_t
3234 : *
3235 : * Gets the current scaled font for a #cairo_t.
3236 : *
3237 : * Return value: the current scaled font. This object is owned by
3238 : * cairo. To keep a reference to it, you must call
3239 : * cairo_scaled_font_reference().
3240 : *
3241 : * This function never returns %NULL. If memory cannot be allocated, a
3242 : * special "nil" #cairo_scaled_font_t object will be returned on which
3243 : * cairo_scaled_font_status() returns %CAIRO_STATUS_NO_MEMORY. Using
3244 : * this nil object will cause its error state to propagate to other
3245 : * objects it is passed to, (for example, calling
3246 : * cairo_set_scaled_font() with a nil font will trigger an error that
3247 : * will shutdown the #cairo_t object).
3248 : *
3249 : * Since: 1.4
3250 : **/
3251 : cairo_scaled_font_t *
3252 0 : cairo_get_scaled_font (cairo_t *cr)
3253 : {
3254 : cairo_status_t status;
3255 : cairo_scaled_font_t *scaled_font;
3256 :
3257 0 : if (unlikely (cr->status))
3258 0 : return _cairo_scaled_font_create_in_error (cr->status);
3259 :
3260 0 : status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font);
3261 0 : if (unlikely (status)) {
3262 0 : _cairo_set_error (cr, status);
3263 0 : return _cairo_scaled_font_create_in_error (status);
3264 : }
3265 :
3266 0 : return scaled_font;
3267 : }
3268 :
3269 : /**
3270 : * cairo_text_extents:
3271 : * @cr: a #cairo_t
3272 : * @utf8: a NUL-terminated string of text encoded in UTF-8, or %NULL
3273 : * @extents: a #cairo_text_extents_t object into which the results
3274 : * will be stored
3275 : *
3276 : * Gets the extents for a string of text. The extents describe a
3277 : * user-space rectangle that encloses the "inked" portion of the text,
3278 : * (as it would be drawn by cairo_show_text()). Additionally, the
3279 : * x_advance and y_advance values indicate the amount by which the
3280 : * current point would be advanced by cairo_show_text().
3281 : *
3282 : * Note that whitespace characters do not directly contribute to the
3283 : * size of the rectangle (extents.width and extents.height). They do
3284 : * contribute indirectly by changing the position of non-whitespace
3285 : * characters. In particular, trailing whitespace characters are
3286 : * likely to not affect the size of the rectangle, though they will
3287 : * affect the x_advance and y_advance values.
3288 : **/
3289 : void
3290 0 : cairo_text_extents (cairo_t *cr,
3291 : const char *utf8,
3292 : cairo_text_extents_t *extents)
3293 : {
3294 : cairo_status_t status;
3295 0 : cairo_glyph_t *glyphs = NULL;
3296 : int num_glyphs;
3297 : double x, y;
3298 :
3299 0 : extents->x_bearing = 0.0;
3300 0 : extents->y_bearing = 0.0;
3301 0 : extents->width = 0.0;
3302 0 : extents->height = 0.0;
3303 0 : extents->x_advance = 0.0;
3304 0 : extents->y_advance = 0.0;
3305 :
3306 0 : if (unlikely (cr->status))
3307 0 : return;
3308 :
3309 0 : if (utf8 == NULL)
3310 0 : return;
3311 :
3312 0 : cairo_get_current_point (cr, &x, &y);
3313 :
3314 0 : status = _cairo_gstate_text_to_glyphs (cr->gstate,
3315 : x, y,
3316 0 : utf8, strlen (utf8),
3317 : &glyphs, &num_glyphs,
3318 : NULL, NULL,
3319 : NULL);
3320 :
3321 0 : if (status == CAIRO_STATUS_SUCCESS)
3322 0 : status = _cairo_gstate_glyph_extents (cr->gstate,
3323 : glyphs, num_glyphs,
3324 : extents);
3325 0 : cairo_glyph_free (glyphs);
3326 :
3327 0 : if (unlikely (status))
3328 0 : _cairo_set_error (cr, status);
3329 : }
3330 :
3331 : /**
3332 : * cairo_glyph_extents:
3333 : * @cr: a #cairo_t
3334 : * @glyphs: an array of #cairo_glyph_t objects
3335 : * @num_glyphs: the number of elements in @glyphs
3336 : * @extents: a #cairo_text_extents_t object into which the results
3337 : * will be stored
3338 : *
3339 : * Gets the extents for an array of glyphs. The extents describe a
3340 : * user-space rectangle that encloses the "inked" portion of the
3341 : * glyphs, (as they would be drawn by cairo_show_glyphs()).
3342 : * Additionally, the x_advance and y_advance values indicate the
3343 : * amount by which the current point would be advanced by
3344 : * cairo_show_glyphs().
3345 : *
3346 : * Note that whitespace glyphs do not contribute to the size of the
3347 : * rectangle (extents.width and extents.height).
3348 : **/
3349 : void
3350 0 : cairo_glyph_extents (cairo_t *cr,
3351 : const cairo_glyph_t *glyphs,
3352 : int num_glyphs,
3353 : cairo_text_extents_t *extents)
3354 : {
3355 : cairo_status_t status;
3356 :
3357 0 : extents->x_bearing = 0.0;
3358 0 : extents->y_bearing = 0.0;
3359 0 : extents->width = 0.0;
3360 0 : extents->height = 0.0;
3361 0 : extents->x_advance = 0.0;
3362 0 : extents->y_advance = 0.0;
3363 :
3364 0 : if (unlikely (cr->status))
3365 0 : return;
3366 :
3367 0 : if (num_glyphs == 0)
3368 0 : return;
3369 :
3370 0 : if (num_glyphs < 0) {
3371 0 : _cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT);
3372 0 : return;
3373 : }
3374 :
3375 0 : if (glyphs == NULL) {
3376 0 : _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
3377 0 : return;
3378 : }
3379 :
3380 0 : status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs,
3381 : extents);
3382 0 : if (unlikely (status))
3383 0 : _cairo_set_error (cr, status);
3384 : }
3385 :
3386 : /**
3387 : * cairo_show_text:
3388 : * @cr: a cairo context
3389 : * @utf8: a NUL-terminated string of text encoded in UTF-8, or %NULL
3390 : *
3391 : * A drawing operator that generates the shape from a string of UTF-8
3392 : * characters, rendered according to the current font_face, font_size
3393 : * (font_matrix), and font_options.
3394 : *
3395 : * This function first computes a set of glyphs for the string of
3396 : * text. The first glyph is placed so that its origin is at the
3397 : * current point. The origin of each subsequent glyph is offset from
3398 : * that of the previous glyph by the advance values of the previous
3399 : * glyph.
3400 : *
3401 : * After this call the current point is moved to the origin of where
3402 : * the next glyph would be placed in this same progression. That is,
3403 : * the current point will be at the origin of the final glyph offset
3404 : * by its advance values. This allows for easy display of a single
3405 : * logical string with multiple calls to cairo_show_text().
3406 : *
3407 : * Note: The cairo_show_text() function call is part of what the cairo
3408 : * designers call the "toy" text API. It is convenient for short demos
3409 : * and simple programs, but it is not expected to be adequate for
3410 : * serious text-using applications. See cairo_show_glyphs() for the
3411 : * "real" text display API in cairo.
3412 : **/
3413 : void
3414 0 : cairo_show_text (cairo_t *cr, const char *utf8)
3415 : {
3416 : cairo_text_extents_t extents;
3417 : cairo_status_t status;
3418 : cairo_glyph_t *glyphs, *last_glyph;
3419 : cairo_text_cluster_t *clusters;
3420 : int utf8_len, num_glyphs, num_clusters;
3421 : cairo_text_cluster_flags_t cluster_flags;
3422 : double x, y;
3423 : cairo_bool_t has_show_text_glyphs;
3424 : cairo_glyph_t stack_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)];
3425 : cairo_text_cluster_t stack_clusters[CAIRO_STACK_ARRAY_LENGTH (cairo_text_cluster_t)];
3426 :
3427 0 : if (unlikely (cr->status))
3428 0 : return;
3429 :
3430 0 : if (utf8 == NULL)
3431 0 : return;
3432 :
3433 0 : cairo_get_current_point (cr, &x, &y);
3434 :
3435 0 : utf8_len = strlen (utf8);
3436 :
3437 0 : has_show_text_glyphs =
3438 0 : cairo_surface_has_show_text_glyphs (cairo_get_target (cr));
3439 :
3440 0 : glyphs = stack_glyphs;
3441 0 : num_glyphs = ARRAY_LENGTH (stack_glyphs);
3442 :
3443 0 : if (has_show_text_glyphs) {
3444 0 : clusters = stack_clusters;
3445 0 : num_clusters = ARRAY_LENGTH (stack_clusters);
3446 : } else {
3447 0 : clusters = NULL;
3448 0 : num_clusters = 0;
3449 : }
3450 :
3451 0 : status = _cairo_gstate_text_to_glyphs (cr->gstate,
3452 : x, y,
3453 : utf8, utf8_len,
3454 : &glyphs, &num_glyphs,
3455 : has_show_text_glyphs ? &clusters : NULL, &num_clusters,
3456 : &cluster_flags);
3457 0 : if (unlikely (status))
3458 0 : goto BAIL;
3459 :
3460 0 : if (num_glyphs == 0)
3461 0 : return;
3462 :
3463 0 : status = _cairo_gstate_show_text_glyphs (cr->gstate,
3464 : utf8, utf8_len,
3465 : glyphs, num_glyphs,
3466 : clusters, num_clusters,
3467 : cluster_flags);
3468 0 : if (unlikely (status))
3469 0 : goto BAIL;
3470 :
3471 0 : last_glyph = &glyphs[num_glyphs - 1];
3472 0 : status = _cairo_gstate_glyph_extents (cr->gstate,
3473 : last_glyph, 1,
3474 : &extents);
3475 0 : if (unlikely (status))
3476 0 : goto BAIL;
3477 :
3478 0 : x = last_glyph->x + extents.x_advance;
3479 0 : y = last_glyph->y + extents.y_advance;
3480 0 : cairo_move_to (cr, x, y);
3481 :
3482 : BAIL:
3483 0 : if (glyphs != stack_glyphs)
3484 0 : cairo_glyph_free (glyphs);
3485 0 : if (clusters != stack_clusters)
3486 0 : cairo_text_cluster_free (clusters);
3487 :
3488 0 : if (unlikely (status))
3489 0 : _cairo_set_error (cr, status);
3490 : }
3491 :
3492 : /**
3493 : * cairo_show_glyphs:
3494 : * @cr: a cairo context
3495 : * @glyphs: array of glyphs to show
3496 : * @num_glyphs: number of glyphs to show
3497 : *
3498 : * A drawing operator that generates the shape from an array of glyphs,
3499 : * rendered according to the current font face, font size
3500 : * (font matrix), and font options.
3501 : **/
3502 : void
3503 0 : cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
3504 : {
3505 : cairo_status_t status;
3506 :
3507 0 : if (unlikely (cr->status))
3508 0 : return;
3509 :
3510 0 : if (num_glyphs == 0)
3511 0 : return;
3512 :
3513 0 : if (num_glyphs < 0) {
3514 0 : _cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT);
3515 0 : return;
3516 : }
3517 :
3518 0 : if (glyphs == NULL) {
3519 0 : _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
3520 0 : return;
3521 : }
3522 :
3523 0 : status = _cairo_gstate_show_text_glyphs (cr->gstate,
3524 : NULL, 0,
3525 : glyphs, num_glyphs,
3526 : NULL, 0,
3527 : FALSE);
3528 0 : if (unlikely (status))
3529 0 : _cairo_set_error (cr, status);
3530 : }
3531 :
3532 : /**
3533 : * cairo_show_text_glyphs:
3534 : * @cr: a cairo context
3535 : * @utf8: a string of text encoded in UTF-8
3536 : * @utf8_len: length of @utf8 in bytes, or -1 if it is NUL-terminated
3537 : * @glyphs: array of glyphs to show
3538 : * @num_glyphs: number of glyphs to show
3539 : * @clusters: array of cluster mapping information
3540 : * @num_clusters: number of clusters in the mapping
3541 : * @cluster_flags: cluster mapping flags
3542 : *
3543 : * This operation has rendering effects similar to cairo_show_glyphs()
3544 : * but, if the target surface supports it, uses the provided text and
3545 : * cluster mapping to embed the text for the glyphs shown in the output.
3546 : * If the target does not support the extended attributes, this function
3547 : * acts like the basic cairo_show_glyphs() as if it had been passed
3548 : * @glyphs and @num_glyphs.
3549 : *
3550 : * The mapping between @utf8 and @glyphs is provided by an array of
3551 : * <firstterm>clusters</firstterm>. Each cluster covers a number of
3552 : * text bytes and glyphs, and neighboring clusters cover neighboring
3553 : * areas of @utf8 and @glyphs. The clusters should collectively cover @utf8
3554 : * and @glyphs in entirety.
3555 : *
3556 : * The first cluster always covers bytes from the beginning of @utf8.
3557 : * If @cluster_flags do not have the %CAIRO_TEXT_CLUSTER_FLAG_BACKWARD
3558 : * set, the first cluster also covers the beginning
3559 : * of @glyphs, otherwise it covers the end of the @glyphs array and
3560 : * following clusters move backward.
3561 : *
3562 : * See #cairo_text_cluster_t for constraints on valid clusters.
3563 : *
3564 : * Since: 1.8
3565 : **/
3566 : void
3567 0 : cairo_show_text_glyphs (cairo_t *cr,
3568 : const char *utf8,
3569 : int utf8_len,
3570 : const cairo_glyph_t *glyphs,
3571 : int num_glyphs,
3572 : const cairo_text_cluster_t *clusters,
3573 : int num_clusters,
3574 : cairo_text_cluster_flags_t cluster_flags)
3575 : {
3576 : cairo_status_t status;
3577 :
3578 0 : if (unlikely (cr->status))
3579 0 : return;
3580 :
3581 : /* A slew of sanity checks */
3582 :
3583 : /* Special case for NULL and -1 */
3584 0 : if (utf8 == NULL && utf8_len == -1)
3585 0 : utf8_len = 0;
3586 :
3587 : /* No NULLs for non-zeros */
3588 0 : if ((num_glyphs && glyphs == NULL) ||
3589 0 : (utf8_len && utf8 == NULL) ||
3590 0 : (num_clusters && clusters == NULL)) {
3591 0 : _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
3592 0 : return;
3593 : }
3594 :
3595 : /* A -1 for utf8_len means NUL-terminated */
3596 0 : if (utf8_len == -1)
3597 0 : utf8_len = strlen (utf8);
3598 :
3599 : /* Apart from that, no negatives */
3600 0 : if (num_glyphs < 0 || utf8_len < 0 || num_clusters < 0) {
3601 0 : _cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT);
3602 0 : return;
3603 : }
3604 :
3605 : /* Make sure clusters cover the entire glyphs and utf8 arrays,
3606 : * and that cluster boundaries are UTF-8 boundaries. */
3607 0 : status = _cairo_validate_text_clusters (utf8, utf8_len,
3608 : glyphs, num_glyphs,
3609 : clusters, num_clusters, cluster_flags);
3610 0 : if (status == CAIRO_STATUS_INVALID_CLUSTERS) {
3611 : /* Either got invalid UTF-8 text, or cluster mapping is bad.
3612 : * Differentiate those. */
3613 :
3614 : cairo_status_t status2;
3615 :
3616 0 : status2 = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, NULL);
3617 0 : if (status2)
3618 0 : status = status2;
3619 :
3620 0 : _cairo_set_error (cr, status);
3621 0 : return;
3622 : }
3623 :
3624 0 : if (num_glyphs == 0 && utf8_len == 0)
3625 0 : return;
3626 :
3627 0 : status = _cairo_gstate_show_text_glyphs (cr->gstate,
3628 : utf8, utf8_len,
3629 : glyphs, num_glyphs,
3630 : clusters, num_clusters, cluster_flags);
3631 0 : if (unlikely (status))
3632 0 : _cairo_set_error (cr, status);
3633 : }
3634 :
3635 : /**
3636 : * cairo_text_path:
3637 : * @cr: a cairo context
3638 : * @utf8: a NUL-terminated string of text encoded in UTF-8, or %NULL
3639 : *
3640 : * Adds closed paths for text to the current path. The generated
3641 : * path if filled, achieves an effect similar to that of
3642 : * cairo_show_text().
3643 : *
3644 : * Text conversion and positioning is done similar to cairo_show_text().
3645 : *
3646 : * Like cairo_show_text(), After this call the current point is
3647 : * moved to the origin of where the next glyph would be placed in
3648 : * this same progression. That is, the current point will be at
3649 : * the origin of the final glyph offset by its advance values.
3650 : * This allows for chaining multiple calls to to cairo_text_path()
3651 : * without having to set current point in between.
3652 : *
3653 : * Note: The cairo_text_path() function call is part of what the cairo
3654 : * designers call the "toy" text API. It is convenient for short demos
3655 : * and simple programs, but it is not expected to be adequate for
3656 : * serious text-using applications. See cairo_glyph_path() for the
3657 : * "real" text path API in cairo.
3658 : **/
3659 : void
3660 0 : cairo_text_path (cairo_t *cr, const char *utf8)
3661 : {
3662 : cairo_status_t status;
3663 : cairo_text_extents_t extents;
3664 : cairo_glyph_t stack_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)];
3665 : cairo_glyph_t *glyphs, *last_glyph;
3666 : int num_glyphs;
3667 : double x, y;
3668 :
3669 0 : if (unlikely (cr->status))
3670 0 : return;
3671 :
3672 0 : if (utf8 == NULL)
3673 0 : return;
3674 :
3675 0 : cairo_get_current_point (cr, &x, &y);
3676 :
3677 0 : glyphs = stack_glyphs;
3678 0 : num_glyphs = ARRAY_LENGTH (stack_glyphs);
3679 :
3680 0 : status = _cairo_gstate_text_to_glyphs (cr->gstate,
3681 : x, y,
3682 0 : utf8, strlen (utf8),
3683 : &glyphs, &num_glyphs,
3684 : NULL, NULL,
3685 : NULL);
3686 :
3687 0 : if (unlikely (status))
3688 0 : goto BAIL;
3689 :
3690 0 : if (num_glyphs == 0)
3691 0 : return;
3692 :
3693 0 : status = _cairo_gstate_glyph_path (cr->gstate,
3694 : glyphs, num_glyphs,
3695 : cr->path);
3696 :
3697 0 : if (unlikely (status))
3698 0 : goto BAIL;
3699 :
3700 0 : last_glyph = &glyphs[num_glyphs - 1];
3701 0 : status = _cairo_gstate_glyph_extents (cr->gstate,
3702 : last_glyph, 1,
3703 : &extents);
3704 :
3705 0 : if (unlikely (status))
3706 0 : goto BAIL;
3707 :
3708 0 : x = last_glyph->x + extents.x_advance;
3709 0 : y = last_glyph->y + extents.y_advance;
3710 0 : cairo_move_to (cr, x, y);
3711 :
3712 : BAIL:
3713 0 : if (glyphs != stack_glyphs)
3714 0 : cairo_glyph_free (glyphs);
3715 :
3716 0 : if (unlikely (status))
3717 0 : _cairo_set_error (cr, status);
3718 : }
3719 :
3720 : /**
3721 : * cairo_glyph_path:
3722 : * @cr: a cairo context
3723 : * @glyphs: array of glyphs to show
3724 : * @num_glyphs: number of glyphs to show
3725 : *
3726 : * Adds closed paths for the glyphs to the current path. The generated
3727 : * path if filled, achieves an effect similar to that of
3728 : * cairo_show_glyphs().
3729 : **/
3730 : void
3731 0 : cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
3732 : {
3733 : cairo_status_t status;
3734 :
3735 0 : if (unlikely (cr->status))
3736 0 : return;
3737 :
3738 0 : if (num_glyphs == 0)
3739 0 : return;
3740 :
3741 0 : if (num_glyphs < 0) {
3742 0 : _cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT);
3743 0 : return;
3744 : }
3745 :
3746 0 : if (glyphs == NULL) {
3747 0 : _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
3748 0 : return;
3749 : }
3750 :
3751 0 : status = _cairo_gstate_glyph_path (cr->gstate,
3752 : glyphs, num_glyphs,
3753 : cr->path);
3754 0 : if (unlikely (status))
3755 0 : _cairo_set_error (cr, status);
3756 : }
3757 :
3758 : /**
3759 : * cairo_get_operator:
3760 : * @cr: a cairo context
3761 : *
3762 : * Gets the current compositing operator for a cairo context.
3763 : *
3764 : * Return value: the current compositing operator.
3765 : **/
3766 : cairo_operator_t
3767 0 : cairo_get_operator (cairo_t *cr)
3768 : {
3769 0 : if (unlikely (cr->status))
3770 0 : return CAIRO_GSTATE_OPERATOR_DEFAULT;
3771 :
3772 0 : return _cairo_gstate_get_operator (cr->gstate);
3773 : }
3774 :
3775 : /**
3776 : * cairo_get_tolerance:
3777 : * @cr: a cairo context
3778 : *
3779 : * Gets the current tolerance value, as set by cairo_set_tolerance().
3780 : *
3781 : * Return value: the current tolerance value.
3782 : **/
3783 : double
3784 0 : cairo_get_tolerance (cairo_t *cr)
3785 : {
3786 0 : if (unlikely (cr->status))
3787 0 : return CAIRO_GSTATE_TOLERANCE_DEFAULT;
3788 :
3789 0 : return _cairo_gstate_get_tolerance (cr->gstate);
3790 : }
3791 : slim_hidden_def (cairo_get_tolerance);
3792 :
3793 : /**
3794 : * cairo_get_antialias:
3795 : * @cr: a cairo context
3796 : *
3797 : * Gets the current shape antialiasing mode, as set by cairo_set_shape_antialias().
3798 : *
3799 : * Return value: the current shape antialiasing mode.
3800 : **/
3801 : cairo_antialias_t
3802 0 : cairo_get_antialias (cairo_t *cr)
3803 : {
3804 0 : if (unlikely (cr->status))
3805 0 : return CAIRO_ANTIALIAS_DEFAULT;
3806 :
3807 0 : return _cairo_gstate_get_antialias (cr->gstate);
3808 : }
3809 :
3810 : /**
3811 : * cairo_has_current_point:
3812 : * @cr: a cairo context
3813 : *
3814 : * Returns whether a current point is defined on the current path.
3815 : * See cairo_get_current_point() for details on the current point.
3816 : *
3817 : * Return value: whether a current point is defined.
3818 : *
3819 : * Since: 1.6
3820 : **/
3821 : cairo_bool_t
3822 0 : cairo_has_current_point (cairo_t *cr)
3823 : {
3824 0 : if (unlikely (cr->status))
3825 0 : return FALSE;
3826 :
3827 0 : return cr->path->has_current_point;
3828 : }
3829 :
3830 : /**
3831 : * cairo_get_current_point:
3832 : * @cr: a cairo context
3833 : * @x: return value for X coordinate of the current point
3834 : * @y: return value for Y coordinate of the current point
3835 : *
3836 : * Gets the current point of the current path, which is
3837 : * conceptually the final point reached by the path so far.
3838 : *
3839 : * The current point is returned in the user-space coordinate
3840 : * system. If there is no defined current point or if @cr is in an
3841 : * error status, @x and @y will both be set to 0.0. It is possible to
3842 : * check this in advance with cairo_has_current_point().
3843 : *
3844 : * Most path construction functions alter the current point. See the
3845 : * following for details on how they affect the current point:
3846 : * cairo_new_path(), cairo_new_sub_path(),
3847 : * cairo_append_path(), cairo_close_path(),
3848 : * cairo_move_to(), cairo_line_to(), cairo_curve_to(),
3849 : * cairo_rel_move_to(), cairo_rel_line_to(), cairo_rel_curve_to(),
3850 : * cairo_arc(), cairo_arc_negative(), cairo_rectangle(),
3851 : * cairo_text_path(), cairo_glyph_path(), cairo_stroke_to_path().
3852 : *
3853 : * Some functions use and alter the current point but do not
3854 : * otherwise change current path:
3855 : * cairo_show_text().
3856 : *
3857 : * Some functions unset the current path and as a result, current point:
3858 : * cairo_fill(), cairo_stroke().
3859 : **/
3860 : void
3861 0 : cairo_get_current_point (cairo_t *cr, double *x_ret, double *y_ret)
3862 : {
3863 : cairo_fixed_t x_fixed, y_fixed;
3864 : double x, y;
3865 :
3866 0 : if (cr->status == CAIRO_STATUS_SUCCESS &&
3867 0 : _cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed))
3868 : {
3869 0 : x = _cairo_fixed_to_double (x_fixed);
3870 0 : y = _cairo_fixed_to_double (y_fixed);
3871 0 : _cairo_gstate_backend_to_user (cr->gstate, &x, &y);
3872 : }
3873 : else
3874 : {
3875 0 : x = 0.0;
3876 0 : y = 0.0;
3877 : }
3878 :
3879 0 : if (x_ret)
3880 0 : *x_ret = x;
3881 0 : if (y_ret)
3882 0 : *y_ret = y;
3883 0 : }
3884 : slim_hidden_def(cairo_get_current_point);
3885 :
3886 : /**
3887 : * cairo_get_fill_rule:
3888 : * @cr: a cairo context
3889 : *
3890 : * Gets the current fill rule, as set by cairo_set_fill_rule().
3891 : *
3892 : * Return value: the current fill rule.
3893 : **/
3894 : cairo_fill_rule_t
3895 0 : cairo_get_fill_rule (cairo_t *cr)
3896 : {
3897 0 : if (unlikely (cr->status))
3898 0 : return CAIRO_GSTATE_FILL_RULE_DEFAULT;
3899 :
3900 0 : return _cairo_gstate_get_fill_rule (cr->gstate);
3901 : }
3902 :
3903 : /**
3904 : * cairo_get_line_width:
3905 : * @cr: a cairo context
3906 : *
3907 : * This function returns the current line width value exactly as set by
3908 : * cairo_set_line_width(). Note that the value is unchanged even if
3909 : * the CTM has changed between the calls to cairo_set_line_width() and
3910 : * cairo_get_line_width().
3911 : *
3912 : * Return value: the current line width.
3913 : **/
3914 : double
3915 0 : cairo_get_line_width (cairo_t *cr)
3916 : {
3917 0 : if (unlikely (cr->status))
3918 0 : return CAIRO_GSTATE_LINE_WIDTH_DEFAULT;
3919 :
3920 0 : return _cairo_gstate_get_line_width (cr->gstate);
3921 : }
3922 : slim_hidden_def (cairo_get_line_width);
3923 :
3924 : /**
3925 : * cairo_get_line_cap:
3926 : * @cr: a cairo context
3927 : *
3928 : * Gets the current line cap style, as set by cairo_set_line_cap().
3929 : *
3930 : * Return value: the current line cap style.
3931 : **/
3932 : cairo_line_cap_t
3933 0 : cairo_get_line_cap (cairo_t *cr)
3934 : {
3935 0 : if (unlikely (cr->status))
3936 0 : return CAIRO_GSTATE_LINE_CAP_DEFAULT;
3937 :
3938 0 : return _cairo_gstate_get_line_cap (cr->gstate);
3939 : }
3940 :
3941 : /**
3942 : * cairo_get_line_join:
3943 : * @cr: a cairo context
3944 : *
3945 : * Gets the current line join style, as set by cairo_set_line_join().
3946 : *
3947 : * Return value: the current line join style.
3948 : **/
3949 : cairo_line_join_t
3950 0 : cairo_get_line_join (cairo_t *cr)
3951 : {
3952 0 : if (unlikely (cr->status))
3953 0 : return CAIRO_GSTATE_LINE_JOIN_DEFAULT;
3954 :
3955 0 : return _cairo_gstate_get_line_join (cr->gstate);
3956 : }
3957 :
3958 : /**
3959 : * cairo_get_miter_limit:
3960 : * @cr: a cairo context
3961 : *
3962 : * Gets the current miter limit, as set by cairo_set_miter_limit().
3963 : *
3964 : * Return value: the current miter limit.
3965 : **/
3966 : double
3967 0 : cairo_get_miter_limit (cairo_t *cr)
3968 : {
3969 0 : if (unlikely (cr->status))
3970 0 : return CAIRO_GSTATE_MITER_LIMIT_DEFAULT;
3971 :
3972 0 : return _cairo_gstate_get_miter_limit (cr->gstate);
3973 : }
3974 :
3975 : /**
3976 : * cairo_get_matrix:
3977 : * @cr: a cairo context
3978 : * @matrix: return value for the matrix
3979 : *
3980 : * Stores the current transformation matrix (CTM) into @matrix.
3981 : **/
3982 : void
3983 0 : cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix)
3984 : {
3985 0 : if (unlikely (cr->status)) {
3986 0 : cairo_matrix_init_identity (matrix);
3987 0 : return;
3988 : }
3989 :
3990 0 : _cairo_gstate_get_matrix (cr->gstate, matrix);
3991 : }
3992 : slim_hidden_def (cairo_get_matrix);
3993 :
3994 : /**
3995 : * cairo_get_target:
3996 : * @cr: a cairo context
3997 : *
3998 : * Gets the target surface for the cairo context as passed to
3999 : * cairo_create().
4000 : *
4001 : * This function will always return a valid pointer, but the result
4002 : * can be a "nil" surface if @cr is already in an error state,
4003 : * (ie. cairo_status() <literal>!=</literal> %CAIRO_STATUS_SUCCESS).
4004 : * A nil surface is indicated by cairo_surface_status()
4005 : * <literal>!=</literal> %CAIRO_STATUS_SUCCESS.
4006 : *
4007 : * Return value: the target surface. This object is owned by cairo. To
4008 : * keep a reference to it, you must call cairo_surface_reference().
4009 : **/
4010 : cairo_surface_t *
4011 0 : cairo_get_target (cairo_t *cr)
4012 : {
4013 0 : if (unlikely (cr->status))
4014 0 : return _cairo_surface_create_in_error (cr->status);
4015 :
4016 0 : return _cairo_gstate_get_original_target (cr->gstate);
4017 : }
4018 : slim_hidden_def (cairo_get_target);
4019 :
4020 : /**
4021 : * cairo_get_group_target:
4022 : * @cr: a cairo context
4023 : *
4024 : * Gets the current destination surface for the context. This is either
4025 : * the original target surface as passed to cairo_create() or the target
4026 : * surface for the current group as started by the most recent call to
4027 : * cairo_push_group() or cairo_push_group_with_content().
4028 : *
4029 : * This function will always return a valid pointer, but the result
4030 : * can be a "nil" surface if @cr is already in an error state,
4031 : * (ie. cairo_status() <literal>!=</literal> %CAIRO_STATUS_SUCCESS).
4032 : * A nil surface is indicated by cairo_surface_status()
4033 : * <literal>!=</literal> %CAIRO_STATUS_SUCCESS.
4034 : *
4035 : * Return value: the target surface. This object is owned by cairo. To
4036 : * keep a reference to it, you must call cairo_surface_reference().
4037 : *
4038 : * Since: 1.2
4039 : **/
4040 : cairo_surface_t *
4041 0 : cairo_get_group_target (cairo_t *cr)
4042 : {
4043 0 : if (unlikely (cr->status))
4044 0 : return _cairo_surface_create_in_error (cr->status);
4045 :
4046 0 : return _cairo_gstate_get_target (cr->gstate);
4047 : }
4048 :
4049 : /**
4050 : * cairo_copy_path:
4051 : * @cr: a cairo context
4052 : *
4053 : * Creates a copy of the current path and returns it to the user as a
4054 : * #cairo_path_t. See #cairo_path_data_t for hints on how to iterate
4055 : * over the returned data structure.
4056 : *
4057 : * This function will always return a valid pointer, but the result
4058 : * will have no data (<literal>data==%NULL</literal> and
4059 : * <literal>num_data==0</literal>), if either of the following
4060 : * conditions hold:
4061 : *
4062 : * <orderedlist>
4063 : * <listitem>If there is insufficient memory to copy the path. In this
4064 : * case <literal>path->status</literal> will be set to
4065 : * %CAIRO_STATUS_NO_MEMORY.</listitem>
4066 : * <listitem>If @cr is already in an error state. In this case
4067 : * <literal>path->status</literal> will contain the same status that
4068 : * would be returned by cairo_status().</listitem>
4069 : * </orderedlist>
4070 : *
4071 : * Return value: the copy of the current path. The caller owns the
4072 : * returned object and should call cairo_path_destroy() when finished
4073 : * with it.
4074 : **/
4075 : cairo_path_t *
4076 0 : cairo_copy_path (cairo_t *cr)
4077 : {
4078 0 : if (unlikely (cr->status))
4079 0 : return _cairo_path_create_in_error (cr->status);
4080 :
4081 0 : return _cairo_path_create (cr->path, cr->gstate);
4082 : }
4083 :
4084 : /**
4085 : * cairo_copy_path_flat:
4086 : * @cr: a cairo context
4087 : *
4088 : * Gets a flattened copy of the current path and returns it to the
4089 : * user as a #cairo_path_t. See #cairo_path_data_t for hints on
4090 : * how to iterate over the returned data structure.
4091 : *
4092 : * This function is like cairo_copy_path() except that any curves
4093 : * in the path will be approximated with piecewise-linear
4094 : * approximations, (accurate to within the current tolerance
4095 : * value). That is, the result is guaranteed to not have any elements
4096 : * of type %CAIRO_PATH_CURVE_TO which will instead be replaced by a
4097 : * series of %CAIRO_PATH_LINE_TO elements.
4098 : *
4099 : * This function will always return a valid pointer, but the result
4100 : * will have no data (<literal>data==%NULL</literal> and
4101 : * <literal>num_data==0</literal>), if either of the following
4102 : * conditions hold:
4103 : *
4104 : * <orderedlist>
4105 : * <listitem>If there is insufficient memory to copy the path. In this
4106 : * case <literal>path->status</literal> will be set to
4107 : * %CAIRO_STATUS_NO_MEMORY.</listitem>
4108 : * <listitem>If @cr is already in an error state. In this case
4109 : * <literal>path->status</literal> will contain the same status that
4110 : * would be returned by cairo_status().</listitem>
4111 : * </orderedlist>
4112 : *
4113 : * Return value: the copy of the current path. The caller owns the
4114 : * returned object and should call cairo_path_destroy() when finished
4115 : * with it.
4116 : **/
4117 : cairo_path_t *
4118 0 : cairo_copy_path_flat (cairo_t *cr)
4119 : {
4120 0 : if (unlikely (cr->status))
4121 0 : return _cairo_path_create_in_error (cr->status);
4122 :
4123 0 : return _cairo_path_create_flat (cr->path, cr->gstate);
4124 : }
4125 :
4126 : /**
4127 : * cairo_append_path:
4128 : * @cr: a cairo context
4129 : * @path: path to be appended
4130 : *
4131 : * Append the @path onto the current path. The @path may be either the
4132 : * return value from one of cairo_copy_path() or
4133 : * cairo_copy_path_flat() or it may be constructed manually. See
4134 : * #cairo_path_t for details on how the path data structure should be
4135 : * initialized, and note that <literal>path->status</literal> must be
4136 : * initialized to %CAIRO_STATUS_SUCCESS.
4137 : **/
4138 : void
4139 0 : cairo_append_path (cairo_t *cr,
4140 : const cairo_path_t *path)
4141 : {
4142 : cairo_status_t status;
4143 :
4144 0 : if (unlikely (cr->status))
4145 0 : return;
4146 :
4147 0 : if (path == NULL) {
4148 0 : _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
4149 0 : return;
4150 : }
4151 :
4152 0 : if (path->status) {
4153 0 : if (path->status > CAIRO_STATUS_SUCCESS &&
4154 0 : path->status <= CAIRO_STATUS_LAST_STATUS)
4155 0 : _cairo_set_error (cr, path->status);
4156 : else
4157 0 : _cairo_set_error (cr, CAIRO_STATUS_INVALID_STATUS);
4158 0 : return;
4159 : }
4160 :
4161 0 : if (path->num_data == 0)
4162 0 : return;
4163 :
4164 0 : if (path->data == NULL) {
4165 0 : _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
4166 0 : return;
4167 : }
4168 :
4169 0 : status = _cairo_path_append_to_context (path, cr);
4170 0 : if (unlikely (status))
4171 0 : _cairo_set_error (cr, status);
4172 : }
4173 :
4174 : /**
4175 : * cairo_status:
4176 : * @cr: a cairo context
4177 : *
4178 : * Checks whether an error has previously occurred for this context.
4179 : *
4180 : * Returns: the current status of this context, see #cairo_status_t
4181 : **/
4182 : cairo_status_t
4183 0 : cairo_status (cairo_t *cr)
4184 : {
4185 0 : return cr->status;
4186 : }
4187 : slim_hidden_def (cairo_status);
|