mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-08 12:38:02 +02:00
Note that self-copy now works with the PS backend.
Add _cairo_array_init_snapshot and checks for is_snapshot throughout. Add a new surface->backend->snapshot function. Implement _cairo_meta_surface_snapshot and _cairo_meta_surface_acquire/release_source_image. Change _cairo_meta_surface_create to require the width and height in pixels to be used when replaying for purposed of _cairo_meta_surface_aquire_source_image. Track change in prototype of _cairo_meta_surface_create. Implement _cairo_ps_surface_snapshot by deferring down into _cairo_meta_surface_snapshot.
This commit is contained in:
parent
96be55124f
commit
964c56e72b
8 changed files with 257 additions and 36 deletions
35
ChangeLog
35
ChangeLog
|
|
@ -1,3 +1,38 @@
|
|||
2005-12-07 Carl Worth <cworth@cworth.org>
|
||||
|
||||
* ROADMAP: Note that self-copy now works with the PS backend.
|
||||
|
||||
* src/cairo-array.c: (_cairo_array_init),
|
||||
(_cairo_array_init_snapshot), (_cairo_array_fini),
|
||||
(_cairo_array_grow_by), (_cairo_array_truncate),
|
||||
(_cairo_array_append), (_cairo_array_append_multiple),
|
||||
(_cairo_array_allocate): Add _cairo_array_init_snapshot and checks
|
||||
for is_snapshot throughout.
|
||||
|
||||
* src/cairoint.h:
|
||||
* src/cairo-surface.c: (_cairo_surface_acquire_source_image),
|
||||
(_fallback_snapshot), (_cairo_surface_snapshot): Add a new
|
||||
surface->backend->snapshot function.
|
||||
|
||||
* src/cairo-meta-surface-private.h:
|
||||
* src/cairo-meta-surface.c: (_cairo_meta_surface_create),
|
||||
(_cairo_meta_surface_create_similar), (_cairo_meta_surface_finish),
|
||||
(_cairo_meta_surface_acquire_source_image),
|
||||
(_cairo_meta_surface_release_source_image),
|
||||
(_cairo_meta_surface_snapshot), (_cairo_meta_surface_get_extents):
|
||||
Implement _cairo_meta_surface_snapshot and
|
||||
_cairo_meta_surface_acquire/release_source_image. Change
|
||||
_cairo_meta_surface_create to require the width and height in
|
||||
pixels to be used when replaying for purposed of
|
||||
_cairo_meta_surface_aquire_source_image.
|
||||
|
||||
* src/cairo-ps-surface.c:
|
||||
(_cairo_ps_surface_create_for_stream_internal),
|
||||
(_cairo_ps_surface_show_page), (_cairo_ps_surface_snapshot),
|
||||
(_ps_output_old_show_glyphs): Track change in prototype of
|
||||
_cairo_meta_surface_create. Implement _cairo_ps_surface_snapshot
|
||||
by deferring down into _cairo_meta_surface_snapshot.
|
||||
|
||||
2005-12-07 Carl Worth <cworth@cworth.org>
|
||||
|
||||
* test/cairo-test.c: (create_ps_surface): Fix to check
|
||||
|
|
|
|||
6
ROADMAP
6
ROADMAP
|
|
@ -11,17 +11,17 @@ The release won't happen without these being complete.
|
|||
========================================================
|
||||
A. PS backend
|
||||
----------
|
||||
1. Mark PS backend as supported:
|
||||
✓1. Mark PS backend as supported:
|
||||
|
||||
✓a. Incorporate into test suite
|
||||
|
||||
b. Correct output for the entire test suite
|
||||
✓b. Correct output for the entire test suite
|
||||
✓clip-operator
|
||||
✓composite-integer-translate-source
|
||||
✓linear-gradient
|
||||
✓operator-clear
|
||||
✓operator-source
|
||||
self-copy
|
||||
✓self-copy
|
||||
✓text-pattern
|
||||
✓trap-clip
|
||||
✓unbounded-operator
|
||||
|
|
|
|||
|
|
@ -58,6 +58,29 @@ _cairo_array_init (cairo_array_t *array, int element_size)
|
|||
array->num_elements = 0;
|
||||
array->element_size = element_size;
|
||||
array->elements = NULL;
|
||||
|
||||
array->is_snapshot = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_array_init_snapshot:
|
||||
* @array: A #cairo_array_t to be initialized as a snapshot
|
||||
* @other: The #cairo_array_t from which to create the snapshot
|
||||
*
|
||||
* Initialize @array as an immutable copy of @other. It is an error to
|
||||
* call an array-modifying function (other than _cairo_array_fini) on
|
||||
* @array after calling this function.
|
||||
**/
|
||||
void
|
||||
_cairo_array_init_snapshot (cairo_array_t *array,
|
||||
const cairo_array_t *other)
|
||||
{
|
||||
array->size = other->size;
|
||||
array->num_elements = other->num_elements;
|
||||
array->element_size = other->element_size;
|
||||
array->elements = other->elements;
|
||||
|
||||
array->is_snapshot = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -70,6 +93,9 @@ _cairo_array_init (cairo_array_t *array, int element_size)
|
|||
void
|
||||
_cairo_array_fini (cairo_array_t *array)
|
||||
{
|
||||
if (array->is_snapshot)
|
||||
return;
|
||||
|
||||
free (array->elements);
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +114,8 @@ _cairo_array_grow_by (cairo_array_t *array, int additional)
|
|||
int required_size = array->num_elements + additional;
|
||||
int new_size;
|
||||
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
if (required_size <= old_size)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
|
@ -123,6 +151,8 @@ _cairo_array_grow_by (cairo_array_t *array, int additional)
|
|||
void
|
||||
_cairo_array_truncate (cairo_array_t *array, int num_elements)
|
||||
{
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
if (num_elements < array->num_elements)
|
||||
array->num_elements = num_elements;
|
||||
}
|
||||
|
|
@ -184,6 +214,8 @@ cairo_status_t
|
|||
_cairo_array_append (cairo_array_t *array,
|
||||
const void *element)
|
||||
{
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
return _cairo_array_append_multiple (array, element, 1);
|
||||
}
|
||||
|
||||
|
|
@ -206,6 +238,8 @@ _cairo_array_append_multiple (cairo_array_t *array,
|
|||
cairo_status_t status;
|
||||
void *dest;
|
||||
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
status = _cairo_array_allocate (array, num_elements, &dest);
|
||||
if (status)
|
||||
return status;
|
||||
|
|
@ -234,6 +268,8 @@ _cairo_array_allocate (cairo_array_t *array,
|
|||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (! array->is_snapshot);
|
||||
|
||||
status = _cairo_array_grow_by (array, num_elements);
|
||||
if (status)
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -179,13 +179,21 @@ typedef union _cairo_command {
|
|||
|
||||
typedef struct _cairo_meta_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
/* A meta-surface is logically unbounded, but when used as a
|
||||
* source we need to render it to an image, so we need a size at
|
||||
* which to create that image. */
|
||||
int width_pixels;
|
||||
int height_pixels;
|
||||
|
||||
cairo_array_t commands;
|
||||
cairo_surface_t *commands_owner;
|
||||
} cairo_meta_surface_t;
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_meta_surface_create (void);
|
||||
_cairo_meta_surface_create (int width_pixels, int height_pixels);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
cairo_private cairo_status_t
|
||||
_cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
static const cairo_surface_backend_t cairo_meta_surface_backend;
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_meta_surface_create (void)
|
||||
_cairo_meta_surface_create (int width_pixels, int height_pixels)
|
||||
{
|
||||
cairo_meta_surface_t *meta;
|
||||
|
||||
|
|
@ -52,7 +52,12 @@ _cairo_meta_surface_create (void)
|
|||
}
|
||||
|
||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend);
|
||||
|
||||
meta->width_pixels = width_pixels;
|
||||
meta->height_pixels = height_pixels;
|
||||
|
||||
_cairo_array_init (&meta->commands, sizeof (cairo_command_t *));
|
||||
meta->commands_owner = NULL;
|
||||
|
||||
return &meta->base;
|
||||
}
|
||||
|
|
@ -63,7 +68,7 @@ _cairo_meta_surface_create_similar (void *abstract_surface,
|
|||
int width,
|
||||
int height)
|
||||
{
|
||||
return _cairo_meta_surface_create ();
|
||||
return _cairo_meta_surface_create (width, height);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -74,6 +79,11 @@ _cairo_meta_surface_finish (void *abstract_surface)
|
|||
cairo_command_t **elements;
|
||||
int i, num_elements;
|
||||
|
||||
if (meta->commands_owner) {
|
||||
cairo_surface_destroy (meta->commands_owner);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
num_elements = meta->commands.num_elements;
|
||||
elements = (cairo_command_t **) meta->commands.elements;
|
||||
for (i = 0; i < num_elements; i++) {
|
||||
|
|
@ -149,6 +159,39 @@ _cairo_meta_surface_finish (void *abstract_surface)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_meta_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t **image_out,
|
||||
void **image_extra)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_meta_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image;
|
||||
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
surface->width_pixels,
|
||||
surface->height_pixels);
|
||||
|
||||
status = _cairo_meta_surface_replay (&surface->base, image);
|
||||
if (status) {
|
||||
cairo_surface_destroy (image);
|
||||
return status;
|
||||
}
|
||||
|
||||
*image_out = (cairo_image_surface_t *) image;
|
||||
*image_extra = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_meta_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
void *image_extra)
|
||||
{
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_init_pattern_with_snapshot (cairo_pattern_t *pattern,
|
||||
const cairo_pattern_t *other)
|
||||
|
|
@ -397,6 +440,43 @@ _cairo_meta_surface_show_glyphs (void *abstract_surface,
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_meta_surface_snapshot
|
||||
* @surface: a #cairo_surface_t which must be a meta surface
|
||||
*
|
||||
* Make an immutable copy of @surface. It is an error to call a
|
||||
* surface-modifying function on the result of this function.
|
||||
*
|
||||
* The caller owns the return value and should call
|
||||
* cairo_surface_destroy when finished with it. This function will not
|
||||
* return NULL, but will return a nil surface instead.
|
||||
*
|
||||
* Return value: The snapshot surface.
|
||||
**/
|
||||
static cairo_surface_t *
|
||||
_cairo_meta_surface_snapshot (void *abstract_other)
|
||||
{
|
||||
cairo_meta_surface_t *other = abstract_other;
|
||||
cairo_meta_surface_t *meta;
|
||||
|
||||
meta = malloc (sizeof (cairo_meta_surface_t));
|
||||
if (meta == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_surface_t*) &_cairo_surface_nil;
|
||||
}
|
||||
|
||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend);
|
||||
meta->base.is_snapshot = TRUE;
|
||||
|
||||
meta->width_pixels = other->width_pixels;
|
||||
meta->height_pixels = other->height_pixels;
|
||||
|
||||
_cairo_array_init_snapshot (&meta->commands, &other->commands);
|
||||
meta->commands_owner = cairo_surface_reference (&other->base);
|
||||
|
||||
return &meta->base;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_composite (cairo_operator_t operator,
|
||||
cairo_pattern_t *src_pattern,
|
||||
|
|
@ -594,6 +674,26 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* A meta-surface is logically unbounded, but when it is used as a
|
||||
* source, the drawing code can optimize based on the extents of the
|
||||
* surface.
|
||||
*
|
||||
* XXX: The optimization being attempted here would only actually work
|
||||
* if the meta-surface kept track of its extents as commands were
|
||||
* added to it.
|
||||
*/
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
rectangle->x = 0;
|
||||
rectangle->y = 0;
|
||||
rectangle->width = CAIRO_MAXSHORT;
|
||||
rectangle->height = CAIRO_MAXSHORT;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_surface_is_meta:
|
||||
* @surface: a #cairo_surface_t
|
||||
|
|
@ -611,8 +711,8 @@ _cairo_surface_is_meta (const cairo_surface_t *surface)
|
|||
static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
||||
_cairo_meta_surface_create_similar,
|
||||
_cairo_meta_surface_finish,
|
||||
NULL, /* acquire_source_image */
|
||||
NULL, /* release_source_image */
|
||||
_cairo_meta_surface_acquire_source_image,
|
||||
_cairo_meta_surface_release_source_image,
|
||||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
|
|
@ -623,7 +723,7 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
|||
NULL, /* show_page */
|
||||
NULL, /* set_clip_region */
|
||||
_cairo_meta_surface_intersect_clip_path,
|
||||
NULL, /* get_extents */
|
||||
_cairo_meta_surface_get_extents,
|
||||
NULL, /* old_show_glyphs */
|
||||
NULL, /* get_font_options */
|
||||
NULL, /* flush */
|
||||
|
|
@ -639,10 +739,12 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
|||
_cairo_meta_surface_mask,
|
||||
_cairo_meta_surface_stroke,
|
||||
_cairo_meta_surface_fill,
|
||||
_cairo_meta_surface_show_glyphs
|
||||
_cairo_meta_surface_show_glyphs,
|
||||
|
||||
_cairo_meta_surface_snapshot
|
||||
};
|
||||
|
||||
cairo_int_status_t
|
||||
cairo_status_t
|
||||
_cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
|||
surface->base.device_x_scale = surface->x_dpi / 72.0;
|
||||
surface->base.device_y_scale = surface->y_dpi / 72.0;
|
||||
|
||||
surface->current_page = _cairo_meta_surface_create ();
|
||||
surface->current_page = _cairo_meta_surface_create (width * surface->x_dpi / 72,
|
||||
height * surface->y_dpi / 72);
|
||||
if (surface->current_page->status) {
|
||||
free (surface);
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
|
@ -343,7 +344,8 @@ _cairo_ps_surface_show_page (void *abstract_surface)
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
surface->current_page = _cairo_meta_surface_create ();
|
||||
surface->current_page = _cairo_meta_surface_create (surface->width * surface->x_dpi / 72,
|
||||
surface->height * surface->y_dpi / 72);
|
||||
if (surface->current_page->status)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
|
|
@ -549,6 +551,16 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
|
|||
scaled_font);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_ps_surface_snapshot (void *abstract_surface)
|
||||
{
|
||||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
|
||||
assert (_cairo_surface_is_meta (surface->current_page));
|
||||
|
||||
return _cairo_surface_snapshot (surface->current_page);
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_ps_surface_backend = {
|
||||
NULL, /* create_similar */
|
||||
_cairo_ps_surface_finish,
|
||||
|
|
@ -578,7 +590,9 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = {
|
|||
_cairo_ps_surface_mask,
|
||||
_cairo_ps_surface_stroke,
|
||||
_cairo_ps_surface_fill,
|
||||
_cairo_ps_surface_show_glyphs
|
||||
_cairo_ps_surface_show_glyphs,
|
||||
|
||||
_cairo_ps_surface_snapshot
|
||||
};
|
||||
|
||||
static cairo_int_status_t
|
||||
|
|
@ -1400,6 +1414,9 @@ _ps_output_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
if (! _cairo_scaled_font_is_ft (scaled_font))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
if (surface->fallback)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (pattern_operation_needs_fallback (operator, pattern))
|
||||
return _ps_output_add_fallback_area (surface, dest_x, dest_y, width, height);
|
||||
|
||||
|
|
|
|||
|
|
@ -581,7 +581,8 @@ _cairo_surface_acquire_source_image (cairo_surface_t *surface,
|
|||
{
|
||||
assert (!surface->finished);
|
||||
|
||||
return surface->backend->acquire_source_image (surface, image_out, image_extra);
|
||||
return surface->backend->acquire_source_image (surface,
|
||||
image_out, image_extra);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -722,21 +723,11 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_surface_snapshot
|
||||
* @surface: a #cairo_surface_t
|
||||
* @snapshot_out: return value surface---not necessarily of the same type as @surface
|
||||
*
|
||||
* Make an immutable copy of @surface. It is an error to call a
|
||||
* surface-modifying function on the result of this function.
|
||||
*
|
||||
* The caller owns the return value and should call
|
||||
* cairo_surface_destroy when finished with it. This function will not
|
||||
* return NULL, but will return a nil surface instead.
|
||||
**/
|
||||
cairo_surface_t *
|
||||
_cairo_surface_snapshot (cairo_surface_t *surface)
|
||||
/* XXX: Shouldn't really need to do this here. */
|
||||
#include "cairo-meta-surface-private.h"
|
||||
|
||||
static cairo_surface_t *
|
||||
_fallback_snapshot (cairo_surface_t *surface)
|
||||
{
|
||||
cairo_surface_t *snapshot;
|
||||
cairo_status_t status;
|
||||
|
|
@ -744,12 +735,6 @@ _cairo_surface_snapshot (cairo_surface_t *surface)
|
|||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
|
||||
if (surface->finished)
|
||||
return (cairo_surface_t *) &_cairo_surface_nil;
|
||||
|
||||
/* XXX: Will need to do something very different here to snapshot
|
||||
* a meta-surface. */
|
||||
|
||||
status = _cairo_surface_acquire_source_image (surface,
|
||||
&image, &image_extra);
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
|
|
@ -783,6 +768,32 @@ _cairo_surface_snapshot (cairo_surface_t *surface)
|
|||
return snapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_surface_snapshot
|
||||
* @surface: a #cairo_surface_t
|
||||
*
|
||||
* Make an immutable copy of @surface. It is an error to call a
|
||||
* surface-modifying function on the result of this function.
|
||||
*
|
||||
* The caller owns the return value and should call
|
||||
* cairo_surface_destroy when finished with it. This function will not
|
||||
* return NULL, but will return a nil surface instead.
|
||||
*
|
||||
* Return value: The snapshot surface. Note that the return surface
|
||||
* may not necessarily be of the same type as @surface.
|
||||
**/
|
||||
cairo_surface_t *
|
||||
_cairo_surface_snapshot (cairo_surface_t *surface)
|
||||
{
|
||||
if (surface->finished)
|
||||
return (cairo_surface_t *) &_cairo_surface_nil;
|
||||
|
||||
if (surface->backend->snapshot)
|
||||
return surface->backend->snapshot (surface);
|
||||
|
||||
return _fallback_snapshot (surface);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
cairo_surface_t *dst;
|
||||
cairo_rectangle_t extents;
|
||||
|
|
|
|||
|
|
@ -318,11 +318,17 @@ struct _cairo_array {
|
|||
int num_elements;
|
||||
int element_size;
|
||||
char *elements;
|
||||
|
||||
cairo_bool_t is_snapshot;
|
||||
};
|
||||
|
||||
cairo_private void
|
||||
_cairo_array_init (cairo_array_t *array, int element_size);
|
||||
|
||||
void
|
||||
_cairo_array_init_snapshot (cairo_array_t *array,
|
||||
const cairo_array_t *other);
|
||||
|
||||
cairo_private void
|
||||
_cairo_array_fini (cairo_array_t *array);
|
||||
|
||||
|
|
@ -790,6 +796,9 @@ struct _cairo_surface_backend {
|
|||
const cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font);
|
||||
|
||||
cairo_surface_t *
|
||||
(*snapshot) (void *surface);
|
||||
};
|
||||
|
||||
typedef struct _cairo_format_masks {
|
||||
|
|
@ -1843,6 +1852,9 @@ _cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
|
|||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_image (const cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_meta (const cairo_surface_t *surface);
|
||||
|
||||
/* cairo_pen.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pen_init (cairo_pen_t *pen,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue