dc8c359a91f757a3cb28555d1c294ba73d436546
[framework/graphics/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         return pattern->status;
299
300     status = _cairo_default_context_set_source (cr, pattern);
301     cairo_pattern_destroy (pattern);
302
303     return status;
304 }
305
306 static cairo_status_t
307 _cairo_default_context_set_source_surface (void *abstract_cr,
308                                            cairo_surface_t *surface,
309                                            double          x,
310                                            double          y)
311 {
312     cairo_default_context_t *cr = abstract_cr;
313     cairo_pattern_t *pattern;
314     cairo_matrix_t matrix;
315     cairo_status_t status;
316
317     /* push the current pattern to the freed lists */
318     _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
319
320     pattern = cairo_pattern_create_for_surface (surface);
321     if (unlikely (pattern->status))
322         return pattern->status;
323
324     cairo_matrix_init_translate (&matrix, -x, -y);
325     cairo_pattern_set_matrix (pattern, &matrix);
326
327     status = _cairo_default_context_set_source (cr, pattern);
328     cairo_pattern_destroy (pattern);
329
330     return status;
331 }
332
333 static cairo_pattern_t *
334 _cairo_default_context_get_source (void *abstract_cr)
335 {
336     cairo_default_context_t *cr = abstract_cr;
337
338     return _cairo_gstate_get_source (cr->gstate);
339 }
340
341 static cairo_status_t
342 _cairo_default_context_set_tolerance (void *abstract_cr,
343                                       double tolerance)
344 {
345     cairo_default_context_t *cr = abstract_cr;
346
347     if (tolerance < CAIRO_TOLERANCE_MINIMUM)
348         tolerance = CAIRO_TOLERANCE_MINIMUM;
349
350     return _cairo_gstate_set_tolerance (cr->gstate, tolerance);
351 }
352
353 static cairo_status_t
354 _cairo_default_context_set_operator (void *abstract_cr, cairo_operator_t op)
355 {
356     cairo_default_context_t *cr = abstract_cr;
357
358     return _cairo_gstate_set_operator (cr->gstate, op);
359 }
360
361 static cairo_status_t
362 _cairo_default_context_set_opacity (void *abstract_cr, double opacity)
363 {
364     cairo_default_context_t *cr = abstract_cr;
365
366     return _cairo_gstate_set_opacity (cr->gstate, opacity);
367 }
368
369 static cairo_status_t
370 _cairo_default_context_set_antialias (void *abstract_cr,
371                                       cairo_antialias_t antialias)
372 {
373     cairo_default_context_t *cr = abstract_cr;
374
375     return _cairo_gstate_set_antialias (cr->gstate, antialias);
376 }
377
378 static cairo_status_t
379 _cairo_default_context_set_fill_rule (void *abstract_cr,
380                                       cairo_fill_rule_t fill_rule)
381 {
382     cairo_default_context_t *cr = abstract_cr;
383
384     return _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
385 }
386
387 static cairo_status_t
388 _cairo_default_context_set_line_width (void *abstract_cr,
389                                        double line_width)
390 {
391     cairo_default_context_t *cr = abstract_cr;
392
393     return _cairo_gstate_set_line_width (cr->gstate, line_width);
394 }
395
396 static cairo_status_t
397 _cairo_default_context_set_line_cap (void *abstract_cr,
398                                      cairo_line_cap_t line_cap)
399 {
400     cairo_default_context_t *cr = abstract_cr;
401
402     return _cairo_gstate_set_line_cap (cr->gstate, line_cap);
403 }
404
405 static cairo_status_t
406 _cairo_default_context_set_line_join (void *abstract_cr,
407                                       cairo_line_join_t line_join)
408 {
409     cairo_default_context_t *cr = abstract_cr;
410
411     return _cairo_gstate_set_line_join (cr->gstate, line_join);
412 }
413
414 static cairo_status_t
415 _cairo_default_context_set_dash (void *abstract_cr,
416                                  const double *dashes,
417                                  int          num_dashes,
418                                  double       offset)
419 {
420     cairo_default_context_t *cr = abstract_cr;
421
422     return _cairo_gstate_set_dash (cr->gstate,
423                                    dashes, num_dashes, offset);
424 }
425
426 static cairo_status_t
427 _cairo_default_context_set_miter_limit (void *abstract_cr,
428                                         double limit)
429 {
430     cairo_default_context_t *cr = abstract_cr;
431
432     return _cairo_gstate_set_miter_limit (cr->gstate, limit);
433 }
434
435 static cairo_antialias_t
436 _cairo_default_context_get_antialias (void *abstract_cr)
437 {
438     cairo_default_context_t *cr = abstract_cr;
439
440     return _cairo_gstate_get_antialias (cr->gstate);
441 }
442
443 static void
444 _cairo_default_context_get_dash (void *abstract_cr,
445                                  double *dashes,
446                                  int *num_dashes,
447                                  double *offset)
448 {
449     cairo_default_context_t *cr = abstract_cr;
450
451     _cairo_gstate_get_dash (cr->gstate, dashes, num_dashes, offset);
452 }
453
454 static cairo_fill_rule_t
455 _cairo_default_context_get_fill_rule (void *abstract_cr)
456 {
457     cairo_default_context_t *cr = abstract_cr;
458
459     return _cairo_gstate_get_fill_rule (cr->gstate);
460 }
461
462 static double
463 _cairo_default_context_get_line_width (void *abstract_cr)
464 {
465     cairo_default_context_t *cr = abstract_cr;
466
467     return _cairo_gstate_get_line_width (cr->gstate);
468 }
469
470 static cairo_line_cap_t
471 _cairo_default_context_get_line_cap (void *abstract_cr)
472 {
473     cairo_default_context_t *cr = abstract_cr;
474
475     return _cairo_gstate_get_line_cap (cr->gstate);
476 }
477
478 static cairo_line_join_t
479 _cairo_default_context_get_line_join (void *abstract_cr)
480 {
481     cairo_default_context_t *cr = abstract_cr;
482
483     return _cairo_gstate_get_line_join (cr->gstate);
484 }
485
486 static double
487 _cairo_default_context_get_miter_limit (void *abstract_cr)
488 {
489     cairo_default_context_t *cr = abstract_cr;
490
491     return _cairo_gstate_get_miter_limit (cr->gstate);
492 }
493
494 static cairo_operator_t
495 _cairo_default_context_get_operator (void *abstract_cr)
496 {
497     cairo_default_context_t *cr = abstract_cr;
498
499     return _cairo_gstate_get_operator (cr->gstate);
500 }
501
502 static double
503 _cairo_default_context_get_opacity (void *abstract_cr)
504 {
505     cairo_default_context_t *cr = abstract_cr;
506
507     return _cairo_gstate_get_opacity (cr->gstate);
508 }
509
510 static double
511 _cairo_default_context_get_tolerance (void *abstract_cr)
512 {
513     cairo_default_context_t *cr = abstract_cr;
514
515     return _cairo_gstate_get_tolerance (cr->gstate);
516 }
517
518
519 /* Current tranformation matrix */
520
521 static cairo_status_t
522 _cairo_default_context_translate (void *abstract_cr,
523                                   double tx,
524                                   double ty)
525 {
526     cairo_default_context_t *cr = abstract_cr;
527
528     return _cairo_gstate_translate (cr->gstate, tx, ty);
529 }
530
531 static cairo_status_t
532 _cairo_default_context_scale (void *abstract_cr,
533                               double sx,
534                               double sy)
535 {
536     cairo_default_context_t *cr = abstract_cr;
537
538     return _cairo_gstate_scale (cr->gstate, sx, sy);
539 }
540
541 static cairo_status_t
542 _cairo_default_context_rotate (void *abstract_cr,
543                                double theta)
544 {
545     cairo_default_context_t *cr = abstract_cr;
546
547     return _cairo_gstate_rotate (cr->gstate, theta);
548 }
549
550 static cairo_status_t
551 _cairo_default_context_transform (void *abstract_cr,
552                                   const cairo_matrix_t *matrix)
553 {
554     cairo_default_context_t *cr = abstract_cr;
555
556     return _cairo_gstate_transform (cr->gstate, matrix);
557 }
558
559 static cairo_status_t
560 _cairo_default_context_set_matrix (void *abstract_cr,
561                                    const cairo_matrix_t *matrix)
562 {
563     cairo_default_context_t *cr = abstract_cr;
564
565     return _cairo_gstate_set_matrix (cr->gstate, matrix);
566 }
567
568 static cairo_status_t
569 _cairo_default_context_set_identity_matrix (void *abstract_cr)
570 {
571     cairo_default_context_t *cr = abstract_cr;
572
573     _cairo_gstate_identity_matrix (cr->gstate);
574     return CAIRO_STATUS_SUCCESS;
575 }
576
577 static void
578 _cairo_default_context_get_matrix (void *abstract_cr,
579                                    cairo_matrix_t *matrix)
580 {
581     cairo_default_context_t *cr = abstract_cr;
582
583     _cairo_gstate_get_matrix (cr->gstate, matrix);
584 }
585
586 static void
587 _cairo_default_context_user_to_device (void *abstract_cr,
588                                        double *x,
589                                        double *y)
590 {
591     cairo_default_context_t *cr = abstract_cr;
592
593     _cairo_gstate_user_to_device (cr->gstate, x, y);
594 }
595
596 static void
597 _cairo_default_context_user_to_device_distance (void *abstract_cr, double *dx, double *dy)
598 {
599     cairo_default_context_t *cr = abstract_cr;
600
601     _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
602 }
603
604 static void
605 _cairo_default_context_device_to_user (void *abstract_cr,
606                                        double *x,
607                                        double *y)
608 {
609     cairo_default_context_t *cr = abstract_cr;
610
611     _cairo_gstate_device_to_user (cr->gstate, x, y);
612 }
613
614 static void
615 _cairo_default_context_device_to_user_distance (void *abstract_cr,
616                                                 double *dx,
617                                                 double *dy)
618 {
619     cairo_default_context_t *cr = abstract_cr;
620
621     _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
622 }
623
624 /* Path constructor */
625
626 static cairo_status_t
627 _cairo_default_context_new_path (void *abstract_cr)
628 {
629     cairo_default_context_t *cr = abstract_cr;
630
631     _cairo_path_fixed_fini (cr->path);
632     _cairo_path_fixed_init (cr->path);
633
634     return CAIRO_STATUS_SUCCESS;
635 }
636
637 static cairo_status_t
638 _cairo_default_context_new_sub_path (void *abstract_cr)
639 {
640     cairo_default_context_t *cr = abstract_cr;
641
642     _cairo_path_fixed_new_sub_path (cr->path);
643
644     return CAIRO_STATUS_SUCCESS;
645 }
646
647 static cairo_status_t
648 _cairo_default_context_move_to (void *abstract_cr, double x, double y)
649 {
650     cairo_default_context_t *cr = abstract_cr;
651     cairo_fixed_t x_fixed, y_fixed;
652
653     _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
654     x_fixed = _cairo_fixed_from_double (x);
655     y_fixed = _cairo_fixed_from_double (y);
656
657     return _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed);
658 }
659
660 static cairo_status_t
661 _cairo_default_context_line_to (void *abstract_cr, double x, double y)
662 {
663     cairo_default_context_t *cr = abstract_cr;
664     cairo_fixed_t x_fixed, y_fixed;
665
666     _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
667     x_fixed = _cairo_fixed_from_double (x);
668     y_fixed = _cairo_fixed_from_double (y);
669
670     return _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
671 }
672
673 static cairo_status_t
674 _cairo_default_context_curve_to (void *abstract_cr,
675                                  double x1, double y1,
676                                  double x2, double y2,
677                                  double x3, double y3)
678 {
679     cairo_default_context_t *cr = abstract_cr;
680     cairo_fixed_t x1_fixed, y1_fixed;
681     cairo_fixed_t x2_fixed, y2_fixed;
682     cairo_fixed_t x3_fixed, y3_fixed;
683
684     _cairo_gstate_user_to_backend (cr->gstate, &x1, &y1);
685     _cairo_gstate_user_to_backend (cr->gstate, &x2, &y2);
686     _cairo_gstate_user_to_backend (cr->gstate, &x3, &y3);
687
688     x1_fixed = _cairo_fixed_from_double (x1);
689     y1_fixed = _cairo_fixed_from_double (y1);
690
691     x2_fixed = _cairo_fixed_from_double (x2);
692     y2_fixed = _cairo_fixed_from_double (y2);
693
694     x3_fixed = _cairo_fixed_from_double (x3);
695     y3_fixed = _cairo_fixed_from_double (y3);
696
697     return _cairo_path_fixed_curve_to (cr->path,
698                                        x1_fixed, y1_fixed,
699                                        x2_fixed, y2_fixed,
700                                        x3_fixed, y3_fixed);
701 }
702
703 static cairo_status_t
704 _cairo_default_context_arc (void *abstract_cr,
705                             double xc, double yc, double radius,
706                             double angle1, double angle2,
707                             cairo_bool_t forward)
708 {
709     cairo_default_context_t *cr = abstract_cr;
710     cairo_status_t status;
711
712     /* Do nothing, successfully, if radius is <= 0 */
713     if (radius <= 0.0) {
714         cairo_fixed_t x_fixed, y_fixed;
715
716         _cairo_gstate_user_to_backend (cr->gstate, &xc, &yc);
717         x_fixed = _cairo_fixed_from_double (xc);
718         y_fixed = _cairo_fixed_from_double (yc);
719         status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
720         if (unlikely (status))
721             return status;
722
723         status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
724         if (unlikely (status))
725             return status;
726
727         return CAIRO_STATUS_SUCCESS;
728     }
729
730     status = _cairo_default_context_line_to (cr,
731                                              xc + radius * cos (angle1),
732                                              yc + radius * sin (angle1));
733
734     if (unlikely (status))
735         return status;
736
737     if (forward)
738         _cairo_arc_path (&cr->base, xc, yc, radius, angle1, angle2);
739     else
740         _cairo_arc_path_negative (&cr->base, xc, yc, radius, angle1, angle2);
741
742     return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */
743 }
744
745 static cairo_status_t
746 _cairo_default_context_rel_move_to (void *abstract_cr, double dx, double dy)
747 {
748     cairo_default_context_t *cr = abstract_cr;
749     cairo_fixed_t dx_fixed, dy_fixed;
750
751     _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
752
753     dx_fixed = _cairo_fixed_from_double (dx);
754     dy_fixed = _cairo_fixed_from_double (dy);
755
756     return _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
757 }
758
759 static cairo_status_t
760 _cairo_default_context_rel_line_to (void *abstract_cr, double dx, double dy)
761 {
762     cairo_default_context_t *cr = abstract_cr;
763     cairo_fixed_t dx_fixed, dy_fixed;
764
765     _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
766
767     dx_fixed = _cairo_fixed_from_double (dx);
768     dy_fixed = _cairo_fixed_from_double (dy);
769
770     return _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
771 }
772
773
774 static cairo_status_t
775 _cairo_default_context_rel_curve_to (void *abstract_cr,
776                                      double dx1, double dy1,
777                                      double dx2, double dy2,
778                                      double dx3, double dy3)
779 {
780     cairo_default_context_t *cr = abstract_cr;
781     cairo_fixed_t dx1_fixed, dy1_fixed;
782     cairo_fixed_t dx2_fixed, dy2_fixed;
783     cairo_fixed_t dx3_fixed, dy3_fixed;
784
785     _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1);
786     _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2);
787     _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3);
788
789     dx1_fixed = _cairo_fixed_from_double (dx1);
790     dy1_fixed = _cairo_fixed_from_double (dy1);
791
792     dx2_fixed = _cairo_fixed_from_double (dx2);
793     dy2_fixed = _cairo_fixed_from_double (dy2);
794
795     dx3_fixed = _cairo_fixed_from_double (dx3);
796     dy3_fixed = _cairo_fixed_from_double (dy3);
797
798     return _cairo_path_fixed_rel_curve_to (cr->path,
799                                            dx1_fixed, dy1_fixed,
800                                            dx2_fixed, dy2_fixed,
801                                            dx3_fixed, dy3_fixed);
802 }
803
804 static cairo_status_t
805 _cairo_default_context_close_path (void *abstract_cr)
806 {
807     cairo_default_context_t *cr = abstract_cr;
808
809     return _cairo_path_fixed_close_path (cr->path);
810 }
811
812 static cairo_status_t
813 _cairo_default_context_rectangle (void *abstract_cr,
814                                   double x, double y,
815                                   double width, double height)
816 {
817     cairo_default_context_t *cr = abstract_cr;
818     cairo_status_t status;
819
820     status = _cairo_default_context_move_to (cr, x, y);
821     if (unlikely (status))
822         return status;
823
824     status = _cairo_default_context_rel_line_to (cr, width, 0);
825     if (unlikely (status))
826         return status;
827
828     status = _cairo_default_context_rel_line_to (cr, 0, height);
829     if (unlikely (status))
830         return status;
831
832     status = _cairo_default_context_rel_line_to (cr, -width, 0);
833     if (unlikely (status))
834         return status;
835
836     return _cairo_default_context_close_path (cr);
837 }
838
839 static void
840 _cairo_default_context_path_extents (void *abstract_cr,
841                                      double *x1,
842                                      double *y1,
843                                      double *x2,
844                                      double *y2)
845 {
846     cairo_default_context_t *cr = abstract_cr;
847
848     _cairo_gstate_path_extents (cr->gstate,
849                                 cr->path,
850                                 x1, y1, x2, y2);
851 }
852
853 static cairo_bool_t
854 _cairo_default_context_has_current_point (void *abstract_cr)
855 {
856     cairo_default_context_t *cr = abstract_cr;
857
858     return cr->path->has_current_point;
859 }
860
861 static cairo_bool_t
862 _cairo_default_context_get_current_point (void *abstract_cr,
863                                           double *x,
864                                           double *y)
865 {
866     cairo_default_context_t *cr = abstract_cr;
867     cairo_fixed_t x_fixed, y_fixed;
868
869     if (_cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed))
870     {
871         *x = _cairo_fixed_to_double (x_fixed);
872         *y = _cairo_fixed_to_double (y_fixed);
873         _cairo_gstate_backend_to_user (cr->gstate, x, y);
874
875         return TRUE;
876     }
877     else
878     {
879         return FALSE;
880     }
881 }
882
883 static cairo_path_t *
884 _cairo_default_context_copy_path (void *abstract_cr)
885 {
886     cairo_default_context_t *cr = abstract_cr;
887
888     return _cairo_path_create (cr->path, &cr->base);
889 }
890
891 static cairo_path_t *
892 _cairo_default_context_copy_path_flat (void *abstract_cr)
893 {
894     cairo_default_context_t *cr = abstract_cr;
895
896     return _cairo_path_create_flat (cr->path, &cr->base);
897 }
898
899 static cairo_status_t
900 _cairo_default_context_append_path (void *abstract_cr,
901                                     const cairo_path_t *path)
902 {
903     cairo_default_context_t *cr = abstract_cr;
904
905     return _cairo_path_append_to_context (path, &cr->base);
906 }
907
908 static cairo_status_t
909 _cairo_default_context_paint (void *abstract_cr)
910 {
911     cairo_default_context_t *cr = abstract_cr;
912
913     return _cairo_gstate_paint (cr->gstate);
914 }
915
916 static cairo_status_t
917 _cairo_default_context_paint_with_alpha (void *abstract_cr,
918                                          double alpha)
919 {
920     cairo_default_context_t *cr = abstract_cr;
921     cairo_solid_pattern_t pattern;
922     cairo_status_t status;
923     cairo_color_t color;
924
925     if (CAIRO_ALPHA_IS_OPAQUE (alpha))
926         return _cairo_gstate_paint (cr->gstate);
927
928     if (CAIRO_ALPHA_IS_ZERO (alpha) &&
929         _cairo_operator_bounded_by_mask (cr->gstate->op)) {
930         return CAIRO_STATUS_SUCCESS;
931     }
932
933     _cairo_color_init_rgba (&color, 0., 0., 0., alpha);
934     _cairo_pattern_init_solid (&pattern, &color);
935
936     status = _cairo_gstate_mask (cr->gstate, &pattern.base);
937     _cairo_pattern_fini (&pattern.base);
938
939     return status;
940 }
941
942 static cairo_status_t
943 _cairo_default_context_mask (void *abstract_cr,
944                              cairo_pattern_t *mask)
945 {
946     cairo_default_context_t *cr = abstract_cr;
947
948     return _cairo_gstate_mask (cr->gstate, mask);
949 }
950
951 static cairo_status_t
952 _cairo_default_context_stroke_preserve (void *abstract_cr)
953 {
954     cairo_default_context_t *cr = abstract_cr;
955
956     return _cairo_gstate_stroke (cr->gstate, cr->path);
957 }
958
959 static cairo_status_t
960 _cairo_default_context_stroke (void *abstract_cr)
961 {
962     cairo_default_context_t *cr = abstract_cr;
963     cairo_status_t status;
964
965     status = _cairo_gstate_stroke (cr->gstate, cr->path);
966     if (unlikely (status))
967         return status;
968
969     return _cairo_default_context_new_path (cr);
970 }
971
972 static cairo_status_t
973 _cairo_default_context_in_stroke (void *abstract_cr,
974                                   double x, double y,
975                                   cairo_bool_t *inside)
976 {
977     cairo_default_context_t *cr = abstract_cr;
978
979     return _cairo_gstate_in_stroke (cr->gstate,
980                                     cr->path,
981                                     x, y,
982                                     inside);
983 }
984
985 static cairo_status_t
986 _cairo_default_context_stroke_extents (void *abstract_cr,
987                                        double *x1, double *y1, double *x2, double *y2)
988 {
989     cairo_default_context_t *cr = abstract_cr;
990
991     return _cairo_gstate_stroke_extents (cr->gstate,
992                                          cr->path,
993                                          x1, y1, x2, y2);
994 }
995
996 static cairo_status_t
997 _cairo_default_context_fill_preserve (void *abstract_cr)
998 {
999     cairo_default_context_t *cr = abstract_cr;
1000
1001     return _cairo_gstate_fill (cr->gstate, cr->path);
1002 }
1003
1004 static cairo_status_t
1005 _cairo_default_context_fill (void *abstract_cr)
1006 {
1007     cairo_default_context_t *cr = abstract_cr;
1008     cairo_status_t status;
1009
1010     status = _cairo_gstate_fill (cr->gstate, cr->path);
1011     if (unlikely (status))
1012         return status;
1013
1014     return _cairo_default_context_new_path (cr);
1015 }
1016
1017 static cairo_status_t
1018 _cairo_default_context_in_fill (void *abstract_cr,
1019                                 double x, double y,
1020                                 cairo_bool_t *inside)
1021 {
1022     cairo_default_context_t *cr = abstract_cr;
1023
1024     *inside = _cairo_gstate_in_fill (cr->gstate,
1025                                      cr->path,
1026                                      x, y);
1027     return CAIRO_STATUS_SUCCESS;
1028 }
1029
1030 static cairo_status_t
1031 _cairo_default_context_fill_extents (void *abstract_cr,
1032                                      double *x1, double *y1, double *x2, double *y2)
1033 {
1034     cairo_default_context_t *cr = abstract_cr;
1035
1036     return _cairo_gstate_fill_extents (cr->gstate,
1037                                        cr->path,
1038                                        x1, y1, x2, y2);
1039 }
1040
1041 static cairo_status_t
1042 _cairo_default_context_clip_preserve (void *abstract_cr)
1043 {
1044     cairo_default_context_t *cr = abstract_cr;
1045
1046     return _cairo_gstate_clip (cr->gstate, cr->path);
1047 }
1048
1049 static cairo_status_t
1050 _cairo_default_context_clip (void *abstract_cr)
1051 {
1052     cairo_default_context_t *cr = abstract_cr;
1053     cairo_status_t status;
1054
1055     status = _cairo_gstate_clip (cr->gstate, cr->path);
1056     if (unlikely (status))
1057         return status;
1058
1059     return _cairo_default_context_new_path (cr);
1060 }
1061
1062 static cairo_status_t
1063 _cairo_default_context_in_clip (void *abstract_cr,
1064                                 double x, double y,
1065                                 cairo_bool_t *inside)
1066 {
1067     cairo_default_context_t *cr = abstract_cr;
1068
1069     *inside = _cairo_gstate_in_clip (cr->gstate, x, y);
1070     return CAIRO_STATUS_SUCCESS;
1071 }
1072
1073 static cairo_status_t
1074 _cairo_default_context_reset_clip (void *abstract_cr)
1075 {
1076     cairo_default_context_t *cr = abstract_cr;
1077
1078     return _cairo_gstate_reset_clip (cr->gstate);
1079 }
1080
1081 static cairo_status_t
1082 _cairo_default_context_clip_extents (void *abstract_cr,
1083                                      double *x1, double *y1, double *x2, double *y2)
1084 {
1085     cairo_default_context_t *cr = abstract_cr;
1086
1087     if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) {
1088         *x1 = -INFINITY;
1089         *y1 = -INFINITY;
1090         *x2 = +INFINITY;
1091         *y2 = +INFINITY;
1092     }
1093
1094     return CAIRO_STATUS_SUCCESS;
1095 }
1096
1097 static cairo_rectangle_list_t *
1098 _cairo_default_context_copy_clip_rectangle_list (void *abstract_cr)
1099 {
1100     cairo_default_context_t *cr = abstract_cr;
1101
1102     return _cairo_gstate_copy_clip_rectangle_list (cr->gstate);
1103 }
1104
1105 static cairo_status_t
1106 _cairo_default_context_copy_page (void *abstract_cr)
1107 {
1108     cairo_default_context_t *cr = abstract_cr;
1109
1110     return _cairo_gstate_copy_page (cr->gstate);
1111 }
1112
1113 static cairo_status_t
1114 _cairo_default_context_show_page (void *abstract_cr)
1115 {
1116     cairo_default_context_t *cr = abstract_cr;
1117
1118     return _cairo_gstate_show_page (cr->gstate);
1119 }
1120
1121 static cairo_status_t
1122 _cairo_default_context_set_font_face (void *abstract_cr,
1123                                       cairo_font_face_t *font_face)
1124 {
1125     cairo_default_context_t *cr = abstract_cr;
1126
1127     return _cairo_gstate_set_font_face (cr->gstate, font_face);
1128 }
1129
1130 static cairo_font_face_t *
1131 _cairo_default_context_get_font_face (void *abstract_cr)
1132 {
1133     cairo_default_context_t *cr = abstract_cr;
1134     cairo_font_face_t *font_face;
1135     cairo_status_t status;
1136
1137     status = _cairo_gstate_get_font_face (cr->gstate, &font_face);
1138     if (unlikely (status)) {
1139         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
1140         return (cairo_font_face_t *) &_cairo_font_face_nil;
1141     }
1142
1143     return font_face;
1144 }
1145
1146 static cairo_status_t
1147 _cairo_default_context_font_extents (void *abstract_cr,
1148                                      cairo_font_extents_t *extents)
1149 {
1150     cairo_default_context_t *cr = abstract_cr;
1151
1152     return _cairo_gstate_get_font_extents (cr->gstate, extents);
1153 }
1154
1155 static cairo_status_t
1156 _cairo_default_context_set_font_size (void *abstract_cr,
1157                                       double size)
1158 {
1159     cairo_default_context_t *cr = abstract_cr;
1160
1161     return _cairo_gstate_set_font_size (cr->gstate, size);
1162 }
1163
1164 static cairo_status_t
1165 _cairo_default_context_set_font_matrix (void *abstract_cr,
1166                                         const cairo_matrix_t *matrix)
1167 {
1168     cairo_default_context_t *cr = abstract_cr;
1169
1170     return _cairo_gstate_set_font_matrix (cr->gstate, matrix);
1171 }
1172
1173 static void
1174 _cairo_default_context_get_font_matrix (void *abstract_cr,
1175                                         cairo_matrix_t *matrix)
1176 {
1177     cairo_default_context_t *cr = abstract_cr;
1178
1179     _cairo_gstate_get_font_matrix (cr->gstate, matrix);
1180 }
1181
1182 static cairo_status_t
1183 _cairo_default_context_set_font_options (void *abstract_cr,
1184                                          const cairo_font_options_t *options)
1185 {
1186     cairo_default_context_t *cr = abstract_cr;
1187
1188     _cairo_gstate_set_font_options (cr->gstate, options);
1189     return CAIRO_STATUS_SUCCESS;
1190 }
1191
1192 static void
1193 _cairo_default_context_get_font_options (void *abstract_cr,
1194                                          cairo_font_options_t *options)
1195 {
1196     cairo_default_context_t *cr = abstract_cr;
1197
1198     _cairo_gstate_get_font_options (cr->gstate, options);
1199 }
1200
1201 static cairo_status_t
1202 _cairo_default_context_set_scaled_font (void *abstract_cr,
1203                                         cairo_scaled_font_t *scaled_font)
1204 {
1205     cairo_default_context_t *cr = abstract_cr;
1206     cairo_bool_t was_previous;
1207     cairo_status_t status;
1208
1209     if (scaled_font == cr->gstate->scaled_font)
1210         return CAIRO_STATUS_SUCCESS;
1211
1212     was_previous = scaled_font == cr->gstate->previous_scaled_font;
1213
1214     status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
1215     if (unlikely (status))
1216         return status;
1217
1218     status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
1219     if (unlikely (status))
1220         return status;
1221
1222     _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
1223
1224     if (was_previous)
1225         cr->gstate->scaled_font = cairo_scaled_font_reference (scaled_font);
1226
1227     return CAIRO_STATUS_SUCCESS;
1228 }
1229
1230 static cairo_scaled_font_t *
1231 _cairo_default_context_get_scaled_font (void *abstract_cr)
1232 {
1233     cairo_default_context_t *cr = abstract_cr;
1234     cairo_scaled_font_t *scaled_font;
1235     cairo_status_t status;
1236
1237     status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font);
1238     if (unlikely (status))
1239         return _cairo_scaled_font_create_in_error (status);
1240
1241     return scaled_font;
1242 }
1243
1244 static cairo_status_t
1245 _cairo_default_context_glyphs (void *abstract_cr,
1246                                const cairo_glyph_t *glyphs,
1247                                int num_glyphs,
1248                                cairo_glyph_text_info_t *info)
1249 {
1250     cairo_default_context_t *cr = abstract_cr;
1251
1252     return _cairo_gstate_show_text_glyphs (cr->gstate, glyphs, num_glyphs, info);
1253 }
1254
1255 static cairo_status_t
1256 _cairo_default_context_glyph_path (void *abstract_cr,
1257                                    const cairo_glyph_t *glyphs,
1258                                    int num_glyphs)
1259 {
1260     cairo_default_context_t *cr = abstract_cr;
1261
1262     return _cairo_gstate_glyph_path (cr->gstate,
1263                                      glyphs, num_glyphs,
1264                                      cr->path);
1265 }
1266
1267 static cairo_status_t
1268 _cairo_default_context_glyph_extents (void                *abstract_cr,
1269                                       const cairo_glyph_t    *glyphs,
1270                                       int                    num_glyphs,
1271                                       cairo_text_extents_t   *extents)
1272 {
1273     cairo_default_context_t *cr = abstract_cr;
1274
1275     return _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
1276 }
1277
1278 static const cairo_backend_t _cairo_default_context_backend = {
1279     CAIRO_TYPE_DEFAULT,
1280     _cairo_default_context_destroy,
1281
1282     _cairo_default_context_get_original_target,
1283     _cairo_default_context_get_current_target,
1284
1285     _cairo_default_context_save,
1286     _cairo_default_context_restore,
1287
1288     _cairo_default_context_push_group,
1289     _cairo_default_context_pop_group,
1290
1291     _cairo_default_context_set_source_rgba,
1292     _cairo_default_context_set_source_surface,
1293     _cairo_default_context_set_source,
1294     _cairo_default_context_get_source,
1295
1296     _cairo_default_context_set_antialias,
1297     _cairo_default_context_set_dash,
1298     _cairo_default_context_set_fill_rule,
1299     _cairo_default_context_set_line_cap,
1300     _cairo_default_context_set_line_join,
1301     _cairo_default_context_set_line_width,
1302     _cairo_default_context_set_miter_limit,
1303     _cairo_default_context_set_opacity,
1304     _cairo_default_context_set_operator,
1305     _cairo_default_context_set_tolerance,
1306     _cairo_default_context_get_antialias,
1307     _cairo_default_context_get_dash,
1308     _cairo_default_context_get_fill_rule,
1309     _cairo_default_context_get_line_cap,
1310     _cairo_default_context_get_line_join,
1311     _cairo_default_context_get_line_width,
1312     _cairo_default_context_get_miter_limit,
1313     _cairo_default_context_get_opacity,
1314     _cairo_default_context_get_operator,
1315     _cairo_default_context_get_tolerance,
1316
1317     _cairo_default_context_translate,
1318     _cairo_default_context_scale,
1319     _cairo_default_context_rotate,
1320     _cairo_default_context_transform,
1321     _cairo_default_context_set_matrix,
1322     _cairo_default_context_set_identity_matrix,
1323     _cairo_default_context_get_matrix,
1324     _cairo_default_context_user_to_device,
1325     _cairo_default_context_user_to_device_distance,
1326     _cairo_default_context_device_to_user,
1327     _cairo_default_context_device_to_user_distance,
1328
1329     _cairo_default_context_new_path,
1330     _cairo_default_context_new_sub_path,
1331     _cairo_default_context_move_to,
1332     _cairo_default_context_rel_move_to,
1333     _cairo_default_context_line_to,
1334     _cairo_default_context_rel_line_to,
1335     _cairo_default_context_curve_to,
1336     _cairo_default_context_rel_curve_to,
1337     NULL, /* arc-to */
1338     NULL, /* rel-arc-to */
1339     _cairo_default_context_close_path,
1340     _cairo_default_context_arc,
1341     _cairo_default_context_rectangle,
1342     _cairo_default_context_path_extents,
1343     _cairo_default_context_has_current_point,
1344     _cairo_default_context_get_current_point,
1345     _cairo_default_context_copy_path,
1346     _cairo_default_context_copy_path_flat,
1347     _cairo_default_context_append_path,
1348
1349     NULL, /* stroke-to-path */
1350
1351     _cairo_default_context_clip,
1352     _cairo_default_context_clip_preserve,
1353     _cairo_default_context_in_clip,
1354     _cairo_default_context_clip_extents,
1355     _cairo_default_context_reset_clip,
1356     _cairo_default_context_copy_clip_rectangle_list,
1357
1358     _cairo_default_context_paint,
1359     _cairo_default_context_paint_with_alpha,
1360     _cairo_default_context_mask,
1361
1362     _cairo_default_context_stroke,
1363     _cairo_default_context_stroke_preserve,
1364     _cairo_default_context_in_stroke,
1365     _cairo_default_context_stroke_extents,
1366
1367     _cairo_default_context_fill,
1368     _cairo_default_context_fill_preserve,
1369     _cairo_default_context_in_fill,
1370     _cairo_default_context_fill_extents,
1371
1372     _cairo_default_context_set_font_face,
1373     _cairo_default_context_get_font_face,
1374     _cairo_default_context_set_font_size,
1375     _cairo_default_context_set_font_matrix,
1376     _cairo_default_context_get_font_matrix,
1377     _cairo_default_context_set_font_options,
1378     _cairo_default_context_get_font_options,
1379     _cairo_default_context_set_scaled_font,
1380     _cairo_default_context_get_scaled_font,
1381     _cairo_default_context_font_extents,
1382
1383     _cairo_default_context_glyphs,
1384     _cairo_default_context_glyph_path,
1385     _cairo_default_context_glyph_extents,
1386
1387     _cairo_default_context_copy_page,
1388     _cairo_default_context_show_page,
1389 };
1390
1391 cairo_status_t
1392 _cairo_default_context_init (cairo_default_context_t *cr, void *target)
1393 {
1394     _cairo_init (&cr->base, &_cairo_default_context_backend);
1395     _cairo_path_fixed_init (cr->path);
1396
1397     cr->gstate = &cr->gstate_tail[0];
1398     cr->gstate_freelist = &cr->gstate_tail[1];
1399     cr->gstate_tail[1].next = NULL;
1400
1401     return _cairo_gstate_init (cr->gstate, target);
1402 }
1403
1404 cairo_t *
1405 _cairo_default_context_create (void *target)
1406 {
1407     cairo_default_context_t *cr;
1408     cairo_status_t status;
1409
1410     cr = _freed_pool_get (&context_pool);
1411     if (unlikely (cr == NULL)) {
1412         cr = malloc (sizeof (cairo_default_context_t));
1413         if (unlikely (cr == NULL))
1414             return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
1415     }
1416
1417     status = _cairo_default_context_init (cr, target);
1418     if (unlikely (status)) {
1419         _freed_pool_put (&context_pool, cr);
1420         return _cairo_create_in_error (status);
1421     }
1422
1423     return &cr->base;
1424 }