1 /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2 /* cairo - a vector graphics library with display and print output
4 * Copyright © 2002 University of Southern California
5 * Copyright © 2005 Red Hat, Inc.
6 * Copyright © 2011 Intel Corporation
8 * This library is free software; you can redistribute it and/or
9 * modify it either under the terms of the GNU Lesser General Public
10 * License version 2.1 as published by the Free Software Foundation
11 * (the "LGPL") or, at your option, under the terms of the Mozilla
12 * Public License Version 1.1 (the "MPL"). If you do not alter this
13 * notice, a recipient may use your version of this file under either
14 * the MPL or the LGPL.
16 * You should have received a copy of the LGPL along with this library
17 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
19 * You should have received a copy of the MPL along with this library
20 * in the file COPYING-MPL-1.1
22 * The contents of this file are subject to the Mozilla Public License
23 * Version 1.1 (the "License"); you may not use this file except in
24 * compliance with the License. You may obtain a copy of the License at
25 * http://www.mozilla.org/MPL/
27 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
28 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
29 * the specific language governing rights and limitations.
31 * The Original Code is the cairo graphics library.
33 * The Initial Developer of the Original Code is University of Southern
37 * Carl D. Worth <cworth@cworth.org>
38 * Chris Wilson <chris@chris-wilson.co.uk>
43 #include "cairo-private.h"
44 #include "cairo-arc-private.h"
45 #include "cairo-backend-private.h"
46 #include "cairo-clip-inline.h"
47 #include "cairo-default-context-private.h"
48 #include "cairo-error-private.h"
49 #include "cairo-freed-pool-private.h"
50 #include "cairo-path-private.h"
51 #include "cairo-pattern-private.h"
53 #define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1)
55 #if !defined(INFINITY)
56 #define INFINITY HUGE_VAL
59 static freed_pool_t context_pool;
62 _cairo_default_context_reset_static_data (void)
64 _freed_pool_reset (&context_pool);
68 _cairo_default_context_fini (cairo_default_context_t *cr)
70 while (cr->gstate != &cr->gstate_tail[0]) {
71 if (_cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist))
75 _cairo_gstate_fini (cr->gstate);
76 cr->gstate_freelist = cr->gstate_freelist->next; /* skip over tail[1] */
77 while (cr->gstate_freelist != NULL) {
78 cairo_gstate_t *gstate = cr->gstate_freelist;
79 cr->gstate_freelist = gstate->next;
83 _cairo_path_fixed_fini (cr->path);
85 _cairo_fini (&cr->base);
89 _cairo_default_context_destroy (void *abstract_cr)
91 cairo_default_context_t *cr = abstract_cr;
93 _cairo_default_context_fini (cr);
95 /* mark the context as invalid to protect against misuse */
96 cr->base.status = CAIRO_STATUS_NULL_POINTER;
97 _freed_pool_put (&context_pool, cr);
100 static cairo_surface_t *
101 _cairo_default_context_get_original_target (void *abstract_cr)
103 cairo_default_context_t *cr = abstract_cr;
105 return _cairo_gstate_get_original_target (cr->gstate);
108 static cairo_surface_t *
109 _cairo_default_context_get_current_target (void *abstract_cr)
111 cairo_default_context_t *cr = abstract_cr;
113 return _cairo_gstate_get_target (cr->gstate);
116 static cairo_status_t
117 _cairo_default_context_save (void *abstract_cr)
119 cairo_default_context_t *cr = abstract_cr;
121 return _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
124 static cairo_status_t
125 _cairo_default_context_restore (void *abstract_cr)
127 cairo_default_context_t *cr = abstract_cr;
129 if (unlikely (_cairo_gstate_is_group (cr->gstate)))
130 return _cairo_error (CAIRO_STATUS_INVALID_RESTORE);
132 return _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
135 static cairo_status_t
136 _cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
138 cairo_default_context_t *cr = abstract_cr;
139 cairo_surface_t *group_surface;
141 cairo_status_t status;
143 clip = _cairo_gstate_get_clip (cr->gstate);
144 if (_cairo_clip_is_all_clipped (clip)) {
145 group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
146 status = group_surface->status;
147 if (unlikely (status))
150 cairo_surface_t *parent_surface;
151 cairo_rectangle_int_t extents;
152 cairo_bool_t is_empty;
154 parent_surface = _cairo_gstate_get_target (cr->gstate);
156 /* Get the extents that we'll use in creating our new group surface */
157 is_empty = _cairo_surface_get_extents (parent_surface, &extents);
159 is_empty = _cairo_rectangle_intersect (&extents,
160 _cairo_clip_get_extents (clip));
162 /* XXX unbounded surface creation */
164 group_surface = _cairo_surface_create_similar_solid (parent_surface,
168 CAIRO_COLOR_TRANSPARENT);
169 status = group_surface->status;
170 if (unlikely (status))
173 /* Set device offsets on the new surface so that logically it appears at
174 * the same location on the parent surface -- when we pop_group this,
175 * the source pattern will get fixed up for the appropriate target surface
176 * device offsets, so we want to set our own surface offsets from /that/,
177 * and not from the device origin. */
178 cairo_surface_set_device_offset (group_surface,
179 parent_surface->device_transform.x0 - extents.x,
180 parent_surface->device_transform.y0 - extents.y);
182 /* If we have a current path, we need to adjust it to compensate for
183 * the device offset just applied. */
184 _cairo_path_fixed_translate (cr->path,
185 _cairo_fixed_from_int (-extents.x),
186 _cairo_fixed_from_int (-extents.y));
189 /* create a new gstate for the redirect */
190 status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
191 if (unlikely (status))
194 status = _cairo_gstate_redirect_target (cr->gstate, group_surface);
197 cairo_surface_destroy (group_surface);
201 static cairo_pattern_t *
202 _cairo_default_context_pop_group (void *abstract_cr)
204 cairo_default_context_t *cr = abstract_cr;
205 cairo_surface_t *group_surface;
206 cairo_pattern_t *group_pattern;
207 cairo_matrix_t group_matrix, device_transform_matrix;
208 cairo_status_t status;
210 /* Verify that we are at the right nesting level */
211 if (unlikely (! _cairo_gstate_is_group (cr->gstate)))
212 return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP);
214 /* Get a reference to the active surface before restoring */
215 group_surface = _cairo_gstate_get_target (cr->gstate);
216 group_surface = cairo_surface_reference (group_surface);
218 status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
219 assert (status == CAIRO_STATUS_SUCCESS);
221 group_pattern = cairo_pattern_create_for_surface (group_surface);
222 status = group_pattern->status;
223 if (unlikely (status))
226 _cairo_gstate_get_matrix (cr->gstate, &group_matrix);
227 /* Transform by group_matrix centered around device_transform so that when
228 * we call _cairo_gstate_copy_transformed_pattern the result is a pattern
229 * with a matrix equivalent to the device_transform of group_surface. */
230 if (_cairo_surface_has_device_transform (group_surface)) {
231 cairo_pattern_set_matrix (group_pattern, &group_surface->device_transform);
232 _cairo_pattern_transform (group_pattern, &group_matrix);
233 _cairo_pattern_transform (group_pattern, &group_surface->device_transform_inverse);
235 cairo_pattern_set_matrix (group_pattern, &group_matrix);
238 /* If we have a current path, we need to adjust it to compensate for
239 * the device offset just removed. */
240 cairo_matrix_multiply (&device_transform_matrix,
241 &_cairo_gstate_get_target (cr->gstate)->device_transform,
242 &group_surface->device_transform_inverse);
243 _cairo_path_fixed_transform (cr->path, &device_transform_matrix);
246 cairo_surface_destroy (group_surface);
248 return group_pattern;
251 static cairo_status_t
252 _cairo_default_context_set_source (void *abstract_cr,
253 cairo_pattern_t *source)
255 cairo_default_context_t *cr = abstract_cr;
257 return _cairo_gstate_set_source (cr->gstate, source);
261 _current_source_matches_solid (const cairo_pattern_t *pattern,
269 if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
272 red = _cairo_restrict_value (red, 0.0, 1.0);
273 green = _cairo_restrict_value (green, 0.0, 1.0);
274 blue = _cairo_restrict_value (blue, 0.0, 1.0);
275 alpha = _cairo_restrict_value (alpha, 0.0, 1.0);
277 _cairo_color_init_rgba (&color, red, green, blue, alpha);
278 return _cairo_color_equal (&color,
279 &((cairo_solid_pattern_t *) pattern)->color);
282 static cairo_status_t
283 _cairo_default_context_set_source_rgba (void *abstract_cr, double red, double green, double blue, double alpha)
285 cairo_default_context_t *cr = abstract_cr;
286 cairo_pattern_t *pattern;
287 cairo_status_t status;
289 if (_current_source_matches_solid (cr->gstate->source,
290 red, green, blue, alpha))
291 return CAIRO_STATUS_SUCCESS;
293 /* push the current pattern to the freed lists */
294 _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
296 pattern = cairo_pattern_create_rgba (red, green, blue, alpha);
297 if (unlikely (pattern->status)) {
298 status = pattern->status;
299 cairo_pattern_destroy (pattern);
300 return pattern->status;
303 status = _cairo_default_context_set_source (cr, pattern);
304 cairo_pattern_destroy (pattern);
309 static cairo_status_t
310 _cairo_default_context_set_source_surface (void *abstract_cr,
311 cairo_surface_t *surface,
315 cairo_default_context_t *cr = abstract_cr;
316 cairo_pattern_t *pattern;
317 cairo_matrix_t matrix;
318 cairo_status_t status;
320 /* push the current pattern to the freed lists */
321 _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
323 pattern = cairo_pattern_create_for_surface (surface);
324 if (unlikely (pattern->status)) {
325 status = pattern->status;
326 cairo_pattern_destroy (pattern);
330 cairo_matrix_init_translate (&matrix, -x, -y);
331 cairo_pattern_set_matrix (pattern, &matrix);
333 status = _cairo_default_context_set_source (cr, pattern);
334 cairo_pattern_destroy (pattern);
339 static cairo_pattern_t *
340 _cairo_default_context_get_source (void *abstract_cr)
342 cairo_default_context_t *cr = abstract_cr;
344 return _cairo_gstate_get_source (cr->gstate);
347 static cairo_status_t
348 _cairo_default_context_set_tolerance (void *abstract_cr,
351 cairo_default_context_t *cr = abstract_cr;
353 if (tolerance < CAIRO_TOLERANCE_MINIMUM)
354 tolerance = CAIRO_TOLERANCE_MINIMUM;
356 return _cairo_gstate_set_tolerance (cr->gstate, tolerance);
359 static cairo_status_t
360 _cairo_default_context_set_operator (void *abstract_cr, cairo_operator_t op)
362 cairo_default_context_t *cr = abstract_cr;
364 return _cairo_gstate_set_operator (cr->gstate, op);
367 static cairo_status_t
368 _cairo_default_context_set_opacity (void *abstract_cr, double opacity)
370 cairo_default_context_t *cr = abstract_cr;
372 return _cairo_gstate_set_opacity (cr->gstate, opacity);
375 static cairo_status_t
376 _cairo_default_context_set_antialias (void *abstract_cr,
377 cairo_antialias_t antialias)
379 cairo_default_context_t *cr = abstract_cr;
381 return _cairo_gstate_set_antialias (cr->gstate, antialias);
384 static cairo_status_t
385 _cairo_default_context_set_fill_rule (void *abstract_cr,
386 cairo_fill_rule_t fill_rule)
388 cairo_default_context_t *cr = abstract_cr;
390 return _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
393 static cairo_status_t
394 _cairo_default_context_set_line_width (void *abstract_cr,
397 cairo_default_context_t *cr = abstract_cr;
399 return _cairo_gstate_set_line_width (cr->gstate, line_width);
402 static cairo_status_t
403 _cairo_default_context_set_line_cap (void *abstract_cr,
404 cairo_line_cap_t line_cap)
406 cairo_default_context_t *cr = abstract_cr;
408 return _cairo_gstate_set_line_cap (cr->gstate, line_cap);
411 static cairo_status_t
412 _cairo_default_context_set_line_join (void *abstract_cr,
413 cairo_line_join_t line_join)
415 cairo_default_context_t *cr = abstract_cr;
417 return _cairo_gstate_set_line_join (cr->gstate, line_join);
420 static cairo_status_t
421 _cairo_default_context_set_dash (void *abstract_cr,
422 const double *dashes,
426 cairo_default_context_t *cr = abstract_cr;
428 return _cairo_gstate_set_dash (cr->gstate,
429 dashes, num_dashes, offset);
432 static cairo_status_t
433 _cairo_default_context_set_miter_limit (void *abstract_cr,
436 cairo_default_context_t *cr = abstract_cr;
438 return _cairo_gstate_set_miter_limit (cr->gstate, limit);
441 static cairo_antialias_t
442 _cairo_default_context_get_antialias (void *abstract_cr)
444 cairo_default_context_t *cr = abstract_cr;
446 return _cairo_gstate_get_antialias (cr->gstate);
450 _cairo_default_context_get_dash (void *abstract_cr,
455 cairo_default_context_t *cr = abstract_cr;
457 _cairo_gstate_get_dash (cr->gstate, dashes, num_dashes, offset);
460 static cairo_fill_rule_t
461 _cairo_default_context_get_fill_rule (void *abstract_cr)
463 cairo_default_context_t *cr = abstract_cr;
465 return _cairo_gstate_get_fill_rule (cr->gstate);
469 _cairo_default_context_get_line_width (void *abstract_cr)
471 cairo_default_context_t *cr = abstract_cr;
473 return _cairo_gstate_get_line_width (cr->gstate);
476 static cairo_line_cap_t
477 _cairo_default_context_get_line_cap (void *abstract_cr)
479 cairo_default_context_t *cr = abstract_cr;
481 return _cairo_gstate_get_line_cap (cr->gstate);
484 static cairo_line_join_t
485 _cairo_default_context_get_line_join (void *abstract_cr)
487 cairo_default_context_t *cr = abstract_cr;
489 return _cairo_gstate_get_line_join (cr->gstate);
493 _cairo_default_context_get_miter_limit (void *abstract_cr)
495 cairo_default_context_t *cr = abstract_cr;
497 return _cairo_gstate_get_miter_limit (cr->gstate);
500 static cairo_operator_t
501 _cairo_default_context_get_operator (void *abstract_cr)
503 cairo_default_context_t *cr = abstract_cr;
505 return _cairo_gstate_get_operator (cr->gstate);
509 _cairo_default_context_get_opacity (void *abstract_cr)
511 cairo_default_context_t *cr = abstract_cr;
513 return _cairo_gstate_get_opacity (cr->gstate);
517 _cairo_default_context_get_tolerance (void *abstract_cr)
519 cairo_default_context_t *cr = abstract_cr;
521 return _cairo_gstate_get_tolerance (cr->gstate);
525 /* Current tranformation matrix */
527 static cairo_status_t
528 _cairo_default_context_translate (void *abstract_cr,
532 cairo_default_context_t *cr = abstract_cr;
534 return _cairo_gstate_translate (cr->gstate, tx, ty);
537 static cairo_status_t
538 _cairo_default_context_scale (void *abstract_cr,
542 cairo_default_context_t *cr = abstract_cr;
544 return _cairo_gstate_scale (cr->gstate, sx, sy);
547 static cairo_status_t
548 _cairo_default_context_rotate (void *abstract_cr,
551 cairo_default_context_t *cr = abstract_cr;
553 return _cairo_gstate_rotate (cr->gstate, theta);
556 static cairo_status_t
557 _cairo_default_context_transform (void *abstract_cr,
558 const cairo_matrix_t *matrix)
560 cairo_default_context_t *cr = abstract_cr;
562 return _cairo_gstate_transform (cr->gstate, matrix);
565 static cairo_status_t
566 _cairo_default_context_set_matrix (void *abstract_cr,
567 const cairo_matrix_t *matrix)
569 cairo_default_context_t *cr = abstract_cr;
571 return _cairo_gstate_set_matrix (cr->gstate, matrix);
574 static cairo_status_t
575 _cairo_default_context_set_identity_matrix (void *abstract_cr)
577 cairo_default_context_t *cr = abstract_cr;
579 _cairo_gstate_identity_matrix (cr->gstate);
580 return CAIRO_STATUS_SUCCESS;
584 _cairo_default_context_get_matrix (void *abstract_cr,
585 cairo_matrix_t *matrix)
587 cairo_default_context_t *cr = abstract_cr;
589 _cairo_gstate_get_matrix (cr->gstate, matrix);
593 _cairo_default_context_user_to_device (void *abstract_cr,
597 cairo_default_context_t *cr = abstract_cr;
599 _cairo_gstate_user_to_device (cr->gstate, x, y);
603 _cairo_default_context_user_to_device_distance (void *abstract_cr, double *dx, double *dy)
605 cairo_default_context_t *cr = abstract_cr;
607 _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
611 _cairo_default_context_device_to_user (void *abstract_cr,
615 cairo_default_context_t *cr = abstract_cr;
617 _cairo_gstate_device_to_user (cr->gstate, x, y);
621 _cairo_default_context_device_to_user_distance (void *abstract_cr,
625 cairo_default_context_t *cr = abstract_cr;
627 _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
631 _cairo_default_context_backend_to_user (void *abstract_cr,
635 cairo_default_context_t *cr = abstract_cr;
637 _cairo_gstate_backend_to_user (cr->gstate, x, y);
641 _cairo_default_context_backend_to_user_distance (void *abstract_cr, double *dx, double *dy)
643 cairo_default_context_t *cr = abstract_cr;
645 _cairo_gstate_backend_to_user_distance (cr->gstate, dx, dy);
649 _cairo_default_context_user_to_backend (void *abstract_cr,
653 cairo_default_context_t *cr = abstract_cr;
655 _cairo_gstate_user_to_backend (cr->gstate, x, y);
659 _cairo_default_context_user_to_backend_distance (void *abstract_cr,
663 cairo_default_context_t *cr = abstract_cr;
665 _cairo_gstate_user_to_backend_distance (cr->gstate, dx, dy);
668 /* Path constructor */
670 static cairo_status_t
671 _cairo_default_context_new_path (void *abstract_cr)
673 cairo_default_context_t *cr = abstract_cr;
675 _cairo_path_fixed_fini (cr->path);
676 _cairo_path_fixed_init (cr->path);
678 return CAIRO_STATUS_SUCCESS;
681 static cairo_status_t
682 _cairo_default_context_new_sub_path (void *abstract_cr)
684 cairo_default_context_t *cr = abstract_cr;
686 _cairo_path_fixed_new_sub_path (cr->path);
688 return CAIRO_STATUS_SUCCESS;
691 static cairo_status_t
692 _cairo_default_context_move_to (void *abstract_cr, double x, double y)
694 cairo_default_context_t *cr = abstract_cr;
695 cairo_fixed_t x_fixed, y_fixed;
697 _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
698 x_fixed = _cairo_fixed_from_double (x);
699 y_fixed = _cairo_fixed_from_double (y);
701 return _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed);
704 static cairo_status_t
705 _cairo_default_context_line_to (void *abstract_cr, double x, double y)
707 cairo_default_context_t *cr = abstract_cr;
708 cairo_fixed_t x_fixed, y_fixed;
710 _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
711 x_fixed = _cairo_fixed_from_double (x);
712 y_fixed = _cairo_fixed_from_double (y);
714 return _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
717 static cairo_status_t
718 _cairo_default_context_curve_to (void *abstract_cr,
719 double x1, double y1,
720 double x2, double y2,
721 double x3, double y3)
723 cairo_default_context_t *cr = abstract_cr;
724 cairo_fixed_t x1_fixed, y1_fixed;
725 cairo_fixed_t x2_fixed, y2_fixed;
726 cairo_fixed_t x3_fixed, y3_fixed;
728 _cairo_gstate_user_to_backend (cr->gstate, &x1, &y1);
729 _cairo_gstate_user_to_backend (cr->gstate, &x2, &y2);
730 _cairo_gstate_user_to_backend (cr->gstate, &x3, &y3);
732 x1_fixed = _cairo_fixed_from_double (x1);
733 y1_fixed = _cairo_fixed_from_double (y1);
735 x2_fixed = _cairo_fixed_from_double (x2);
736 y2_fixed = _cairo_fixed_from_double (y2);
738 x3_fixed = _cairo_fixed_from_double (x3);
739 y3_fixed = _cairo_fixed_from_double (y3);
741 return _cairo_path_fixed_curve_to (cr->path,
747 static cairo_status_t
748 _cairo_default_context_arc (void *abstract_cr,
749 double xc, double yc, double radius,
750 double angle1, double angle2,
751 cairo_bool_t forward)
753 cairo_default_context_t *cr = abstract_cr;
754 cairo_status_t status;
756 /* Do nothing, successfully, if radius is <= 0 */
758 cairo_fixed_t x_fixed, y_fixed;
760 _cairo_gstate_user_to_backend (cr->gstate, &xc, &yc);
761 x_fixed = _cairo_fixed_from_double (xc);
762 y_fixed = _cairo_fixed_from_double (yc);
763 status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
764 if (unlikely (status))
767 status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
768 if (unlikely (status))
771 return CAIRO_STATUS_SUCCESS;
774 status = _cairo_default_context_line_to (cr,
775 xc + radius * cos (angle1),
776 yc + radius * sin (angle1));
778 if (unlikely (status))
782 _cairo_arc_path (&cr->base, xc, yc, radius, angle1, angle2);
784 _cairo_arc_path_negative (&cr->base, xc, yc, radius, angle1, angle2);
786 return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */
789 static cairo_status_t
790 _cairo_default_context_rel_move_to (void *abstract_cr, double dx, double dy)
792 cairo_default_context_t *cr = abstract_cr;
793 cairo_fixed_t dx_fixed, dy_fixed;
795 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy);
797 dx_fixed = _cairo_fixed_from_double (dx);
798 dy_fixed = _cairo_fixed_from_double (dy);
800 return _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
803 static cairo_status_t
804 _cairo_default_context_rel_line_to (void *abstract_cr, double dx, double dy)
806 cairo_default_context_t *cr = abstract_cr;
807 cairo_fixed_t dx_fixed, dy_fixed;
809 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy);
811 dx_fixed = _cairo_fixed_from_double (dx);
812 dy_fixed = _cairo_fixed_from_double (dy);
814 return _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
818 static cairo_status_t
819 _cairo_default_context_rel_curve_to (void *abstract_cr,
820 double dx1, double dy1,
821 double dx2, double dy2,
822 double dx3, double dy3)
824 cairo_default_context_t *cr = abstract_cr;
825 cairo_fixed_t dx1_fixed, dy1_fixed;
826 cairo_fixed_t dx2_fixed, dy2_fixed;
827 cairo_fixed_t dx3_fixed, dy3_fixed;
829 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx1, &dy1);
830 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx2, &dy2);
831 _cairo_gstate_user_to_backend_distance (cr->gstate, &dx3, &dy3);
833 dx1_fixed = _cairo_fixed_from_double (dx1);
834 dy1_fixed = _cairo_fixed_from_double (dy1);
836 dx2_fixed = _cairo_fixed_from_double (dx2);
837 dy2_fixed = _cairo_fixed_from_double (dy2);
839 dx3_fixed = _cairo_fixed_from_double (dx3);
840 dy3_fixed = _cairo_fixed_from_double (dy3);
842 return _cairo_path_fixed_rel_curve_to (cr->path,
843 dx1_fixed, dy1_fixed,
844 dx2_fixed, dy2_fixed,
845 dx3_fixed, dy3_fixed);
848 static cairo_status_t
849 _cairo_default_context_close_path (void *abstract_cr)
851 cairo_default_context_t *cr = abstract_cr;
853 return _cairo_path_fixed_close_path (cr->path);
856 static cairo_status_t
857 _cairo_default_context_rectangle (void *abstract_cr,
859 double width, double height)
861 cairo_default_context_t *cr = abstract_cr;
862 cairo_status_t status;
864 status = _cairo_default_context_move_to (cr, x, y);
865 if (unlikely (status))
868 status = _cairo_default_context_rel_line_to (cr, width, 0);
869 if (unlikely (status))
872 status = _cairo_default_context_rel_line_to (cr, 0, height);
873 if (unlikely (status))
876 status = _cairo_default_context_rel_line_to (cr, -width, 0);
877 if (unlikely (status))
880 return _cairo_default_context_close_path (cr);
884 _cairo_default_context_path_extents (void *abstract_cr,
890 cairo_default_context_t *cr = abstract_cr;
892 _cairo_gstate_path_extents (cr->gstate,
898 _cairo_default_context_has_current_point (void *abstract_cr)
900 cairo_default_context_t *cr = abstract_cr;
902 return cr->path->has_current_point;
906 _cairo_default_context_get_current_point (void *abstract_cr,
910 cairo_default_context_t *cr = abstract_cr;
911 cairo_fixed_t x_fixed, y_fixed;
913 if (_cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed))
915 *x = _cairo_fixed_to_double (x_fixed);
916 *y = _cairo_fixed_to_double (y_fixed);
917 _cairo_gstate_backend_to_user (cr->gstate, x, y);
927 static cairo_path_t *
928 _cairo_default_context_copy_path (void *abstract_cr)
930 cairo_default_context_t *cr = abstract_cr;
932 return _cairo_path_create (cr->path, &cr->base);
935 static cairo_path_t *
936 _cairo_default_context_copy_path_flat (void *abstract_cr)
938 cairo_default_context_t *cr = abstract_cr;
940 return _cairo_path_create_flat (cr->path, &cr->base);
943 static cairo_status_t
944 _cairo_default_context_append_path (void *abstract_cr,
945 const cairo_path_t *path)
947 cairo_default_context_t *cr = abstract_cr;
949 return _cairo_path_append_to_context (path, &cr->base);
952 static cairo_status_t
953 _cairo_default_context_paint (void *abstract_cr)
955 cairo_default_context_t *cr = abstract_cr;
957 return _cairo_gstate_paint (cr->gstate);
960 static cairo_status_t
961 _cairo_default_context_paint_with_alpha (void *abstract_cr,
964 cairo_default_context_t *cr = abstract_cr;
965 cairo_solid_pattern_t pattern;
966 cairo_status_t status;
969 if (CAIRO_ALPHA_IS_OPAQUE (alpha))
970 return _cairo_gstate_paint (cr->gstate);
972 if (CAIRO_ALPHA_IS_ZERO (alpha) &&
973 _cairo_operator_bounded_by_mask (cr->gstate->op)) {
974 return CAIRO_STATUS_SUCCESS;
977 _cairo_color_init_rgba (&color, 0., 0., 0., alpha);
978 _cairo_pattern_init_solid (&pattern, &color);
980 status = _cairo_gstate_mask (cr->gstate, &pattern.base);
981 _cairo_pattern_fini (&pattern.base);
986 static cairo_status_t
987 _cairo_default_context_mask (void *abstract_cr,
988 cairo_pattern_t *mask)
990 cairo_default_context_t *cr = abstract_cr;
992 return _cairo_gstate_mask (cr->gstate, mask);
995 static cairo_status_t
996 _cairo_default_context_stroke_preserve (void *abstract_cr)
998 cairo_default_context_t *cr = abstract_cr;
1000 return _cairo_gstate_stroke (cr->gstate, cr->path);
1003 static cairo_status_t
1004 _cairo_default_context_stroke (void *abstract_cr)
1006 cairo_default_context_t *cr = abstract_cr;
1007 cairo_status_t status;
1009 status = _cairo_gstate_stroke (cr->gstate, cr->path);
1010 if (unlikely (status))
1013 return _cairo_default_context_new_path (cr);
1016 static cairo_status_t
1017 _cairo_default_context_in_stroke (void *abstract_cr,
1019 cairo_bool_t *inside)
1021 cairo_default_context_t *cr = abstract_cr;
1023 return _cairo_gstate_in_stroke (cr->gstate,
1029 static cairo_status_t
1030 _cairo_default_context_stroke_extents (void *abstract_cr,
1031 double *x1, double *y1, double *x2, double *y2)
1033 cairo_default_context_t *cr = abstract_cr;
1035 return _cairo_gstate_stroke_extents (cr->gstate,
1040 static cairo_status_t
1041 _cairo_default_context_fill_preserve (void *abstract_cr)
1043 cairo_default_context_t *cr = abstract_cr;
1045 return _cairo_gstate_fill (cr->gstate, cr->path);
1048 static cairo_status_t
1049 _cairo_default_context_fill (void *abstract_cr)
1051 cairo_default_context_t *cr = abstract_cr;
1052 cairo_status_t status;
1054 status = _cairo_gstate_fill (cr->gstate, cr->path);
1055 if (unlikely (status))
1058 return _cairo_default_context_new_path (cr);
1061 static cairo_status_t
1062 _cairo_default_context_in_fill (void *abstract_cr,
1064 cairo_bool_t *inside)
1066 cairo_default_context_t *cr = abstract_cr;
1068 *inside = _cairo_gstate_in_fill (cr->gstate,
1071 return CAIRO_STATUS_SUCCESS;
1074 static cairo_status_t
1075 _cairo_default_context_fill_extents (void *abstract_cr,
1076 double *x1, double *y1, double *x2, double *y2)
1078 cairo_default_context_t *cr = abstract_cr;
1080 return _cairo_gstate_fill_extents (cr->gstate,
1085 static cairo_status_t
1086 _cairo_default_context_clip_preserve (void *abstract_cr)
1088 cairo_default_context_t *cr = abstract_cr;
1090 return _cairo_gstate_clip (cr->gstate, cr->path);
1093 static cairo_status_t
1094 _cairo_default_context_clip (void *abstract_cr)
1096 cairo_default_context_t *cr = abstract_cr;
1097 cairo_status_t status;
1099 status = _cairo_gstate_clip (cr->gstate, cr->path);
1100 if (unlikely (status))
1103 return _cairo_default_context_new_path (cr);
1106 static cairo_status_t
1107 _cairo_default_context_in_clip (void *abstract_cr,
1109 cairo_bool_t *inside)
1111 cairo_default_context_t *cr = abstract_cr;
1113 *inside = _cairo_gstate_in_clip (cr->gstate, x, y);
1114 return CAIRO_STATUS_SUCCESS;
1117 static cairo_status_t
1118 _cairo_default_context_reset_clip (void *abstract_cr)
1120 cairo_default_context_t *cr = abstract_cr;
1122 return _cairo_gstate_reset_clip (cr->gstate);
1125 static cairo_status_t
1126 _cairo_default_context_clip_extents (void *abstract_cr,
1127 double *x1, double *y1, double *x2, double *y2)
1129 cairo_default_context_t *cr = abstract_cr;
1131 if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) {
1138 return CAIRO_STATUS_SUCCESS;
1141 static cairo_rectangle_list_t *
1142 _cairo_default_context_copy_clip_rectangle_list (void *abstract_cr)
1144 cairo_default_context_t *cr = abstract_cr;
1146 return _cairo_gstate_copy_clip_rectangle_list (cr->gstate);
1149 static cairo_status_t
1150 _cairo_default_context_copy_page (void *abstract_cr)
1152 cairo_default_context_t *cr = abstract_cr;
1154 return _cairo_gstate_copy_page (cr->gstate);
1157 static cairo_status_t
1158 _cairo_default_context_show_page (void *abstract_cr)
1160 cairo_default_context_t *cr = abstract_cr;
1162 return _cairo_gstate_show_page (cr->gstate);
1165 static cairo_status_t
1166 _cairo_default_context_set_font_face (void *abstract_cr,
1167 cairo_font_face_t *font_face)
1169 cairo_default_context_t *cr = abstract_cr;
1171 return _cairo_gstate_set_font_face (cr->gstate, font_face);
1174 static cairo_font_face_t *
1175 _cairo_default_context_get_font_face (void *abstract_cr)
1177 cairo_default_context_t *cr = abstract_cr;
1178 cairo_font_face_t *font_face;
1179 cairo_status_t status;
1181 status = _cairo_gstate_get_font_face (cr->gstate, &font_face);
1182 if (unlikely (status)) {
1183 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
1184 return (cairo_font_face_t *) &_cairo_font_face_nil;
1190 static cairo_status_t
1191 _cairo_default_context_font_extents (void *abstract_cr,
1192 cairo_font_extents_t *extents)
1194 cairo_default_context_t *cr = abstract_cr;
1196 return _cairo_gstate_get_font_extents (cr->gstate, extents);
1199 static cairo_status_t
1200 _cairo_default_context_set_font_size (void *abstract_cr,
1203 cairo_default_context_t *cr = abstract_cr;
1205 return _cairo_gstate_set_font_size (cr->gstate, size);
1208 static cairo_status_t
1209 _cairo_default_context_set_font_matrix (void *abstract_cr,
1210 const cairo_matrix_t *matrix)
1212 cairo_default_context_t *cr = abstract_cr;
1214 return _cairo_gstate_set_font_matrix (cr->gstate, matrix);
1218 _cairo_default_context_get_font_matrix (void *abstract_cr,
1219 cairo_matrix_t *matrix)
1221 cairo_default_context_t *cr = abstract_cr;
1223 _cairo_gstate_get_font_matrix (cr->gstate, matrix);
1226 static cairo_status_t
1227 _cairo_default_context_set_font_options (void *abstract_cr,
1228 const cairo_font_options_t *options)
1230 cairo_default_context_t *cr = abstract_cr;
1232 _cairo_gstate_set_font_options (cr->gstate, options);
1233 return CAIRO_STATUS_SUCCESS;
1237 _cairo_default_context_get_font_options (void *abstract_cr,
1238 cairo_font_options_t *options)
1240 cairo_default_context_t *cr = abstract_cr;
1242 _cairo_gstate_get_font_options (cr->gstate, options);
1245 static cairo_status_t
1246 _cairo_default_context_set_scaled_font (void *abstract_cr,
1247 cairo_scaled_font_t *scaled_font)
1249 cairo_default_context_t *cr = abstract_cr;
1250 cairo_bool_t was_previous;
1251 cairo_status_t status;
1253 if (scaled_font == cr->gstate->scaled_font)
1254 return CAIRO_STATUS_SUCCESS;
1256 was_previous = scaled_font == cr->gstate->previous_scaled_font;
1258 status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
1259 if (unlikely (status))
1262 status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
1263 if (unlikely (status))
1266 _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
1269 cr->gstate->scaled_font = cairo_scaled_font_reference (scaled_font);
1271 return CAIRO_STATUS_SUCCESS;
1274 static cairo_scaled_font_t *
1275 _cairo_default_context_get_scaled_font (void *abstract_cr)
1277 cairo_default_context_t *cr = abstract_cr;
1278 cairo_scaled_font_t *scaled_font;
1279 cairo_status_t status;
1281 status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font);
1282 if (unlikely (status))
1283 return _cairo_scaled_font_create_in_error (status);
1288 static cairo_status_t
1289 _cairo_default_context_glyphs (void *abstract_cr,
1290 const cairo_glyph_t *glyphs,
1292 cairo_glyph_text_info_t *info)
1294 cairo_default_context_t *cr = abstract_cr;
1296 return _cairo_gstate_show_text_glyphs (cr->gstate, glyphs, num_glyphs, info);
1299 static cairo_status_t
1300 _cairo_default_context_glyph_path (void *abstract_cr,
1301 const cairo_glyph_t *glyphs,
1304 cairo_default_context_t *cr = abstract_cr;
1306 return _cairo_gstate_glyph_path (cr->gstate,
1311 static cairo_status_t
1312 _cairo_default_context_glyph_extents (void *abstract_cr,
1313 const cairo_glyph_t *glyphs,
1315 cairo_text_extents_t *extents)
1317 cairo_default_context_t *cr = abstract_cr;
1319 return _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
1322 static const cairo_backend_t _cairo_default_context_backend = {
1324 _cairo_default_context_destroy,
1326 _cairo_default_context_get_original_target,
1327 _cairo_default_context_get_current_target,
1329 _cairo_default_context_save,
1330 _cairo_default_context_restore,
1332 _cairo_default_context_push_group,
1333 _cairo_default_context_pop_group,
1335 _cairo_default_context_set_source_rgba,
1336 _cairo_default_context_set_source_surface,
1337 _cairo_default_context_set_source,
1338 _cairo_default_context_get_source,
1340 _cairo_default_context_set_antialias,
1341 _cairo_default_context_set_dash,
1342 _cairo_default_context_set_fill_rule,
1343 _cairo_default_context_set_line_cap,
1344 _cairo_default_context_set_line_join,
1345 _cairo_default_context_set_line_width,
1346 _cairo_default_context_set_miter_limit,
1347 _cairo_default_context_set_opacity,
1348 _cairo_default_context_set_operator,
1349 _cairo_default_context_set_tolerance,
1350 _cairo_default_context_get_antialias,
1351 _cairo_default_context_get_dash,
1352 _cairo_default_context_get_fill_rule,
1353 _cairo_default_context_get_line_cap,
1354 _cairo_default_context_get_line_join,
1355 _cairo_default_context_get_line_width,
1356 _cairo_default_context_get_miter_limit,
1357 _cairo_default_context_get_opacity,
1358 _cairo_default_context_get_operator,
1359 _cairo_default_context_get_tolerance,
1361 _cairo_default_context_translate,
1362 _cairo_default_context_scale,
1363 _cairo_default_context_rotate,
1364 _cairo_default_context_transform,
1365 _cairo_default_context_set_matrix,
1366 _cairo_default_context_set_identity_matrix,
1367 _cairo_default_context_get_matrix,
1369 _cairo_default_context_user_to_device,
1370 _cairo_default_context_user_to_device_distance,
1371 _cairo_default_context_device_to_user,
1372 _cairo_default_context_device_to_user_distance,
1374 _cairo_default_context_user_to_backend,
1375 _cairo_default_context_user_to_backend_distance,
1376 _cairo_default_context_backend_to_user,
1377 _cairo_default_context_backend_to_user_distance,
1379 _cairo_default_context_new_path,
1380 _cairo_default_context_new_sub_path,
1381 _cairo_default_context_move_to,
1382 _cairo_default_context_rel_move_to,
1383 _cairo_default_context_line_to,
1384 _cairo_default_context_rel_line_to,
1385 _cairo_default_context_curve_to,
1386 _cairo_default_context_rel_curve_to,
1388 NULL, /* rel-arc-to */
1389 _cairo_default_context_close_path,
1390 _cairo_default_context_arc,
1391 _cairo_default_context_rectangle,
1392 _cairo_default_context_path_extents,
1393 _cairo_default_context_has_current_point,
1394 _cairo_default_context_get_current_point,
1395 _cairo_default_context_copy_path,
1396 _cairo_default_context_copy_path_flat,
1397 _cairo_default_context_append_path,
1399 NULL, /* stroke-to-path */
1401 _cairo_default_context_clip,
1402 _cairo_default_context_clip_preserve,
1403 _cairo_default_context_in_clip,
1404 _cairo_default_context_clip_extents,
1405 _cairo_default_context_reset_clip,
1406 _cairo_default_context_copy_clip_rectangle_list,
1408 _cairo_default_context_paint,
1409 _cairo_default_context_paint_with_alpha,
1410 _cairo_default_context_mask,
1412 _cairo_default_context_stroke,
1413 _cairo_default_context_stroke_preserve,
1414 _cairo_default_context_in_stroke,
1415 _cairo_default_context_stroke_extents,
1417 _cairo_default_context_fill,
1418 _cairo_default_context_fill_preserve,
1419 _cairo_default_context_in_fill,
1420 _cairo_default_context_fill_extents,
1422 _cairo_default_context_set_font_face,
1423 _cairo_default_context_get_font_face,
1424 _cairo_default_context_set_font_size,
1425 _cairo_default_context_set_font_matrix,
1426 _cairo_default_context_get_font_matrix,
1427 _cairo_default_context_set_font_options,
1428 _cairo_default_context_get_font_options,
1429 _cairo_default_context_set_scaled_font,
1430 _cairo_default_context_get_scaled_font,
1431 _cairo_default_context_font_extents,
1433 _cairo_default_context_glyphs,
1434 _cairo_default_context_glyph_path,
1435 _cairo_default_context_glyph_extents,
1437 _cairo_default_context_copy_page,
1438 _cairo_default_context_show_page,
1442 _cairo_default_context_init (cairo_default_context_t *cr, void *target)
1444 _cairo_init (&cr->base, &_cairo_default_context_backend);
1445 _cairo_path_fixed_init (cr->path);
1447 cr->gstate = &cr->gstate_tail[0];
1448 cr->gstate_freelist = &cr->gstate_tail[1];
1449 cr->gstate_tail[1].next = NULL;
1451 return _cairo_gstate_init (cr->gstate, target);
1455 _cairo_default_context_create (void *target)
1457 cairo_default_context_t *cr;
1458 cairo_status_t status;
1460 cr = _freed_pool_get (&context_pool);
1461 if (unlikely (cr == NULL)) {
1462 cr = malloc (sizeof (cairo_default_context_t));
1463 if (unlikely (cr == NULL))
1464 return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
1467 status = _cairo_default_context_init (cr, target);
1468 if (unlikely (status)) {
1469 _freed_pool_put (&context_pool, cr);
1470 return _cairo_create_in_error (status);