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