diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-04-23 19:45:26 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-07-15 11:05:19 +0100 |
commit | 83bfd85a1378e61b8bdc3f554f5e07900311f61f (patch) | |
tree | 380f96e0021d420799db02f4abe3e364745ec476 | |
parent | 2055732ffcd6316c3feb05ac330fbaf8698df5c4 (diff) |
Implement cairo_backend_t
Allow a backend to completely reimplement the Cairo API as it wants. The
goal is to pass operations to the native backends such as Quartz,
Direct2D, Qt, Skia, OpenVG with no overhead. And to permit complete
logging contexts, and whatever else the imagination holds. Perhaps to
experiment with double-paths?
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
52 files changed, 2321 insertions, 809 deletions
diff --git a/src/Makefile.sources b/src/Makefile.sources index 966e03d9a..03b203016 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -62,6 +62,7 @@ cairo_private = \ cairo-combsort-private.h \ cairo-compiler-private.h \ cairo-composite-rectangles-private.h \ + cairo-default-context-private.h \ cairo-device-private.h \ cairo-error-private.h \ cairo-fixed-private.h \ @@ -122,6 +123,7 @@ cairo_sources = \ cairo-color.c \ cairo-composite-rectangles.c \ cairo-debug.c \ + cairo-default-context.c \ cairo-device.c \ cairo-error.c \ cairo-fixed.c \ diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index 5468eac0c..affa55634 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -37,6 +37,7 @@ #include "cairoint.h" #include "cairo-analysis-surface-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-paginated-private.h" #include "cairo-recording-surface-private.h" @@ -646,6 +647,8 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, static const cairo_surface_backend_t cairo_analysis_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS, + NULL, + NULL, /* create_similar */ _cairo_analysis_surface_finish, NULL, /* acquire_source_image */ @@ -843,6 +846,7 @@ typedef cairo_int_status_t static const cairo_surface_backend_t cairo_null_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_NULL, + _cairo_default_context_create, /* XXX */ NULL, /* create_similar */ NULL, /* finish */ diff --git a/src/cairo-backend-private.h b/src/cairo-backend-private.h new file mode 100644 index 000000000..720b28c30 --- /dev/null +++ b/src/cairo-backend-private.h @@ -0,0 +1,170 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2010 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 + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Intel Corporation + * + * Contributor(s): + * Chris Wilson <chris@chris-wilson.co.uk> + */ + +#ifndef CAIRO_BACKEND_PRIVATE_H +#define CAIRO_BACKEND_PRIVATE_H + +#include "cairo-types-private.h" + +typedef enum _cairo_backend_type { + CAIRO_TYPE_DEFAULT, +} cairo_backend_type_t; + +struct _cairo_backend { + cairo_backend_type_t type; + void (*destroy) (void *cr); + + cairo_surface_t *(*get_original_target) (void *cr); + cairo_surface_t *(*get_current_target) (void *cr); + + cairo_status_t (*save) (void *cr); + cairo_status_t (*restore) (void *cr); + + cairo_status_t (*push_group) (void *cr, cairo_content_t content); + cairo_pattern_t *(*pop_group) (void *cr); + + cairo_status_t (*set_source_rgba) (void *cr, double red, double green, double blue, double alpha); + cairo_status_t (*set_source_surface) (void *cr, cairo_surface_t *surface, double x, double y); + cairo_status_t (*set_source) (void *cr, cairo_pattern_t *source); + cairo_pattern_t *(*get_source) (void *cr); + + cairo_status_t (*set_antialias) (void *cr, cairo_antialias_t antialias); + cairo_status_t (*set_dash) (void *cr, const double *dashes, int num_dashes, double offset); + cairo_status_t (*set_fill_rule) (void *cr, cairo_fill_rule_t fill_rule); + cairo_status_t (*set_line_cap) (void *cr, cairo_line_cap_t line_cap); + cairo_status_t (*set_line_join) (void *cr, cairo_line_join_t line_join); + cairo_status_t (*set_line_width) (void *cr, double line_width); + cairo_status_t (*set_miter_limit) (void *cr, double limit); + cairo_status_t (*set_opacity) (void *cr, double opacity); + cairo_status_t (*set_operator) (void *cr, cairo_operator_t op); + cairo_status_t (*set_tolerance) (void *cr, double tolerance); + + cairo_antialias_t (*get_antialias) (void *cr); + void (*get_dash) (void *cr, double *dashes, int *num_dashes, double *offset); + cairo_fill_rule_t (*get_fill_rule) (void *cr); + cairo_line_cap_t (*get_line_cap) (void *cr); + cairo_line_join_t (*get_line_join) (void *cr); + double (*get_line_width) (void *cr); + double (*get_miter_limit) (void *cr); + double (*get_opacity) (void *cr); + cairo_operator_t (*get_operator) (void *cr); + double (*get_tolerance) (void *cr); + + cairo_status_t (*translate) (void *cr, double tx, double ty); + cairo_status_t (*scale) (void *cr, double sx, double sy); + cairo_status_t (*rotate) (void *cr, double theta); + cairo_status_t (*transform) (void *cr, const cairo_matrix_t *matrix); + cairo_status_t (*set_matrix) (void *cr, const cairo_matrix_t *matrix); + cairo_status_t (*set_identity_matrix) (void *cr); + void (*get_matrix) (void *cr, cairo_matrix_t *matrix); + + void (*user_to_device) (void *cr, double *x, double *y); + void (*user_to_device_distance) (void *cr, double *x, double *y); + void (*device_to_user) (void *cr, double *x, double *y); + void (*device_to_user_distance) (void *cr, double *x, double *y); + + cairo_status_t (*new_path) (void *cr); + cairo_status_t (*new_sub_path) (void *cr); + cairo_status_t (*move_to) (void *cr, double x, double y); + cairo_status_t (*rel_move_to) (void *cr, double dx, double dy); + cairo_status_t (*line_to) (void *cr, double x, double y); + cairo_status_t (*rel_line_to) (void *cr, double dx, double dy); + cairo_status_t (*curve_to) (void *cr, double x1, double y1, double x2, double y2, double x3, double y3); + cairo_status_t (*rel_curve_to) (void *cr, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3); + cairo_status_t (*arc_to) (void *cr, double x1, double y1, double x2, double y2, double radius); + cairo_status_t (*rel_arc_to) (void *cr, double dx1, double dy1, double dx2, double dy2, double radius); + cairo_status_t (*close_path) (void *cr); + + cairo_status_t (*arc) (void *cr, double xc, double yc, double radius, double angle1, double angle2, cairo_bool_t forward); + cairo_status_t (*rectangle) (void *cr, double x, double y, double width, double height); + + void (*path_extents) (void *cr, double *x1, double *y1, double *x2, double *y2); + cairo_bool_t (*has_current_point) (void *cr); + cairo_bool_t (*get_current_point) (void *cr, double *x, double *y); + + cairo_path_t *(*copy_path) (void *cr); + cairo_path_t *(*copy_path_flat) (void *cr); + cairo_status_t (*append_path) (void *cr, const cairo_path_t *path); + + cairo_status_t (*stroke_to_path) (void *cr); + + cairo_status_t (*clip) (void *cr); + cairo_status_t (*clip_preserve) (void *cr); + cairo_status_t (*in_clip) (void *cr, double x, double y, cairo_bool_t *inside); + cairo_status_t (*clip_extents) (void *cr, double *x1, double *y1, double *x2, double *y2); + cairo_status_t (*reset_clip) (void *cr); + cairo_rectangle_list_t *(*clip_copy_rectangle_list) (void *cr); + + cairo_status_t (*paint) (void *cr); + cairo_status_t (*paint_with_alpha) (void *cr, double opacity); + cairo_status_t (*mask) (void *cr, cairo_pattern_t *pattern); + + cairo_status_t (*stroke) (void *cr); + cairo_status_t (*stroke_preserve) (void *cr); + cairo_status_t (*in_stroke) (void *cr, double x, double y, cairo_bool_t *inside); + cairo_status_t (*stroke_extents) (void *cr, double *x1, double *y1, double *x2, double *y2); + + cairo_status_t (*fill) (void *cr); + cairo_status_t (*fill_preserve) (void *cr); + cairo_status_t (*in_fill) (void *cr, double x, double y, cairo_bool_t *inside); + cairo_status_t (*fill_extents) (void *cr, double *x1, double *y1, double *x2, double *y2); + + cairo_status_t (*set_font_face) (void *cr, cairo_font_face_t *font_face); + cairo_font_face_t *(*get_font_face) (void *cr); + cairo_status_t (*set_font_size) (void *cr, double size); + cairo_status_t (*set_font_matrix) (void *cr, const cairo_matrix_t *matrix); + void (*get_font_matrix) (void *cr, cairo_matrix_t *matrix); + cairo_status_t (*set_font_options) (void *cr, const cairo_font_options_t *options); + void (*get_font_options) (void *cr, cairo_font_options_t *options); + cairo_status_t (*set_scaled_font) (void *cr, cairo_scaled_font_t *scaled_font); + cairo_scaled_font_t *(*get_scaled_font) (void *cr); + cairo_status_t (*font_extents) (void *cr, cairo_font_extents_t *extents); + + cairo_status_t (*glyphs) (void *cr, + const cairo_glyph_t *glyphs, int num_glyphs, + cairo_glyph_text_info_t *info); + cairo_status_t (*glyph_path) (void *cr, + const cairo_glyph_t *glyphs, int num_glyphs); + + cairo_status_t (*glyph_extents) (void *cr, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_text_extents_t *extents); + + cairo_status_t (*copy_page) (void *cr); + cairo_status_t (*show_page) (void *cr); +}; + +#endif /* CAIRO_BACKEND_PRIVATE_H */ diff --git a/src/cairo-clip.c b/src/cairo-clip.c index d78a17c22..929c10734 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -513,10 +513,13 @@ static cairo_status_t _cairo_clip_apply_clip_path (cairo_clip_t *clip, const cairo_clip_path_t *path) { - cairo_status_t status; + if (path->prev != NULL) { + cairo_status_t status; - if (path->prev != NULL) status = _cairo_clip_apply_clip_path (clip, path->prev); + if (unlikely (status)) + return status; + } return _cairo_clip_intersect_path (clip, &path->path, diff --git a/src/cairo-debug.c b/src/cairo-debug.c index 1aa57791e..f8ef717e1 100644 --- a/src/cairo-debug.c +++ b/src/cairo-debug.c @@ -87,7 +87,7 @@ cairo_debug_reset_static_data (void) _cairo_drm_device_reset_static_data (); #endif - _cairo_reset_static_data (); + _cairo_default_context_reset_static_data (); CAIRO_MUTEX_FINALIZE (); } diff --git a/src/cairo-default-context-private.h b/src/cairo-default-context-private.h new file mode 100644 index 000000000..e2d780d25 --- /dev/null +++ b/src/cairo-default-context-private.h @@ -0,0 +1,58 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Carl D. Worth <cworth@redhat.com> + */ + +#ifndef CAIRO_DEFAULT_CONTEXT_PRIVATE_H +#define CAIRO_DEFAULT_CONTEXT_PRIVATE_H + +#include "cairo-private.h" +#include "cairo-gstate-private.h" +#include "cairo-path-fixed-private.h" + +typedef struct _cairo_default_context cairo_default_context_t; + +struct _cairo_default_context { + cairo_t base; + + cairo_gstate_t *gstate; + cairo_gstate_t gstate_tail[2]; + cairo_gstate_t *gstate_freelist; + + cairo_path_fixed_t path[1]; +}; + +cairo_private cairo_t * +_cairo_default_context_create (void *target); + +#endif /* CAIRO_DEFAULT_CONTEXT_PRIVATE_H */ diff --git a/src/cairo-default-context.c b/src/cairo-default-context.c new file mode 100644 index 000000000..dbd014a68 --- /dev/null +++ b/src/cairo-default-context.c @@ -0,0 +1,1406 @@ +/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ +/* cairo - a vector graphics library with display and print output + * + * 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 + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * 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-default-context-private.h" +#include "cairo-error-private.h" +#include "cairo-freed-pool-private.h" +#include "cairo-path-private.h" + +#define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1) + +#if !defined(INFINITY) +#define INFINITY HUGE_VAL +#endif + +static freed_pool_t context_pool; + +void +_cairo_default_context_reset_static_data (void) +{ + _freed_pool_reset (&context_pool); +} + +static void +_cairo_default_context_destroy (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + while (cr->gstate != &cr->gstate_tail[0]) { + if (_cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist)) + break; + } + + _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_fini (&cr->base); + + /* mark the context as invalid to protect against misuse */ + cr->base.status = CAIRO_STATUS_NULL_POINTER; + _freed_pool_put (&context_pool, cr); +} + +static cairo_surface_t * +_cairo_default_context_get_original_target (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_original_target (cr->gstate); +} + +static cairo_surface_t * +_cairo_default_context_get_current_target (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_target (cr->gstate); +} + +static cairo_status_t +_cairo_default_context_save (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist); +} + +static cairo_status_t +_cairo_default_context_restore (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); +} + +static cairo_status_t +_cairo_default_context_push_group (void *abstract_cr, cairo_content_t content) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_surface_t *group_surface; + cairo_clip_t *clip; + cairo_status_t status; + + 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; + 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 */ + status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist); + if (unlikely (status)) + goto bail; + + status = _cairo_gstate_redirect_target (cr->gstate, group_surface); + +bail: + cairo_surface_destroy (group_surface); + return status; +} + +static cairo_pattern_t * +_cairo_default_context_pop_group (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_surface_t *group_surface; + cairo_pattern_t *group_pattern; + cairo_matrix_t group_matrix, device_transform_matrix; + cairo_status_t status; + + /* Verify that we are at the right nesting level */ + if (unlikely (! _cairo_gstate_is_group (cr->gstate))) + return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP); + + /* Get a reference to the active surface before restoring */ + group_surface = _cairo_gstate_get_target (cr->gstate); + group_surface = cairo_surface_reference (group_surface); + + status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); + assert (status == CAIRO_STATUS_SUCCESS); + + group_pattern = cairo_pattern_create_for_surface (group_surface); + status = group_pattern->status; + if (unlikely (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; +} + +static cairo_status_t +_cairo_default_context_set_source (void *abstract_cr, + cairo_pattern_t *source) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_source (cr->gstate, source); +} + +static cairo_bool_t +_current_source_matches_solid (const cairo_pattern_t *pattern, + double red, + double green, + double blue, + double alpha) +{ + cairo_color_t color; + + if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) + return FALSE; + + 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); + + _cairo_color_init_rgba (&color, red, green, blue, alpha); + return _cairo_color_equal (&color, + &((cairo_solid_pattern_t *) pattern)->color); +} + +static cairo_status_t +_cairo_default_context_set_source_rgba (void *abstract_cr, double red, double green, double blue, double alpha) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_pattern_t *pattern; + cairo_status_t status; + + if (_current_source_matches_solid (cr->gstate->source, red, green, blue, 1.)) + return CAIRO_STATUS_SUCCESS; + + /* push the current pattern to the freed lists */ + _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black); + + pattern = cairo_pattern_create_rgba (red, green, blue, alpha); + if (unlikely (pattern->status)) + return pattern->status; + + status = _cairo_default_context_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + return status; +} + +static cairo_status_t +_cairo_default_context_set_source_surface (void *abstract_cr, + cairo_surface_t *surface, + double x, + double y) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_pattern_t *pattern; + cairo_matrix_t matrix; + cairo_status_t status; + + /* push the current pattern to the freed lists */ + _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black); + + pattern = cairo_pattern_create_for_surface (surface); + if (unlikely (pattern->status)) + return pattern->status; + + cairo_matrix_init_translate (&matrix, -x, -y); + cairo_pattern_set_matrix (pattern, &matrix); + + status = _cairo_default_context_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + return status; +} + +static cairo_pattern_t * +_cairo_default_context_get_source (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_source (cr->gstate); +} + +static cairo_status_t +_cairo_default_context_set_tolerance (void *abstract_cr, + double tolerance) +{ + cairo_default_context_t *cr = abstract_cr; + + if (tolerance < CAIRO_TOLERANCE_MINIMUM) + tolerance = CAIRO_TOLERANCE_MINIMUM; + + return _cairo_gstate_set_tolerance (cr->gstate, tolerance); +} + +static cairo_status_t +_cairo_default_context_set_operator (void *abstract_cr, cairo_operator_t op) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_operator (cr->gstate, op); +} + +static cairo_status_t +_cairo_default_context_set_opacity (void *abstract_cr, double opacity) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_opacity (cr->gstate, opacity); +} + +static cairo_status_t +_cairo_default_context_set_antialias (void *abstract_cr, + cairo_antialias_t antialias) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_antialias (cr->gstate, antialias); +} + +static cairo_status_t +_cairo_default_context_set_fill_rule (void *abstract_cr, + cairo_fill_rule_t fill_rule) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_fill_rule (cr->gstate, fill_rule); +} + +static cairo_status_t +_cairo_default_context_set_line_width (void *abstract_cr, + double line_width) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_line_width (cr->gstate, line_width); +} + +static cairo_status_t +_cairo_default_context_set_line_cap (void *abstract_cr, + cairo_line_cap_t line_cap) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_line_cap (cr->gstate, line_cap); +} + +static cairo_status_t +_cairo_default_context_set_line_join (void *abstract_cr, + cairo_line_join_t line_join) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_line_join (cr->gstate, line_join); +} + +static cairo_status_t +_cairo_default_context_set_dash (void *abstract_cr, + const double *dashes, + int num_dashes, + double offset) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_dash (cr->gstate, + dashes, num_dashes, offset); +} + +static cairo_status_t +_cairo_default_context_set_miter_limit (void *abstract_cr, + double limit) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_miter_limit (cr->gstate, limit); +} + +static cairo_antialias_t +_cairo_default_context_get_antialias (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_antialias (cr->gstate); +} + +static void +_cairo_default_context_get_dash (void *abstract_cr, + double *dashes, + int *num_dashes, + double *offset) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_get_dash (cr->gstate, dashes, num_dashes, offset); +} + +static cairo_fill_rule_t +_cairo_default_context_get_fill_rule (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_fill_rule (cr->gstate); +} + +static double +_cairo_default_context_get_line_width (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_line_width (cr->gstate); +} + +static cairo_line_cap_t +_cairo_default_context_get_line_cap (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_line_cap (cr->gstate); +} + +static cairo_line_join_t +_cairo_default_context_get_line_join (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_line_join (cr->gstate); +} + +static double +_cairo_default_context_get_miter_limit (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_miter_limit (cr->gstate); +} + +static cairo_operator_t +_cairo_default_context_get_operator (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_operator (cr->gstate); +} + +static double +_cairo_default_context_get_opacity (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_opacity (cr->gstate); +} + +static double +_cairo_default_context_get_tolerance (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_tolerance (cr->gstate); +} + + +/* Current tranformation matrix */ + +static cairo_status_t +_cairo_default_context_translate (void *abstract_cr, + double tx, + double ty) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_translate (cr->gstate, tx, ty); +} + +static cairo_status_t +_cairo_default_context_scale (void *abstract_cr, + double sx, + double sy) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_scale (cr->gstate, sx, sy); +} + +static cairo_status_t +_cairo_default_context_rotate (void *abstract_cr, + double theta) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_rotate (cr->gstate, theta); +} + +static cairo_status_t +_cairo_default_context_transform (void *abstract_cr, + const cairo_matrix_t *matrix) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_transform (cr->gstate, matrix); +} + +static cairo_status_t +_cairo_default_context_set_matrix (void *abstract_cr, + const cairo_matrix_t *matrix) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_matrix (cr->gstate, matrix); +} + +static cairo_status_t +_cairo_default_context_set_identity_matrix (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_identity_matrix (cr->gstate); + return CAIRO_STATUS_SUCCESS; +} + +static void +_cairo_default_context_get_matrix (void *abstract_cr, + cairo_matrix_t *matrix) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_get_matrix (cr->gstate, matrix); +} + +static void +_cairo_default_context_user_to_device (void *abstract_cr, + double *x, + double *y) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_user_to_device (cr->gstate, x, y); +} + +static void +_cairo_default_context_user_to_device_distance (void *abstract_cr, double *dx, double *dy) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy); +} + +static void +_cairo_default_context_device_to_user (void *abstract_cr, + double *x, + double *y) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_device_to_user (cr->gstate, x, y); +} + +static void +_cairo_default_context_device_to_user_distance (void *abstract_cr, + double *dx, + double *dy) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy); +} + +/* Path constructor */ + +static cairo_status_t +_cairo_default_context_new_path (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_path_fixed_fini (cr->path); + _cairo_path_fixed_init (cr->path); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_default_context_new_sub_path (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_path_fixed_new_sub_path (cr->path); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_default_context_move_to (void *abstract_cr, double x, double y) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_fixed_t x_fixed, y_fixed; + + _cairo_gstate_user_to_backend (cr->gstate, &x, &y); + x_fixed = _cairo_fixed_from_double (x); + y_fixed = _cairo_fixed_from_double (y); + + return _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed); +} + +static cairo_status_t +_cairo_default_context_line_to (void *abstract_cr, double x, double y) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_fixed_t x_fixed, y_fixed; + + _cairo_gstate_user_to_backend (cr->gstate, &x, &y); + x_fixed = _cairo_fixed_from_double (x); + y_fixed = _cairo_fixed_from_double (y); + + return _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); +} + +static cairo_status_t +_cairo_default_context_curve_to (void *abstract_cr, + double x1, double y1, + double x2, double y2, + double x3, double y3) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_fixed_t x1_fixed, y1_fixed; + cairo_fixed_t x2_fixed, y2_fixed; + cairo_fixed_t x3_fixed, y3_fixed; + + _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); + + return _cairo_path_fixed_curve_to (cr->path, + x1_fixed, y1_fixed, + x2_fixed, y2_fixed, + x3_fixed, y3_fixed); +} + +static cairo_status_t +_cairo_default_context_arc (void *abstract_cr, + double xc, double yc, double radius, + double angle1, double angle2, + cairo_bool_t forward) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_status_t status; + + /* Do nothing, successfully, if radius is <= 0 */ + if (radius <= 0.0) { + cairo_fixed_t x_fixed, y_fixed; + + _cairo_gstate_user_to_backend (cr->gstate, &xc, &yc); + x_fixed = _cairo_fixed_from_double (xc); + y_fixed = _cairo_fixed_from_double (yc); + status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); + if (unlikely (status)) + return status; + + status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); + if (unlikely (status)) + return status; + + return CAIRO_STATUS_SUCCESS; + } + + status = _cairo_default_context_line_to (cr, + xc + radius * cos (angle1), + yc + radius * sin (angle1)); + + if (unlikely (status)) + return status; + + if (forward) + _cairo_arc_path (&cr->base, xc, yc, radius, angle1, angle2); + else + _cairo_arc_path_negative (&cr->base, xc, yc, radius, angle1, angle2); + + return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */ +} + +static cairo_status_t +_cairo_default_context_rel_move_to (void *abstract_cr, double dx, double dy) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_fixed_t dx_fixed, dy_fixed; + + _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); + + dx_fixed = _cairo_fixed_from_double (dx); + dy_fixed = _cairo_fixed_from_double (dy); + + return _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed); +} + +static cairo_status_t +_cairo_default_context_rel_line_to (void *abstract_cr, double dx, double dy) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_fixed_t dx_fixed, dy_fixed; + + _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy); + + dx_fixed = _cairo_fixed_from_double (dx); + dy_fixed = _cairo_fixed_from_double (dy); + + return _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed); +} + + +static cairo_status_t +_cairo_default_context_rel_curve_to (void *abstract_cr, + double dx1, double dy1, + double dx2, double dy2, + double dx3, double dy3) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_fixed_t dx1_fixed, dy1_fixed; + cairo_fixed_t dx2_fixed, dy2_fixed; + cairo_fixed_t dx3_fixed, dy3_fixed; + + _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); + + return _cairo_path_fixed_rel_curve_to (cr->path, + dx1_fixed, dy1_fixed, + dx2_fixed, dy2_fixed, + dx3_fixed, dy3_fixed); +} + +static cairo_status_t +_cairo_default_context_close_path (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_path_fixed_close_path (cr->path); +} + +static cairo_status_t +_cairo_default_context_rectangle (void *abstract_cr, + double x, double y, + double width, double height) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_status_t status; + + status = _cairo_default_context_move_to (cr, x, y); + if (unlikely (status)) + return status; + + status = _cairo_default_context_rel_line_to (cr, width, 0); + if (unlikely (status)) + return status; + + status = _cairo_default_context_rel_line_to (cr, 0, height); + if (unlikely (status)) + return status; + + status = _cairo_default_context_rel_line_to (cr, -width, 0); + if (unlikely (status)) + return status; + + return _cairo_default_context_close_path (cr); +} + +static void +_cairo_default_context_path_extents (void *abstract_cr, + double *x1, + double *y1, + double *x2, + double *y2) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_path_extents (cr->gstate, + cr->path, + x1, y1, x2, y2); +} + +static cairo_bool_t +_cairo_default_context_has_current_point (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return cr->path->has_current_point; +} + +static cairo_bool_t +_cairo_default_context_get_current_point (void *abstract_cr, + double *x, + double *y) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_fixed_t x_fixed, y_fixed; + + if (_cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed)) + { + *x = _cairo_fixed_to_double (x_fixed); + *y = _cairo_fixed_to_double (y_fixed); + _cairo_gstate_backend_to_user (cr->gstate, x, y); + + return TRUE; + } + else + { + return FALSE; + } +} + +static cairo_path_t * +_cairo_default_context_copy_path (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_path_create (cr->path, &cr->base); +} + +static cairo_path_t * +_cairo_default_context_copy_path_flat (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_path_create_flat (cr->path, &cr->base); +} + +static cairo_status_t +_cairo_default_context_append_path (void *abstract_cr, + const cairo_path_t *path) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_path_append_to_context (path, &cr->base); +} + +static cairo_status_t +_cairo_default_context_paint (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_paint (cr->gstate); +} + +static cairo_status_t +_cairo_default_context_paint_with_alpha (void *abstract_cr, + double alpha) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_solid_pattern_t pattern; + cairo_status_t status; + cairo_color_t color; + + if (CAIRO_ALPHA_IS_OPAQUE (alpha)) + return _cairo_gstate_paint (cr->gstate); + + if (CAIRO_ALPHA_IS_ZERO (alpha) && + _cairo_operator_bounded_by_mask (cr->gstate->op)) { + return CAIRO_STATUS_SUCCESS; + } + + _cairo_color_init_rgba (&color, 0., 0., 0., alpha); + _cairo_pattern_init_solid (&pattern, &color); + + status = _cairo_gstate_mask (cr->gstate, &pattern.base); + _cairo_pattern_fini (&pattern.base); + + return status; +} + +static cairo_status_t +_cairo_default_context_mask (void *abstract_cr, + cairo_pattern_t *mask) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_mask (cr->gstate, mask); +} + +static cairo_status_t +_cairo_default_context_stroke_preserve (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_stroke (cr->gstate, cr->path); +} + +static cairo_status_t +_cairo_default_context_stroke (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_status_t status; + + status = _cairo_gstate_stroke (cr->gstate, cr->path); + if (unlikely (status)) + return status; + + return _cairo_default_context_new_path (cr); +} + +static cairo_status_t +_cairo_default_context_in_stroke (void *abstract_cr, + double x, double y, + cairo_bool_t *inside) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_in_stroke (cr->gstate, + cr->path, + x, y, + inside); +} + +static cairo_status_t +_cairo_default_context_stroke_extents (void *abstract_cr, + double *x1, double *y1, double *x2, double *y2) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_stroke_extents (cr->gstate, + cr->path, + x1, y1, x2, y2); +} + +static cairo_status_t +_cairo_default_context_fill_preserve (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_fill (cr->gstate, cr->path); +} + +static cairo_status_t +_cairo_default_context_fill (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_status_t status; + + status = _cairo_gstate_fill (cr->gstate, cr->path); + if (unlikely (status)) + return status; + + return _cairo_default_context_new_path (cr); +} + +static cairo_status_t +_cairo_default_context_in_fill (void *abstract_cr, + double x, double y, + cairo_bool_t *inside) +{ + cairo_default_context_t *cr = abstract_cr; + + *inside = _cairo_gstate_in_fill (cr->gstate, + cr->path, + x, y); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_default_context_fill_extents (void *abstract_cr, + double *x1, double *y1, double *x2, double *y2) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_fill_extents (cr->gstate, + cr->path, + x1, y1, x2, y2); +} + +static cairo_status_t +_cairo_default_context_clip_preserve (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_clip (cr->gstate, cr->path); +} + +static cairo_status_t +_cairo_default_context_clip (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_status_t status; + + status = _cairo_gstate_clip (cr->gstate, cr->path); + if (unlikely (status)) + return status; + + return _cairo_default_context_new_path (cr); +} + +static cairo_status_t +_cairo_default_context_in_clip (void *abstract_cr, + double x, double y, + cairo_bool_t *inside) +{ + cairo_default_context_t *cr = abstract_cr; + + *inside = _cairo_gstate_in_clip (cr->gstate, x, y); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_default_context_reset_clip (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_reset_clip (cr->gstate); +} + +static cairo_status_t +_cairo_default_context_clip_extents (void *abstract_cr, + double *x1, double *y1, double *x2, double *y2) +{ + cairo_default_context_t *cr = abstract_cr; + + if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) { + *x1 = -INFINITY; + *y1 = -INFINITY; + *x2 = +INFINITY; + *y2 = +INFINITY; + } + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_rectangle_list_t * +_cairo_default_context_copy_clip_rectangle_list (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_copy_clip_rectangle_list (cr->gstate); +} + +static cairo_status_t +_cairo_default_context_copy_page (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_copy_page (cr->gstate); +} + +static cairo_status_t +_cairo_default_context_show_page (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_show_page (cr->gstate); +} + +static cairo_status_t +_cairo_default_context_set_font_face (void *abstract_cr, + cairo_font_face_t *font_face) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_font_face (cr->gstate, font_face); +} + +static cairo_font_face_t * +_cairo_default_context_get_font_face (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_font_face_t *font_face; + cairo_status_t status; + + status = _cairo_gstate_get_font_face (cr->gstate, &font_face); + if (unlikely (status)) { + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); + return (cairo_font_face_t *) &_cairo_font_face_nil; + } + + return font_face; +} + +static cairo_status_t +_cairo_default_context_font_extents (void *abstract_cr, + cairo_font_extents_t *extents) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_font_extents (cr->gstate, extents); +} + +static cairo_status_t +_cairo_default_context_set_font_size (void *abstract_cr, + double size) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_font_size (cr->gstate, size); +} + +static cairo_status_t +_cairo_default_context_set_font_matrix (void *abstract_cr, + const cairo_matrix_t *matrix) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_font_matrix (cr->gstate, matrix); +} + +static void +_cairo_default_context_get_font_matrix (void *abstract_cr, + cairo_matrix_t *matrix) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_get_font_matrix (cr->gstate, matrix); +} + +static cairo_status_t +_cairo_default_context_set_font_options (void *abstract_cr, + const cairo_font_options_t *options) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_set_font_options (cr->gstate, options); + return CAIRO_STATUS_SUCCESS; +} + +static void +_cairo_default_context_get_font_options (void *abstract_cr, + cairo_font_options_t *options) +{ + cairo_default_context_t *cr = abstract_cr; + + _cairo_gstate_get_font_options (cr->gstate, options); +} + +static cairo_status_t +_cairo_default_context_set_scaled_font (void *abstract_cr, + cairo_scaled_font_t *scaled_font) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_bool_t was_previous; + cairo_status_t status; + + if (scaled_font == cr->gstate->scaled_font) + return CAIRO_STATUS_SUCCESS; + + was_previous = scaled_font == cr->gstate->previous_scaled_font; + + status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face); + if (unlikely (status)) + return status; + + status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix); + if (unlikely (status)) + return status; + + _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options); + + if (was_previous) + cr->gstate->scaled_font = cairo_scaled_font_reference (scaled_font); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_scaled_font_t * +_cairo_default_context_get_scaled_font (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + cairo_scaled_font_t *scaled_font; + cairo_status_t status; + + status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font); + if (unlikely (status)) + return _cairo_scaled_font_create_in_error (status); + + return scaled_font; +} + +static cairo_status_t +_cairo_default_context_glyphs (void *abstract_cr, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_glyph_text_info_t *info) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_show_text_glyphs (cr->gstate, glyphs, num_glyphs, info); +} + +static cairo_status_t +_cairo_default_context_glyph_path (void *abstract_cr, + const cairo_glyph_t *glyphs, + int num_glyphs) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_glyph_path (cr->gstate, + glyphs, num_glyphs, + cr->path); +} + +static cairo_status_t +_cairo_default_context_glyph_extents (void *abstract_cr, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_text_extents_t *extents) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents); +} + +static const cairo_backend_t _cairo_default_context_backend = { + CAIRO_TYPE_DEFAULT, + _cairo_default_context_destroy, + + _cairo_default_context_get_original_target, + _cairo_default_context_get_current_target, + + _cairo_default_context_save, + _cairo_default_context_restore, + + _cairo_default_context_push_group, + _cairo_default_context_pop_group, + + _cairo_default_context_set_source_rgba, + _cairo_default_context_set_source_surface, + _cairo_default_context_set_source, + _cairo_default_context_get_source, + + _cairo_default_context_set_antialias, + _cairo_default_context_set_dash, + _cairo_default_context_set_fill_rule, + _cairo_default_context_set_line_cap, + _cairo_default_context_set_line_join, + _cairo_default_context_set_line_width, + _cairo_default_context_set_miter_limit, + _cairo_default_context_set_opacity, + _cairo_default_context_set_operator, + _cairo_default_context_set_tolerance, + _cairo_default_context_get_antialias, + _cairo_default_context_get_dash, + _cairo_default_context_get_fill_rule, + _cairo_default_context_get_line_cap, + _cairo_default_context_get_line_join, + _cairo_default_context_get_line_width, + _cairo_default_context_get_miter_limit, + _cairo_default_context_get_opacity, + _cairo_default_context_get_operator, + _cairo_default_context_get_tolerance, + + _cairo_default_context_translate, + _cairo_default_context_scale, + _cairo_default_context_rotate, + _cairo_default_context_transform, + _cairo_default_context_set_matrix, + _cairo_default_context_set_identity_matrix, + _cairo_default_context_get_matrix, + _cairo_default_context_user_to_device, + _cairo_default_context_user_to_device_distance, + _cairo_default_context_device_to_user, + _cairo_default_context_device_to_user_distance, + + _cairo_default_context_new_path, + _cairo_default_context_new_sub_path, + _cairo_default_context_move_to, + _cairo_default_context_rel_move_to, + _cairo_default_context_line_to, + _cairo_default_context_rel_line_to, + _cairo_default_context_curve_to, + _cairo_default_context_rel_curve_to, + NULL, /* arc-to */ + NULL, /* rel-arc-to */ + _cairo_default_context_close_path, + _cairo_default_context_arc, + _cairo_default_context_rectangle, + _cairo_default_context_path_extents, + _cairo_default_context_has_current_point, + _cairo_default_context_get_current_point, + _cairo_default_context_copy_path, + _cairo_default_context_copy_path_flat, + _cairo_default_context_append_path, + + NULL, /* stroke-to-path */ + + _cairo_default_context_clip, + _cairo_default_context_clip_preserve, + _cairo_default_context_in_clip, + _cairo_default_context_clip_extents, + _cairo_default_context_reset_clip, + _cairo_default_context_copy_clip_rectangle_list, + + _cairo_default_context_paint, + _cairo_default_context_paint_with_alpha, + _cairo_default_context_mask, + + _cairo_default_context_stroke, + _cairo_default_context_stroke_preserve, + _cairo_default_context_in_stroke, + _cairo_default_context_stroke_extents, + + _cairo_default_context_fill, + _cairo_default_context_fill_preserve, + _cairo_default_context_in_fill, + _cairo_default_context_fill_extents, + + _cairo_default_context_set_font_face, + _cairo_default_context_get_font_face, + _cairo_default_context_set_font_size, + _cairo_default_context_set_font_matrix, + _cairo_default_context_get_font_matrix, + _cairo_default_context_set_font_options, + _cairo_default_context_get_font_options, + _cairo_default_context_set_scaled_font, + _cairo_default_context_get_scaled_font, + _cairo_default_context_font_extents, + + _cairo_default_context_glyphs, + _cairo_default_context_glyph_path, + _cairo_default_context_glyph_extents, + + _cairo_default_context_copy_page, + _cairo_default_context_show_page, +}; + +cairo_t * +_cairo_default_context_create (void *target) +{ + cairo_default_context_t *cr; + cairo_status_t status; + + cr = _freed_pool_get (&context_pool); + if (unlikely (cr == NULL)) { + cr = malloc (sizeof (cairo_default_context_t)); + if (unlikely (cr == NULL)) + return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); + } + + _cairo_init (&cr->base, &_cairo_default_context_backend); + _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)) { + _freed_pool_put (&context_pool, cr); + return _cairo_create_in_error (status); + } + + return &cr->base; +} diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c index fc7509c1a..3de016832 100644 --- a/src/cairo-directfb-surface.c +++ b/src/cairo-directfb-surface.c @@ -39,6 +39,7 @@ #include "cairo-directfb.h" #include "cairo-clip-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include <pixman.h> @@ -1827,6 +1828,8 @@ _cairo_directfb_surface_is_similar (void *surface_a, void *surface_b) static cairo_surface_backend_t _cairo_directfb_surface_backend = { CAIRO_SURFACE_TYPE_DIRECTFB, /*type*/ + _cairo_default_context_create, + _cairo_directfb_surface_create_similar,/*create_similar*/ _cairo_directfb_surface_finish, /*finish*/ _cairo_directfb_surface_acquire_source_image,/*acquire_source_image*/ diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 813e3542b..eb317f0b6 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -41,6 +41,7 @@ #include "cairoint.h" #include "cairo-composite-rectangles-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-gl-private.h" @@ -1839,6 +1840,8 @@ _cairo_gl_surface_fill (void *abstract_surface, const cairo_surface_backend_t _cairo_gl_surface_backend = { CAIRO_SURFACE_TYPE_GL, + _cairo_default_context_create, + _cairo_gl_surface_create_similar, _cairo_gl_surface_finish, diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h index f1e03b378..9e823fa0f 100644 --- a/src/cairo-gstate-private.h +++ b/src/cairo-gstate-private.h @@ -41,6 +41,7 @@ struct _cairo_gstate { cairo_operator_t op; + double opacity; double tolerance; cairo_antialias_t antialias; @@ -115,6 +116,12 @@ cairo_private cairo_operator_t _cairo_gstate_get_operator (cairo_gstate_t *gstate); cairo_private cairo_status_t +_cairo_gstate_set_opacity (cairo_gstate_t *gstate, double opacity); + +cairo_private double +_cairo_gstate_get_opacity (cairo_gstate_t *gstate); + +cairo_private cairo_status_t _cairo_gstate_set_tolerance (cairo_gstate_t *gstate, double tolerance); cairo_private double @@ -289,10 +296,16 @@ cairo_private cairo_rectangle_list_t* _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate); cairo_private cairo_status_t -_cairo_gstate_select_font_face (cairo_gstate_t *gstate, - const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight); +_cairo_gstate_show_surface (cairo_gstate_t *gstate, + cairo_surface_t *surface, + double x, + double y, + double width, + double height); + +cairo_private cairo_status_t +_cairo_gstate_set_font_size (cairo_gstate_t *gstate, + double size); cairo_private void _cairo_gstate_get_font_matrix (cairo_gstate_t *gstate, @@ -327,18 +340,6 @@ _cairo_gstate_set_font_face (cairo_gstate_t *gstate, cairo_font_face_t *font_face); cairo_private cairo_status_t -_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate, - double x, - double y, - const char *utf8, - int utf8_len, - cairo_glyph_t **glyphs, - int *num_glyphs, - cairo_text_cluster_t **clusters, - int *num_clusters, - cairo_text_cluster_flags_t *cluster_flags); - -cairo_private cairo_status_t _cairo_gstate_glyph_extents (cairo_gstate_t *gstate, const cairo_glyph_t *glyphs, int num_glyphs, @@ -346,13 +347,9 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate, cairo_private cairo_status_t _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, - const char *utf8, - int utf8_len, const cairo_glyph_t *glyphs, int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags); + cairo_glyph_text_info_t *info); cairo_private cairo_status_t _cairo_gstate_glyph_path (cairo_gstate_t *gstate, diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index d9672c22c..7aea6c1d7 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -91,6 +91,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate, gstate->next = NULL; gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT; + gstate->opacity = 1.; gstate->tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT; gstate->antialias = CAIRO_ANTIALIAS_DEFAULT; @@ -147,6 +148,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) VG (VALGRIND_MAKE_MEM_UNDEFINED (gstate, sizeof (cairo_gstate_t))); gstate->op = other->op; + gstate->opacity = other->opacity; gstate->tolerance = other->tolerance; gstate->antialias = other->antialias; @@ -429,6 +431,20 @@ _cairo_gstate_get_operator (cairo_gstate_t *gstate) } cairo_status_t +_cairo_gstate_set_opacity (cairo_gstate_t *gstate, double op) +{ + gstate->opacity = op; + + return CAIRO_STATUS_SUCCESS; +} + +double +_cairo_gstate_get_opacity (cairo_gstate_t *gstate) +{ + return gstate->opacity; +} + +cairo_status_t _cairo_gstate_set_tolerance (cairo_gstate_t *gstate, double tolerance) { gstate->tolerance = tolerance; @@ -1066,6 +1082,8 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, if (_clipped (gstate)) return CAIRO_STATUS_SUCCESS; + assert (gstate->opacity == 1.0); + if (_cairo_pattern_is_opaque (mask, NULL)) return _cairo_gstate_paint (gstate); @@ -1143,6 +1161,8 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) if (_clipped (gstate)) return CAIRO_STATUS_SUCCESS; + assert (gstate->opacity == 1.0); + memcpy (&style, &gstate->stroke_style, sizeof (gstate->stroke_style)); if (_cairo_stroke_style_dash_can_approximate (&gstate->stroke_style, &gstate->ctm, gstate->tolerance)) { style.dash = dash; @@ -1243,6 +1263,8 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) if (_clipped (gstate)) return CAIRO_STATUS_SUCCESS; + assert (gstate->opacity == 1.0); + if (_cairo_path_fixed_fill_is_empty (path)) { if (_cairo_operator_bounded_by_mask (gstate->op)) return CAIRO_STATUS_SUCCESS; @@ -1580,22 +1602,14 @@ _cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate) } cairo_status_t -_cairo_gstate_select_font_face (cairo_gstate_t *gstate, - const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight) +_cairo_gstate_set_font_size (cairo_gstate_t *gstate, + double size) { - cairo_font_face_t *font_face; - cairo_status_t status; - - font_face = cairo_toy_font_face_create (family, slant, weight); - if (font_face->status) - return font_face->status; + _cairo_gstate_unset_scaled_font (gstate); - status = _cairo_gstate_set_font_face (gstate, font_face); - cairo_font_face_destroy (font_face); + cairo_matrix_init_scale (&gstate->font_matrix, size, size); - return status; + return CAIRO_STATUS_SUCCESS; } cairo_status_t @@ -1810,31 +1824,6 @@ _cairo_gstate_get_font_extents (cairo_gstate_t *gstate, } cairo_status_t -_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate, - double x, - double y, - const char *utf8, - int utf8_len, - cairo_glyph_t **glyphs, - int *num_glyphs, - cairo_text_cluster_t **clusters, - int *num_clusters, - cairo_text_cluster_flags_t *cluster_flags) -{ - cairo_status_t status; - - status = _cairo_gstate_ensure_scaled_font (gstate); - if (unlikely (status)) - return status; - - return cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags); -} - -cairo_status_t _cairo_gstate_set_font_face (cairo_gstate_t *gstate, cairo_font_face_t *font_face) { @@ -1873,20 +1862,16 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate, cairo_status_t _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, - const char *utf8, - int utf8_len, const cairo_glyph_t *glyphs, int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags) + cairo_glyph_text_info_t *info) { cairo_pattern_union_t source_pattern; const cairo_pattern_t *pattern; cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)]; cairo_glyph_t *transformed_glyphs; cairo_text_cluster_t stack_transformed_clusters[CAIRO_STACK_ARRAY_LENGTH (cairo_text_cluster_t)]; - cairo_text_cluster_t *transformed_clusters; + cairo_text_cluster_t *transformed_clusters = NULL; cairo_operator_t op; cairo_status_t status; cairo_clip_t clip; @@ -1906,8 +1891,6 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, return status; transformed_glyphs = stack_transformed_glyphs; - transformed_clusters = stack_transformed_clusters; - if (num_glyphs > ARRAY_LENGTH (stack_transformed_glyphs)) { transformed_glyphs = cairo_glyph_allocate (num_glyphs); if (unlikely (transformed_glyphs == NULL)) { @@ -1916,26 +1899,32 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, } } - /* Just in case */ - if (!clusters) - num_clusters = 0; - - if (num_clusters > ARRAY_LENGTH (stack_transformed_clusters)) { - transformed_clusters = cairo_text_cluster_allocate (num_clusters); - if (unlikely (transformed_clusters == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_GLYPHS; + if (info != NULL) { + transformed_clusters = stack_transformed_clusters; + if (info->num_clusters > ARRAY_LENGTH (stack_transformed_clusters)) { + transformed_clusters = cairo_text_cluster_allocate (info->num_clusters); + if (unlikely (transformed_clusters == NULL)) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto CLEANUP_GLYPHS; + } } - } - status = _cairo_gstate_transform_glyphs_to_backend (gstate, - glyphs, num_glyphs, - clusters, - num_clusters, - cluster_flags, - transformed_glyphs, - &num_glyphs, - transformed_clusters); + status = _cairo_gstate_transform_glyphs_to_backend (gstate, + glyphs, num_glyphs, + info->clusters, + info->num_clusters, + info->cluster_flags, + transformed_glyphs, + &num_glyphs, + transformed_clusters); + } else { + status = _cairo_gstate_transform_glyphs_to_backend (gstate, + glyphs, num_glyphs, + NULL, 0, 0, + transformed_glyphs, + &num_glyphs, + NULL); + } if (status || num_glyphs == 0) goto CLEANUP_GLYPHS; @@ -1961,13 +1950,22 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, if (cairo_surface_has_show_text_glyphs (gstate->target) || _cairo_scaled_font_get_max_scale (gstate->scaled_font) <= 10240) { - status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern, - utf8, utf8_len, - transformed_glyphs, num_glyphs, - transformed_clusters, num_clusters, - cluster_flags, - gstate->scaled_font, - _gstate_get_clip (gstate, &clip)); + if (info != NULL) { + status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern, + info->utf8, info->utf8_len, + transformed_glyphs, num_glyphs, + transformed_clusters, info->num_clusters, + info->cluster_flags, + gstate->scaled_font, + _gstate_get_clip (gstate, &clip)); + } else { + status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern, + NULL, 0, + transformed_glyphs, num_glyphs, + NULL, 0, 0, + gstate->scaled_font, + _gstate_get_clip (gstate, &clip)); + } } else { @@ -2028,7 +2026,7 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, glyphs, num_glyphs, NULL, 0, 0, transformed_glyphs, - NULL, NULL); + &num_glyphs, NULL); if (unlikely (status)) goto CLEANUP_GLYPHS; diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 2c538d5fb..71d8d8841 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -42,6 +42,7 @@ #include "cairo-boxes-private.h" #include "cairo-clip-private.h" #include "cairo-composite-rectangles-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-region-private.h" #include "cairo-scaled-font-private.h" @@ -4601,6 +4602,8 @@ _cairo_surface_is_image (const cairo_surface_t *surface) const cairo_surface_backend_t _cairo_image_surface_backend = { CAIRO_SURFACE_TYPE_IMAGE, + _cairo_default_context_create, + _cairo_image_surface_create_similar, _cairo_image_surface_finish, _cairo_image_surface_acquire_source_image, diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c index b9758281d..c8a545832 100644 --- a/src/cairo-os2-surface.c +++ b/src/cairo-os2-surface.c @@ -39,6 +39,7 @@ #include "cairoint.h" #include "cairo-os2-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #if CAIRO_HAS_FC_FONT @@ -1438,6 +1439,8 @@ _cairo_os2_surface_mark_dirty_rectangle (void *surface, static const cairo_surface_backend_t cairo_os2_surface_backend = { CAIRO_SURFACE_TYPE_OS2, + _cairo_default_context_create, + NULL, /* create_similar */ _cairo_os2_surface_finish, _cairo_os2_surface_acquire_source_image, diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index 9e65f7ba0..74c8468e2 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -641,8 +641,17 @@ _cairo_paginated_surface_snapshot (void *abstract_other) return _cairo_surface_snapshot (other->recording_surface); } +static cairo_t * +_cairo_paginated_context_create (void *target) +{ + cairo_paginated_surface_t *surface = target; + return cairo_create (surface->recording_surface); +} + static const cairo_surface_backend_t cairo_paginated_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED, + _cairo_paginated_context_create, + _cairo_paginated_surface_create_similar, _cairo_paginated_surface_finish, _cairo_paginated_surface_acquire_source_image, diff --git a/src/cairo-path-private.h b/src/cairo-path-private.h index 61b4060fa..7b54317e2 100644 --- a/src/cairo-path-private.h +++ b/src/cairo-path-private.h @@ -41,11 +41,11 @@ cairo_private cairo_path_t * _cairo_path_create (cairo_path_fixed_t *path, - cairo_gstate_t *gstate); + cairo_t *cr); cairo_private cairo_path_t * _cairo_path_create_flat (cairo_path_fixed_t *path, - cairo_gstate_t *gstate); + cairo_t *cr); cairo_private cairo_path_t * _cairo_path_create_in_error (cairo_status_t status); diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index 522f1ab20..6b0df9cc1 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -1382,7 +1382,7 @@ BAIL: return status; } -cairo_status_t +cairo_int_status_t _cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path, const cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, @@ -1390,7 +1390,7 @@ _cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path, double tolerance, cairo_traps_t *traps) { - cairo_status_t status; + cairo_int_status_t status; cairo_polygon_t polygon; /* Before we do anything else, we attempt the rectilinear diff --git a/src/cairo-path.c b/src/cairo-path.c index bc5b731b3..16447a4db 100644 --- a/src/cairo-path.c +++ b/src/cairo-path.c @@ -138,7 +138,7 @@ _cairo_path_count (cairo_path_t *path, /* Closure for path interpretation. */ typedef struct cairo_path_populate { cairo_path_data_t *data; - cairo_gstate_t *gstate; + cairo_t *cr; } cpp_t; static cairo_status_t @@ -152,7 +152,7 @@ _cpp_move_to (void *closure, x = _cairo_fixed_to_double (point->x); y = _cairo_fixed_to_double (point->y); - _cairo_gstate_backend_to_user (cpp->gstate, &x, &y); + cairo_device_to_user (cpp->cr, &x, &y); data->header.type = CAIRO_PATH_MOVE_TO; data->header.length = 2; @@ -177,7 +177,7 @@ _cpp_line_to (void *closure, x = _cairo_fixed_to_double (point->x); y = _cairo_fixed_to_double (point->y); - _cairo_gstate_backend_to_user (cpp->gstate, &x, &y); + cairo_device_to_user (cpp->cr, &x, &y); data->header.type = CAIRO_PATH_LINE_TO; data->header.length = 2; @@ -205,15 +205,15 @@ _cpp_curve_to (void *closure, x1 = _cairo_fixed_to_double (p1->x); y1 = _cairo_fixed_to_double (p1->y); - _cairo_gstate_backend_to_user (cpp->gstate, &x1, &y1); + cairo_device_to_user (cpp->cr, &x1, &y1); x2 = _cairo_fixed_to_double (p2->x); y2 = _cairo_fixed_to_double (p2->y); - _cairo_gstate_backend_to_user (cpp->gstate, &x2, &y2); + cairo_device_to_user (cpp->cr, &x2, &y2); x3 = _cairo_fixed_to_double (p3->x); y3 = _cairo_fixed_to_double (p3->y); - _cairo_gstate_backend_to_user (cpp->gstate, &x3, &y3); + cairo_device_to_user (cpp->cr, &x3, &y3); data->header.type = CAIRO_PATH_CURVE_TO; data->header.length = 4; @@ -250,23 +250,22 @@ _cpp_close_path (void *closure) static cairo_status_t _cairo_path_populate (cairo_path_t *path, cairo_path_fixed_t *path_fixed, - cairo_gstate_t *gstate, + cairo_t *cr, cairo_bool_t flatten) { cairo_status_t status; cpp_t cpp; cpp.data = path->data; - cpp.gstate = gstate; + cpp.cr = cr; if (flatten) { - double tolerance = _cairo_gstate_get_tolerance (gstate); status = _cairo_path_fixed_interpret_flat (path_fixed, _cpp_move_to, _cpp_line_to, _cpp_close_path, &cpp, - tolerance); + cairo_get_tolerance (cr)); } else { status = _cairo_path_fixed_interpret (path_fixed, _cpp_move_to, @@ -309,7 +308,7 @@ _cairo_path_create_in_error (cairo_status_t status) static cairo_path_t * _cairo_path_create_internal (cairo_path_fixed_t *path_fixed, - cairo_gstate_t *gstate, + cairo_t *cr, cairo_bool_t flatten) { cairo_path_t *path; @@ -321,7 +320,7 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed, } path->num_data = _cairo_path_count (path, path_fixed, - _cairo_gstate_get_tolerance (gstate), + cairo_get_tolerance (cr), flatten); if (path->num_data < 0) { free (path); @@ -337,8 +336,7 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed, return (cairo_path_t*) &_cairo_path_nil; } - path->status = _cairo_path_populate (path, path_fixed, - gstate, flatten); + path->status = _cairo_path_populate (path, path_fixed, cr, flatten); } else { path->data = NULL; path->status = CAIRO_STATUS_SUCCESS; @@ -377,10 +375,10 @@ slim_hidden_def (cairo_path_destroy); /** * _cairo_path_create: * @path: a fixed-point, device-space path to be converted and copied - * @gstate: the current graphics state + * @cr: the current graphics context * * Creates a user-space #cairo_path_t copy of the given device-space - * @path. The @gstate parameter provides the inverse CTM for the + * @path. The @cr parameter provides the inverse CTM for the * conversion. * * Return value: the new copy of the path. If there is insufficient @@ -389,19 +387,19 @@ slim_hidden_def (cairo_path_destroy); * data==%NULL. **/ cairo_path_t * -_cairo_path_create (cairo_path_fixed_t *path, - cairo_gstate_t *gstate) +_cairo_path_create (cairo_path_fixed_t *path, + cairo_t *cr) { - return _cairo_path_create_internal (path, gstate, FALSE); + return _cairo_path_create_internal (path, cr, FALSE); } /** * _cairo_path_create_flat: * @path: a fixed-point, device-space path to be flattened, converted and copied - * @gstate: the current graphics state + * @cr: the current graphics context * * Creates a flattened, user-space #cairo_path_t copy of the given - * device-space @path. The @gstate parameter provide the inverse CTM + * device-space @path. The @cr parameter provide the inverse CTM * for the conversion, as well as the tolerance value to control the * accuracy of the flattening. * @@ -412,9 +410,9 @@ _cairo_path_create (cairo_path_fixed_t *path, **/ cairo_path_t * _cairo_path_create_flat (cairo_path_fixed_t *path, - cairo_gstate_t *gstate) + cairo_t *cr) { - return _cairo_path_create_internal (path, gstate, TRUE); + return _cairo_path_create_internal (path, cr, TRUE); } /** @@ -432,17 +430,6 @@ _cairo_path_append_to_context (const cairo_path_t *path, cairo_t *cr) { const cairo_path_data_t *p, *end; - cairo_fixed_t x1_fixed, y1_fixed; - cairo_fixed_t x2_fixed, y2_fixed; - cairo_fixed_t x3_fixed, y3_fixed; - cairo_matrix_t user_to_backend; - cairo_status_t status; - double x, y; - - user_to_backend = cr->gstate->ctm; - cairo_matrix_multiply (&user_to_backend, - &user_to_backend, - &cr->gstate->target->device_transform); end = &path->data[path->num_data]; for (p = &path->data[0]; p < end; p += p->header.length) { @@ -451,64 +438,39 @@ _cairo_path_append_to_context (const cairo_path_t *path, if (unlikely (p->header.length < 2)) return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - x = p[1].point.x, y = p[1].point.y; - cairo_matrix_transform_point (&user_to_backend, &x, &y); - x1_fixed = _cairo_fixed_from_double (x); - y1_fixed = _cairo_fixed_from_double (y); - - status = _cairo_path_fixed_move_to (cr->path, x1_fixed, y1_fixed); + cairo_move_to (cr, p[1].point.x, p[1].point.y); break; case CAIRO_PATH_LINE_TO: if (unlikely (p->header.length < 2)) return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - x = p[1].point.x, y = p[1].point.y; - cairo_matrix_transform_point (&user_to_backend, &x, &y); - x1_fixed = _cairo_fixed_from_double (x); - y1_fixed = _cairo_fixed_from_double (y); - - status = _cairo_path_fixed_line_to (cr->path, x1_fixed, y1_fixed); + cairo_line_to (cr, p[1].point.x, p[1].point.y); break; case CAIRO_PATH_CURVE_TO: if (unlikely (p->header.length < 4)) return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - x = p[1].point.x, y = p[1].point.y; - cairo_matrix_transform_point (&user_to_backend, &x, &y); - x1_fixed = _cairo_fixed_from_double (x); - y1_fixed = _cairo_fixed_from_double (y); - - x = p[2].point.x, y = p[2].point.y; - cairo_matrix_transform_point (&user_to_backend, &x, &y); - x2_fixed = _cairo_fixed_from_double (x); - y2_fixed = _cairo_fixed_from_double (y); - - x = p[3].point.x, y = p[3].point.y; - cairo_matrix_transform_point (&user_to_backend, &x, &y); - x3_fixed = _cairo_fixed_from_double (x); - y3_fixed = _cairo_fixed_from_double (y); - - status = _cairo_path_fixed_curve_to (cr->path, - x1_fixed, y1_fixed, - x2_fixed, y2_fixed, - x3_fixed, y3_fixed); + cairo_curve_to (cr, + p[1].point.x, p[1].point.y, + p[2].point.x, p[2].point.y, + p[3].point.x, p[3].point.y); break; case CAIRO_PATH_CLOSE_PATH: if (unlikely (p->header.length < 1)) return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - status = _cairo_path_fixed_close_path (cr->path); + cairo_close_path (cr); break; default: return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); } - if (unlikely (status)) - return status; + if (unlikely (cr->status)) + return cr->status; } return CAIRO_STATUS_SUCCESS; diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index b4b2981e3..9447c3629 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -47,6 +47,7 @@ #include "cairo-pdf-shading-private.h" #include "cairo-analysis-surface-private.h" #include "cairo-composite-rectangles-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-image-info-private.h" #include "cairo-recording-surface-private.h" @@ -6566,6 +6567,8 @@ _cairo_pdf_surface_set_paginated_mode (void *abstract_surface, static const cairo_surface_backend_t cairo_pdf_surface_backend = { CAIRO_SURFACE_TYPE_PDF, + _cairo_default_context_create, + NULL, /* create similar: handled by wrapper */ _cairo_pdf_surface_finish, NULL, /* acquire_source_image */ diff --git a/src/cairo-private.h b/src/cairo-private.h index 901a69a31..9f4f55b7c 100644 --- a/src/cairo-private.h +++ b/src/cairo-private.h @@ -36,22 +36,29 @@ #ifndef CAIRO_PRIVATE_H #define CAIRO_PRIVATE_H +#include "cairo-types-private.h" #include "cairo-reference-count-private.h" -#include "cairo-gstate-private.h" -#include "cairo-path-fixed-private.h" + +CAIRO_BEGIN_DECLS struct _cairo { cairo_reference_count_t ref_count; - cairo_status_t status; - cairo_user_data_array_t user_data; - cairo_gstate_t *gstate; - cairo_gstate_t gstate_tail[2]; - cairo_gstate_t *gstate_freelist; - - cairo_path_fixed_t path[1]; + const cairo_backend_t *backend; }; +cairo_private cairo_t * +_cairo_create_in_error (cairo_status_t status); + +cairo_private void +_cairo_init (cairo_t *cr, + const cairo_backend_t *backend); + +cairo_private void +_cairo_fini (cairo_t *cr); + +CAIRO_END_DECLS + #endif /* CAIRO_PRIVATE_H */ diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 5c83453d2..cf6908fa7 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -60,6 +60,7 @@ #include "cairo-pdf-operators-private.h" #include "cairo-pdf-shading-private.h" #include "cairo-composite-rectangles-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-scaled-font-subsets-private.h" #include "cairo-paginated-private.h" @@ -3931,6 +3932,8 @@ _cairo_ps_surface_supports_fine_grained_fallbacks (void *abstract_surface) static const cairo_surface_backend_t cairo_ps_surface_backend = { CAIRO_SURFACE_TYPE_PS, + _cairo_default_context_create, + NULL, /* create similar: handled by wrapper */ _cairo_ps_surface_finish, NULL, /* acquire_source_image */ diff --git a/src/cairo-qt-surface.cpp b/src/cairo-qt-surface.cpp index 25ee9e9f8..772d610c1 100644 --- a/src/cairo-qt-surface.cpp +++ b/src/cairo-qt-surface.cpp @@ -40,6 +40,7 @@ #include "cairoint.h" #include "cairo-clip-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-region-private.h" #include "cairo-surface-clipper-private.h" @@ -1551,6 +1552,8 @@ _cairo_qt_surface_mark_dirty (void *abstract_surface, static const cairo_surface_backend_t cairo_qt_surface_backend = { CAIRO_SURFACE_TYPE_QT, + _cairo_default_context_create, + _cairo_qt_surface_create_similar, _cairo_qt_surface_finish, _cairo_qt_surface_acquire_source_image, diff --git a/src/cairo-quartz-image-surface.c b/src/cairo-quartz-image-surface.c index 81ed5fe28..cd675a157 100644 --- a/src/cairo-quartz-image-surface.c +++ b/src/cairo-quartz-image-surface.c @@ -159,6 +159,8 @@ _cairo_quartz_image_surface_flush (void *asurface) static const cairo_surface_backend_t cairo_quartz_image_surface_backend = { CAIRO_SURFACE_TYPE_QUARTZ_IMAGE, + _cairo_default_context_create, + _cairo_quartz_image_surface_create_similar, _cairo_quartz_image_surface_finish, _cairo_quartz_image_surface_acquire_source_image, diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c index ce8a95abf..84ae347a0 100644 --- a/src/cairo-recording-surface.c +++ b/src/cairo-recording-surface.c @@ -79,6 +79,7 @@ #include "cairoint.h" #include "cairo-analysis-surface-private.h" #include "cairo-clip-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-recording-surface-private.h" #include "cairo-surface-wrapper-private.h" @@ -707,6 +708,8 @@ _cairo_surface_is_recording (const cairo_surface_t *surface) static const cairo_surface_backend_t cairo_recording_surface_backend = { CAIRO_SURFACE_TYPE_RECORDING, + _cairo_default_context_create, + _cairo_recording_surface_create_similar, _cairo_recording_surface_finish, _cairo_recording_surface_acquire_source_image, diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c index f5e6dec2a..ec228ca31 100644 --- a/src/cairo-scaled-font-subsets.c +++ b/src/cairo-scaled-font-subsets.c @@ -630,6 +630,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, * create a separate subset just for the .notdef glyph. */ is_latin = FALSE; + latin_character = -1; if (sub_font->use_latin_subset && (! _cairo_font_face_is_user (sub_font->scaled_font->font_face))) { diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c index 89311a008..6b59464b0 100644 --- a/src/cairo-script-surface.c +++ b/src/cairo-script-surface.c @@ -3405,6 +3405,8 @@ _cairo_script_surface_get_extents (void *abstract_surface, static const cairo_surface_backend_t _cairo_script_surface_backend = { CAIRO_SURFACE_TYPE_SCRIPT, + _cairo_default_context_create, + _cairo_script_surface_create_similar, _cairo_script_surface_finish, _cairo_script_surface_acquire_source_image, diff --git a/src/cairo-surface-snapshot.c b/src/cairo-surface-snapshot.c index 20cc6b9ad..757ec1e6f 100644 --- a/src/cairo-surface-snapshot.c +++ b/src/cairo-surface-snapshot.c @@ -89,6 +89,7 @@ _cairo_surface_snapshot_get_extents (void *abstract_surface, static const cairo_surface_backend_t _cairo_surface_snapshot_backend = { CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT, + NULL, NULL, /* create similar */ _cairo_surface_snapshot_finish, diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c index 3cf833024..ff1df839a 100644 --- a/src/cairo-surface-subsurface.c +++ b/src/cairo-surface-subsurface.c @@ -442,8 +442,17 @@ _cairo_surface_subsurface_snapshot (void *abstract_surface) return &snapshot->base; } +static cairo_t * +_cairo_surface_subsurface_create_context(void *target) +{ + cairo_surface_subsurface_t *surface = target; + return cairo_create (surface->target); +} + static const cairo_surface_backend_t _cairo_surface_subsurface_backend = { CAIRO_SURFACE_TYPE_SUBSURFACE, + _cairo_surface_subsurface_create_context, + _cairo_surface_subsurface_create_similar, _cairo_surface_subsurface_finish, diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index bb5bccff9..7adcfb726 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -43,6 +43,7 @@ #include "cairoint.h" #include "cairo-svg.h" #include "cairo-analysis-surface-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-image-info-private.h" #include "cairo-recording-surface-private.h" @@ -2574,6 +2575,8 @@ _cairo_svg_surface_get_font_options (void *abstract_surface, static const cairo_surface_backend_t cairo_svg_surface_backend = { CAIRO_SURFACE_TYPE_SVG, + _cairo_default_context_create, + NULL, /* create_similar: handled by wrapper */ _cairo_svg_surface_finish, NULL, /* acquire_source_image */ diff --git a/src/cairo-tee-surface.c b/src/cairo-tee-surface.c index 83811bd7a..df0ae9970 100644 --- a/src/cairo-tee-surface.c +++ b/src/cairo-tee-surface.c @@ -42,6 +42,7 @@ #include "cairo-tee.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-tee-surface-private.h" #include "cairo-surface-wrapper-private.h" @@ -395,6 +396,8 @@ _cairo_tee_surface_show_text_glyphs (void *abstract_surface, static const cairo_surface_backend_t cairo_tee_surface_backend = { CAIRO_SURFACE_TYPE_TEE, + _cairo_default_context_create, /* XXX */ + _cairo_tee_surface_create_similar, _cairo_tee_surface_finish, _cairo_tee_surface_acquire_source_image, diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c index 74257d4bf..e9e831150 100644 --- a/src/cairo-type3-glyph-surface.c +++ b/src/cairo-type3-glyph-surface.c @@ -42,6 +42,7 @@ #include "cairo-output-stream-private.h" #include "cairo-recording-surface-private.h" #include "cairo-analysis-surface-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-surface-clipper-private.h" @@ -321,6 +322,8 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface, static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_TYPE3_GLYPH, + _cairo_default_context_create, + NULL, /* _cairo_type3_glyph_surface_create_similar */ _cairo_type3_glyph_surface_finish, NULL, /* acquire_source_image */ diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index 967781c10..5460a42bc 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -64,6 +64,8 @@ typedef struct _cairo_color_stop cairo_color_stop_t; typedef struct _cairo_device_backend cairo_device_backend_t; typedef struct _cairo_font_face_backend cairo_font_face_backend_t; typedef struct _cairo_gstate cairo_gstate_t; +typedef struct _cairo_gstate_backend cairo_gstate_backend_t; +typedef struct _cairo_glyph_text_info cairo_glyph_text_info_t; typedef struct _cairo_hash_entry cairo_hash_entry_t; typedef struct _cairo_hash_table cairo_hash_table_t; typedef struct _cairo_image_surface cairo_image_surface_t; @@ -174,6 +176,16 @@ struct _cairo_font_options { cairo_round_glyph_positions_t round_glyph_positions; }; +struct _cairo_glyph_text_info { + const char *utf8; + int utf8_len; + + const cairo_text_cluster_t *clusters; + int num_clusters; + cairo_text_cluster_flags_t cluster_flags; +}; + + /* XXX: Right now, the _cairo_color structure puts unpremultiplied color in the doubles and premultiplied color in the shorts. Yes, this is crazy insane, (but at least we don't export this @@ -209,7 +221,7 @@ struct _cairo_color_stop { typedef enum _cairo_paginated_mode { CAIRO_PAGINATED_MODE_ANALYZE, /* analyze page regions */ CAIRO_PAGINATED_MODE_RENDER, /* render page contents */ - CAIRO_PAGINATED_MODE_FALLBACK /* paint fallback images */ + CAIRO_PAGINATED_MODE_FALLBACK /* paint fallback images */ } cairo_paginated_mode_t; /* Sure wish C had a real enum type so that this would be distinct diff --git a/src/cairo-vg-surface.c b/src/cairo-vg-surface.c index 0034d73bc..06d46c1c5 100644 --- a/src/cairo-vg-surface.c +++ b/src/cairo-vg-surface.c @@ -39,6 +39,7 @@ #include "cairo-vg.h" #include "cairo-cache-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-path-fixed-private.h" #include "cairo-recording-surface-private.h" @@ -1547,6 +1548,8 @@ _vg_surface_finish (void *abstract_surface) static const cairo_surface_backend_t cairo_vg_surface_backend = { CAIRO_SURFACE_TYPE_VG, + _cairo_default_context_create, /* XXX */ + _vg_surface_create_similar, _vg_surface_finish, diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c index 8023335ab..58d404a6e 100644 --- a/src/cairo-win32-printing-surface.c +++ b/src/cairo-win32-printing-surface.c @@ -46,6 +46,7 @@ #include "cairoint.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-paginated-private.h" @@ -1861,6 +1862,8 @@ _cairo_surface_is_win32_printing (cairo_surface_t *surface) static const cairo_surface_backend_t cairo_win32_printing_surface_backend = { CAIRO_SURFACE_TYPE_WIN32_PRINTING, + _cairo_default_context_create, + _cairo_win32_printing_surface_create_similar, _cairo_win32_surface_finish, NULL, /* acquire_source_image */ diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index 1be219249..24b1ba653 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -49,6 +49,7 @@ #include "cairo-clip-private.h" #include "cairo-composite-rectangles-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-paginated-private.h" #include "cairo-win32-private.h" @@ -2089,6 +2090,8 @@ _cairo_win32_surface_create_span_renderer (cairo_operator_t op, static const cairo_surface_backend_t cairo_win32_surface_backend = { CAIRO_SURFACE_TYPE_WIN32, + _cairo_default_context_create, + _cairo_win32_surface_create_similar, _cairo_win32_surface_finish, _cairo_win32_surface_acquire_source_image, diff --git a/src/cairo-xcb-surface-core.c b/src/cairo-xcb-surface-core.c index 6801e3f23..1a2bcadac 100644 --- a/src/cairo-xcb-surface-core.c +++ b/src/cairo-xcb-surface-core.c @@ -75,6 +75,7 @@ _cairo_xcb_pixmap_finish (void *abstract_surface) static const cairo_surface_backend_t _cairo_xcb_pixmap_backend = { CAIRO_SURFACE_TYPE_XCB, NULL, + NULL, _cairo_xcb_pixmap_finish, }; diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c index 5a0bb224f..065e89679 100644 --- a/src/cairo-xcb-surface-render.c +++ b/src/cairo-xcb-surface-render.c @@ -95,6 +95,7 @@ _cairo_xcb_picture_finish (void *abstract_surface) static const cairo_surface_backend_t _cairo_xcb_picture_backend = { CAIRO_SURFACE_TYPE_XCB, NULL, + NULL, _cairo_xcb_picture_finish, }; diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index bba7a9c75..a890fe8b8 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -43,6 +43,8 @@ #include "cairo-xcb.h" #include "cairo-xcb-private.h" +#include "cairo-default-context-private.h" + #define AllPlanes ((unsigned) -1) #define CAIRO_ASSUME_PIXMAP 20 #define XLIB_COORD_MAX 32767 @@ -923,6 +925,7 @@ _cairo_xcb_surface_glyphs (void *abstract_surface, const cairo_surface_backend_t _cairo_xcb_surface_backend = { CAIRO_SURFACE_TYPE_XCB, + _cairo_default_context_create, _cairo_xcb_surface_create_similar, _cairo_xcb_surface_finish, diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 85852086c..4aecac5be 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -52,6 +52,7 @@ #include "cairo-xlib-private.h" #include "cairo-xlib-surface-private.h" #include "cairo-clip-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-scaled-font-private.h" #include "cairo-surface-snapshot-private.h" @@ -3133,6 +3134,8 @@ _cairo_xlib_surface_is_similar (void *surface_a, static const cairo_surface_backend_t cairo_xlib_surface_backend = { CAIRO_SURFACE_TYPE_XLIB, + _cairo_default_context_create, + _cairo_xlib_surface_create_similar, _cairo_xlib_surface_finish, _cairo_xlib_surface_acquire_source_image, diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c index 0ffbc4c5d..6381e05c5 100644 --- a/src/cairo-xlib-xcb-surface.c +++ b/src/cairo-xlib-xcb-surface.c @@ -46,6 +46,8 @@ #include "cairo-xcb-private.h" #include "cairo-xlib-xrender-private.h" +#include "cairo-default-context-private.h" + #include <X11/Xlib-xcb.h> #include <X11/Xlibint.h> /* For XESetCloseDisplay */ @@ -60,7 +62,7 @@ struct cairo_xlib_xcb_display_t { }; typedef struct cairo_xlib_xcb_display_t cairo_xlib_xcb_display_t; -/* List of all cairo_xlib_xcb_display_t alive, +/* List of all #cairo_xlib_xcb_display_t alive, * protected by _cairo_xlib_display_mutex */ static cairo_list_t displays; @@ -232,6 +234,8 @@ _cairo_xlib_xcb_surface_mark_dirty (void *abstract_surface, static const cairo_surface_backend_t _cairo_xlib_xcb_surface_backend = { CAIRO_SURFACE_TYPE_XLIB, + _cairo_default_context_create, /* XXX */ + _cairo_xlib_xcb_surface_create_similar, _cairo_xlib_xcb_surface_finish, _cairo_xlib_xcb_surface_acquire_source_image, diff --git a/src/cairo-xml-surface.c b/src/cairo-xml-surface.c index 83d4f912e..cf99ee6c9 100644 --- a/src/cairo-xml-surface.c +++ b/src/cairo-xml-surface.c @@ -46,6 +46,7 @@ #include "cairo-clip-private.h" #include "cairo-device-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-output-stream-private.h" #include "cairo-recording-surface-private.h" @@ -989,6 +990,8 @@ _cairo_xml_surface_glyphs (void *abstract_surface, static const cairo_surface_backend_t _cairo_xml_surface_backend = { CAIRO_SURFACE_TYPE_XML, + _cairo_default_context_create, + _cairo_xml_surface_create_similar, NULL, NULL, NULL, /* source image */ diff --git a/src/cairo.c b/src/cairo.c index 0aae04b2b..42e3b5f73 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -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,18 @@ * * 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-freed-pool-private.h" #include "cairo-path-private.h" +#include "cairo-surface-private.h" + +#include <assert.h> /** * SECTION:cairo @@ -101,34 +105,12 @@ * space</firstterm>. */ -#define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1) - -#if !defined(INFINITY) -#define INFINITY HUGE_VAL -#endif - #define DEFINE_NIL_CONTEXT(status) \ { \ CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \ status, /* 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 */ \ - TRUE, /* needs_move_to */ \ - FALSE, /* has_extents */ \ - FALSE, /* has_curve_to */ \ - TRUE, /* stroke_is_rectilinear */ \ - TRUE, /* fill_is_rectilinear */ \ - TRUE, /* fill_maybe_region */ \ - TRUE, /* fill_is_empty */ \ - {{0, 0}, {0, 0}}, /* extents */ \ - {{{NULL,NULL}}} /* link */ \ - }} \ + NULL \ } static const cairo_t _cairo_nil[] = { @@ -170,11 +152,8 @@ static const cairo_t _cairo_nil[] = { 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); -#include <assert.h> - /** * _cairo_set_error: * @cr: a cairo context @@ -199,9 +178,7 @@ _cairo_set_error (cairo_t *cr, cairo_status_t status) _cairo_status_set_error (&cr->status, _cairo_error (status)); } -static freed_pool_t context_pool; - -static cairo_t * +cairo_t * _cairo_create_in_error (cairo_status_t status) { cairo_t *cr; @@ -214,12 +191,6 @@ _cairo_create_in_error (cairo_status_t status) return cr; } -void -_cairo_reset_static_data (void) -{ - _freed_pool_reset (&context_pool); -} - /** * cairo_create: * @target: target surface for the context @@ -247,41 +218,26 @@ _cairo_reset_static_data (void) 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 = _freed_pool_get (&context_pool); - if (unlikely (cr == NULL)) { - cr = malloc (sizeof (cairo_t)); - if (unlikely (cr == NULL)) - return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } + return target->backend->create_context (target); - CAIRO_REFERENCE_COUNT_INIT (&cr->ref_count, 1); +} +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)) { - _freed_pool_put (&context_pool, cr); - cr = _cairo_create_in_error (status); - } - return cr; + cr->backend = backend; } -slim_hidden_def (cairo_create); /** * cairo_reference: @@ -309,6 +265,12 @@ cairo_reference (cairo_t *cr) return cr; } +void +_cairo_fini (cairo_t *cr) +{ + _cairo_user_data_array_fini (&cr->user_data); +} + /** * cairo_destroy: * @cr: a #cairo_t @@ -328,27 +290,7 @@ cairo_destroy (cairo_t *cr) 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; - } - - _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; - - _freed_pool_put (&context_pool, cr); + cr->backend->destroy (cr); } slim_hidden_def (cairo_destroy); @@ -370,8 +312,7 @@ void * 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); } /** @@ -449,7 +390,7 @@ cairo_save (cairo_t *cr) 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); } @@ -471,12 +412,7 @@ cairo_restore (cairo_t *cr) if (unlikely (cr->status)) return; - if (unlikely (_cairo_gstate_is_group (cr->gstate))) { - _cairo_set_error (cr, _cairo_error (CAIRO_STATUS_INVALID_RESTORE)); - return; - } - - status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); + status = cr->backend->restore (cr); if (unlikely (status)) _cairo_set_error (cr, status); } @@ -554,68 +490,12 @@ cairo_push_group (cairo_t *cr) 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; - 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) - _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); + status = cr->backend->push_group (cr, content); if (unlikely (status)) _cairo_set_error (cr, status); } @@ -645,55 +525,14 @@ slim_hidden_def(cairo_push_group_with_content); cairo_pattern_t * cairo_pop_group (cairo_t *cr) { - cairo_surface_t *group_surface; 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); - /* Verify that we are at the right nesting level */ - if (unlikely (! _cairo_gstate_is_group (cr->gstate))) { - _cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP); - return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP); - } - - /* Get a reference to the active surface before restoring */ - group_surface = _cairo_gstate_get_target (cr->gstate); - group_surface = cairo_surface_reference (group_surface); - - status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); - assert (status == CAIRO_STATUS_SUCCESS); - - 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); + group_pattern = cr->backend->pop_group (cr); + if (unlikely (group_pattern->status)) + _cairo_set_error (cr, group_pattern->status); return group_pattern; } @@ -755,36 +594,39 @@ cairo_set_operator (cairo_t *cr, cairo_operator_t op) 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); } 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. + **/ +void +cairo_set_opacity (cairo_t *cr, double opacity) { - const cairo_pattern_t *current; - cairo_color_t color; - - current = cr->gstate->source; - if (current->type != CAIRO_PATTERN_TYPE_SOLID) - return FALSE; + cairo_status_t status; - 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); + if (unlikely (cr->status)) + return; - _cairo_color_init_rgba (&color, red, green, blue, alpha); - return _cairo_color_equal (&color, - &((cairo_solid_pattern_t *) current)->color); + status = cr->backend->set_opacity (cr, opacity); + if (unlikely (status)) + _cairo_set_error (cr, status); } +#endif + /** * cairo_set_source_rgb * @cr: a cairo context @@ -806,20 +648,14 @@ _current_source_matches_solid (cairo_t *cr, 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); @@ -847,20 +683,14 @@ cairo_set_source_rgba (cairo_t *cr, 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); } /** @@ -892,22 +722,19 @@ cairo_set_source_surface (cairo_t *cr, 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); - - pattern = cairo_pattern_create_for_surface (surface); - - cairo_matrix_init_translate (&matrix, -x, -y); - cairo_pattern_set_matrix (pattern, &matrix); + if (unlikely (surface == NULL)) { + _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); + return; + } - 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); @@ -938,17 +765,17 @@ cairo_set_source (cairo_t *cr, cairo_pattern_t *source) 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); } @@ -970,7 +797,7 @@ cairo_get_source (cairo_t *cr) 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); } /** @@ -997,10 +824,7 @@ cairo_set_tolerance (cairo_t *cr, double tolerance) 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); } @@ -1027,7 +851,7 @@ cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias) 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); } @@ -1053,7 +877,7 @@ cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule) 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); } @@ -1095,7 +919,7 @@ cairo_set_line_width (cairo_t *cr, double width) 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); } @@ -1125,7 +949,7 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap) 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); } @@ -1155,7 +979,7 @@ cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join) 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); } @@ -1204,8 +1028,7 @@ cairo_set_dash (cairo_t *cr, 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); } @@ -1231,7 +1054,7 @@ cairo_get_dash_count (cairo_t *cr) 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; } @@ -1256,7 +1079,7 @@ cairo_get_dash (cairo_t *cr, if (unlikely (cr->status)) return; - _cairo_gstate_get_dash (cr->gstate, dashes, NULL, offset); + cr->backend->get_dash (cr, dashes, NULL, offset); } /** @@ -1295,7 +1118,7 @@ cairo_set_miter_limit (cairo_t *cr, double limit) 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); } @@ -1320,7 +1143,7 @@ cairo_translate (cairo_t *cr, double tx, double ty) 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); } @@ -1345,7 +1168,7 @@ cairo_scale (cairo_t *cr, double sx, double sy) 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); } @@ -1371,7 +1194,7 @@ cairo_rotate (cairo_t *cr, double angle) 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); } @@ -1394,7 +1217,7 @@ cairo_transform (cairo_t *cr, 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); } @@ -1417,7 +1240,7 @@ cairo_set_matrix (cairo_t *cr, 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); } @@ -1435,10 +1258,14 @@ slim_hidden_def (cairo_set_matrix); 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); } /** @@ -1457,7 +1284,7 @@ cairo_user_to_device (cairo_t *cr, double *x, double *y) 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); @@ -1478,7 +1305,7 @@ cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy) 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); @@ -1498,8 +1325,9 @@ cairo_device_to_user (cairo_t *cr, double *x, double *y) 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: @@ -1518,7 +1346,7 @@ cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy) if (unlikely (cr->status)) return; - _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy); + cr->backend->device_to_user_distance (cr, dx, dy); } /** @@ -1531,41 +1359,16 @@ cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy) 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: @@ -1588,13 +1391,41 @@ slim_hidden_def(cairo_move_to); 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). + **/ +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 @@ -1611,16 +1442,11 @@ 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); } @@ -1652,30 +1478,14 @@ cairo_curve_to (cairo_t *cr, 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); } @@ -1735,15 +1545,10 @@ cairo_arc (cairo_t *cr, double radius, double angle1, double angle2) { - if (unlikely (cr->status)) - return; + cairo_status_t status; - /* 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); + if (unlikely (cr->status)) return; - } if (angle2 < angle1) { /* increase angle2 by multiples of full circle until it @@ -1754,12 +1559,9 @@ cairo_arc (cairo_t *cr, angle2 += angle1; } - 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); } /** @@ -1786,15 +1588,10 @@ cairo_arc_negative (cairo_t *cr, double radius, double angle1, double angle2) { - if (unlikely (cr->status)) - return; + cairo_status_t status; - /* 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); + if (unlikely (cr->status)) return; - } if (angle2 > angle1) { /* decrease angle2 by multiples of full circle until it @@ -1805,12 +1602,9 @@ cairo_arc_negative (cairo_t *cr, 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 @@ -1825,10 +1619,23 @@ cairo_arc_to (cairo_t *cr, 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); } @@ -1853,18 +1660,12 @@ cairo_arc_to (cairo_t *cr, 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); } @@ -1890,18 +1691,12 @@ cairo_rel_move_to (cairo_t *cr, double dx, double dy) 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); } @@ -1938,31 +1733,15 @@ cairo_rel_curve_to (cairo_t *cr, 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); } @@ -1992,14 +1771,14 @@ cairo_rectangle (cairo_t *cr, 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 @@ -2054,7 +1833,7 @@ cairo_close_path (cairo_t *cr) 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); } @@ -2108,9 +1887,7 @@ cairo_path_extents (cairo_t *cr, return; } - _cairo_gstate_path_extents (cr->gstate, - cr->path, - x1, y1, x2, y2); + cr->backend->path_extents (cr, x1, y1, x2, y2); } /** @@ -2128,7 +1905,7 @@ cairo_paint (cairo_t *cr) if (unlikely (cr->status)) return; - status = _cairo_gstate_paint (cr->gstate); + status = cr->backend->paint (cr); if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2149,30 +1926,13 @@ cairo_paint_with_alpha (cairo_t *cr, 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); } /** @@ -2194,17 +1954,17 @@ cairo_mask (cairo_t *cr, 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); } @@ -2279,9 +2039,14 @@ cairo_mask_surface (cairo_t *cr, 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); @@ -2306,7 +2071,7 @@ cairo_stroke_preserve (cairo_t *cr) 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); } @@ -2325,9 +2090,14 @@ slim_hidden_def(cairo_stroke_preserve); void cairo_fill (cairo_t *cr) { - cairo_fill_preserve (cr); + cairo_status_t status; + + if (unlikely (cr->status)) + return; - cairo_new_path (cr); + status = cr->backend->fill (cr); + if (unlikely (status)) + _cairo_set_error (cr, status); } /** @@ -2349,7 +2119,7 @@ cairo_fill_preserve (cairo_t *cr) 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); } @@ -2375,7 +2145,7 @@ cairo_copy_page (cairo_t *cr) 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); } @@ -2398,7 +2168,7 @@ cairo_show_page (cairo_t *cr) 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); } @@ -2430,9 +2200,7 @@ cairo_in_stroke (cairo_t *cr, double x, double y) 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); @@ -2458,10 +2226,17 @@ cairo_in_stroke (cairo_t *cr, double x, double y) 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; } /** @@ -2511,9 +2286,7 @@ cairo_stroke_extents (cairo_t *cr, 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); } @@ -2562,9 +2335,7 @@ cairo_fill_extents (cairo_t *cr, 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); } @@ -2594,9 +2365,14 @@ cairo_fill_extents (cairo_t *cr, 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); } /** @@ -2629,7 +2405,7 @@ cairo_clip_preserve (cairo_t *cr) 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); } @@ -2659,7 +2435,7 @@ cairo_reset_clip (cairo_t *cr) 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); } @@ -2682,25 +2458,23 @@ cairo_clip_extents (cairo_t *cr, double *x1, double *y1, double *x2, double *y2) { - if (unlikely (cr->status)) { - if (x1) - *x1 = 0.0; - if (y1) - *y1 = 0.0; - if (x2) - *x2 = 0.0; - if (y2) - *y2 = 0.0; + cairo_status_t status; + + if (x1) + *x1 = 0.0; + if (y1) + *y1 = 0.0; + if (x2) + *x2 = 0.0; + 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); } /** @@ -2723,10 +2497,17 @@ cairo_clip_extents (cairo_t *cr, 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); + + return inside; } /** @@ -2752,7 +2533,7 @@ cairo_copy_clip_rectangle_list (cairo_t *cr) 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); } /** @@ -2812,12 +2593,21 @@ cairo_select_font_face (cairo_t *cr, 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); } @@ -2845,7 +2635,7 @@ cairo_font_extents (cairo_t *cr, 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); } @@ -2868,7 +2658,7 @@ cairo_set_font_face (cairo_t *cr, 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); } @@ -2894,19 +2684,10 @@ cairo_set_font_face (cairo_t *cr, 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 font_face; + return cr->backend->get_font_face (cr); } /** @@ -2927,11 +2708,14 @@ cairo_get_font_face (cairo_t *cr) void cairo_set_font_size (cairo_t *cr, double size) { - cairo_matrix_t scale; + cairo_status_t status; - cairo_matrix_init_scale (&scale, size, size); + if (unlikely (cr->status)) + return; - cairo_set_font_matrix (cr, &scale); + status = cr->backend->set_font_size (cr, size); + if (unlikely (status)) + _cairo_set_error (cr, status); } slim_hidden_def (cairo_set_font_size); @@ -2957,7 +2741,7 @@ cairo_set_font_matrix (cairo_t *cr, 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); } @@ -2979,7 +2763,7 @@ cairo_get_font_matrix (cairo_t *cr, cairo_matrix_t *matrix) return; } - _cairo_gstate_get_font_matrix (cr->gstate, matrix); + cr->backend->get_font_matrix (cr, matrix); } /** @@ -3008,7 +2792,9 @@ cairo_set_font_options (cairo_t *cr, 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); @@ -3036,7 +2822,7 @@ cairo_get_font_options (cairo_t *cr, return; } - _cairo_gstate_get_font_options (cr->gstate, options); + cr->backend->get_font_options (cr, options); } /** @@ -3057,42 +2843,24 @@ cairo_set_scaled_font (cairo_t *cr, 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); - if (unlikely (status)) - goto BAIL; - - status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix); + status = cr->backend->set_scaled_font (cr, (cairo_scaled_font_t *) scaled_font); 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); + _cairo_set_error (cr, status); } /** @@ -3118,20 +2886,12 @@ BAIL: 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 scaled_font; + return cr->backend->get_scaled_font (cr); } +slim_hidden_def (cairo_get_scaled_font); /** * cairo_text_extents: @@ -3159,8 +2919,9 @@ cairo_text_extents (cairo_t *cr, 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; @@ -3176,19 +2937,24 @@ cairo_text_extents (cairo_t *cr, 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; + } - status = _cairo_gstate_text_to_glyphs (cr->gstate, - x, y, - utf8, strlen (utf8), - &glyphs, &num_glyphs, - NULL, NULL, - NULL); - - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_gstate_glyph_extents (cr->gstate, - glyphs, num_glyphs, - extents); + cairo_get_current_point (cr, &x, &y); + status = cairo_scaled_font_text_to_glyphs (scaled_font, + x, y, + utf8, -1, + &glyphs, &num_glyphs, + NULL, NULL, NULL); + + if (likely (status == CAIRO_STATUS_SUCCESS)) { + status = cr->backend->glyph_extents (cr, + glyphs, num_glyphs, + extents); + } cairo_glyph_free (glyphs); if (unlikely (status)) @@ -3234,18 +3000,17 @@ cairo_glyph_extents (cairo_t *cr, 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); } @@ -3290,6 +3055,8 @@ cairo_show_text (cairo_t *cr, const char *utf8) 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; if (unlikely (cr->status)) return; @@ -3297,7 +3064,11 @@ cairo_show_text (cairo_t *cr, const char *utf8) 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); @@ -3315,36 +3086,37 @@ cairo_show_text (cairo_t *cr, const char *utf8) num_clusters = 0; } - status = _cairo_gstate_text_to_glyphs (cr->gstate, - x, y, - utf8, utf8_len, - &glyphs, &num_glyphs, - has_show_text_glyphs ? &clusters : NULL, &num_clusters, - &cluster_flags); + cairo_get_current_point (cr, &x, &y); + status = cairo_scaled_font_text_to_glyphs (scaled_font, + x, y, + utf8, utf8_len, + &glyphs, &num_glyphs, + has_show_text_glyphs ? &clusters : NULL, &num_clusters, + &cluster_flags); if (unlikely (status)) goto BAIL; if (num_glyphs == 0) return; - status = _cairo_gstate_show_text_glyphs (cr->gstate, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags); + 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 (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) @@ -3387,11 +3159,7 @@ cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) 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); } @@ -3469,32 +3237,38 @@ cairo_show_text_glyphs (cairo_t *cr, return; } - /* 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, - glyphs, num_glyphs, - clusters, num_clusters, cluster_flags); - if (status == CAIRO_STATUS_INVALID_CLUSTERS) { - /* Either got invalid UTF-8 text, or cluster mapping is bad. - * Differentiate those. */ - - cairo_status_t status2; - - status2 = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, NULL); - if (status2) - status = status2; - - _cairo_set_error (cr, status); - return; - } - 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); + 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, + glyphs, num_glyphs, + clusters, num_clusters, cluster_flags); + if (status == CAIRO_STATUS_INVALID_CLUSTERS) { + /* Either got invalid UTF-8 text, or cluster mapping is bad. + * Differentiate those. */ + + cairo_status_t status2; + + status2 = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, NULL); + if (status2) + status = status2; + } else { + cairo_glyph_text_info_t info; + + 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); + } + } else { + status = cr->backend->glyphs (cr, glyphs, num_glyphs, NULL); + } if (unlikely (status)) _cairo_set_error (cr, status); } @@ -3524,12 +3298,13 @@ cairo_show_text_glyphs (cairo_t *cr, * "real" text path API in cairo. **/ void -cairo_text_path (cairo_t *cr, const char *utf8) +cairo_text_path (cairo_t *cr, const char *utf8) { cairo_status_t status; 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; @@ -3539,42 +3314,40 @@ cairo_text_path (cairo_t *cr, const char *utf8) 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, - x, y, - utf8, strlen (utf8), - &glyphs, &num_glyphs, - NULL, NULL, - NULL); + scaled_font = cairo_get_scaled_font (cr); + if (unlikely (scaled_font->status)) { + _cairo_set_error (cr, scaled_font->status); + return; + } - if (unlikely (status)) - goto BAIL; + cairo_get_current_point (cr, &x, &y); + status = cairo_scaled_font_text_to_glyphs (scaled_font, + x, y, + utf8, -1, + &glyphs, &num_glyphs, + NULL, NULL, NULL); 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; 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) @@ -3605,19 +3378,17 @@ cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) 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); } @@ -3636,8 +3407,27 @@ cairo_get_operator (cairo_t *cr) 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. + **/ +double +cairo_get_opacity (cairo_t *cr) +{ + if (unlikely (cr->status)) + return 1.; + + return cr->backend->get_opacity (cr); } +#endif /** * cairo_get_tolerance: @@ -3653,7 +3443,7 @@ cairo_get_tolerance (cairo_t *cr) 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); @@ -3672,7 +3462,7 @@ cairo_get_antialias (cairo_t *cr) if (unlikely (cr->status)) return CAIRO_ANTIALIAS_DEFAULT; - return _cairo_gstate_get_antialias (cr->gstate); + return cr->backend->get_antialias (cr); } /** @@ -3690,9 +3480,9 @@ cairo_bool_t cairo_has_current_point (cairo_t *cr) { if (unlikely (cr->status)) - return FALSE; + return FALSE; - return cr->path->has_current_point; + return cr->backend->has_current_point (cr); } /** @@ -3728,20 +3518,13 @@ cairo_has_current_point (cairo_t *cr) 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)) - { - x = _cairo_fixed_to_double (x_fixed); - y = _cairo_fixed_to_double (y_fixed); - _cairo_gstate_backend_to_user (cr->gstate, &x, &y); - } - else + cr->backend->has_current_point (cr)) { - x = 0.0; - y = 0.0; + cr->backend->get_current_point (cr, &x, &y); } if (x_ret) @@ -3765,7 +3548,7 @@ cairo_get_fill_rule (cairo_t *cr) 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); } /** @@ -3785,7 +3568,7 @@ cairo_get_line_width (cairo_t *cr) 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); @@ -3803,7 +3586,7 @@ cairo_get_line_cap (cairo_t *cr) 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); } /** @@ -3820,7 +3603,7 @@ cairo_get_line_join (cairo_t *cr) 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); } /** @@ -3837,7 +3620,7 @@ cairo_get_miter_limit (cairo_t *cr) 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); } /** @@ -3855,7 +3638,7 @@ cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix) return; } - _cairo_gstate_get_matrix (cr->gstate, matrix); + cr->backend->get_matrix (cr, matrix); } slim_hidden_def (cairo_get_matrix); @@ -3881,7 +3664,7 @@ cairo_get_target (cairo_t *cr) 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); @@ -3911,7 +3694,7 @@ cairo_get_group_target (cairo_t *cr) 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); } /** @@ -3946,7 +3729,7 @@ cairo_copy_path (cairo_t *cr) 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); } /** @@ -3988,7 +3771,7 @@ cairo_copy_path_flat (cairo_t *cr) 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); } /** @@ -4012,12 +3795,12 @@ cairo_append_path (cairo_t *cr, 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); @@ -4029,12 +3812,12 @@ cairo_append_path (cairo_t *cr, 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); } diff --git a/src/cairoint.h b/src/cairoint.h index 3ab770167..13d155566 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -409,7 +409,7 @@ struct _cairo_font_face { }; cairo_private void -_cairo_reset_static_data (void); +_cairo_default_context_reset_static_data (void); cairo_private void _cairo_toy_font_face_reset_static_data (void); @@ -599,6 +599,9 @@ extern const cairo_private struct _cairo_font_face_backend _cairo_quartz_font_fa struct _cairo_surface_backend { cairo_surface_type_t type; + cairo_t * + (*create_context) (void *surface); + cairo_surface_t * (*create_similar) (void *surface, cairo_content_t content, @@ -1357,7 +1360,7 @@ _cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t *path, const cairo_matrix_t *ctm, cairo_boxes_t *boxes); -cairo_private cairo_status_t +cairo_private cairo_int_status_t _cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path, const cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, @@ -2404,6 +2407,7 @@ slim_hidden_proto (cairo_format_stride_for_width); slim_hidden_proto (cairo_get_current_point); slim_hidden_proto (cairo_get_line_width); slim_hidden_proto (cairo_get_matrix); +slim_hidden_proto (cairo_get_scaled_font); slim_hidden_proto (cairo_get_target); slim_hidden_proto (cairo_get_tolerance); slim_hidden_proto (cairo_glyph_allocate); @@ -2511,6 +2515,7 @@ slim_hidden_proto (cairo_user_font_face_create); slim_hidden_proto (cairo_user_font_face_set_init_func); slim_hidden_proto (cairo_user_font_face_set_render_glyph_func); slim_hidden_proto (cairo_user_font_face_set_unicode_to_glyph_func); +slim_hidden_proto (cairo_device_to_user); slim_hidden_proto (cairo_user_to_device); slim_hidden_proto (cairo_user_to_device_distance); slim_hidden_proto (cairo_version_string); diff --git a/src/drm/cairo-drm-gallium-surface.c b/src/drm/cairo-drm-gallium-surface.c index 76fbae645..b48975302 100644 --- a/src/drm/cairo-drm-gallium-surface.c +++ b/src/drm/cairo-drm-gallium-surface.c @@ -34,6 +34,7 @@ #include "cairoint.h" #include "cairo-drm-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include <dlfcn.h> @@ -462,6 +463,8 @@ gallium_surface_glyphs (void *abstract_surface, static const cairo_surface_backend_t gallium_surface_backend = { CAIRO_SURFACE_TYPE_DRM, + _cairo_default_context_create, + gallium_surface_create_similar, gallium_surface_finish, diff --git a/src/drm/cairo-drm-i915-surface.c b/src/drm/cairo-drm-i915-surface.c index 247d8ad5c..2a55889fe 100644 --- a/src/drm/cairo-drm-i915-surface.c +++ b/src/drm/cairo-drm-i915-surface.c @@ -103,6 +103,7 @@ #include "cairo-boxes-private.h" #include "cairo-cache-private.h" #include "cairo-composite-rectangles-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-freelist-private.h" #include "cairo-list-private.h" @@ -2338,6 +2339,7 @@ i915_surface_fill (void *abstract_dst, static const cairo_surface_backend_t i915_surface_backend = { CAIRO_SURFACE_TYPE_DRM, + _cairo_default_context_create, i915_surface_create_similar, i915_surface_finish, diff --git a/src/drm/cairo-drm-i965-surface.c b/src/drm/cairo-drm-i965-surface.c index 394783621..71061a0e9 100644 --- a/src/drm/cairo-drm-i965-surface.c +++ b/src/drm/cairo-drm-i965-surface.c @@ -56,6 +56,7 @@ #include "cairo-boxes-private.h" #include "cairo-composite-rectangles-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-region-private.h" #include "cairo-surface-offset-private.h" @@ -1490,6 +1491,7 @@ CLEANUP_BOXES: static const cairo_surface_backend_t i965_surface_backend = { CAIRO_SURFACE_TYPE_DRM, + _cairo_default_context_create, i965_surface_create_similar, i965_surface_finish, diff --git a/src/drm/cairo-drm-intel-surface.c b/src/drm/cairo-drm-intel-surface.c index 96d46159c..f28c75003 100644 --- a/src/drm/cairo-drm-intel-surface.c +++ b/src/drm/cairo-drm-intel-surface.c @@ -32,6 +32,7 @@ #include "cairo-drm-private.h" #include "cairo-drm-intel-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" /* Basic generic/stub surface for intel chipsets */ @@ -248,6 +249,7 @@ intel_surface_glyphs (void *abstract_surface, static const cairo_surface_backend_t intel_surface_backend = { CAIRO_SURFACE_TYPE_DRM, + _cairo_default_context_create, intel_surface_create_similar, intel_surface_finish, diff --git a/src/drm/cairo-drm-radeon-surface.c b/src/drm/cairo-drm-radeon-surface.c index cbcef2a52..9335d7b72 100644 --- a/src/drm/cairo-drm-radeon-surface.c +++ b/src/drm/cairo-drm-radeon-surface.c @@ -32,6 +32,7 @@ #include "cairo-drm-private.h" #include "cairo-drm-radeon-private.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" /* Basic stub surface for radeon chipsets */ @@ -252,6 +253,7 @@ radeon_surface_glyphs (void *abstract_surface, static const cairo_surface_backend_t radeon_surface_backend = { CAIRO_SURFACE_TYPE_DRM, + _cairo_default_context_create, radeon_surface_create_similar, radeon_surface_finish, diff --git a/src/test-fallback-surface.c b/src/test-fallback-surface.c index 66399d4ab..5695dc960 100644 --- a/src/test-fallback-surface.c +++ b/src/test-fallback-surface.c @@ -54,6 +54,7 @@ #include "cairoint.h" #include "test-fallback-surface.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" typedef struct _test_fallback_surface { @@ -207,6 +208,8 @@ _test_fallback_surface_get_extents (void *abstract_surface, static const cairo_surface_backend_t test_fallback_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK, + _cairo_default_context_create, + _test_fallback_surface_create_similar, _test_fallback_surface_finish, _test_fallback_surface_acquire_source_image, diff --git a/src/test-fallback16-surface.c b/src/test-fallback16-surface.c index ce2febca5..2f4da5bf8 100644 --- a/src/test-fallback16-surface.c +++ b/src/test-fallback16-surface.c @@ -43,6 +43,7 @@ #include "cairoint.h" #include "test-fallback16-surface.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" typedef struct _test_fallback16_surface { @@ -204,6 +205,8 @@ _test_fallback16_surface_get_extents (void *abstract_surface, static const cairo_surface_backend_t test_fallback16_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK, + _cairo_default_context_create, + _test_fallback16_surface_create_similar, _test_fallback16_surface_finish, _test_fallback16_surface_acquire_source_image, diff --git a/src/test-null-surface.c b/src/test-null-surface.c index 0247d9240..620dd2f1a 100644 --- a/src/test-null-surface.c +++ b/src/test-null-surface.c @@ -40,6 +40,7 @@ #include "test-null-surface.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" slim_hidden_proto (_cairo_test_null_surface_create); @@ -133,6 +134,7 @@ _cairo_null_surface_has_show_text_glyphs (void *surface) static const cairo_surface_backend_t null_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_NULL, + _cairo_default_context_create, _cairo_null_surface_create_similar, NULL, /* finish */ diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c index e06cbed71..241f1bd1f 100644 --- a/src/test-paginated-surface.c +++ b/src/test-paginated-surface.c @@ -49,6 +49,7 @@ #include "test-paginated-surface.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-paginated-private.h" @@ -240,6 +241,7 @@ _test_paginated_surface_set_paginated_mode (void *abstract_surface, static const cairo_surface_backend_t test_paginated_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED, + _cairo_default_context_create, /* Since we are a paginated user, we get to regard most of the * surface backend interface as historical cruft and ignore it. */ diff --git a/src/test-wrapping-surface.c b/src/test-wrapping-surface.c index 4a60139d7..4dd6c4c68 100644 --- a/src/test-wrapping-surface.c +++ b/src/test-wrapping-surface.c @@ -43,6 +43,7 @@ #include "test-wrapping-surface.h" +#include "cairo-default-context-private.h" #include "cairo-error-private.h" #include "cairo-surface-wrapper-private.h" @@ -234,6 +235,8 @@ _test_wrapping_surface_show_text_glyphs (void *abstract_surface, static const cairo_surface_backend_t test_wrapping_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_TEST_WRAPPING, + _cairo_default_context_create, + _test_wrapping_surface_create_similar, _test_wrapping_surface_finish, _test_wrapping_surface_acquire_source_image, |