TINF-96: add cairo-gobject and cairo-gobject-devel; deps for gobject-introspection
[profile/ivi/cairo.git] / src / cairo-default-context.c
1 /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2 /* cairo - a vector graphics library with display and print output
3  *
4  * Copyright © 2002 University of Southern California
5  * Copyright © 2005 Red Hat, Inc.
6  * Copyright © 2011 Intel Corporation
7  *
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.
15  *
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
21  *
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/
26  *
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.
30  *
31  * The Original Code is the cairo graphics library.
32  *
33  * The Initial Developer of the Original Code is University of Southern
34  * California.
35  *
36  * Contributor(s):
37  *      Carl D. Worth <cworth@cworth.org>
38  *      Chris Wilson <chris@chris-wilson.co.uk>
39  */
40
41 #include "cairoint.h"
42
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"
52
53 #define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1)
54
55 #if !defined(INFINITY)
56 #define INFINITY HUGE_VAL
57 #endif
58
59 static freed_pool_t context_pool;
60
61 void
62 _cairo_default_context_reset_static_data (void)
63 {
64     _freed_pool_reset (&context_pool);
65 }
66
67 void
68 _cairo_default_context_fini (cairo_default_context_t *cr)
69 {
70     while (cr->gstate != &cr->gstate_tail[0]) {
71         if (_cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist))
72             break;
73     }
74
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;
80         free (gstate);
81     }
82
83     _cairo_path_fixed_fini (cr->path);
84
85     _cairo_fini (&cr->base);
86 }
87
88 static void
89 _cairo_default_context_destroy (void *abstract_cr)
90 {
91     cairo_default_context_t *cr = abstract_cr;
92
93     _cairo_default_context_fini (cr);
94
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);
98 }
99
100 static cairo_surface_t *
101 _cairo_default_context_get_original_target (void *abstract_cr)
102 {
103     cairo_default_context_t *cr = abstract_cr;
104
105     return _cairo_gstate_get_original_target (cr->gstate);
106 }
107
108 static cairo_surface_t *
109 _cairo_default_context_get_current_target (void *abstract_cr)
110 {
111     cairo_default_context_t *cr = abstract_cr;
112
113     return _cairo_gstate_get_target (cr->gstate);
114 }
115
116 static cairo_status_t
117 _cairo_default_context_save (void *abstract_cr)
118 {
119     cairo_default_context_t *cr = abstract_cr;
120
121     return _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
122 }
123
124 static cairo_status_t
125 _cairo_default_context_restore (void *abstract_cr)
126 {
127     cairo_default_context_t *cr = abstract_cr;
128
129     if (unlikely (_cairo_gstate_is_group (cr->gstate)))
130         return _cairo_error (CAIRO_STATUS_INVALID_RESTORE);
131
132     return _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
133 }
134
135 static cairo_status_t
136 _cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
137 {
138     cairo_default_context_t *cr = abstract_cr;
139     cairo_surface_t *group_surface;
140     cairo_clip_t *clip;
141     cairo_status_t status;
142
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))
148             goto bail;
149     } else {
150         cairo_surface_t *parent_surface;
151         cairo_rectangle_int_t extents;
152         cairo_bool_t is_empty;
153
154         parent_surface = _cairo_gstate_get_target (cr->gstate);
155
156         /* Get the extents that we'll use in creating our new group surface */
157         is_empty = _cairo_surface_get_extents (parent_surface, &extents);
158         if (clip)
159             is_empty = _cairo_rectangle_intersect (&extents,
160                                                    _cairo_clip_get_extents (clip));
161
162         /* XXX unbounded surface creation */
163
164         group_surface = _cairo_surface_create_similar_solid (parent_surface,
165                                                              content,
166                                                              extents.width,
167                                                              extents.height,
168                                                              CAIRO_COLOR_TRANSPARENT);
169         status = group_surface->status;
170         if (unlikely (status))
171             goto bail;
172
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);
181
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));
187     }
188
189     /* create a new gstate for the redirect */
190     status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
191     if (unlikely (status))
192         goto bail;
193
194     status = _cairo_gstate_redirect_target (cr->gstate, group_surface);
195
196 bail:
197     cairo_surface_destroy (group_surface);
198     return status;
199 }
200
201 static cairo_pattern_t *
202 _cairo_default_context_pop_group (void *abstract_cr)
203 {
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;
209
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);
213
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);
217
218     status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
219     assert (status == CAIRO_STATUS_SUCCESS);
220
221     group_pattern = cairo_pattern_create_for_surface (group_surface);
222     status = group_pattern->status;
223     if (unlikely (status))
224         goto done;
225
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);
234     } else {
235         cairo_pattern_set_matrix (group_pattern, &group_matrix);
236     }
237
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);
244
245 done:
246     cairo_surface_destroy (group_surface);
247
248     return group_pattern;
249 }
250
251 static cairo_status_t
252 _cairo_default_context_set_source (void *abstract_cr,
253                                    cairo_pattern_t *source)
254 {
255     cairo_default_context_t *cr = abstract_cr;
256
257     return _cairo_gstate_set_source (cr->gstate, source);
258 }
259
260 static cairo_bool_t
261 _current_source_matches_solid (const cairo_pattern_t *pattern,
262                                double red,
263                                double green,
264                                double blue,
265                                double alpha)
266 {
267     cairo_color_t color;
268
269     if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
270         return FALSE;
271
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);
276
277     _cairo_color_init_rgba (&color, red, green, blue, alpha);
278     return _cairo_color_equal (&color,
279                                &((cairo_solid_pattern_t *) pattern)->color);
280 }
281
282 static cairo_status_t
283 _cairo_default_context_set_source_rgba (void *abstract_cr, double red, double green, double blue, double alpha)
284 {
285     cairo_default_context_t *cr = abstract_cr;
286     cairo_pattern_t *pattern;
287     cairo_status_t status;
288
289     if (_current_source_matches_solid (cr->gstate->source,
290                                        red, green, blue, alpha))
291         return CAIRO_STATUS_SUCCESS;
292
293     /* push the current pattern to the freed lists */
294     _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
295
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;
301     }
302
303     status = _cairo_default_context_set_source (cr, pattern);
304     cairo_pattern_destroy (pattern);
305
306     return status;
307 }
308
309 static cairo_status_t
310 _cairo_default_context_set_source_surface (void *abstract_cr,
311                                            cairo_surface_t *surface,
312                                            double          x,
313                                            double          y)
314 {
315     cairo_default_context_t *cr = abstract_cr;
316     cairo_pattern_t *pattern;
317     cairo_matrix_t matrix;
318     cairo_status_t status;
319
320     /* push the current pattern to the freed lists */
321     _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
322
323     pattern = cairo_pattern_create_for_surface (surface);
324     if (unlikely (pattern->status)) {
325         status = pattern->status;
326         cairo_pattern_destroy (pattern);
327         return status;
328     }
329
330     cairo_matrix_init_translate (&matrix, -x, -y);
331     cairo_pattern_set_matrix (pattern, &matrix);
332
333     status = _cairo_default_context_set_source (cr, pattern);
334     cairo_pattern_destroy (pattern);
335
336     return status;
337 }
338
339 static cairo_pattern_t *
340 _cairo_default_context_get_source (void *abstract_cr)
341 {
342     cairo_default_context_t *cr = abstract_cr;
343
344     return _cairo_gstate_get_source (cr->gstate);
345 }
346
347 static cairo_status_t
348 _cairo_default_context_set_tolerance (void *abstract_cr,
349                                       double tolerance)
350 {
351     cairo_default_context_t *cr = abstract_cr;
352
353     if (tolerance < CAIRO_TOLERANCE_MINIMUM)
354         tolerance = CAIRO_TOLERANCE_MINIMUM;
355
356     return _cairo_gstate_set_tolerance (cr->gstate, tolerance);
357 }
358
359 static cairo_status_t
360 _cairo_default_context_set_operator (void *abstract_cr, cairo_operator_t op)
361 {
362     cairo_default_context_t *cr = abstract_cr;
363
364     return _cairo_gstate_set_operator (cr->gstate, op);
365 }
366
367 static cairo_status_t
368 _cairo_default_context_set_opacity (void *abstract_cr, double opacity)
369 {
370     cairo_default_context_t *cr = abstract_cr;
371
372     return _cairo_gstate_set_opacity (cr->gstate, opacity);
373 }
374
375 static cairo_status_t
376 _cairo_default_context_set_antialias (void *abstract_cr,
377                                       cairo_antialias_t antialias)
378 {
379     cairo_default_context_t *cr = abstract_cr;
380
381     return _cairo_gstate_set_antialias (cr->gstate, antialias);
382 }
383
384 static cairo_status_t
385 _cairo_default_context_set_fill_rule (void *abstract_cr,
386                                       cairo_fill_rule_t fill_rule)
387 {
388     cairo_default_context_t *cr = abstract_cr;
389
390     return _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
391 }
392
393 static cairo_status_t
394 _cairo_default_context_set_line_width (void *abstract_cr,
395                                        double line_width)
396 {
397     cairo_default_context_t *cr = abstract_cr;
398
399     return _cairo_gstate_set_line_width (cr->gstate, line_width);
400 }
401
402 static cairo_status_t
403 _cairo_default_context_set_line_cap (void *abstract_cr,
404                                      cairo_line_cap_t line_cap)
405 {
406     cairo_default_context_t *cr = abstract_cr;
407
408     return _cairo_gstate_set_line_cap (cr->gstate, line_cap);
409 }
410
411 static cairo_status_t
412 _cairo_default_context_set_line_join (void *abstract_cr,
413                                       cairo_line_join_t line_join)
414 {
415     cairo_default_context_t *cr = abstract_cr;
416
417     return _cairo_gstate_set_line_join (cr->gstate, line_join);
418 }
419
420 static cairo_status_t
421 _cairo_default_context_set_dash (void *abstract_cr,
422                                  const double *dashes,
423                                  int          num_dashes,
424                                  double       offset)
425 {
426     cairo_default_context_t *cr = abstract_cr;
427
428     return _cairo_gstate_set_dash (cr->gstate,
429                                    dashes, num_dashes, offset);
430 }
431
432 static cairo_status_t
433 _cairo_default_context_set_miter_limit (void *abstract_cr,
434                                         double limit)
435 {
436     cairo_default_context_t *cr = abstract_cr;
437
438     return _cairo_gstate_set_miter_limit (cr->gstate, limit);
439 }
440
441 static cairo_antialias_t
442 _cairo_default_context_get_antialias (void *abstract_cr)
443 {
444     cairo_default_context_t *cr = abstract_cr;
445
446     return _cairo_gstate_get_antialias (cr->gstate);
447 }
448
449 static void
450 _cairo_default_context_get_dash (void *abstract_cr,
451                                  double *dashes,
452                                  int *num_dashes,
453                                  double *offset)
454 {
455     cairo_default_context_t *cr = abstract_cr;
456
457     _cairo_gstate_get_dash (cr->gstate, dashes, num_dashes, offset);
458 }
459
460 static cairo_fill_rule_t
461 _cairo_default_context_get_fill_rule (void *abstract_cr)
462 {
463     cairo_default_context_t *cr = abstract_cr;
464
465     return _cairo_gstate_get_fill_rule (cr->gstate);
466 }
467
468 static double
469 _cairo_default_context_get_line_width (void *abstract_cr)
470 {
471     cairo_default_context_t *cr = abstract_cr;
472
473     return _cairo_gstate_get_line_width (cr->gstate);
474 }
475
476 static cairo_line_cap_t
477 _cairo_default_context_get_line_cap (void *abstract_cr)
478 {
479     cairo_default_context_t *cr = abstract_cr;
480
481     return _cairo_gstate_get_line_cap (cr->gstate);
482 }
483
484 static cairo_line_join_t
485 _cairo_default_context_get_line_join (void *abstract_cr)
486 {
487     cairo_default_context_t *cr = abstract_cr;
488
489     return _cairo_gstate_get_line_join (cr->gstate);
490 }
491
492 static double
493 _cairo_default_context_get_miter_limit (void *abstract_cr)
494 {
495     cairo_default_context_t *cr = abstract_cr;
496
497     return _cairo_gstate_get_miter_limit (cr->gstate);
498 }
499
500 static cairo_operator_t
501 _cairo_default_context_get_operator (void *abstract_cr)
502 {
503     cairo_default_context_t *cr = abstract_cr;
504
505     return _cairo_gstate_get_operator (cr->gstate);
506 }
507
508 static double
509 _cairo_default_context_get_opacity (void *abstract_cr)
510 {
511     cairo_default_context_t *cr = abstract_cr;
512
513     return _cairo_gstate_get_opacity (cr->gstate);
514 }
515
516 static double
517 _cairo_default_context_get_tolerance (void *abstract_cr)
518 {
519     cairo_default_context_t *cr = abstract_cr;
520
521     return _cairo_gstate_get_tolerance (cr->gstate);
522 }
523
524
525 /* Current tranformation matrix */
526
527 static cairo_status_t
528 _cairo_default_context_translate (void *abstract_cr,
529                                   double tx,
530                                   double ty)
531 {
532     cairo_default_context_t *cr = abstract_cr;
533
534     return _cairo_gstate_translate (cr->gstate, tx, ty);
535 }
536
537 static cairo_status_t
538 _cairo_default_context_scale (void *abstract_cr,
539                               double sx,
540                               double sy)
541 {
542     cairo_default_context_t *cr = abstract_cr;
543
544     return _cairo_gstate_scale (cr->gstate, sx, sy);
545 }
546
547 static cairo_status_t
548 _cairo_default_context_rotate (void *abstract_cr,
549                                double theta)
550 {
551     cairo_default_context_t *cr = abstract_cr;
552
553     return _cairo_gstate_rotate (cr->gstate, theta);
554 }
555
556 static cairo_status_t
557 _cairo_default_context_transform (void *abstract_cr,
558                                   const cairo_matrix_t *matrix)
559 {
560     cairo_default_context_t *cr = abstract_cr;
561
562     return _cairo_gstate_transform (cr->gstate, matrix);
563 }
564
565 static cairo_status_t
566 _cairo_default_context_set_matrix (void *abstract_cr,
567                                    const cairo_matrix_t *matrix)
568 {
569     cairo_default_context_t *cr = abstract_cr;
570
571     return _cairo_gstate_set_matrix (cr->gstate, matrix);
572 }
573
574 static cairo_status_t
575 _cairo_default_context_set_identity_matrix (void *abstract_cr)
576 {
577     cairo_default_context_t *cr = abstract_cr;
578
579     _cairo_gstate_identity_matrix (cr->gstate);
580     return CAIRO_STATUS_SUCCESS;
581 }
582
583 static void
584 _cairo_default_context_get_matrix (void *abstract_cr,
585                                    cairo_matrix_t *matrix)
586 {
587     cairo_default_context_t *cr = abstract_cr;
588
589     _cairo_gstate_get_matrix (cr->gstate, matrix);
590 }
591
592 static void
593 _cairo_default_context_user_to_device (void *abstract_cr,
594                                        double *x,
595                                        double *y)
596 {
597     cairo_default_context_t *cr = abstract_cr;
598
599     _cairo_gstate_user_to_device (cr->gstate, x, y);
600 }
601
602 static void
603 _cairo_default_context_user_to_device_distance (void *abstract_cr, double *dx, double *dy)
604 {
605     cairo_default_context_t *cr = abstract_cr;
606
607     _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
608 }
609
610 static void
611 _cairo_default_context_device_to_user (void *abstract_cr,
612                                        double *x,
613                                        double *y)
614 {
615     cairo_default_context_t *cr = abstract_cr;
616
617     _cairo_gstate_device_to_user (cr->gstate, x, y);
618 }
619
620 static void
621 _cairo_default_context_device_to_user_distance (void *abstract_cr,
622                                                 double *dx,
623                                                 double *dy)
624 {
625     cairo_default_context_t *cr = abstract_cr;
626
627     _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
628 }
629
630 static void
631 _cairo_default_context_backend_to_user (void *abstract_cr,
632                                         double *x,
633                                         double *y)
634 {
635     cairo_default_context_t *cr = abstract_cr;
636
637     _cairo_gstate_backend_to_user (cr->gstate, x, y);
638 }
639
640 static void
641 _cairo_default_context_backend_to_user_distance (void *abstract_cr, double *dx, double *dy)
642 {
643     cairo_default_context_t *cr = abstract_cr;
644
645     _cairo_gstate_backend_to_user_distance (cr->gstate, dx, dy);
646 }
647
648 static void
649 _cairo_default_context_user_to_backend (void *abstract_cr,
650                                         double *x,
651                                         double *y)
652 {
653     cairo_default_context_t *cr = abstract_cr;
654
655     _cairo_gstate_user_to_backend (cr->gstate, x, y);
656 }
657
658 static void
659 _cairo_default_context_user_to_backend_distance (void *abstract_cr,
660                                                  double *dx,
661                                                  double *dy)
662 {
663     cairo_default_context_t *cr = abstract_cr;
664
665     _cairo_gstate_user_to_backend_distance (cr->gstate, dx, dy);
666 }
667
668 /* Path constructor */
669
670 static cairo_status_t
671 _cairo_default_context_new_path (void *abstract_cr)
672 {
673     cairo_default_context_t *cr = abstract_cr;
674
675     _cairo_path_fixed_fini (cr->path);
676     _cairo_path_fixed_init (cr->path);
677
678     return CAIRO_STATUS_SUCCESS;
679 }
680
681 static cairo_status_t
682 _cairo_default_context_new_sub_path (void *abstract_cr)
683 {
684     cairo_default_context_t *cr = abstract_cr;
685
686     _cairo_path_fixed_new_sub_path (cr->path);
687
688     return CAIRO_STATUS_SUCCESS;
689 }
690
691 static cairo_status_t
692 _cairo_default_context_move_to (void *abstract_cr, double x, double y)
693 {
694     cairo_default_context_t *cr = abstract_cr;
695     cairo_fixed_t x_fixed, y_fixed;
696
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);
700
701     return _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed);
702 }
703
704 static cairo_status_t
705 _cairo_default_context_line_to (void *abstract_cr, double x, double y)
706 {
707     cairo_default_context_t *cr = abstract_cr;
708     cairo_fixed_t x_fixed, y_fixed;
709
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);
713
714     return _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
715 }
716
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)
722 {
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;
727
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);
731
732     x1_fixed = _cairo_fixed_from_double (x1);
733     y1_fixed = _cairo_fixed_from_double (y1);
734
735     x2_fixed = _cairo_fixed_from_double (x2);
736     y2_fixed = _cairo_fixed_from_double (y2);
737
738     x3_fixed = _cairo_fixed_from_double (x3);
739     y3_fixed = _cairo_fixed_from_double (y3);
740
741     return _cairo_path_fixed_curve_to (cr->path,
742                                        x1_fixed, y1_fixed,
743                                        x2_fixed, y2_fixed,
744                                        x3_fixed, y3_fixed);
745 }
746
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)
752 {
753     cairo_default_context_t *cr = abstract_cr;
754     cairo_status_t status;
755
756     /* Do nothing, successfully, if radius is <= 0 */
757     if (radius <= 0.0) {
758         cairo_fixed_t x_fixed, y_fixed;
759
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))
765             return status;
766
767         status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
768         if (unlikely (status))
769             return status;
770
771         return CAIRO_STATUS_SUCCESS;
772     }
773
774     status = _cairo_default_context_line_to (cr,
775                                              xc + radius * cos (angle1),
776                                              yc + radius * sin (angle1));
777
778     if (unlikely (status))
779         return status;
780
781     if (forward)
782         _cairo_arc_path (&cr->base, xc, yc, radius, angle1, angle2);
783     else
784         _cairo_arc_path_negative (&cr->base, xc, yc, radius, angle1, angle2);
785
786     return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */
787 }
788
789 static cairo_status_t
790 _cairo_default_context_rel_move_to (void *abstract_cr, double dx, double dy)
791 {
792     cairo_default_context_t *cr = abstract_cr;
793     cairo_fixed_t dx_fixed, dy_fixed;
794
795     _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy);
796
797     dx_fixed = _cairo_fixed_from_double (dx);
798     dy_fixed = _cairo_fixed_from_double (dy);
799
800     return _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
801 }
802
803 static cairo_status_t
804 _cairo_default_context_rel_line_to (void *abstract_cr, double dx, double dy)
805 {
806     cairo_default_context_t *cr = abstract_cr;
807     cairo_fixed_t dx_fixed, dy_fixed;
808
809     _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy);
810
811     dx_fixed = _cairo_fixed_from_double (dx);
812     dy_fixed = _cairo_fixed_from_double (dy);
813
814     return _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
815 }
816
817
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)
823 {
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;
828
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);
832
833     dx1_fixed = _cairo_fixed_from_double (dx1);
834     dy1_fixed = _cairo_fixed_from_double (dy1);
835
836     dx2_fixed = _cairo_fixed_from_double (dx2);
837     dy2_fixed = _cairo_fixed_from_double (dy2);
838
839     dx3_fixed = _cairo_fixed_from_double (dx3);
840     dy3_fixed = _cairo_fixed_from_double (dy3);
841
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);
846 }
847
848 static cairo_status_t
849 _cairo_default_context_close_path (void *abstract_cr)
850 {
851     cairo_default_context_t *cr = abstract_cr;
852
853     return _cairo_path_fixed_close_path (cr->path);
854 }
855
856 static cairo_status_t
857 _cairo_default_context_rectangle (void *abstract_cr,
858                                   double x, double y,
859                                   double width, double height)
860 {
861     cairo_default_context_t *cr = abstract_cr;
862     cairo_status_t status;
863
864     status = _cairo_default_context_move_to (cr, x, y);
865     if (unlikely (status))
866         return status;
867
868     status = _cairo_default_context_rel_line_to (cr, width, 0);
869     if (unlikely (status))
870         return status;
871
872     status = _cairo_default_context_rel_line_to (cr, 0, height);
873     if (unlikely (status))
874         return status;
875
876     status = _cairo_default_context_rel_line_to (cr, -width, 0);
877     if (unlikely (status))
878         return status;
879
880     return _cairo_default_context_close_path (cr);
881 }
882
883 static void
884 _cairo_default_context_path_extents (void *abstract_cr,
885                                      double *x1,
886                                      double *y1,
887                                      double *x2,
888                                      double *y2)
889 {
890     cairo_default_context_t *cr = abstract_cr;
891
892     _cairo_gstate_path_extents (cr->gstate,
893                                 cr->path,
894                                 x1, y1, x2, y2);
895 }
896
897 static cairo_bool_t
898 _cairo_default_context_has_current_point (void *abstract_cr)
899 {
900     cairo_default_context_t *cr = abstract_cr;
901
902     return cr->path->has_current_point;
903 }
904
905 static cairo_bool_t
906 _cairo_default_context_get_current_point (void *abstract_cr,
907                                           double *x,
908                                           double *y)
909 {
910     cairo_default_context_t *cr = abstract_cr;
911     cairo_fixed_t x_fixed, y_fixed;
912
913     if (_cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed))
914     {
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);
918
919         return TRUE;
920     }
921     else
922     {
923         return FALSE;
924     }
925 }
926
927 static cairo_path_t *
928 _cairo_default_context_copy_path (void *abstract_cr)
929 {
930     cairo_default_context_t *cr = abstract_cr;
931
932     return _cairo_path_create (cr->path, &cr->base);
933 }
934
935 static cairo_path_t *
936 _cairo_default_context_copy_path_flat (void *abstract_cr)
937 {
938     cairo_default_context_t *cr = abstract_cr;
939
940     return _cairo_path_create_flat (cr->path, &cr->base);
941 }
942
943 static cairo_status_t
944 _cairo_default_context_append_path (void *abstract_cr,
945                                     const cairo_path_t *path)
946 {
947     cairo_default_context_t *cr = abstract_cr;
948
949     return _cairo_path_append_to_context (path, &cr->base);
950 }
951
952 static cairo_status_t
953 _cairo_default_context_paint (void *abstract_cr)
954 {
955     cairo_default_context_t *cr = abstract_cr;
956
957     return _cairo_gstate_paint (cr->gstate);
958 }
959
960 static cairo_status_t
961 _cairo_default_context_paint_with_alpha (void *abstract_cr,
962                                          double alpha)
963 {
964     cairo_default_context_t *cr = abstract_cr;
965     cairo_solid_pattern_t pattern;
966     cairo_status_t status;
967     cairo_color_t color;
968
969     if (CAIRO_ALPHA_IS_OPAQUE (alpha))
970         return _cairo_gstate_paint (cr->gstate);
971
972     if (CAIRO_ALPHA_IS_ZERO (alpha) &&
973         _cairo_operator_bounded_by_mask (cr->gstate->op)) {
974         return CAIRO_STATUS_SUCCESS;
975     }
976
977     _cairo_color_init_rgba (&color, 0., 0., 0., alpha);
978     _cairo_pattern_init_solid (&pattern, &color);
979
980     status = _cairo_gstate_mask (cr->gstate, &pattern.base);
981     _cairo_pattern_fini (&pattern.base);
982
983     return status;
984 }
985
986 static cairo_status_t
987 _cairo_default_context_mask (void *abstract_cr,
988                              cairo_pattern_t *mask)
989 {
990     cairo_default_context_t *cr = abstract_cr;
991
992     return _cairo_gstate_mask (cr->gstate, mask);
993 }
994
995 static cairo_status_t
996 _cairo_default_context_stroke_preserve (void *abstract_cr)
997 {
998     cairo_default_context_t *cr = abstract_cr;
999
1000     return _cairo_gstate_stroke (cr->gstate, cr->path);
1001 }
1002
1003 static cairo_status_t
1004 _cairo_default_context_stroke (void *abstract_cr)
1005 {
1006     cairo_default_context_t *cr = abstract_cr;
1007     cairo_status_t status;
1008
1009     status = _cairo_gstate_stroke (cr->gstate, cr->path);
1010     if (unlikely (status))
1011         return status;
1012
1013     return _cairo_default_context_new_path (cr);
1014 }
1015
1016 static cairo_status_t
1017 _cairo_default_context_in_stroke (void *abstract_cr,
1018                                   double x, double y,
1019                                   cairo_bool_t *inside)
1020 {
1021     cairo_default_context_t *cr = abstract_cr;
1022
1023     return _cairo_gstate_in_stroke (cr->gstate,
1024                                     cr->path,
1025                                     x, y,
1026                                     inside);
1027 }
1028
1029 static cairo_status_t
1030 _cairo_default_context_stroke_extents (void *abstract_cr,
1031                                        double *x1, double *y1, double *x2, double *y2)
1032 {
1033     cairo_default_context_t *cr = abstract_cr;
1034
1035     return _cairo_gstate_stroke_extents (cr->gstate,
1036                                          cr->path,
1037                                          x1, y1, x2, y2);
1038 }
1039
1040 static cairo_status_t
1041 _cairo_default_context_fill_preserve (void *abstract_cr)
1042 {
1043     cairo_default_context_t *cr = abstract_cr;
1044
1045     return _cairo_gstate_fill (cr->gstate, cr->path);
1046 }
1047
1048 static cairo_status_t
1049 _cairo_default_context_fill (void *abstract_cr)
1050 {
1051     cairo_default_context_t *cr = abstract_cr;
1052     cairo_status_t status;
1053
1054     status = _cairo_gstate_fill (cr->gstate, cr->path);
1055     if (unlikely (status))
1056         return status;
1057
1058     return _cairo_default_context_new_path (cr);
1059 }
1060
1061 static cairo_status_t
1062 _cairo_default_context_in_fill (void *abstract_cr,
1063                                 double x, double y,
1064                                 cairo_bool_t *inside)
1065 {
1066     cairo_default_context_t *cr = abstract_cr;
1067
1068     *inside = _cairo_gstate_in_fill (cr->gstate,
1069                                      cr->path,
1070                                      x, y);
1071     return CAIRO_STATUS_SUCCESS;
1072 }
1073
1074 static cairo_status_t
1075 _cairo_default_context_fill_extents (void *abstract_cr,
1076                                      double *x1, double *y1, double *x2, double *y2)
1077 {
1078     cairo_default_context_t *cr = abstract_cr;
1079
1080     return _cairo_gstate_fill_extents (cr->gstate,
1081                                        cr->path,
1082                                        x1, y1, x2, y2);
1083 }
1084
1085 static cairo_status_t
1086 _cairo_default_context_clip_preserve (void *abstract_cr)
1087 {
1088     cairo_default_context_t *cr = abstract_cr;
1089
1090     return _cairo_gstate_clip (cr->gstate, cr->path);
1091 }
1092
1093 static cairo_status_t
1094 _cairo_default_context_clip (void *abstract_cr)
1095 {
1096     cairo_default_context_t *cr = abstract_cr;
1097     cairo_status_t status;
1098
1099     status = _cairo_gstate_clip (cr->gstate, cr->path);
1100     if (unlikely (status))
1101         return status;
1102
1103     return _cairo_default_context_new_path (cr);
1104 }
1105
1106 static cairo_status_t
1107 _cairo_default_context_in_clip (void *abstract_cr,
1108                                 double x, double y,
1109                                 cairo_bool_t *inside)
1110 {
1111     cairo_default_context_t *cr = abstract_cr;
1112
1113     *inside = _cairo_gstate_in_clip (cr->gstate, x, y);
1114     return CAIRO_STATUS_SUCCESS;
1115 }
1116
1117 static cairo_status_t
1118 _cairo_default_context_reset_clip (void *abstract_cr)
1119 {
1120     cairo_default_context_t *cr = abstract_cr;
1121
1122     return _cairo_gstate_reset_clip (cr->gstate);
1123 }
1124
1125 static cairo_status_t
1126 _cairo_default_context_clip_extents (void *abstract_cr,
1127                                      double *x1, double *y1, double *x2, double *y2)
1128 {
1129     cairo_default_context_t *cr = abstract_cr;
1130
1131     if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) {
1132         *x1 = -INFINITY;
1133         *y1 = -INFINITY;
1134         *x2 = +INFINITY;
1135         *y2 = +INFINITY;
1136     }
1137
1138     return CAIRO_STATUS_SUCCESS;
1139 }
1140
1141 static cairo_rectangle_list_t *
1142 _cairo_default_context_copy_clip_rectangle_list (void *abstract_cr)
1143 {
1144     cairo_default_context_t *cr = abstract_cr;
1145
1146     return _cairo_gstate_copy_clip_rectangle_list (cr->gstate);
1147 }
1148
1149 static cairo_status_t
1150 _cairo_default_context_copy_page (void *abstract_cr)
1151 {
1152     cairo_default_context_t *cr = abstract_cr;
1153
1154     return _cairo_gstate_copy_page (cr->gstate);
1155 }
1156
1157 static cairo_status_t
1158 _cairo_default_context_show_page (void *abstract_cr)
1159 {
1160     cairo_default_context_t *cr = abstract_cr;
1161
1162     return _cairo_gstate_show_page (cr->gstate);
1163 }
1164
1165 static cairo_status_t
1166 _cairo_default_context_set_font_face (void *abstract_cr,
1167                                       cairo_font_face_t *font_face)
1168 {
1169     cairo_default_context_t *cr = abstract_cr;
1170
1171     return _cairo_gstate_set_font_face (cr->gstate, font_face);
1172 }
1173
1174 static cairo_font_face_t *
1175 _cairo_default_context_get_font_face (void *abstract_cr)
1176 {
1177     cairo_default_context_t *cr = abstract_cr;
1178     cairo_font_face_t *font_face;
1179     cairo_status_t status;
1180
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;
1185     }
1186
1187     return font_face;
1188 }
1189
1190 static cairo_status_t
1191 _cairo_default_context_font_extents (void *abstract_cr,
1192                                      cairo_font_extents_t *extents)
1193 {
1194     cairo_default_context_t *cr = abstract_cr;
1195
1196     return _cairo_gstate_get_font_extents (cr->gstate, extents);
1197 }
1198
1199 static cairo_status_t
1200 _cairo_default_context_set_font_size (void *abstract_cr,
1201                                       double size)
1202 {
1203     cairo_default_context_t *cr = abstract_cr;
1204
1205     return _cairo_gstate_set_font_size (cr->gstate, size);
1206 }
1207
1208 static cairo_status_t
1209 _cairo_default_context_set_font_matrix (void *abstract_cr,
1210                                         const cairo_matrix_t *matrix)
1211 {
1212     cairo_default_context_t *cr = abstract_cr;
1213
1214     return _cairo_gstate_set_font_matrix (cr->gstate, matrix);
1215 }
1216
1217 static void
1218 _cairo_default_context_get_font_matrix (void *abstract_cr,
1219                                         cairo_matrix_t *matrix)
1220 {
1221     cairo_default_context_t *cr = abstract_cr;
1222
1223     _cairo_gstate_get_font_matrix (cr->gstate, matrix);
1224 }
1225
1226 static cairo_status_t
1227 _cairo_default_context_set_font_options (void *abstract_cr,
1228                                          const cairo_font_options_t *options)
1229 {
1230     cairo_default_context_t *cr = abstract_cr;
1231
1232     _cairo_gstate_set_font_options (cr->gstate, options);
1233     return CAIRO_STATUS_SUCCESS;
1234 }
1235
1236 static void
1237 _cairo_default_context_get_font_options (void *abstract_cr,
1238                                          cairo_font_options_t *options)
1239 {
1240     cairo_default_context_t *cr = abstract_cr;
1241
1242     _cairo_gstate_get_font_options (cr->gstate, options);
1243 }
1244
1245 static cairo_status_t
1246 _cairo_default_context_set_scaled_font (void *abstract_cr,
1247                                         cairo_scaled_font_t *scaled_font)
1248 {
1249     cairo_default_context_t *cr = abstract_cr;
1250     cairo_bool_t was_previous;
1251     cairo_status_t status;
1252
1253     if (scaled_font == cr->gstate->scaled_font)
1254         return CAIRO_STATUS_SUCCESS;
1255
1256     was_previous = scaled_font == cr->gstate->previous_scaled_font;
1257
1258     status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
1259     if (unlikely (status))
1260         return status;
1261
1262     status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
1263     if (unlikely (status))
1264         return status;
1265
1266     _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
1267
1268     if (was_previous)
1269         cr->gstate->scaled_font = cairo_scaled_font_reference (scaled_font);
1270
1271     return CAIRO_STATUS_SUCCESS;
1272 }
1273
1274 static cairo_scaled_font_t *
1275 _cairo_default_context_get_scaled_font (void *abstract_cr)
1276 {
1277     cairo_default_context_t *cr = abstract_cr;
1278     cairo_scaled_font_t *scaled_font;
1279     cairo_status_t status;
1280
1281     status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font);
1282     if (unlikely (status))
1283         return _cairo_scaled_font_create_in_error (status);
1284
1285     return scaled_font;
1286 }
1287
1288 static cairo_status_t
1289 _cairo_default_context_glyphs (void *abstract_cr,
1290                                const cairo_glyph_t *glyphs,
1291                                int num_glyphs,
1292                                cairo_glyph_text_info_t *info)
1293 {
1294     cairo_default_context_t *cr = abstract_cr;
1295
1296     return _cairo_gstate_show_text_glyphs (cr->gstate, glyphs, num_glyphs, info);
1297 }
1298
1299 static cairo_status_t
1300 _cairo_default_context_glyph_path (void *abstract_cr,
1301                                    const cairo_glyph_t *glyphs,
1302                                    int num_glyphs)
1303 {
1304     cairo_default_context_t *cr = abstract_cr;
1305
1306     return _cairo_gstate_glyph_path (cr->gstate,
1307                                      glyphs, num_glyphs,
1308                                      cr->path);
1309 }
1310
1311 static cairo_status_t
1312 _cairo_default_context_glyph_extents (void                *abstract_cr,
1313                                       const cairo_glyph_t    *glyphs,
1314                                       int                    num_glyphs,
1315                                       cairo_text_extents_t   *extents)
1316 {
1317     cairo_default_context_t *cr = abstract_cr;
1318
1319     return _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
1320 }
1321
1322 static const cairo_backend_t _cairo_default_context_backend = {
1323     CAIRO_TYPE_DEFAULT,
1324     _cairo_default_context_destroy,
1325
1326     _cairo_default_context_get_original_target,
1327     _cairo_default_context_get_current_target,
1328
1329     _cairo_default_context_save,
1330     _cairo_default_context_restore,
1331
1332     _cairo_default_context_push_group,
1333     _cairo_default_context_pop_group,
1334
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,
1339
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,
1360
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,
1368
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,
1373
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,
1378
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,
1387     NULL, /* arc-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,
1398
1399     NULL, /* stroke-to-path */
1400
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,
1407
1408     _cairo_default_context_paint,
1409     _cairo_default_context_paint_with_alpha,
1410     _cairo_default_context_mask,
1411
1412     _cairo_default_context_stroke,
1413     _cairo_default_context_stroke_preserve,
1414     _cairo_default_context_in_stroke,
1415     _cairo_default_context_stroke_extents,
1416
1417     _cairo_default_context_fill,
1418     _cairo_default_context_fill_preserve,
1419     _cairo_default_context_in_fill,
1420     _cairo_default_context_fill_extents,
1421
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,
1432
1433     _cairo_default_context_glyphs,
1434     _cairo_default_context_glyph_path,
1435     _cairo_default_context_glyph_extents,
1436
1437     _cairo_default_context_copy_page,
1438     _cairo_default_context_show_page,
1439 };
1440
1441 cairo_status_t
1442 _cairo_default_context_init (cairo_default_context_t *cr, void *target)
1443 {
1444     _cairo_init (&cr->base, &_cairo_default_context_backend);
1445     _cairo_path_fixed_init (cr->path);
1446
1447     cr->gstate = &cr->gstate_tail[0];
1448     cr->gstate_freelist = &cr->gstate_tail[1];
1449     cr->gstate_tail[1].next = NULL;
1450
1451     return _cairo_gstate_init (cr->gstate, target);
1452 }
1453
1454 cairo_t *
1455 _cairo_default_context_create (void *target)
1456 {
1457     cairo_default_context_t *cr;
1458     cairo_status_t status;
1459
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));
1465     }
1466
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);
1471     }
1472
1473     return &cr->base;
1474 }