3,6 → 3,7 |
* |
* Copyright © 2002 University of Southern California |
* Copyright © 2005 Red Hat, Inc. |
* Copyright © 2011 Intel Corporation |
* |
* This library is free software; you can redistribute it and/or |
* modify it either under the terms of the GNU Lesser General Public |
34,15 → 35,21 |
* |
* Contributor(s): |
* Carl D. Worth <cworth@cworth.org> |
* Chris Wilson <chris@chris-wilson.co.uk> |
*/ |
|
#include "cairoint.h" |
#include "cairo-private.h" |
|
#include "cairo-arc-private.h" |
#include "cairo-backend-private.h" |
#include "cairo-error-private.h" |
#include "cairo-path-private.h" |
#include "cairo-pattern-private.h" |
#include "cairo-surface-private.h" |
#include "cairo-surface-backend-private.h" |
|
#include <assert.h> |
|
/** |
* SECTION:cairo |
* @Title: cairo_t |
56,9 → 63,9 |
* draw shapes with cairo_stroke() or cairo_fill(). |
* |
* #cairo_t<!-- -->'s can be pushed to a stack via cairo_save(). |
* They may then safely be changed, without loosing the current state. |
* They may then safely be changed, without losing the current state. |
* Use cairo_restore() to restore to the saved state. |
*/ |
**/ |
|
/** |
* SECTION:cairo-text |
85,7 → 92,7 |
* the pangocairo that is part of the Pango text layout and rendering library. |
* Pango is available from <ulink |
* url="http://www.pango.org/">http://www.pango.org/</ulink>. |
*/ |
**/ |
|
/** |
* SECTION:cairo-transforms |
98,84 → 105,58 |
* drawing instruments from the <firstterm>user space</firstterm> into the |
* surface's canonical coordinate system, also known as the <firstterm>device |
* space</firstterm>. |
*/ |
**/ |
|
#define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1) |
#define DEFINE_NIL_CONTEXT(status) \ |
{ \ |
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \ |
status, /* status */ \ |
{ 0, 0, 0, NULL }, /* user_data */ \ |
NULL \ |
} |
|
#if !defined(INFINITY) |
#define INFINITY HUGE_VAL |
#endif |
|
static const cairo_t _cairo_nil = { |
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ |
CAIRO_STATUS_NO_MEMORY, /* status */ |
{ 0, 0, 0, NULL }, /* user_data */ |
NULL, /* gstate */ |
{{ 0 }, { 0 }}, /* gstate_tail */ |
NULL, /* gstate_freelist */ |
{{ /* path */ |
{ 0, 0 }, /* last_move_point */ |
{ 0, 0 }, /* current point */ |
FALSE, /* has_current_point */ |
FALSE, /* has_last_move_point */ |
FALSE, /* has_curve_to */ |
FALSE, /* is_box */ |
FALSE, /* maybe_fill_region */ |
TRUE, /* is_empty_fill */ |
{ {0, 0}, {0, 0}}, /* extents */ |
{{{NULL,NULL}}} /* link */ |
}} |
static const cairo_t _cairo_nil[] = { |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_NO_MEMORY), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_RESTORE), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_POP_GROUP), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_NO_CURRENT_POINT), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_MATRIX), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_STATUS), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_NULL_POINTER), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_STRING), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_PATH_DATA), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_READ_ERROR), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_WRITE_ERROR), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_SURFACE_FINISHED), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_SURFACE_TYPE_MISMATCH), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_PATTERN_TYPE_MISMATCH), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_CONTENT), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_FORMAT), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_VISUAL), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_FILE_NOT_FOUND), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_DASH), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_DSC_COMMENT), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_INDEX), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_TEMP_FILE_ERROR), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_STRIDE), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_FONT_TYPE_MISMATCH), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_USER_FONT_IMMUTABLE), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_USER_FONT_ERROR), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_NEGATIVE_COUNT), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_CLUSTERS), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_SLANT), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_WEIGHT), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_SIZE), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_TYPE_MISMATCH), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_ERROR), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_MESH_CONSTRUCTION), |
DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_FINISHED) |
}; |
COMPILE_TIME_ASSERT (ARRAY_LENGTH (_cairo_nil) == CAIRO_STATUS_LAST_STATUS - 1); |
|
static const cairo_t _cairo_nil__null_pointer = { |
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ |
CAIRO_STATUS_NULL_POINTER, /* status */ |
{ 0, 0, 0, NULL }, /* user_data */ |
NULL, /* gstate */ |
{{ 0 }, { 0 }}, /* gstate_tail */ |
NULL, /* gstate_freelist */ |
{{ /* path */ |
{ 0, 0 }, /* last_move_point */ |
{ 0, 0 }, /* current point */ |
FALSE, /* has_current_point */ |
FALSE, /* has_last_move_point */ |
FALSE, /* has_curve_to */ |
FALSE, /* is_box */ |
FALSE, /* maybe_fill_region */ |
TRUE, /* is_empty_fill */ |
{ {0, 0}, {0, 0}}, /* extents */ |
{{{NULL,NULL}}} /* link */ |
}} |
}; |
#include <assert.h> |
|
/** |
* _cairo_error: |
* @status: a status value indicating an error, (eg. not |
* %CAIRO_STATUS_SUCCESS) |
* |
* Checks that status is an error status, but does nothing else. |
* |
* All assignments of an error status to any user-visible object |
* within the cairo application should result in a call to |
* _cairo_error(). |
* |
* The purpose of this function is to allow the user to set a |
* breakpoint in _cairo_error() to generate a stack trace for when the |
* user causes cairo to detect an error. |
* |
* Return value: the error status. |
**/ |
cairo_status_t |
_cairo_error (cairo_status_t status) |
{ |
CAIRO_ENSURE_UNIQUE; |
assert (_cairo_status_is_error (status)); |
|
return status; |
} |
|
/** |
* _cairo_set_error: |
* @cr: a cairo context |
* @status: a status value indicating an error |
199,89 → 180,7 |
_cairo_status_set_error (&cr->status, _cairo_error (status)); |
} |
|
/* We keep a small stash of contexts to reduce malloc pressure */ |
#define CAIRO_STASH_SIZE 4 |
#if CAIRO_NO_MUTEX |
static struct { |
cairo_t pool[CAIRO_STASH_SIZE]; |
int occupied; |
} _context_stash; |
|
static cairo_t * |
_context_get (void) |
{ |
int avail; |
|
avail = ffs (~_context_stash.occupied) - 1; |
if (avail >= CAIRO_STASH_SIZE) |
return malloc (sizeof (cairo_t)); |
|
_context_stash.occupied |= 1 << avail; |
return &_context_stash.pool[avail]; |
} |
|
static void |
_context_put (cairo_t *cr) |
{ |
if (cr < &_context_stash.pool[0] || |
cr >= &_context_stash.pool[CAIRO_STASH_SIZE]) |
{ |
free (cr); |
return; |
} |
|
_context_stash.occupied &= ~(1 << (cr - &_context_stash.pool[0])); |
} |
#elif HAS_ATOMIC_OPS |
static struct { |
cairo_t pool[CAIRO_STASH_SIZE]; |
cairo_atomic_int_t occupied; |
} _context_stash; |
|
static cairo_t * |
_context_get (void) |
{ |
cairo_atomic_int_t avail, old, new; |
|
do { |
old = _cairo_atomic_int_get (&_context_stash.occupied); |
avail = ffs (~old) - 1; |
if (avail >= CAIRO_STASH_SIZE) |
return malloc (sizeof (cairo_t)); |
|
new = old | (1 << avail); |
} while (! _cairo_atomic_int_cmpxchg (&_context_stash.occupied, old, new)); |
|
return &_context_stash.pool[avail]; |
} |
|
static void |
_context_put (cairo_t *cr) |
{ |
cairo_atomic_int_t old, new, avail; |
|
if (cr < &_context_stash.pool[0] || |
cr >= &_context_stash.pool[CAIRO_STASH_SIZE]) |
{ |
free (cr); |
return; |
} |
|
avail = ~(1 << (cr - &_context_stash.pool[0])); |
do { |
old = _cairo_atomic_int_get (&_context_stash.occupied); |
new = old & avail; |
} while (! _cairo_atomic_int_cmpxchg (&_context_stash.occupied, old, new)); |
} |
#else |
#define _context_get() malloc (sizeof (cairo_t)) |
#define _context_put(cr) free (cr) |
#endif |
|
/* XXX This should disappear in favour of a common pool of error objects. */ |
static cairo_t *_cairo_nil__objects[CAIRO_STATUS_LAST_STATUS + 1]; |
|
static cairo_t * |
cairo_t * |
_cairo_create_in_error (cairo_status_t status) |
{ |
cairo_t *cr; |
288,51 → 187,12 |
|
assert (status != CAIRO_STATUS_SUCCESS); |
|
/* special case OOM in order to avoid another allocation */ |
switch ((int) status) { |
case CAIRO_STATUS_NO_MEMORY: |
return (cairo_t *) &_cairo_nil; |
case CAIRO_STATUS_NULL_POINTER: |
return (cairo_t *) &_cairo_nil__null_pointer; |
} |
cr = (cairo_t *) &_cairo_nil[status - CAIRO_STATUS_NO_MEMORY]; |
assert (status == cr->status); |
|
CAIRO_MUTEX_LOCK (_cairo_error_mutex); |
cr = _cairo_nil__objects[status]; |
if (cr == NULL) { |
cr = malloc (sizeof (cairo_t)); |
if (unlikely (cr == NULL)) { |
CAIRO_MUTEX_UNLOCK (_cairo_error_mutex); |
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY); |
return (cairo_t *) &_cairo_nil; |
} |
|
*cr = _cairo_nil; |
cr->status = status; |
_cairo_nil__objects[status] = cr; |
} |
CAIRO_MUTEX_UNLOCK (_cairo_error_mutex); |
|
return cr; |
} |
|
void |
_cairo_reset_static_data (void) |
{ |
int status; |
|
CAIRO_MUTEX_LOCK (_cairo_error_mutex); |
for (status = CAIRO_STATUS_SUCCESS; |
status <= CAIRO_STATUS_LAST_STATUS; |
status++) |
{ |
if (_cairo_nil__objects[status] != NULL) { |
free (_cairo_nil__objects[status]); |
_cairo_nil__objects[status] = NULL; |
} |
} |
CAIRO_MUTEX_UNLOCK (_cairo_error_mutex); |
} |
|
/** |
* cairo_create: |
* @target: target surface for the context |
341,7 → 201,8 |
* default values and with @target as a target surface. The target |
* surface should be constructed with a backend-specific function such |
* as cairo_image_surface_create() (or any other |
* cairo_<emphasis>backend</emphasis>_surface_create() variant). |
* <function>cairo_<emphasis>backend</emphasis>_surface_create(<!-- -->)</function> |
* variant). |
* |
* This function references @target, so you can immediately |
* call cairo_surface_destroy() on it if you don't need to |
352,46 → 213,41 |
* with cairo_destroy() when you are done using the #cairo_t. |
* This function never returns %NULL. If memory cannot be |
* allocated, a special #cairo_t object will be returned on |
* which cairo_status() returns %CAIRO_STATUS_NO_MEMORY. |
* You can use this object normally, but no drawing will |
* be done. |
* which cairo_status() returns %CAIRO_STATUS_NO_MEMORY. If |
* you attempt to target a surface which does not support |
* writing (such as #cairo_mime_surface_t) then a |
* %CAIRO_STATUS_WRITE_ERROR will be raised. You can use this |
* object normally, but no drawing will be done. |
* |
* Since: 1.0 |
**/ |
cairo_t * |
cairo_create (cairo_surface_t *target) |
{ |
cairo_t *cr; |
cairo_status_t status; |
|
if (unlikely (target == NULL)) |
return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER)); |
if (unlikely (target->status)) |
return _cairo_create_in_error (target->status); |
|
cr = _context_get (); |
if (unlikely (cr == NULL)) |
return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
if (target->backend->create_context == NULL) |
return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_WRITE_ERROR)); |
|
return target->backend->create_context (target); |
|
} |
slim_hidden_def (cairo_create); |
|
void |
_cairo_init (cairo_t *cr, |
const cairo_backend_t *backend) |
{ |
CAIRO_REFERENCE_COUNT_INIT (&cr->ref_count, 1); |
|
cr->status = CAIRO_STATUS_SUCCESS; |
|
_cairo_user_data_array_init (&cr->user_data); |
_cairo_path_fixed_init (cr->path); |
|
cr->gstate = &cr->gstate_tail[0]; |
cr->gstate_freelist = &cr->gstate_tail[1]; |
cr->gstate_tail[1].next = NULL; |
|
status = _cairo_gstate_init (cr->gstate, target); |
if (unlikely (status)) { |
_context_put (cr); |
cr = _cairo_create_in_error (status); |
cr->backend = backend; |
} |
|
return cr; |
} |
slim_hidden_def (cairo_create); |
|
/** |
* cairo_reference: |
* @cr: a #cairo_t |
404,6 → 260,8 |
* cairo_get_reference_count(). |
* |
* Return value: the referenced #cairo_t. |
* |
* Since: 1.0 |
**/ |
cairo_t * |
cairo_reference (cairo_t *cr) |
418,6 → 276,12 |
return cr; |
} |
|
void |
_cairo_fini (cairo_t *cr) |
{ |
_cairo_user_data_array_fini (&cr->user_data); |
} |
|
/** |
* cairo_destroy: |
* @cr: a #cairo_t |
425,6 → 289,8 |
* Decreases the reference count on @cr by one. If the result |
* is zero, then @cr and all associated resources are freed. |
* See cairo_reference(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_destroy (cairo_t *cr) |
437,28 → 303,8 |
if (! _cairo_reference_count_dec_and_test (&cr->ref_count)) |
return; |
|
while (cr->gstate != &cr->gstate_tail[0]) { |
if (_cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist)) |
break; |
cr->backend->destroy (cr); |
} |
|
_cairo_gstate_fini (cr->gstate); |
cr->gstate_freelist = cr->gstate_freelist->next; /* skip over tail[1] */ |
while (cr->gstate_freelist != NULL) { |
cairo_gstate_t *gstate = cr->gstate_freelist; |
cr->gstate_freelist = gstate->next; |
free (gstate); |
} |
|
_cairo_path_fixed_fini (cr->path); |
|
_cairo_user_data_array_fini (&cr->user_data); |
|
/* mark the context as invalid to protect against misuse */ |
cr->status = CAIRO_STATUS_NULL_POINTER; |
|
_context_put (cr); |
} |
slim_hidden_def (cairo_destroy); |
|
/** |
479,8 → 325,7 |
cairo_get_user_data (cairo_t *cr, |
const cairo_user_data_key_t *key) |
{ |
return _cairo_user_data_array_get_data (&cr->user_data, |
key); |
return _cairo_user_data_array_get_data (&cr->user_data, key); |
} |
|
/** |
549,6 → 394,8 |
* a #cairo_t is freed. If the reference count of a #cairo_t |
* drops to zero in response to a call to cairo_destroy(), |
* any saved states will be freed along with the #cairo_t. |
* |
* Since: 1.0 |
**/ |
void |
cairo_save (cairo_t *cr) |
558,7 → 405,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist); |
status = cr->backend->save (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
571,6 → 418,8 |
* Restores @cr to the state saved by a preceding call to |
* cairo_save() and removes that state from the stack of |
* saved states. |
* |
* Since: 1.0 |
**/ |
void |
cairo_restore (cairo_t *cr) |
580,7 → 429,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); |
status = cr->backend->restore (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
629,7 → 478,7 |
* </programlisting></informalexample> |
* |
* Since: 1.2 |
*/ |
**/ |
void |
cairo_push_group (cairo_t *cr) |
{ |
654,73 → 503,17 |
* detailed description of group rendering. |
* |
* Since: 1.2 |
*/ |
**/ |
void |
cairo_push_group_with_content (cairo_t *cr, cairo_content_t content) |
{ |
cairo_surface_t *group_surface; |
cairo_clip_t *clip; |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
clip = _cairo_gstate_get_clip (cr->gstate); |
if (clip->all_clipped) { |
group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0); |
status = group_surface->status; |
status = cr->backend->push_group (cr, content); |
if (unlikely (status)) |
goto bail; |
} else { |
cairo_surface_t *parent_surface; |
const cairo_rectangle_int_t *clip_extents; |
cairo_rectangle_int_t extents; |
cairo_matrix_t matrix; |
cairo_bool_t is_empty; |
|
parent_surface = _cairo_gstate_get_target (cr->gstate); |
|
/* Get the extents that we'll use in creating our new group surface */ |
is_empty = _cairo_surface_get_extents (parent_surface, &extents); |
clip_extents = _cairo_clip_get_extents (_cairo_gstate_get_clip (cr->gstate)); |
if (clip_extents != NULL) |
is_empty = _cairo_rectangle_intersect (&extents, clip_extents); |
|
group_surface = _cairo_surface_create_similar_solid (parent_surface, |
content, |
extents.width, |
extents.height, |
CAIRO_COLOR_TRANSPARENT, |
TRUE); |
status = group_surface->status; |
if (unlikely (status)) |
goto bail; |
|
/* Set device offsets on the new surface so that logically it appears at |
* the same location on the parent surface -- when we pop_group this, |
* the source pattern will get fixed up for the appropriate target surface |
* device offsets, so we want to set our own surface offsets from /that/, |
* and not from the device origin. */ |
cairo_surface_set_device_offset (group_surface, |
parent_surface->device_transform.x0 - extents.x, |
parent_surface->device_transform.y0 - extents.y); |
|
/* If we have a current path, we need to adjust it to compensate for |
* the device offset just applied. */ |
cairo_matrix_init_translate (&matrix, -extents.x, -extents.y); |
_cairo_path_fixed_transform (cr->path, &matrix); |
} |
|
/* create a new gstate for the redirect */ |
cairo_save (cr); |
if (unlikely (cr->status)) |
goto bail; |
|
status = _cairo_gstate_redirect_target (cr->gstate, group_surface); |
|
bail: |
cairo_surface_destroy (group_surface); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
slim_hidden_def(cairo_push_group_with_content); |
749,65 → 542,15 |
cairo_pattern_t * |
cairo_pop_group (cairo_t *cr) |
{ |
cairo_surface_t *group_surface, *parent_target; |
cairo_pattern_t *group_pattern; |
cairo_matrix_t group_matrix, device_transform_matrix; |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return _cairo_pattern_create_in_error (cr->status); |
|
/* Grab the active surfaces */ |
group_surface = _cairo_gstate_get_target (cr->gstate); |
parent_target = _cairo_gstate_get_parent_target (cr->gstate); |
group_pattern = cr->backend->pop_group (cr); |
if (unlikely (group_pattern->status)) |
_cairo_set_error (cr, group_pattern->status); |
|
/* Verify that we are at the right nesting level */ |
if (parent_target == NULL) { |
_cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP); |
return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP); |
} |
|
/* We need to save group_surface before we restore; we don't need |
* to reference parent_target and original_target, since the |
* gstate will still hold refs to them once we restore. */ |
group_surface = cairo_surface_reference (group_surface); |
|
cairo_restore (cr); |
|
if (unlikely (cr->status)) { |
group_pattern = _cairo_pattern_create_in_error (cr->status); |
goto done; |
} |
|
group_pattern = cairo_pattern_create_for_surface (group_surface); |
status = group_pattern->status; |
if (unlikely (status)) { |
_cairo_set_error (cr, status); |
goto done; |
} |
|
_cairo_gstate_get_matrix (cr->gstate, &group_matrix); |
/* Transform by group_matrix centered around device_transform so that when |
* we call _cairo_gstate_copy_transformed_pattern the result is a pattern |
* with a matrix equivalent to the device_transform of group_surface. */ |
if (_cairo_surface_has_device_transform (group_surface)) { |
cairo_pattern_set_matrix (group_pattern, &group_surface->device_transform); |
_cairo_pattern_transform (group_pattern, &group_matrix); |
_cairo_pattern_transform (group_pattern, &group_surface->device_transform_inverse); |
} else { |
cairo_pattern_set_matrix (group_pattern, &group_matrix); |
} |
|
/* If we have a current path, we need to adjust it to compensate for |
* the device offset just removed. */ |
cairo_matrix_multiply (&device_transform_matrix, |
&_cairo_gstate_get_target (cr->gstate)->device_transform, |
&group_surface->device_transform_inverse); |
_cairo_path_fixed_transform (cr->path, &device_transform_matrix); |
|
done: |
cairo_surface_destroy (group_surface); |
|
return group_pattern; |
} |
slim_hidden_def(cairo_pop_group); |
824,7 → 567,7 |
* operations: |
* |
* <informalexample><programlisting> |
* #cairo_pattern_t *group = cairo_pop_group (cr); |
* cairo_pattern_t *group = cairo_pop_group (cr); |
* cairo_set_source (cr, group); |
* cairo_pattern_destroy (group); |
* </programlisting></informalexample> |
859,6 → 602,8 |
* each available compositing operator. |
* |
* The default operator is %CAIRO_OPERATOR_OVER. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_operator (cairo_t *cr, cairo_operator_t op) |
868,7 → 613,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_operator (cr->gstate, op); |
status = cr->backend->set_operator (cr, op); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
875,31 → 620,36 |
slim_hidden_def (cairo_set_operator); |
|
|
static cairo_bool_t |
_current_source_matches_solid (cairo_t *cr, |
double red, |
double green, |
double blue, |
double alpha) |
#if 0 |
/** |
* cairo_set_opacity: |
* @cr: a #cairo_t |
* @opacity: the level of opacity to use when compositing |
* |
* Sets the compositing opacity to be used for all drawing |
* operations. The effect is to fade out the operations |
* using the alpha value. |
* |
* The default opacity is 1. |
* |
* Since: TBD |
**/ |
void |
cairo_set_opacity (cairo_t *cr, double opacity) |
{ |
const cairo_pattern_t *current; |
cairo_color_t color; |
cairo_status_t status; |
|
current = cr->gstate->source; |
if (current->type != CAIRO_PATTERN_TYPE_SOLID) |
return FALSE; |
if (unlikely (cr->status)) |
return; |
|
red = _cairo_restrict_value (red, 0.0, 1.0); |
green = _cairo_restrict_value (green, 0.0, 1.0); |
blue = _cairo_restrict_value (blue, 0.0, 1.0); |
alpha = _cairo_restrict_value (alpha, 0.0, 1.0); |
status = cr->backend->set_opacity (cr, opacity); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
#endif |
|
_cairo_color_init_rgba (&color, red, green, blue, alpha); |
return _cairo_color_equal (&color, |
&((cairo_solid_pattern_t *) current)->color); |
} |
/** |
* cairo_set_source_rgb |
* cairo_set_source_rgb: |
* @cr: a cairo context |
* @red: red component of color |
* @green: green component of color |
915,24 → 665,20 |
* |
* The default source pattern is opaque black, (that is, it is |
* equivalent to cairo_set_source_rgb(cr, 0.0, 0.0, 0.0)). |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue) |
{ |
cairo_pattern_t *pattern; |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
if (_current_source_matches_solid (cr, red, green, blue, 1.)) |
return; |
|
/* push the current pattern to the freed lists */ |
cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black); |
|
pattern = cairo_pattern_create_rgb (red, green, blue); |
cairo_set_source (cr, pattern); |
cairo_pattern_destroy (pattern); |
status = cr->backend->set_source_rgba (cr, red, green, blue, 1.); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
slim_hidden_def (cairo_set_source_rgb); |
|
954,6 → 700,8 |
* |
* The default source pattern is opaque black, (that is, it is |
* equivalent to cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0)). |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_source_rgba (cairo_t *cr, |
960,20 → 708,14 |
double red, double green, double blue, |
double alpha) |
{ |
cairo_pattern_t *pattern; |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
if (_current_source_matches_solid (cr, red, green, blue, alpha)) |
return; |
|
/* push the current pattern to the freed lists */ |
cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black); |
|
pattern = cairo_pattern_create_rgba (red, green, blue, alpha); |
cairo_set_source (cr, pattern); |
cairo_pattern_destroy (pattern); |
status = cr->backend->set_source_rgba (cr, red, green, blue, alpha); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
|
/** |
998,6 → 740,8 |
* The resulting pattern can be queried with cairo_get_source() so |
* that these attributes can be modified if desired, (eg. to create a |
* repeating pattern with cairo_pattern_set_extend()). |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_source_surface (cairo_t *cr, |
1005,27 → 749,24 |
double x, |
double y) |
{ |
cairo_pattern_t *pattern; |
cairo_matrix_t matrix; |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
/* push the current pattern to the freed lists */ |
cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black); |
if (unlikely (surface == NULL)) { |
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); |
return; |
} |
|
pattern = cairo_pattern_create_for_surface (surface); |
|
cairo_matrix_init_translate (&matrix, -x, -y); |
cairo_pattern_set_matrix (pattern, &matrix); |
|
cairo_set_source (cr, pattern); |
cairo_pattern_destroy (pattern); |
status = cr->backend->set_source_surface (cr, surface, x, y); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
slim_hidden_def (cairo_set_source_surface); |
|
/** |
* cairo_set_source |
* cairo_set_source: |
* @cr: a cairo context |
* @source: a #cairo_pattern_t to be used as the source for |
* subsequent drawing operations. |
1042,6 → 783,8 |
* The default source pattern is a solid pattern that is opaque black, |
* (that is, it is equivalent to cairo_set_source_rgb(cr, 0.0, 0.0, |
* 0.0)). |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_source (cairo_t *cr, cairo_pattern_t *source) |
1051,17 → 794,17 |
if (unlikely (cr->status)) |
return; |
|
if (source == NULL) { |
if (unlikely (source == NULL)) { |
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); |
return; |
} |
|
if (source->status) { |
if (unlikely (source->status)) { |
_cairo_set_error (cr, source->status); |
return; |
} |
|
status = _cairo_gstate_set_source (cr->gstate, source); |
status = cr->backend->set_source (cr, source); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1076,6 → 819,8 |
* Return value: the current source pattern. This object is owned by |
* cairo. To keep a reference to it, you must call |
* cairo_pattern_reference(). |
* |
* Since: 1.0 |
**/ |
cairo_pattern_t * |
cairo_get_source (cairo_t *cr) |
1083,7 → 828,7 |
if (unlikely (cr->status)) |
return _cairo_pattern_create_in_error (cr->status); |
|
return _cairo_gstate_get_source (cr->gstate); |
return cr->backend->get_source (cr); |
} |
|
/** |
1101,6 → 846,8 |
* within Cairo is limited by the precision of its internal arithmetic, and |
* the prescribed @tolerance is restricted to the smallest |
* representable internal value. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_tolerance (cairo_t *cr, double tolerance) |
1110,10 → 857,7 |
if (unlikely (cr->status)) |
return; |
|
if (tolerance < CAIRO_TOLERANCE_MINIMUM) |
tolerance = CAIRO_TOLERANCE_MINIMUM; |
|
status = _cairo_gstate_set_tolerance (cr->gstate, tolerance); |
status = cr->backend->set_tolerance (cr, tolerance); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1131,6 → 875,8 |
* |
* Note that this option does not affect text rendering, instead see |
* cairo_font_options_set_antialias(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias) |
1140,7 → 886,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_antialias (cr->gstate, antialias); |
status = cr->backend->set_antialias (cr, antialias); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1157,6 → 903,8 |
* on the semantics of each available fill rule. |
* |
* The default fill rule is %CAIRO_FILL_RULE_WINDING. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule) |
1166,7 → 914,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_fill_rule (cr->gstate, fill_rule); |
status = cr->backend->set_fill_rule (cr, fill_rule); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1196,6 → 944,8 |
* construction. |
* |
* The default line width value is 2.0. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_line_width (cairo_t *cr, double width) |
1208,7 → 958,7 |
if (width < 0.) |
width = 0.; |
|
status = _cairo_gstate_set_line_width (cr->gstate, width); |
status = cr->backend->set_line_width (cr, width); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1229,6 → 979,8 |
* construction. |
* |
* The default line cap style is %CAIRO_LINE_CAP_BUTT. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap) |
1238,7 → 990,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_line_cap (cr->gstate, line_cap); |
status = cr->backend->set_line_cap (cr, line_cap); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1259,6 → 1011,8 |
* construction. |
* |
* The default line join style is %CAIRO_LINE_JOIN_MITER. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join) |
1268,7 → 1022,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_line_join (cr->gstate, line_join); |
status = cr->backend->set_line_join (cr, line_join); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1305,6 → 1059,8 |
* If any value in @dashes is negative, or if all values are 0, then |
* @cr will be put into an error state with a status of |
* %CAIRO_STATUS_INVALID_DASH. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_dash (cairo_t *cr, |
1317,8 → 1073,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_dash (cr->gstate, |
dashes, num_dashes, offset); |
status = cr->backend->set_dash (cr, dashes, num_dashes, offset); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1335,7 → 1090,7 |
* Return value: the length of the dash array, or 0 if no dash array set. |
* |
* Since: 1.4 |
*/ |
**/ |
int |
cairo_get_dash_count (cairo_t *cr) |
{ |
1344,7 → 1099,7 |
if (unlikely (cr->status)) |
return 0; |
|
_cairo_gstate_get_dash (cr->gstate, NULL, &num_dashes, NULL); |
cr->backend->get_dash (cr, NULL, &num_dashes, NULL); |
|
return num_dashes; |
} |
1369,7 → 1124,7 |
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_get_dash (cr->gstate, dashes, NULL, offset); |
cr->backend->get_dash (cr, dashes, NULL, offset); |
} |
|
/** |
1399,6 → 1154,8 |
* |
* A miter limit for a desired angle can be computed as: miter limit = |
* 1/sin(angle/2) |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_miter_limit (cairo_t *cr, double limit) |
1408,7 → 1165,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_miter_limit (cr->gstate, limit); |
status = cr->backend->set_miter_limit (cr, limit); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1424,6 → 1181,8 |
* user-space coordinate according to the CTM in place before the new |
* call to cairo_translate(). In other words, the translation of the |
* user-space origin takes place after any existing transformation. |
* |
* Since: 1.0 |
**/ |
void |
cairo_translate (cairo_t *cr, double tx, double ty) |
1433,7 → 1192,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_translate (cr->gstate, tx, ty); |
status = cr->backend->translate (cr, tx, ty); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1449,6 → 1208,8 |
* and Y user-space axes by @sx and @sy respectively. The scaling of |
* the axes takes place after any existing transformation of user |
* space. |
* |
* Since: 1.0 |
**/ |
void |
cairo_scale (cairo_t *cr, double sx, double sy) |
1458,7 → 1219,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_scale (cr->gstate, sx, sy); |
status = cr->backend->scale (cr, sx, sy); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1475,6 → 1236,8 |
* places after any existing transformation of user space. The |
* rotation direction for positive angles is from the positive X axis |
* toward the positive Y axis. |
* |
* Since: 1.0 |
**/ |
void |
cairo_rotate (cairo_t *cr, double angle) |
1484,7 → 1247,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_rotate (cr->gstate, angle); |
status = cr->backend->rotate (cr, angle); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1497,6 → 1260,8 |
* Modifies the current transformation matrix (CTM) by applying |
* @matrix as an additional transformation. The new transformation of |
* user space takes place after any existing transformation. |
* |
* Since: 1.0 |
**/ |
void |
cairo_transform (cairo_t *cr, |
1507,7 → 1272,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_transform (cr->gstate, matrix); |
status = cr->backend->transform (cr, matrix); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1520,6 → 1285,8 |
* |
* Modifies the current transformation matrix (CTM) by setting it |
* equal to @matrix. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_matrix (cairo_t *cr, |
1530,7 → 1297,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_matrix (cr->gstate, matrix); |
status = cr->backend->set_matrix (cr, matrix); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1544,14 → 1311,20 |
* to the identity matrix. That is, the user-space and device-space |
* axes will be aligned and one user-space unit will transform to one |
* device-space unit. |
* |
* Since: 1.0 |
**/ |
void |
cairo_identity_matrix (cairo_t *cr) |
{ |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_identity_matrix (cr->gstate); |
status = cr->backend->set_identity_matrix (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
|
/** |
1563,6 → 1336,8 |
* Transform a coordinate from user space to device space by |
* multiplying the given point by the current transformation matrix |
* (CTM). |
* |
* Since: 1.0 |
**/ |
void |
cairo_user_to_device (cairo_t *cr, double *x, double *y) |
1570,7 → 1345,7 |
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_user_to_device (cr->gstate, x, y); |
cr->backend->user_to_device (cr, x, y); |
} |
slim_hidden_def (cairo_user_to_device); |
|
1584,6 → 1359,8 |
* function is similar to cairo_user_to_device() except that the |
* translation components of the CTM will be ignored when transforming |
* (@dx,@dy). |
* |
* Since: 1.0 |
**/ |
void |
cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy) |
1591,7 → 1368,7 |
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_user_to_device_distance (cr->gstate, dx, dy); |
cr->backend->user_to_device_distance (cr, dx, dy); |
} |
slim_hidden_def (cairo_user_to_device_distance); |
|
1604,6 → 1381,8 |
* Transform a coordinate from device space to user space by |
* multiplying the given point by the inverse of the current |
* transformation matrix (CTM). |
* |
* Since: 1.0 |
**/ |
void |
cairo_device_to_user (cairo_t *cr, double *x, double *y) |
1611,8 → 1390,9 |
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_device_to_user (cr->gstate, x, y); |
cr->backend->device_to_user (cr, x, y); |
} |
slim_hidden_def (cairo_device_to_user); |
|
/** |
* cairo_device_to_user_distance: |
1624,6 → 1404,8 |
* function is similar to cairo_device_to_user() except that the |
* translation components of the inverse CTM will be ignored when |
* transforming (@dx,@dy). |
* |
* Since: 1.0 |
**/ |
void |
cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy) |
1631,7 → 1413,7 |
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_device_to_user_distance (cr->gstate, dx, dy); |
cr->backend->device_to_user_distance (cr, dx, dy); |
} |
|
/** |
1640,45 → 1422,22 |
* |
* Clears the current path. After this call there will be no path and |
* no current point. |
* |
* Since: 1.0 |
**/ |
void |
cairo_new_path (cairo_t *cr) |
{ |
if (unlikely (cr->status)) |
return; |
|
_cairo_path_fixed_fini (cr->path); |
_cairo_path_fixed_init (cr->path); |
} |
slim_hidden_def(cairo_new_path); |
|
/** |
* cairo_move_to: |
* @cr: a cairo context |
* @x: the X coordinate of the new position |
* @y: the Y coordinate of the new position |
* |
* Begin a new sub-path. After this call the current point will be (@x, |
* @y). |
**/ |
void |
cairo_move_to (cairo_t *cr, double x, double y) |
{ |
cairo_status_t status; |
cairo_fixed_t x_fixed, y_fixed; |
|
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_user_to_backend (cr->gstate, &x, &y); |
x_fixed = _cairo_fixed_from_double (x); |
y_fixed = _cairo_fixed_from_double (y); |
|
status = _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed); |
status = cr->backend->new_path (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
slim_hidden_def(cairo_move_to); |
slim_hidden_def(cairo_new_path); |
|
/** |
* cairo_new_sub_path: |
1701,13 → 1460,43 |
void |
cairo_new_sub_path (cairo_t *cr) |
{ |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
_cairo_path_fixed_new_sub_path (cr->path); |
status = cr->backend->new_sub_path (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
|
/** |
* cairo_move_to: |
* @cr: a cairo context |
* @x: the X coordinate of the new position |
* @y: the Y coordinate of the new position |
* |
* Begin a new sub-path. After this call the current point will be (@x, |
* @y). |
* |
* Since: 1.0 |
**/ |
void |
cairo_move_to (cairo_t *cr, double x, double y) |
{ |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
status = cr->backend->move_to (cr, x, y); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
slim_hidden_def(cairo_move_to); |
|
|
/** |
* cairo_line_to: |
* @cr: a cairo context |
* @x: the X coordinate of the end of the new line |
1719,21 → 1508,18 |
* |
* If there is no current point before the call to cairo_line_to() |
* this function will behave as cairo_move_to(@cr, @x, @y). |
* |
* Since: 1.0 |
**/ |
void |
cairo_line_to (cairo_t *cr, double x, double y) |
{ |
cairo_status_t status; |
cairo_fixed_t x_fixed, y_fixed; |
|
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_user_to_backend (cr->gstate, &x, &y); |
x_fixed = _cairo_fixed_from_double (x); |
y_fixed = _cairo_fixed_from_double (y); |
|
status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); |
status = cr->backend->line_to (cr, x, y); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1757,6 → 1543,8 |
* If there is no current point before the call to cairo_curve_to() |
* this function will behave as if preceded by a call to |
* cairo_move_to(@cr, @x1, @y1). |
* |
* Since: 1.0 |
**/ |
void |
cairo_curve_to (cairo_t *cr, |
1765,30 → 1553,14 |
double x3, double y3) |
{ |
cairo_status_t status; |
cairo_fixed_t x1_fixed, y1_fixed; |
cairo_fixed_t x2_fixed, y2_fixed; |
cairo_fixed_t x3_fixed, y3_fixed; |
|
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_user_to_backend (cr->gstate, &x1, &y1); |
_cairo_gstate_user_to_backend (cr->gstate, &x2, &y2); |
_cairo_gstate_user_to_backend (cr->gstate, &x3, &y3); |
|
x1_fixed = _cairo_fixed_from_double (x1); |
y1_fixed = _cairo_fixed_from_double (y1); |
|
x2_fixed = _cairo_fixed_from_double (x2); |
y2_fixed = _cairo_fixed_from_double (y2); |
|
x3_fixed = _cairo_fixed_from_double (x3); |
y3_fixed = _cairo_fixed_from_double (y3); |
|
status = _cairo_path_fixed_curve_to (cr->path, |
x1_fixed, y1_fixed, |
x2_fixed, y2_fixed, |
x3_fixed, y3_fixed); |
status = cr->backend->curve_to (cr, |
x1, y1, |
x2, y2, |
x3, y3); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1806,8 → 1578,8 |
* Adds a circular arc of the given @radius to the current path. The |
* arc is centered at (@xc, @yc), begins at @angle1 and proceeds in |
* the direction of increasing angles to end at @angle2. If @angle2 is |
* less than @angle1 it will be progressively increased by 2*M_PI |
* until it is greater than @angle1. |
* less than @angle1 it will be progressively increased by |
* <literal>2*M_PI</literal> until it is greater than @angle1. |
* |
* If there is a current point, an initial line segment will be added |
* to the path to connect the current point to the beginning of the |
1815,11 → 1587,12 |
* calling cairo_new_sub_path() before calling cairo_arc(). |
* |
* Angles are measured in radians. An angle of 0.0 is in the direction |
* of the positive X axis (in user space). An angle of %M_PI/2.0 radians |
* (90 degrees) is in the direction of the positive Y axis (in |
* user space). Angles increase in the direction from the positive X |
* axis toward the positive Y axis. So with the default transformation |
* matrix, angles increase in a clockwise direction. |
* of the positive X axis (in user space). An angle of |
* <literal>M_PI/2.0</literal> radians (90 degrees) is in the |
* direction of the positive Y axis (in user space). Angles increase |
* in the direction from the positive X axis toward the positive Y |
* axis. So with the default transformation matrix, angles increase in |
* a clockwise direction. |
* |
* (To convert from degrees to radians, use <literal>degrees * (M_PI / |
* 180.)</literal>.) |
1840,6 → 1613,8 |
* cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI); |
* cairo_restore (cr); |
* </programlisting></informalexample> |
* |
* Since: 1.0 |
**/ |
void |
cairo_arc (cairo_t *cr, |
1847,25 → 1622,23 |
double radius, |
double angle1, double angle2) |
{ |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
/* Do nothing, successfully, if radius is <= 0 */ |
if (radius <= 0.0) { |
cairo_line_to (cr, xc, yc); /* might become a move_to */ |
cairo_line_to (cr, xc, yc); |
return; |
if (angle2 < angle1) { |
/* increase angle2 by multiples of full circle until it |
* satisfies angle2 >= angle1 */ |
angle2 = fmod (angle2 - angle1, 2 * M_PI); |
if (angle2 < 0) |
angle2 += 2 * M_PI; |
angle2 += angle1; |
} |
|
while (angle2 < angle1) |
angle2 += 2 * M_PI; |
|
cairo_line_to (cr, |
xc + radius * cos (angle1), |
yc + radius * sin (angle1)); |
|
_cairo_arc_path (cr, xc, yc, radius, |
angle1, angle2); |
status = cr->backend->arc (cr, xc, yc, radius, angle1, angle2, TRUE); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
|
/** |
1880,11 → 1653,13 |
* Adds a circular arc of the given @radius to the current path. The |
* arc is centered at (@xc, @yc), begins at @angle1 and proceeds in |
* the direction of decreasing angles to end at @angle2. If @angle2 is |
* greater than @angle1 it will be progressively decreased by 2*M_PI |
* until it is less than @angle1. |
* greater than @angle1 it will be progressively decreased by |
* <literal>2*M_PI</literal> until it is less than @angle1. |
* |
* See cairo_arc() for more details. This function differs only in the |
* direction of the arc between the two angles. |
* |
* Since: 1.0 |
**/ |
void |
cairo_arc_negative (cairo_t *cr, |
1892,22 → 1667,23 |
double radius, |
double angle1, double angle2) |
{ |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
/* Do nothing, successfully, if radius is <= 0 */ |
if (radius <= 0.0) |
return; |
|
while (angle2 > angle1) |
if (angle2 > angle1) { |
/* decrease angle2 by multiples of full circle until it |
* satisfies angle2 <= angle1 */ |
angle2 = fmod (angle2 - angle1, 2 * M_PI); |
if (angle2 > 0) |
angle2 -= 2 * M_PI; |
angle2 += angle1; |
} |
|
cairo_line_to (cr, |
xc + radius * cos (angle1), |
yc + radius * sin (angle1)); |
|
_cairo_arc_path_negative (cr, xc, yc, radius, |
angle1, angle2); |
status = cr->backend->arc (cr, xc, yc, radius, angle1, angle2, FALSE); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
|
/* XXX: NYI |
1922,13 → 1698,26 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_arc_to (cr->gstate, |
x1, y1, |
x2, y2, |
radius); |
status = cr->backend->arc_to (cr, x1, y1, x2, y2, radius); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
|
void |
cairo_rel_arc_to (cairo_t *cr, |
double dx1, double dy1, |
double dx2, double dy2, |
double radius) |
{ |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
status = cr->backend->rel_arc_to (cr, dx1, dy1, dx2, dy2, radius); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
*/ |
|
/** |
1946,22 → 1735,18 |
* It is an error to call this function with no current point. Doing |
* so will cause @cr to shutdown with a status of |
* %CAIRO_STATUS_NO_CURRENT_POINT. |
* |
* Since: 1.0 |
**/ |
void |
cairo_rel_move_to (cairo_t *cr, double dx, double dy) |
{ |
cairo_fixed_t dx_fixed, dy_fixed; |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); |
|
dx_fixed = _cairo_fixed_from_double (dx); |
dy_fixed = _cairo_fixed_from_double (dy); |
|
status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed); |
status = cr->backend->rel_move_to (cr, dx, dy); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
1983,22 → 1768,18 |
* It is an error to call this function with no current point. Doing |
* so will cause @cr to shutdown with a status of |
* %CAIRO_STATUS_NO_CURRENT_POINT. |
* |
* Since: 1.0 |
**/ |
void |
cairo_rel_line_to (cairo_t *cr, double dx, double dy) |
{ |
cairo_fixed_t dx_fixed, dy_fixed; |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); |
|
dx_fixed = _cairo_fixed_from_double (dx); |
dy_fixed = _cairo_fixed_from_double (dy); |
|
status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed); |
status = cr->backend->rel_line_to (cr, dx, dy); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2028,6 → 1809,8 |
* It is an error to call this function with no current point. Doing |
* so will cause @cr to shutdown with a status of |
* %CAIRO_STATUS_NO_CURRENT_POINT. |
* |
* Since: 1.0 |
**/ |
void |
cairo_rel_curve_to (cairo_t *cr, |
2035,31 → 1818,15 |
double dx2, double dy2, |
double dx3, double dy3) |
{ |
cairo_fixed_t dx1_fixed, dy1_fixed; |
cairo_fixed_t dx2_fixed, dy2_fixed; |
cairo_fixed_t dx3_fixed, dy3_fixed; |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
_cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1); |
_cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2); |
_cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3); |
|
dx1_fixed = _cairo_fixed_from_double (dx1); |
dy1_fixed = _cairo_fixed_from_double (dy1); |
|
dx2_fixed = _cairo_fixed_from_double (dx2); |
dy2_fixed = _cairo_fixed_from_double (dy2); |
|
dx3_fixed = _cairo_fixed_from_double (dx3); |
dy3_fixed = _cairo_fixed_from_double (dy3); |
|
status = _cairo_path_fixed_rel_curve_to (cr->path, |
dx1_fixed, dy1_fixed, |
dx2_fixed, dy2_fixed, |
dx3_fixed, dy3_fixed); |
status = cr->backend->rel_curve_to (cr, |
dx1, dy1, |
dx2, dy2, |
dx3, dy3); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2083,6 → 1850,8 |
* cairo_rel_line_to (cr, -width, 0); |
* cairo_close_path (cr); |
* </programlisting></informalexample> |
* |
* Since: 1.0 |
**/ |
void |
cairo_rectangle (cairo_t *cr, |
2089,14 → 1858,14 |
double x, double y, |
double width, double height) |
{ |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
cairo_move_to (cr, x, y); |
cairo_rel_line_to (cr, width, 0); |
cairo_rel_line_to (cr, 0, height); |
cairo_rel_line_to (cr, -width, 0); |
cairo_close_path (cr); |
status = cr->backend->rectangle (cr, x, y, width, height); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
|
#if 0 |
2142,6 → 1911,8 |
* not be necessary to save the "last move_to point" during processing |
* as the MOVE_TO immediately after the CLOSE_PATH will provide that |
* point. |
* |
* Since: 1.0 |
**/ |
void |
cairo_close_path (cairo_t *cr) |
2151,7 → 1922,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_path_fixed_close_path (cr->path); |
status = cr->backend->close_path (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2205,9 → 1976,7 |
return; |
} |
|
_cairo_gstate_path_extents (cr->gstate, |
cr->path, |
x1, y1, x2, y2); |
cr->backend->path_extents (cr, x1, y1, x2, y2); |
} |
|
/** |
2216,6 → 1985,8 |
* |
* A drawing operator that paints the current source everywhere within |
* the current clip region. |
* |
* Since: 1.0 |
**/ |
void |
cairo_paint (cairo_t *cr) |
2225,7 → 1996,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_paint (cr->gstate); |
status = cr->backend->paint (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2240,6 → 2011,8 |
* the current clip region using a mask of constant alpha value |
* @alpha. The effect is similar to cairo_paint(), but the drawing |
* is faded out using the alpha value. |
* |
* Since: 1.0 |
**/ |
void |
cairo_paint_with_alpha (cairo_t *cr, |
2246,30 → 2019,13 |
double alpha) |
{ |
cairo_status_t status; |
cairo_color_t color; |
cairo_solid_pattern_t pattern; |
|
if (unlikely (cr->status)) |
return; |
|
if (CAIRO_ALPHA_IS_OPAQUE (alpha)) { |
cairo_paint (cr); |
return; |
} |
|
if (CAIRO_ALPHA_IS_ZERO (alpha) && |
_cairo_operator_bounded_by_mask (cr->gstate->op)) { |
return; |
} |
|
_cairo_color_init_rgba (&color, 0., 0., 0., alpha); |
_cairo_pattern_init_solid (&pattern, &color); |
|
status = _cairo_gstate_mask (cr->gstate, &pattern.base); |
status = cr->backend->paint_with_alpha (cr, alpha); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
|
_cairo_pattern_fini (&pattern.base); |
} |
|
/** |
2281,7 → 2037,9 |
* using the alpha channel of @pattern as a mask. (Opaque |
* areas of @pattern are painted with the source, transparent |
* areas are not painted.) |
*/ |
* |
* Since: 1.0 |
**/ |
void |
cairo_mask (cairo_t *cr, |
cairo_pattern_t *pattern) |
2291,17 → 2049,17 |
if (unlikely (cr->status)) |
return; |
|
if (pattern == NULL) { |
if (unlikely (pattern == NULL)) { |
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); |
return; |
} |
|
if (pattern->status) { |
if (unlikely (pattern->status)) { |
_cairo_set_error (cr, pattern->status); |
return; |
} |
|
status = _cairo_gstate_mask (cr->gstate, pattern); |
status = cr->backend->mask (cr, pattern); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2318,7 → 2076,9 |
* using the alpha channel of @surface as a mask. (Opaque |
* areas of @surface are painted with the source, transparent |
* areas are not painted.) |
*/ |
* |
* Since: 1.0 |
**/ |
void |
cairo_mask_surface (cairo_t *cr, |
cairo_surface_t *surface, |
2372,13 → 2132,20 |
* |
* In no case will a cap style of %CAIRO_LINE_CAP_BUTT cause anything |
* to be drawn in the case of either degenerate segments or sub-paths. |
* |
* Since: 1.0 |
**/ |
void |
cairo_stroke (cairo_t *cr) |
{ |
cairo_stroke_preserve (cr); |
cairo_status_t status; |
|
cairo_new_path (cr); |
if (unlikely (cr->status)) |
return; |
|
status = cr->backend->stroke (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
slim_hidden_def(cairo_stroke); |
|
2394,6 → 2161,8 |
* See cairo_set_line_width(), cairo_set_line_join(), |
* cairo_set_line_cap(), cairo_set_dash(), and |
* cairo_stroke_preserve(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_stroke_preserve (cairo_t *cr) |
2403,7 → 2172,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_stroke (cr->gstate, cr->path); |
status = cr->backend->stroke_preserve (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2418,13 → 2187,20 |
* filled). After cairo_fill(), the current path will be cleared from |
* the cairo context. See cairo_set_fill_rule() and |
* cairo_fill_preserve(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_fill (cairo_t *cr) |
{ |
cairo_fill_preserve (cr); |
cairo_status_t status; |
|
cairo_new_path (cr); |
if (unlikely (cr->status)) |
return; |
|
status = cr->backend->fill (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
|
/** |
2437,6 → 2213,8 |
* path within the cairo context. |
* |
* See cairo_set_fill_rule() and cairo_fill(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_fill_preserve (cairo_t *cr) |
2446,7 → 2224,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_fill (cr->gstate, cr->path); |
status = cr->backend->fill_preserve (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2463,6 → 2241,8 |
* |
* This is a convenience function that simply calls |
* cairo_surface_copy_page() on @cr's target. |
* |
* Since: 1.0 |
**/ |
void |
cairo_copy_page (cairo_t *cr) |
2472,7 → 2252,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_copy_page (cr->gstate); |
status = cr->backend->copy_page (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2486,6 → 2266,8 |
* |
* This is a convenience function that simply calls |
* cairo_surface_show_page() on @cr's target. |
* |
* Since: 1.0 |
**/ |
void |
cairo_show_page (cairo_t *cr) |
2495,7 → 2277,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_show_page (cr->gstate); |
status = cr->backend->show_page (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2517,6 → 2299,8 |
* |
* Return value: A non-zero value if the point is inside, or zero if |
* outside. |
* |
* Since: 1.0 |
**/ |
cairo_bool_t |
cairo_in_stroke (cairo_t *cr, double x, double y) |
2527,9 → 2311,7 |
if (unlikely (cr->status)) |
return FALSE; |
|
status = _cairo_gstate_in_stroke (cr->gstate, |
cr->path, |
x, y, &inside); |
status = cr->backend->in_stroke (cr, x, y, &inside); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
|
2551,14 → 2333,23 |
* |
* Return value: A non-zero value if the point is inside, or zero if |
* outside. |
* |
* Since: 1.0 |
**/ |
cairo_bool_t |
cairo_in_fill (cairo_t *cr, double x, double y) |
{ |
cairo_status_t status; |
cairo_bool_t inside = FALSE; |
|
if (unlikely (cr->status)) |
return FALSE; |
|
return _cairo_gstate_in_fill (cr->gstate, cr->path, x, y); |
status = cr->backend->in_fill (cr, x, y, &inside); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
|
return inside; |
} |
|
/** |
2588,6 → 2379,8 |
* See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(), |
* cairo_set_line_cap(), cairo_set_dash(), and |
* cairo_stroke_preserve(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_stroke_extents (cairo_t *cr, |
2608,9 → 2401,7 |
return; |
} |
|
status = _cairo_gstate_stroke_extents (cr->gstate, |
cr->path, |
x1, y1, x2, y2); |
status = cr->backend->stroke_extents (cr, x1, y1, x2, y2); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2639,6 → 2430,8 |
* if the non-inked path extents are desired. |
* |
* See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_fill_extents (cairo_t *cr, |
2659,9 → 2452,7 |
return; |
} |
|
status = _cairo_gstate_fill_extents (cr->gstate, |
cr->path, |
x1, y1, x2, y2); |
status = cr->backend->fill_extents (cr, x1, y1, x2, y2); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2687,13 → 2478,20 |
* calling cairo_clip() within a cairo_save()/cairo_restore() |
* pair. The only other means of increasing the size of the clip |
* region is cairo_reset_clip(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_clip (cairo_t *cr) |
{ |
cairo_clip_preserve (cr); |
cairo_status_t status; |
|
cairo_new_path (cr); |
if (unlikely (cr->status)) |
return; |
|
status = cr->backend->clip (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
|
/** |
2717,6 → 2515,8 |
* calling cairo_clip_preserve() within a cairo_save()/cairo_restore() |
* pair. The only other means of increasing the size of the clip |
* region is cairo_reset_clip(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_clip_preserve (cairo_t *cr) |
2726,7 → 2526,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_clip (cr->gstate, cr->path); |
status = cr->backend->clip_preserve (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2747,6 → 2547,8 |
* higher-level code which calls cairo_clip(). Consider using |
* cairo_save() and cairo_restore() around cairo_clip() as a more |
* robust means of temporarily restricting the clip region. |
* |
* Since: 1.0 |
**/ |
void |
cairo_reset_clip (cairo_t *cr) |
2756,7 → 2558,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_reset_clip (cr->gstate); |
status = cr->backend->reset_clip (cr); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2779,7 → 2581,8 |
double *x1, double *y1, |
double *x2, double *y2) |
{ |
if (unlikely (cr->status)) { |
cairo_status_t status; |
|
if (x1) |
*x1 = 0.0; |
if (y1) |
2789,16 → 2592,13 |
if (y2) |
*y2 = 0.0; |
|
if (unlikely (cr->status)) |
return; |
} |
|
if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) { |
*x1 = -INFINITY; |
*y1 = -INFINITY; |
*x2 = +INFINITY; |
*y2 = +INFINITY; |
status = cr->backend->clip_extents (cr, x1, y1, x2, y2); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
} |
|
/** |
* cairo_in_clip: |
2820,32 → 2620,19 |
cairo_bool_t |
cairo_in_clip (cairo_t *cr, double x, double y) |
{ |
cairo_status_t status; |
cairo_bool_t inside = FALSE; |
|
if (unlikely (cr->status)) |
return FALSE; |
|
return _cairo_gstate_in_clip (cr->gstate, x, y); |
} |
status = cr->backend->in_clip (cr, x, y, &inside); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
|
static cairo_rectangle_list_t * |
_cairo_rectangle_list_create_in_error (cairo_status_t status) |
{ |
cairo_rectangle_list_t *list; |
|
if (status == CAIRO_STATUS_NO_MEMORY) |
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; |
|
list = malloc (sizeof (cairo_rectangle_list_t)); |
if (unlikely (list == NULL)) { |
status = _cairo_error (CAIRO_STATUS_NO_MEMORY); |
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; |
return inside; |
} |
|
list->status = status; |
list->rectangles = NULL; |
list->num_rectangles = 0; |
return list; |
} |
|
/** |
* cairo_copy_clip_rectangle_list: |
* @cr: a cairo context |
2869,7 → 2656,7 |
if (unlikely (cr->status)) |
return _cairo_rectangle_list_create_in_error (cr->status); |
|
return _cairo_gstate_copy_clip_rectangle_list (cr->gstate); |
return cr->backend->clip_copy_rectangle_list (cr); |
} |
|
/** |
2922,6 → 2709,8 |
* |
* This function is equivalent to a call to cairo_toy_font_face_create() |
* followed by cairo_set_font_face(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_select_font_face (cairo_t *cr, |
2929,12 → 2718,21 |
cairo_font_slant_t slant, |
cairo_font_weight_t weight) |
{ |
cairo_font_face_t *font_face; |
cairo_status_t status; |
|
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_select_font_face (cr->gstate, family, slant, weight); |
font_face = cairo_toy_font_face_create (family, slant, weight); |
if (unlikely (font_face->status)) { |
_cairo_set_error (cr, font_face->status); |
return; |
} |
|
status = cr->backend->set_font_face (cr, font_face); |
cairo_font_face_destroy (font_face); |
|
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2946,6 → 2744,8 |
* will be stored. |
* |
* Gets the font extents for the currently selected font. |
* |
* Since: 1.0 |
**/ |
void |
cairo_font_extents (cairo_t *cr, |
2962,7 → 2762,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_get_font_extents (cr->gstate, extents); |
status = cr->backend->font_extents (cr, extents); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
2975,6 → 2775,8 |
* Replaces the current #cairo_font_face_t object in the #cairo_t with |
* @font_face. The replaced font face in the #cairo_t will be |
* destroyed if there are no other references to it. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_font_face (cairo_t *cr, |
2985,7 → 2787,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_font_face (cr->gstate, font_face); |
status = cr->backend->set_font_face (cr, font_face); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
3007,25 → 2809,18 |
* objects it is passed to, (for example, calling |
* cairo_set_font_face() with a nil font will trigger an error that |
* will shutdown the #cairo_t object). |
* |
* Since: 1.0 |
**/ |
cairo_font_face_t * |
cairo_get_font_face (cairo_t *cr) |
{ |
cairo_status_t status; |
cairo_font_face_t *font_face; |
|
if (unlikely (cr->status)) |
return (cairo_font_face_t*) &_cairo_font_face_nil; |
|
status = _cairo_gstate_get_font_face (cr->gstate, &font_face); |
if (unlikely (status)) { |
_cairo_set_error (cr, status); |
return (cairo_font_face_t*) &_cairo_font_face_nil; |
return cr->backend->get_font_face (cr); |
} |
|
return font_face; |
} |
|
/** |
* cairo_set_font_size: |
* @cr: a #cairo_t |
3040,6 → 2835,8 |
* If text is drawn without a call to cairo_set_font_size(), (nor |
* cairo_set_font_matrix() nor cairo_set_scaled_font()), the default |
* font size is 10.0. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_font_size (cairo_t *cr, double size) |
3049,7 → 2846,7 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_font_size (cr->gstate, size); |
status = cr->backend->set_font_size (cr, size); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
3056,7 → 2853,7 |
slim_hidden_def (cairo_set_font_size); |
|
/** |
* cairo_set_font_matrix |
* cairo_set_font_matrix: |
* @cr: a #cairo_t |
* @matrix: a #cairo_matrix_t describing a transform to be applied to |
* the current font. |
3067,6 → 2864,8 |
* simple scale is used (see cairo_set_font_size()), but a more |
* complex font matrix can be used to shear the font |
* or stretch it unequally along the two axes |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_font_matrix (cairo_t *cr, |
3077,18 → 2876,21 |
if (unlikely (cr->status)) |
return; |
|
status = _cairo_gstate_set_font_matrix (cr->gstate, matrix); |
status = cr->backend->set_font_matrix (cr, matrix); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
slim_hidden_def (cairo_set_font_matrix); |
|
/** |
* cairo_get_font_matrix |
* cairo_get_font_matrix: |
* @cr: a #cairo_t |
* @matrix: return value for the matrix |
* |
* Stores the current font matrix into @matrix. See |
* cairo_set_font_matrix(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_get_font_matrix (cairo_t *cr, cairo_matrix_t *matrix) |
3098,7 → 2900,7 |
return; |
} |
|
_cairo_gstate_get_font_matrix (cr->gstate, matrix); |
cr->backend->get_font_matrix (cr, matrix); |
} |
|
/** |
3111,6 → 2913,8 |
* options derived from underlying surface; if the value in @options |
* has a default value (like %CAIRO_ANTIALIAS_DEFAULT), then the value |
* from the surface is used. |
* |
* Since: 1.0 |
**/ |
void |
cairo_set_font_options (cairo_t *cr, |
3127,7 → 2931,9 |
return; |
} |
|
_cairo_gstate_set_font_options (cr->gstate, options); |
status = cr->backend->set_font_options (cr, options); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
slim_hidden_def (cairo_set_font_options); |
|
3141,6 → 2947,8 |
* Note that the returned options do not include any options derived |
* from the underlying surface; they are literally the options |
* passed to cairo_set_font_options(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_get_font_options (cairo_t *cr, |
3155,7 → 2963,7 |
return; |
} |
|
_cairo_gstate_get_font_options (cr->gstate, options); |
cr->backend->get_font_options (cr, options); |
} |
|
/** |
3176,41 → 2984,23 |
const cairo_scaled_font_t *scaled_font) |
{ |
cairo_status_t status; |
cairo_bool_t was_previous; |
|
if (unlikely (cr->status)) |
return; |
|
if (scaled_font == NULL) { |
status = _cairo_error (CAIRO_STATUS_NULL_POINTER); |
goto BAIL; |
if ((scaled_font == NULL)) { |
_cairo_set_error (cr, _cairo_error (CAIRO_STATUS_NULL_POINTER)); |
return; |
} |
|
status = scaled_font->status; |
if (unlikely (status)) |
goto BAIL; |
|
if (scaled_font == cr->gstate->scaled_font) |
if (unlikely (status)) { |
_cairo_set_error (cr, status); |
return; |
} |
|
was_previous = scaled_font == cr->gstate->previous_scaled_font; |
|
status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face); |
status = cr->backend->set_scaled_font (cr, (cairo_scaled_font_t *) scaled_font); |
if (unlikely (status)) |
goto BAIL; |
|
status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix); |
if (unlikely (status)) |
goto BAIL; |
|
_cairo_gstate_set_font_options (cr->gstate, &scaled_font->options); |
|
if (was_previous) |
cr->gstate->scaled_font = cairo_scaled_font_reference ((cairo_scaled_font_t *) scaled_font); |
|
return; |
|
BAIL: |
_cairo_set_error (cr, status); |
} |
|
3237,21 → 3027,13 |
cairo_scaled_font_t * |
cairo_get_scaled_font (cairo_t *cr) |
{ |
cairo_status_t status; |
cairo_scaled_font_t *scaled_font; |
|
if (unlikely (cr->status)) |
return _cairo_scaled_font_create_in_error (cr->status); |
|
status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font); |
if (unlikely (status)) { |
_cairo_set_error (cr, status); |
return _cairo_scaled_font_create_in_error (status); |
return cr->backend->get_scaled_font (cr); |
} |
slim_hidden_def (cairo_get_scaled_font); |
|
return scaled_font; |
} |
|
/** |
* cairo_text_extents: |
* @cr: a #cairo_t |
3271,6 → 3053,8 |
* characters. In particular, trailing whitespace characters are |
* likely to not affect the size of the rectangle, though they will |
* affect the x_advance and y_advance values. |
* |
* Since: 1.0 |
**/ |
void |
cairo_text_extents (cairo_t *cr, |
3278,8 → 3062,9 |
cairo_text_extents_t *extents) |
{ |
cairo_status_t status; |
cairo_scaled_font_t *scaled_font; |
cairo_glyph_t *glyphs = NULL; |
int num_glyphs; |
int num_glyphs = 0; |
double x, y; |
|
extents->x_bearing = 0.0; |
3295,19 → 3080,24 |
if (utf8 == NULL) |
return; |
|
scaled_font = cairo_get_scaled_font (cr); |
if (unlikely (scaled_font->status)) { |
_cairo_set_error (cr, scaled_font->status); |
return; |
} |
|
cairo_get_current_point (cr, &x, &y); |
|
status = _cairo_gstate_text_to_glyphs (cr->gstate, |
status = cairo_scaled_font_text_to_glyphs (scaled_font, |
x, y, |
utf8, strlen (utf8), |
utf8, -1, |
&glyphs, &num_glyphs, |
NULL, NULL, |
NULL); |
NULL, NULL, NULL); |
|
if (status == CAIRO_STATUS_SUCCESS) |
status = _cairo_gstate_glyph_extents (cr->gstate, |
if (likely (status == CAIRO_STATUS_SUCCESS)) { |
status = cr->backend->glyph_extents (cr, |
glyphs, num_glyphs, |
extents); |
} |
cairo_glyph_free (glyphs); |
|
if (unlikely (status)) |
3331,6 → 3121,8 |
* |
* Note that whitespace glyphs do not contribute to the size of the |
* rectangle (extents.width and extents.height). |
* |
* Since: 1.0 |
**/ |
void |
cairo_glyph_extents (cairo_t *cr, |
3353,18 → 3145,17 |
if (num_glyphs == 0) |
return; |
|
if (num_glyphs < 0) { |
if (unlikely (num_glyphs < 0)) { |
_cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT); |
return; |
} |
|
if (glyphs == NULL) { |
if (unlikely (glyphs == NULL)) { |
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); |
return; |
} |
|
status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, |
extents); |
status = cr->backend->glyph_extents (cr, glyphs, num_glyphs, extents); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
3395,6 → 3186,8 |
* and simple programs, but it is not expected to be adequate for |
* serious text-using applications. See cairo_show_glyphs() for the |
* "real" text display API in cairo. |
* |
* Since: 1.0 |
**/ |
void |
cairo_show_text (cairo_t *cr, const char *utf8) |
3409,6 → 3202,8 |
cairo_bool_t has_show_text_glyphs; |
cairo_glyph_t stack_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)]; |
cairo_text_cluster_t stack_clusters[CAIRO_STACK_ARRAY_LENGTH (cairo_text_cluster_t)]; |
cairo_scaled_font_t *scaled_font; |
cairo_glyph_text_info_t info, *i; |
|
if (unlikely (cr->status)) |
return; |
3416,7 → 3211,11 |
if (utf8 == NULL) |
return; |
|
cairo_get_current_point (cr, &x, &y); |
scaled_font = cairo_get_scaled_font (cr); |
if (unlikely (scaled_font->status)) { |
_cairo_set_error (cr, scaled_font->status); |
return; |
} |
|
utf8_len = strlen (utf8); |
|
3434,7 → 3233,8 |
num_clusters = 0; |
} |
|
status = _cairo_gstate_text_to_glyphs (cr->gstate, |
cairo_get_current_point (cr, &x, &y); |
status = cairo_scaled_font_text_to_glyphs (scaled_font, |
x, y, |
utf8, utf8_len, |
&glyphs, &num_glyphs, |
3446,24 → 3246,28 |
if (num_glyphs == 0) |
return; |
|
status = _cairo_gstate_show_text_glyphs (cr->gstate, |
utf8, utf8_len, |
glyphs, num_glyphs, |
clusters, num_clusters, |
cluster_flags); |
i = NULL; |
if (has_show_text_glyphs) { |
info.utf8 = utf8; |
info.utf8_len = utf8_len; |
info.clusters = clusters; |
info.num_clusters = num_clusters; |
info.cluster_flags = cluster_flags; |
i = &info; |
} |
|
status = cr->backend->glyphs (cr, glyphs, num_glyphs, i); |
if (unlikely (status)) |
goto BAIL; |
|
last_glyph = &glyphs[num_glyphs - 1]; |
status = _cairo_gstate_glyph_extents (cr->gstate, |
last_glyph, 1, |
&extents); |
status = cr->backend->glyph_extents (cr, last_glyph, 1, &extents); |
if (unlikely (status)) |
goto BAIL; |
|
x = last_glyph->x + extents.x_advance; |
y = last_glyph->y + extents.y_advance; |
cairo_move_to (cr, x, y); |
cr->backend->move_to (cr, x, y); |
|
BAIL: |
if (glyphs != stack_glyphs) |
3484,6 → 3288,8 |
* A drawing operator that generates the shape from an array of glyphs, |
* rendered according to the current font face, font size |
* (font matrix), and font options. |
* |
* Since: 1.0 |
**/ |
void |
cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) |
3506,11 → 3312,7 |
return; |
} |
|
status = _cairo_gstate_show_text_glyphs (cr->gstate, |
NULL, 0, |
glyphs, num_glyphs, |
NULL, 0, |
FALSE); |
status = cr->backend->glyphs (cr, glyphs, num_glyphs, NULL); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
3588,6 → 3390,10 |
return; |
} |
|
if (num_glyphs == 0 && utf8_len == 0) |
return; |
|
if (utf8) { |
/* Make sure clusters cover the entire glyphs and utf8 arrays, |
* and that cluster boundaries are UTF-8 boundaries. */ |
status = _cairo_validate_text_clusters (utf8, utf8_len, |
3602,18 → 3408,20 |
status2 = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, NULL); |
if (status2) |
status = status2; |
} else { |
cairo_glyph_text_info_t info; |
|
_cairo_set_error (cr, status); |
return; |
info.utf8 = utf8; |
info.utf8_len = utf8_len; |
info.clusters = clusters; |
info.num_clusters = num_clusters; |
info.cluster_flags = cluster_flags; |
|
status = cr->backend->glyphs (cr, glyphs, num_glyphs, &info); |
} |
|
if (num_glyphs == 0 && utf8_len == 0) |
return; |
|
status = _cairo_gstate_show_text_glyphs (cr->gstate, |
utf8, utf8_len, |
glyphs, num_glyphs, |
clusters, num_clusters, cluster_flags); |
} else { |
status = cr->backend->glyphs (cr, glyphs, num_glyphs, NULL); |
} |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
3641,6 → 3449,8 |
* and simple programs, but it is not expected to be adequate for |
* serious text-using applications. See cairo_glyph_path() for the |
* "real" text path API in cairo. |
* |
* Since: 1.0 |
**/ |
void |
cairo_text_path (cairo_t *cr, const char *utf8) |
3649,6 → 3459,7 |
cairo_text_extents_t extents; |
cairo_glyph_t stack_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)]; |
cairo_glyph_t *glyphs, *last_glyph; |
cairo_scaled_font_t *scaled_font; |
int num_glyphs; |
double x, y; |
|
3658,35 → 3469,33 |
if (utf8 == NULL) |
return; |
|
cairo_get_current_point (cr, &x, &y); |
|
glyphs = stack_glyphs; |
num_glyphs = ARRAY_LENGTH (stack_glyphs); |
|
status = _cairo_gstate_text_to_glyphs (cr->gstate, |
scaled_font = cairo_get_scaled_font (cr); |
if (unlikely (scaled_font->status)) { |
_cairo_set_error (cr, scaled_font->status); |
return; |
} |
|
cairo_get_current_point (cr, &x, &y); |
status = cairo_scaled_font_text_to_glyphs (scaled_font, |
x, y, |
utf8, strlen (utf8), |
utf8, -1, |
&glyphs, &num_glyphs, |
NULL, NULL, |
NULL); |
NULL, NULL, NULL); |
|
if (unlikely (status)) |
goto BAIL; |
|
if (num_glyphs == 0) |
return; |
|
status = _cairo_gstate_glyph_path (cr->gstate, |
glyphs, num_glyphs, |
cr->path); |
status = cr->backend->glyph_path (cr, glyphs, num_glyphs); |
|
if (unlikely (status)) |
goto BAIL; |
|
last_glyph = &glyphs[num_glyphs - 1]; |
status = _cairo_gstate_glyph_extents (cr->gstate, |
last_glyph, 1, |
&extents); |
status = cr->backend->glyph_extents (cr, last_glyph, 1, &extents); |
|
if (unlikely (status)) |
goto BAIL; |
3693,7 → 3502,7 |
|
x = last_glyph->x + extents.x_advance; |
y = last_glyph->y + extents.y_advance; |
cairo_move_to (cr, x, y); |
cr->backend->move_to (cr, x, y); |
|
BAIL: |
if (glyphs != stack_glyphs) |
3712,6 → 3521,8 |
* Adds closed paths for the glyphs to the current path. The generated |
* path if filled, achieves an effect similar to that of |
* cairo_show_glyphs(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) |
3724,19 → 3535,17 |
if (num_glyphs == 0) |
return; |
|
if (num_glyphs < 0) { |
if (unlikely (num_glyphs < 0)) { |
_cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT); |
return; |
} |
|
if (glyphs == NULL) { |
if (unlikely (glyphs == NULL)) { |
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); |
return; |
} |
|
status = _cairo_gstate_glyph_path (cr->gstate, |
glyphs, num_glyphs, |
cr->path); |
status = cr->backend->glyph_path (cr, glyphs, num_glyphs); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
3748,6 → 3557,8 |
* Gets the current compositing operator for a cairo context. |
* |
* Return value: the current compositing operator. |
* |
* Since: 1.0 |
**/ |
cairo_operator_t |
cairo_get_operator (cairo_t *cr) |
3755,10 → 3566,31 |
if (unlikely (cr->status)) |
return CAIRO_GSTATE_OPERATOR_DEFAULT; |
|
return _cairo_gstate_get_operator (cr->gstate); |
return cr->backend->get_operator (cr); |
} |
|
#if 0 |
/** |
* cairo_get_opacity: |
* @cr: a cairo context |
* |
* Gets the current compositing opacity for a cairo context. |
* |
* Return value: the current compositing opacity. |
* |
* Since: TBD |
**/ |
double |
cairo_get_opacity (cairo_t *cr) |
{ |
if (unlikely (cr->status)) |
return 1.; |
|
return cr->backend->get_opacity (cr); |
} |
#endif |
|
/** |
* cairo_get_tolerance: |
* @cr: a cairo context |
* |
3765,6 → 3597,8 |
* Gets the current tolerance value, as set by cairo_set_tolerance(). |
* |
* Return value: the current tolerance value. |
* |
* Since: 1.0 |
**/ |
double |
cairo_get_tolerance (cairo_t *cr) |
3772,7 → 3606,7 |
if (unlikely (cr->status)) |
return CAIRO_GSTATE_TOLERANCE_DEFAULT; |
|
return _cairo_gstate_get_tolerance (cr->gstate); |
return cr->backend->get_tolerance (cr); |
} |
slim_hidden_def (cairo_get_tolerance); |
|
3780,9 → 3614,12 |
* cairo_get_antialias: |
* @cr: a cairo context |
* |
* Gets the current shape antialiasing mode, as set by cairo_set_shape_antialias(). |
* Gets the current shape antialiasing mode, as set by |
* cairo_set_antialias(). |
* |
* Return value: the current shape antialiasing mode. |
* |
* Since: 1.0 |
**/ |
cairo_antialias_t |
cairo_get_antialias (cairo_t *cr) |
3790,7 → 3627,7 |
if (unlikely (cr->status)) |
return CAIRO_ANTIALIAS_DEFAULT; |
|
return _cairo_gstate_get_antialias (cr->gstate); |
return cr->backend->get_antialias (cr); |
} |
|
/** |
3810,7 → 3647,7 |
if (unlikely (cr->status)) |
return FALSE; |
|
return cr->path->has_current_point; |
return cr->backend->has_current_point (cr); |
} |
|
/** |
3842,25 → 3679,20 |
* |
* Some functions unset the current path and as a result, current point: |
* cairo_fill(), cairo_stroke(). |
* |
* Since: 1.0 |
**/ |
void |
cairo_get_current_point (cairo_t *cr, double *x_ret, double *y_ret) |
{ |
cairo_fixed_t x_fixed, y_fixed; |
double x, y; |
|
x = y = 0; |
if (cr->status == CAIRO_STATUS_SUCCESS && |
_cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed)) |
cr->backend->has_current_point (cr)) |
{ |
x = _cairo_fixed_to_double (x_fixed); |
y = _cairo_fixed_to_double (y_fixed); |
_cairo_gstate_backend_to_user (cr->gstate, &x, &y); |
cr->backend->get_current_point (cr, &x, &y); |
} |
else |
{ |
x = 0.0; |
y = 0.0; |
} |
|
if (x_ret) |
*x_ret = x; |
3876,6 → 3708,8 |
* Gets the current fill rule, as set by cairo_set_fill_rule(). |
* |
* Return value: the current fill rule. |
* |
* Since: 1.0 |
**/ |
cairo_fill_rule_t |
cairo_get_fill_rule (cairo_t *cr) |
3883,7 → 3717,7 |
if (unlikely (cr->status)) |
return CAIRO_GSTATE_FILL_RULE_DEFAULT; |
|
return _cairo_gstate_get_fill_rule (cr->gstate); |
return cr->backend->get_fill_rule (cr); |
} |
|
/** |
3896,6 → 3730,8 |
* cairo_get_line_width(). |
* |
* Return value: the current line width. |
* |
* Since: 1.0 |
**/ |
double |
cairo_get_line_width (cairo_t *cr) |
3903,7 → 3739,7 |
if (unlikely (cr->status)) |
return CAIRO_GSTATE_LINE_WIDTH_DEFAULT; |
|
return _cairo_gstate_get_line_width (cr->gstate); |
return cr->backend->get_line_width (cr); |
} |
slim_hidden_def (cairo_get_line_width); |
|
3914,6 → 3750,8 |
* Gets the current line cap style, as set by cairo_set_line_cap(). |
* |
* Return value: the current line cap style. |
* |
* Since: 1.0 |
**/ |
cairo_line_cap_t |
cairo_get_line_cap (cairo_t *cr) |
3921,7 → 3759,7 |
if (unlikely (cr->status)) |
return CAIRO_GSTATE_LINE_CAP_DEFAULT; |
|
return _cairo_gstate_get_line_cap (cr->gstate); |
return cr->backend->get_line_cap (cr); |
} |
|
/** |
3931,6 → 3769,8 |
* Gets the current line join style, as set by cairo_set_line_join(). |
* |
* Return value: the current line join style. |
* |
* Since: 1.0 |
**/ |
cairo_line_join_t |
cairo_get_line_join (cairo_t *cr) |
3938,7 → 3778,7 |
if (unlikely (cr->status)) |
return CAIRO_GSTATE_LINE_JOIN_DEFAULT; |
|
return _cairo_gstate_get_line_join (cr->gstate); |
return cr->backend->get_line_join (cr); |
} |
|
/** |
3948,6 → 3788,8 |
* Gets the current miter limit, as set by cairo_set_miter_limit(). |
* |
* Return value: the current miter limit. |
* |
* Since: 1.0 |
**/ |
double |
cairo_get_miter_limit (cairo_t *cr) |
3955,7 → 3797,7 |
if (unlikely (cr->status)) |
return CAIRO_GSTATE_MITER_LIMIT_DEFAULT; |
|
return _cairo_gstate_get_miter_limit (cr->gstate); |
return cr->backend->get_miter_limit (cr); |
} |
|
/** |
3964,6 → 3806,8 |
* @matrix: return value for the matrix |
* |
* Stores the current transformation matrix (CTM) into @matrix. |
* |
* Since: 1.0 |
**/ |
void |
cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix) |
3973,7 → 3817,7 |
return; |
} |
|
_cairo_gstate_get_matrix (cr->gstate, matrix); |
cr->backend->get_matrix (cr, matrix); |
} |
slim_hidden_def (cairo_get_matrix); |
|
3992,6 → 3836,8 |
* |
* Return value: the target surface. This object is owned by cairo. To |
* keep a reference to it, you must call cairo_surface_reference(). |
* |
* Since: 1.0 |
**/ |
cairo_surface_t * |
cairo_get_target (cairo_t *cr) |
3999,7 → 3845,7 |
if (unlikely (cr->status)) |
return _cairo_surface_create_in_error (cr->status); |
|
return _cairo_gstate_get_original_target (cr->gstate); |
return cr->backend->get_original_target (cr); |
} |
slim_hidden_def (cairo_get_target); |
|
4029,7 → 3875,7 |
if (unlikely (cr->status)) |
return _cairo_surface_create_in_error (cr->status); |
|
return _cairo_gstate_get_target (cr->gstate); |
return cr->backend->get_current_target (cr); |
} |
|
/** |
4057,6 → 3903,8 |
* Return value: the copy of the current path. The caller owns the |
* returned object and should call cairo_path_destroy() when finished |
* with it. |
* |
* Since: 1.0 |
**/ |
cairo_path_t * |
cairo_copy_path (cairo_t *cr) |
4064,7 → 3912,7 |
if (unlikely (cr->status)) |
return _cairo_path_create_in_error (cr->status); |
|
return _cairo_path_create (cr->path, cr->gstate); |
return cr->backend->copy_path (cr); |
} |
|
/** |
4099,6 → 3947,8 |
* Return value: the copy of the current path. The caller owns the |
* returned object and should call cairo_path_destroy() when finished |
* with it. |
* |
* Since: 1.0 |
**/ |
cairo_path_t * |
cairo_copy_path_flat (cairo_t *cr) |
4106,7 → 3956,7 |
if (unlikely (cr->status)) |
return _cairo_path_create_in_error (cr->status); |
|
return _cairo_path_create_flat (cr->path, cr->gstate); |
return cr->backend->copy_path_flat (cr); |
} |
|
/** |
4120,6 → 3970,8 |
* #cairo_path_t for details on how the path data structure should be |
* initialized, and note that <literal>path->status</literal> must be |
* initialized to %CAIRO_STATUS_SUCCESS. |
* |
* Since: 1.0 |
**/ |
void |
cairo_append_path (cairo_t *cr, |
4130,12 → 3982,12 |
if (unlikely (cr->status)) |
return; |
|
if (path == NULL) { |
if (unlikely (path == NULL)) { |
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); |
return; |
} |
|
if (path->status) { |
if (unlikely (path->status)) { |
if (path->status > CAIRO_STATUS_SUCCESS && |
path->status <= CAIRO_STATUS_LAST_STATUS) |
_cairo_set_error (cr, path->status); |
4147,12 → 3999,12 |
if (path->num_data == 0) |
return; |
|
if (path->data == NULL) { |
if (unlikely (path->data == NULL)) { |
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); |
return; |
} |
|
status = _cairo_path_append_to_context (path, cr); |
status = cr->backend->append_path (cr, path); |
if (unlikely (status)) |
_cairo_set_error (cr, status); |
} |
4164,6 → 4016,8 |
* Checks whether an error has previously occurred for this context. |
* |
* Returns: the current status of this context, see #cairo_status_t |
* |
* Since: 1.0 |
**/ |
cairo_status_t |
cairo_status (cairo_t *cr) |