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
608
_cairo_default_context_reset_static_data (void)
63
{
64
608
    _freed_pool_reset (&context_pool);
65
608
}
66

            
67
void
68
34927
_cairo_default_context_fini (cairo_default_context_t *cr)
69
{
70
34935
    while (cr->gstate != &cr->gstate_tail[0]) {
71
8
	if (_cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist))
72
	    break;
73
    }
74

            
75
34927
    _cairo_gstate_fini (cr->gstate);
76
34927
    cr->gstate_freelist = cr->gstate_freelist->next; /* skip over tail[1] */
77
36478
    while (cr->gstate_freelist != NULL) {
78
1551
	cairo_gstate_t *gstate = cr->gstate_freelist;
79
1551
	cr->gstate_freelist = gstate->next;
80
1551
	free (gstate);
81
    }
82

            
83
34927
    _cairo_path_fixed_fini (cr->path);
84

            
85
34927
    _cairo_fini (&cr->base);
86
34927
}
87

            
88
static void
89
34927
_cairo_default_context_destroy (void *abstract_cr)
90
{
91
34927
    cairo_default_context_t *cr = abstract_cr;
92

            
93
34927
    _cairo_default_context_fini (cr);
94

            
95
    /* mark the context as invalid to protect against misuse */
96
34927
    cr->base.status = CAIRO_STATUS_NULL_POINTER;
97
34927
    _freed_pool_put (&context_pool, cr);
98
34927
}
99

            
100
static cairo_surface_t *
101
47993
_cairo_default_context_get_original_target (void *abstract_cr)
102
{
103
47993
    cairo_default_context_t *cr = abstract_cr;
104

            
105
47993
    return _cairo_gstate_get_original_target (cr->gstate);
106
}
107

            
108
static cairo_surface_t *
109
531
_cairo_default_context_get_current_target (void *abstract_cr)
110
{
111
531
    cairo_default_context_t *cr = abstract_cr;
112

            
113
531
    return _cairo_gstate_get_target (cr->gstate);
114
}
115

            
116
static cairo_status_t
117
65241
_cairo_default_context_save (void *abstract_cr)
118
{
119
65241
    cairo_default_context_t *cr = abstract_cr;
120

            
121
65241
    return _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
122
}
123

            
124
static cairo_status_t
125
65239
_cairo_default_context_restore (void *abstract_cr)
126
{
127
65239
    cairo_default_context_t *cr = abstract_cr;
128

            
129
65239
    if (unlikely (_cairo_gstate_is_group (cr->gstate)))
130
1
	return _cairo_error (CAIRO_STATUS_INVALID_RESTORE);
131

            
132
65238
    return _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
133
}
134

            
135
static cairo_status_t
136
659
_cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
137
{
138
659
    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
659
    clip = _cairo_gstate_get_clip (cr->gstate);
144
659
    if (_cairo_clip_is_all_clipped (clip)) {
145
6
	group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
146
6
	status = group_surface->status;
147
6
	if (unlikely (status))
148
	    goto bail;
149
    } else {
150
	cairo_surface_t *parent_surface;
151
	cairo_rectangle_int_t extents;
152
	cairo_bool_t bounded, is_empty;
153

            
154
653
	parent_surface = _cairo_gstate_get_target (cr->gstate);
155

            
156
653
	if (unlikely (parent_surface->status))
157
12
	    return parent_surface->status;
158
653
	if (unlikely (parent_surface->finished))
159
12
	    return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
160

            
161
	/* Get the extents that we'll use in creating our new group surface */
162
641
	bounded = _cairo_surface_get_extents (parent_surface, &extents);
163
641
	if (clip)
164
	    /* XXX: This assignment just fixes a compiler warning? */
165
351
	    is_empty = _cairo_rectangle_intersect (&extents,
166
						   _cairo_clip_get_extents (clip));
167

            
168
641
	if (!bounded) {
169
	    /* XXX: Generic solution? */
170
138
	    group_surface = cairo_recording_surface_create (content, NULL);
171
138
	    extents.x = extents.y = 0;
172
	} else {
173
503
	    group_surface = _cairo_surface_create_scratch (parent_surface,
174
							   content,
175
							   extents.width,
176
							   extents.height,
177
							   CAIRO_COLOR_TRANSPARENT);
178
	}
179
641
	status = group_surface->status;
180
641
	if (unlikely (status))
181
	    goto bail;
182

            
183
	/* Set device offsets on the new surface so that logically it appears at
184
	 * the same location on the parent surface -- when we pop_group this,
185
	 * the source pattern will get fixed up for the appropriate target surface
186
	 * device offsets, so we want to set our own surface offsets from /that/,
187
	 * and not from the device origin. */
188
641
	cairo_surface_set_device_offset (group_surface,
189
641
					 parent_surface->device_transform.x0 - extents.x,
190
641
					 parent_surface->device_transform.y0 - extents.y);
191

            
192
641
	cairo_surface_set_device_scale (group_surface,
193
					parent_surface->device_transform.xx,
194
					parent_surface->device_transform.yy);
195

            
196
	/* If we have a current path, we need to adjust it to compensate for
197
	 * the device offset just applied. */
198
641
	_cairo_path_fixed_translate (cr->path,
199
641
				     _cairo_fixed_from_int (-extents.x),
200
641
				     _cairo_fixed_from_int (-extents.y));
201
    }
202

            
203
    /* create a new gstate for the redirect */
204
647
    status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist);
205
647
    if (unlikely (status))
206
	goto bail;
207

            
208
647
    status = _cairo_gstate_redirect_target (cr->gstate, group_surface);
209

            
210
647
bail:
211
647
    cairo_surface_destroy (group_surface);
212
647
    return status;
213
}
214

            
215
static cairo_pattern_t *
216
646
_cairo_default_context_pop_group (void *abstract_cr)
217
{
218
646
    cairo_default_context_t *cr = abstract_cr;
219
    cairo_surface_t *group_surface;
220
    cairo_pattern_t *group_pattern;
221
    cairo_surface_t *parent_surface;
222
    cairo_matrix_t group_matrix;
223
    cairo_status_t status;
224

            
225
    /* Verify that we are at the right nesting level */
226
646
    if (unlikely (! _cairo_gstate_is_group (cr->gstate)))
227
1
	return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP);
228

            
229
    /* Get a reference to the active surface before restoring */
230
645
    group_surface = _cairo_gstate_get_target (cr->gstate);
231
645
    group_surface = cairo_surface_reference (group_surface);
232

            
233
645
    status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
234
645
    assert (status == CAIRO_STATUS_SUCCESS);
235

            
236
645
    parent_surface = _cairo_gstate_get_target (cr->gstate);
237

            
238
645
    group_pattern = cairo_pattern_create_for_surface (group_surface);
239
645
    status = group_pattern->status;
240
645
    if (unlikely (status))
241
        goto done;
242

            
243
645
    _cairo_gstate_get_matrix (cr->gstate, &group_matrix);
244
645
    cairo_pattern_set_matrix (group_pattern, &group_matrix);
245

            
246
    /* If we have a current path, we need to adjust it to compensate for
247
     * the device offset just removed. */
248
645
    _cairo_path_fixed_translate (cr->path,
249
645
				 _cairo_fixed_from_int (parent_surface->device_transform.x0 - group_surface->device_transform.x0),
250
645
				 _cairo_fixed_from_int (parent_surface->device_transform.y0 - group_surface->device_transform.y0));
251

            
252
645
done:
253
645
    cairo_surface_destroy (group_surface);
254

            
255
645
    return group_pattern;
256
}
257

            
258
static cairo_status_t
259
249550
_cairo_default_context_set_source (void *abstract_cr,
260
				   cairo_pattern_t *source)
261
{
262
249550
    cairo_default_context_t *cr = abstract_cr;
263

            
264
249550
    return _cairo_gstate_set_source (cr->gstate, source);
265
}
266

            
267
static cairo_bool_t
268
117346
_current_source_matches_solid (const cairo_pattern_t *pattern,
269
			       double red,
270
			       double green,
271
			       double blue,
272
			       double alpha)
273
{
274
    cairo_color_t color;
275

            
276
117346
    if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
277
633
	return FALSE;
278

            
279
116713
    red   = _cairo_restrict_value (red,   0.0, 1.0);
280
116713
    green = _cairo_restrict_value (green, 0.0, 1.0);
281
116713
    blue  = _cairo_restrict_value (blue,  0.0, 1.0);
282
116713
    alpha = _cairo_restrict_value (alpha, 0.0, 1.0);
283

            
284
116713
    _cairo_color_init_rgba (&color, red, green, blue, alpha);
285
116713
    return _cairo_color_equal (&color,
286
116713
			       &((cairo_solid_pattern_t *) pattern)->color);
287
}
288

            
289
static cairo_status_t
290
117346
_cairo_default_context_set_source_rgba (void *abstract_cr, double red, double green, double blue, double alpha)
291
{
292
117346
    cairo_default_context_t *cr = abstract_cr;
293
    cairo_pattern_t *pattern;
294
    cairo_status_t status;
295

            
296
117346
    if (_current_source_matches_solid (cr->gstate->source,
297
				       red, green, blue, alpha))
298
4674
	return CAIRO_STATUS_SUCCESS;
299

            
300
    /* push the current pattern to the freed lists */
301
112672
    _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
302

            
303
112672
    pattern = cairo_pattern_create_rgba (red, green, blue, alpha);
304
112672
    if (unlikely (pattern->status))
305
	return pattern->status;
306

            
307
112672
    status = _cairo_default_context_set_source (cr, pattern);
308
112672
    cairo_pattern_destroy (pattern);
309

            
310
112672
    return status;
311
}
312

            
313
static cairo_status_t
314
4708
_cairo_default_context_set_source_surface (void *abstract_cr,
315
					   cairo_surface_t *surface,
316
					   double	   x,
317
					   double	   y)
318
{
319
4708
    cairo_default_context_t *cr = abstract_cr;
320
    cairo_pattern_t *pattern;
321
    cairo_matrix_t matrix;
322
    cairo_status_t status;
323

            
324
    /* push the current pattern to the freed lists */
325
4708
    _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
326

            
327
4708
    pattern = cairo_pattern_create_for_surface (surface);
328
4708
    if (unlikely (pattern->status)) {
329
        status = pattern->status;
330
        cairo_pattern_destroy (pattern);
331
        return status;
332
    }
333

            
334
4708
    cairo_matrix_init_translate (&matrix, -x, -y);
335
4708
    cairo_pattern_set_matrix (pattern, &matrix);
336

            
337
4708
    status = _cairo_default_context_set_source (cr, pattern);
338
4708
    cairo_pattern_destroy (pattern);
339

            
340
4708
    return status;
341
}
342

            
343
static cairo_pattern_t *
344
33861
_cairo_default_context_get_source (void *abstract_cr)
345
{
346
33861
    cairo_default_context_t *cr = abstract_cr;
347

            
348
33861
    return _cairo_gstate_get_source (cr->gstate);
349
}
350

            
351
static cairo_status_t
352
501
_cairo_default_context_set_tolerance (void *abstract_cr,
353
				      double tolerance)
354
{
355
501
    cairo_default_context_t *cr = abstract_cr;
356

            
357
501
    if (tolerance < CAIRO_TOLERANCE_MINIMUM)
358
3
	tolerance = CAIRO_TOLERANCE_MINIMUM;
359

            
360
501
    return _cairo_gstate_set_tolerance (cr->gstate, tolerance);
361
}
362

            
363
static cairo_status_t
364
5520
_cairo_default_context_set_operator (void *abstract_cr, cairo_operator_t op)
365
{
366
5520
    cairo_default_context_t *cr = abstract_cr;
367

            
368
5520
    return _cairo_gstate_set_operator (cr->gstate, op);
369
}
370

            
371
static cairo_status_t
372
_cairo_default_context_set_opacity (void *abstract_cr, double opacity)
373
{
374
    cairo_default_context_t *cr = abstract_cr;
375

            
376
    return _cairo_gstate_set_opacity (cr->gstate, opacity);
377
}
378

            
379
static cairo_status_t
380
138
_cairo_default_context_set_antialias (void *abstract_cr,
381
				      cairo_antialias_t antialias)
382
{
383
138
    cairo_default_context_t *cr = abstract_cr;
384

            
385
138
    return _cairo_gstate_set_antialias (cr->gstate, antialias);
386
}
387

            
388
static cairo_status_t
389
902
_cairo_default_context_set_fill_rule (void *abstract_cr,
390
				      cairo_fill_rule_t fill_rule)
391
{
392
902
    cairo_default_context_t *cr = abstract_cr;
393

            
394
902
    return _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
395
}
396

            
397
static cairo_status_t
398
3705
_cairo_default_context_set_line_width (void *abstract_cr,
399
				       double line_width)
400
{
401
3705
    cairo_default_context_t *cr = abstract_cr;
402

            
403
3705
    return _cairo_gstate_set_line_width (cr->gstate, line_width);
404
}
405

            
406
static cairo_status_t
407
30
_cairo_default_context_set_hairline (void *abstract_cr, cairo_bool_t set_hairline)
408
{
409
30
    cairo_default_context_t *cr = abstract_cr;
410

            
411
30
    return _cairo_gstate_set_hairline (cr->gstate, set_hairline);
412
}
413

            
414
static cairo_status_t
415
2598
_cairo_default_context_set_line_cap (void *abstract_cr,
416
				     cairo_line_cap_t line_cap)
417
{
418
2598
    cairo_default_context_t *cr = abstract_cr;
419

            
420
2598
    return _cairo_gstate_set_line_cap (cr->gstate, line_cap);
421
}
422

            
423
static cairo_status_t
424
1527
_cairo_default_context_set_line_join (void *abstract_cr,
425
				      cairo_line_join_t line_join)
426
{
427
1527
    cairo_default_context_t *cr = abstract_cr;
428

            
429
1527
    return _cairo_gstate_set_line_join (cr->gstate, line_join);
430
}
431

            
432
static cairo_status_t
433
3000
_cairo_default_context_set_dash (void *abstract_cr,
434
				 const double *dashes,
435
				 int	      num_dashes,
436
				 double	      offset)
437
{
438
3000
    cairo_default_context_t *cr = abstract_cr;
439

            
440
3000
    return _cairo_gstate_set_dash (cr->gstate,
441
				   dashes, num_dashes, offset);
442
}
443

            
444
static cairo_status_t
445
297
_cairo_default_context_set_miter_limit (void *abstract_cr,
446
					double limit)
447
{
448
297
    cairo_default_context_t *cr = abstract_cr;
449

            
450
297
    return _cairo_gstate_set_miter_limit (cr->gstate, limit);
451
}
452

            
453
static cairo_antialias_t
454
6
_cairo_default_context_get_antialias (void *abstract_cr)
455
{
456
6
    cairo_default_context_t *cr = abstract_cr;
457

            
458
6
    return _cairo_gstate_get_antialias (cr->gstate);
459
}
460

            
461
static void
462
24
_cairo_default_context_get_dash (void *abstract_cr,
463
				 double *dashes,
464
				 int *num_dashes,
465
				 double *offset)
466
{
467
24
    cairo_default_context_t *cr = abstract_cr;
468

            
469
24
    _cairo_gstate_get_dash (cr->gstate, dashes, num_dashes, offset);
470
24
}
471

            
472
static cairo_fill_rule_t
473
21
_cairo_default_context_get_fill_rule (void *abstract_cr)
474
{
475
21
    cairo_default_context_t *cr = abstract_cr;
476

            
477
21
    return _cairo_gstate_get_fill_rule (cr->gstate);
478
}
479

            
480
static double
481
348
_cairo_default_context_get_line_width (void *abstract_cr)
482
{
483
348
    cairo_default_context_t *cr = abstract_cr;
484

            
485
348
    return _cairo_gstate_get_line_width (cr->gstate);
486
}
487

            
488
static cairo_bool_t
489
45
_cairo_default_context_get_hairline (void *abstract_cr)
490
{
491
45
    cairo_default_context_t *cr = abstract_cr;
492

            
493
45
    return _cairo_gstate_get_hairline (cr->gstate);
494
}
495

            
496
static cairo_line_cap_t
497
12
_cairo_default_context_get_line_cap (void *abstract_cr)
498
{
499
12
    cairo_default_context_t *cr = abstract_cr;
500

            
501
12
    return _cairo_gstate_get_line_cap (cr->gstate);
502
}
503

            
504
static cairo_line_join_t
505
12
_cairo_default_context_get_line_join (void *abstract_cr)
506
{
507
12
    cairo_default_context_t *cr = abstract_cr;
508

            
509
12
    return _cairo_gstate_get_line_join (cr->gstate);
510
}
511

            
512
static double
513
12
_cairo_default_context_get_miter_limit (void *abstract_cr)
514
{
515
12
    cairo_default_context_t *cr = abstract_cr;
516

            
517
12
    return _cairo_gstate_get_miter_limit (cr->gstate);
518
}
519

            
520
static cairo_operator_t
521
12
_cairo_default_context_get_operator (void *abstract_cr)
522
{
523
12
    cairo_default_context_t *cr = abstract_cr;
524

            
525
12
    return _cairo_gstate_get_operator (cr->gstate);
526
}
527

            
528
static double
529
_cairo_default_context_get_opacity (void *abstract_cr)
530
{
531
    cairo_default_context_t *cr = abstract_cr;
532

            
533
    return _cairo_gstate_get_opacity (cr->gstate);
534
}
535

            
536
static double
537
495400
_cairo_default_context_get_tolerance (void *abstract_cr)
538
{
539
495400
    cairo_default_context_t *cr = abstract_cr;
540

            
541
495400
    return _cairo_gstate_get_tolerance (cr->gstate);
542
}
543

            
544

            
545
/* Current transformation matrix */
546

            
547
static cairo_status_t
548
59541
_cairo_default_context_translate (void *abstract_cr,
549
				  double tx,
550
				  double ty)
551
{
552
59541
    cairo_default_context_t *cr = abstract_cr;
553

            
554
59541
    return _cairo_gstate_translate (cr->gstate, tx, ty);
555
}
556

            
557
static cairo_status_t
558
3092
_cairo_default_context_scale (void *abstract_cr,
559
			      double sx,
560
			      double sy)
561
{
562
3092
    cairo_default_context_t *cr = abstract_cr;
563

            
564
3092
    return _cairo_gstate_scale (cr->gstate, sx, sy);
565
}
566

            
567
static cairo_status_t
568
901
_cairo_default_context_rotate (void *abstract_cr,
569
			       double theta)
570
{
571
901
    cairo_default_context_t *cr = abstract_cr;
572

            
573
901
    return _cairo_gstate_rotate (cr->gstate, theta);
574
}
575

            
576
static cairo_status_t
577
276
_cairo_default_context_transform (void *abstract_cr,
578
				  const cairo_matrix_t *matrix)
579
{
580
276
    cairo_default_context_t *cr = abstract_cr;
581

            
582
276
    return _cairo_gstate_transform (cr->gstate, matrix);
583
}
584

            
585
static cairo_status_t
586
1338
_cairo_default_context_set_matrix (void *abstract_cr,
587
				   const cairo_matrix_t *matrix)
588
{
589
1338
    cairo_default_context_t *cr = abstract_cr;
590

            
591
1338
    return _cairo_gstate_set_matrix (cr->gstate, matrix);
592
}
593

            
594
static cairo_status_t
595
60
_cairo_default_context_set_identity_matrix (void *abstract_cr)
596
{
597
60
    cairo_default_context_t *cr = abstract_cr;
598

            
599
60
    _cairo_gstate_identity_matrix (cr->gstate);
600
60
    return CAIRO_STATUS_SUCCESS;
601
}
602

            
603
static void
604
494803
_cairo_default_context_get_matrix (void *abstract_cr,
605
				   cairo_matrix_t *matrix)
606
{
607
494803
    cairo_default_context_t *cr = abstract_cr;
608

            
609
494803
    _cairo_gstate_get_matrix (cr->gstate, matrix);
610
494803
}
611

            
612
static void
613
6
_cairo_default_context_user_to_device (void *abstract_cr,
614
				       double *x,
615
				       double *y)
616
{
617
6
    cairo_default_context_t *cr = abstract_cr;
618

            
619
6
    _cairo_gstate_user_to_device (cr->gstate, x, y);
620
6
}
621

            
622
static void
623
6
_cairo_default_context_user_to_device_distance (void *abstract_cr, double *dx, double *dy)
624
{
625
6
    cairo_default_context_t *cr = abstract_cr;
626

            
627
6
    _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
628
6
}
629

            
630
static void
631
6
_cairo_default_context_device_to_user (void *abstract_cr,
632
				       double *x,
633
				       double *y)
634
{
635
6
    cairo_default_context_t *cr = abstract_cr;
636

            
637
6
    _cairo_gstate_device_to_user (cr->gstate, x, y);
638
6
}
639

            
640
static void
641
6
_cairo_default_context_device_to_user_distance (void *abstract_cr,
642
						double *dx,
643
						double *dy)
644
{
645
6
    cairo_default_context_t *cr = abstract_cr;
646

            
647
6
    _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
648
6
}
649

            
650
static void
651
4266
_cairo_default_context_backend_to_user (void *abstract_cr,
652
					double *x,
653
					double *y)
654
{
655
4266
    cairo_default_context_t *cr = abstract_cr;
656

            
657
4266
    _cairo_gstate_backend_to_user (cr->gstate, x, y);
658
4266
}
659

            
660
static void
661
_cairo_default_context_backend_to_user_distance (void *abstract_cr, double *dx, double *dy)
662
{
663
    cairo_default_context_t *cr = abstract_cr;
664

            
665
    _cairo_gstate_backend_to_user_distance (cr->gstate, dx, dy);
666
}
667

            
668
static void
669
_cairo_default_context_user_to_backend (void *abstract_cr,
670
					double *x,
671
					double *y)
672
{
673
    cairo_default_context_t *cr = abstract_cr;
674

            
675
    _cairo_gstate_user_to_backend (cr->gstate, x, y);
676
}
677

            
678
static void
679
_cairo_default_context_user_to_backend_distance (void *abstract_cr,
680
						 double *dx,
681
						 double *dy)
682
{
683
    cairo_default_context_t *cr = abstract_cr;
684

            
685
    _cairo_gstate_user_to_backend_distance (cr->gstate, dx, dy);
686
}
687

            
688
/* Path constructor */
689

            
690
static cairo_status_t
691
739211
_cairo_default_context_new_path (void *abstract_cr)
692
{
693
739211
    cairo_default_context_t *cr = abstract_cr;
694

            
695
739211
    _cairo_path_fixed_fini (cr->path);
696
739211
    _cairo_path_fixed_init (cr->path);
697

            
698
739211
    return CAIRO_STATUS_SUCCESS;
699
}
700

            
701
static cairo_status_t
702
1531
_cairo_default_context_new_sub_path (void *abstract_cr)
703
{
704
1531
    cairo_default_context_t *cr = abstract_cr;
705

            
706
1531
    _cairo_path_fixed_new_sub_path (cr->path);
707

            
708
1531
    return CAIRO_STATUS_SUCCESS;
709
}
710

            
711
static cairo_status_t
712
27484797
_cairo_default_context_move_to (void *abstract_cr, double x, double y)
713
{
714
27484797
    cairo_default_context_t *cr = abstract_cr;
715
    cairo_fixed_t x_fixed, y_fixed;
716
    double width;
717

            
718
27484797
    _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
719
27484797
    width = _cairo_gstate_get_line_width (cr->gstate);
720
27484797
    x_fixed = _cairo_fixed_from_double_clamped (x, width);
721
27484797
    y_fixed = _cairo_fixed_from_double_clamped (y, width);
722

            
723
27484797
    return _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed);
724
}
725

            
726
static cairo_status_t
727
1261460
_cairo_default_context_line_to (void *abstract_cr, double x, double y)
728
{
729
1261460
    cairo_default_context_t *cr = abstract_cr;
730
    cairo_fixed_t x_fixed, y_fixed;
731
    double width;
732

            
733
1261460
    _cairo_gstate_user_to_backend (cr->gstate, &x, &y);
734
1261460
    width = _cairo_gstate_get_line_width (cr->gstate);
735
1261460
    x_fixed = _cairo_fixed_from_double_clamped (x, width);
736
1261460
    y_fixed = _cairo_fixed_from_double_clamped (y, width);
737

            
738
1261460
    return _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
739
}
740

            
741
static cairo_status_t
742
513100
_cairo_default_context_curve_to (void *abstract_cr,
743
				 double x1, double y1,
744
				 double x2, double y2,
745
				 double x3, double y3)
746
{
747
513100
    cairo_default_context_t *cr = abstract_cr;
748
    cairo_fixed_t x1_fixed, y1_fixed;
749
    cairo_fixed_t x2_fixed, y2_fixed;
750
    cairo_fixed_t x3_fixed, y3_fixed;
751
    double width;
752

            
753
513100
    _cairo_gstate_user_to_backend (cr->gstate, &x1, &y1);
754
513100
    _cairo_gstate_user_to_backend (cr->gstate, &x2, &y2);
755
513100
    _cairo_gstate_user_to_backend (cr->gstate, &x3, &y3);
756
513100
    width = _cairo_gstate_get_line_width (cr->gstate);
757

            
758
513100
    x1_fixed = _cairo_fixed_from_double_clamped (x1, width);
759
513100
    y1_fixed = _cairo_fixed_from_double_clamped (y1, width);
760

            
761
513100
    x2_fixed = _cairo_fixed_from_double_clamped (x2, width);
762
513100
    y2_fixed = _cairo_fixed_from_double_clamped (y2, width);
763

            
764
513100
    x3_fixed = _cairo_fixed_from_double_clamped (x3, width);
765
513100
    y3_fixed = _cairo_fixed_from_double_clamped (y3, width);
766

            
767
513100
    return _cairo_path_fixed_curve_to (cr->path,
768
				       x1_fixed, y1_fixed,
769
				       x2_fixed, y2_fixed,
770
				       x3_fixed, y3_fixed);
771
}
772

            
773
static cairo_status_t
774
3367
_cairo_default_context_arc (void *abstract_cr,
775
			    double xc, double yc, double radius,
776
			    double angle1, double angle2,
777
			    cairo_bool_t forward)
778
{
779
3367
    cairo_default_context_t *cr = abstract_cr;
780
    cairo_status_t status;
781

            
782
    /* Do nothing, successfully, if radius is <= 0 */
783
3367
    if (radius <= 0.0) {
784
	cairo_fixed_t x_fixed, y_fixed;
785

            
786
18
	_cairo_gstate_user_to_backend (cr->gstate, &xc, &yc);
787
18
	x_fixed = _cairo_fixed_from_double (xc);
788
18
	y_fixed = _cairo_fixed_from_double (yc);
789
18
	status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
790
18
	if (unlikely (status))
791
	    return status;
792

            
793
18
	status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
794
18
	if (unlikely (status))
795
	    return status;
796

            
797
18
	return CAIRO_STATUS_SUCCESS;
798
    }
799

            
800
3349
    status = _cairo_default_context_line_to (cr,
801
3349
					     xc + radius * cos (angle1),
802
3349
					     yc + radius * sin (angle1));
803

            
804
3349
    if (unlikely (status))
805
	return status;
806

            
807
3349
    if (forward)
808
3253
	_cairo_arc_path (&cr->base, xc, yc, radius, angle1, angle2);
809
    else
810
96
	_cairo_arc_path_negative (&cr->base, xc, yc, radius, angle1, angle2);
811

            
812
3349
    return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */
813
}
814

            
815
static cairo_status_t
816
12
_cairo_default_context_rel_move_to (void *abstract_cr, double dx, double dy)
817
{
818
12
    cairo_default_context_t *cr = abstract_cr;
819
    cairo_fixed_t dx_fixed, dy_fixed;
820

            
821
12
    _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy);
822

            
823
12
    dx_fixed = _cairo_fixed_from_double (dx);
824
12
    dy_fixed = _cairo_fixed_from_double (dy);
825

            
826
12
    return _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
827
}
828

            
829
static cairo_status_t
830
81466830
_cairo_default_context_rel_line_to (void *abstract_cr, double dx, double dy)
831
{
832
81466830
    cairo_default_context_t *cr = abstract_cr;
833
    cairo_fixed_t dx_fixed, dy_fixed;
834

            
835
81466830
    _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy);
836

            
837
81466830
    dx_fixed = _cairo_fixed_from_double (dx);
838
81466830
    dy_fixed = _cairo_fixed_from_double (dy);
839

            
840
81466830
    return _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
841
}
842

            
843

            
844
static cairo_status_t
845
780
_cairo_default_context_rel_curve_to (void *abstract_cr,
846
				     double dx1, double dy1,
847
				     double dx2, double dy2,
848
				     double dx3, double dy3)
849
{
850
780
    cairo_default_context_t *cr = abstract_cr;
851
    cairo_fixed_t dx1_fixed, dy1_fixed;
852
    cairo_fixed_t dx2_fixed, dy2_fixed;
853
    cairo_fixed_t dx3_fixed, dy3_fixed;
854

            
855
780
    _cairo_gstate_user_to_backend_distance (cr->gstate, &dx1, &dy1);
856
780
    _cairo_gstate_user_to_backend_distance (cr->gstate, &dx2, &dy2);
857
780
    _cairo_gstate_user_to_backend_distance (cr->gstate, &dx3, &dy3);
858

            
859
780
    dx1_fixed = _cairo_fixed_from_double (dx1);
860
780
    dy1_fixed = _cairo_fixed_from_double (dy1);
861

            
862
780
    dx2_fixed = _cairo_fixed_from_double (dx2);
863
780
    dy2_fixed = _cairo_fixed_from_double (dy2);
864

            
865
780
    dx3_fixed = _cairo_fixed_from_double (dx3);
866
780
    dy3_fixed = _cairo_fixed_from_double (dy3);
867

            
868
780
    return _cairo_path_fixed_rel_curve_to (cr->path,
869
					   dx1_fixed, dy1_fixed,
870
					   dx2_fixed, dy2_fixed,
871
					   dx3_fixed, dy3_fixed);
872
}
873

            
874
static cairo_status_t
875
27261370
_cairo_default_context_close_path (void *abstract_cr)
876
{
877
27261370
    cairo_default_context_t *cr = abstract_cr;
878

            
879
27261370
    return _cairo_path_fixed_close_path (cr->path);
880
}
881

            
882
static cairo_status_t
883
741354
_cairo_default_context_rectangle (void *abstract_cr,
884
				  double x, double y,
885
				  double width, double height)
886
{
887
741354
    cairo_default_context_t *cr = abstract_cr;
888
    cairo_status_t status;
889

            
890
741354
    status = _cairo_default_context_move_to (cr, x, y);
891
741354
    if (unlikely (status))
892
	return status;
893

            
894
741354
    status = _cairo_default_context_rel_line_to (cr, width, 0);
895
741354
    if (unlikely (status))
896
	return status;
897

            
898
741354
    status = _cairo_default_context_rel_line_to (cr, 0, height);
899
741354
    if (unlikely (status))
900
	return status;
901

            
902
741354
    status = _cairo_default_context_rel_line_to (cr, -width, 0);
903
741354
    if (unlikely (status))
904
	return status;
905

            
906
741354
    return _cairo_default_context_close_path (cr);
907
}
908

            
909
static void
910
108
_cairo_default_context_path_extents (void *abstract_cr,
911
				     double *x1,
912
				     double *y1,
913
				     double *x2,
914
				     double *y2)
915
{
916
108
    cairo_default_context_t *cr = abstract_cr;
917

            
918
108
    _cairo_gstate_path_extents (cr->gstate,
919
108
				cr->path,
920
				x1, y1, x2, y2);
921
108
}
922

            
923
static cairo_bool_t
924
68829
_cairo_default_context_has_current_point (void *abstract_cr)
925
{
926
68829
    cairo_default_context_t *cr = abstract_cr;
927

            
928
68829
    return cr->path->has_current_point;
929
}
930

            
931
static cairo_bool_t
932
35748
_cairo_default_context_get_current_point (void *abstract_cr,
933
					  double *x,
934
					  double *y)
935
{
936
35748
    cairo_default_context_t *cr = abstract_cr;
937
    cairo_fixed_t x_fixed, y_fixed;
938

            
939
35748
    if (_cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed))
940
    {
941
35748
	*x = _cairo_fixed_to_double (x_fixed);
942
35748
	*y = _cairo_fixed_to_double (y_fixed);
943
35748
	_cairo_gstate_backend_to_user (cr->gstate, x, y);
944

            
945
35748
	return TRUE;
946
    }
947
    else
948
    {
949
	return FALSE;
950
    }
951
}
952

            
953
static cairo_path_t *
954
444
_cairo_default_context_copy_path (void *abstract_cr)
955
{
956
444
    cairo_default_context_t *cr = abstract_cr;
957

            
958
444
    return _cairo_path_create (cr->path, &cr->base);
959
}
960

            
961
static cairo_path_t *
962
12
_cairo_default_context_copy_path_flat (void *abstract_cr)
963
{
964
12
    cairo_default_context_t *cr = abstract_cr;
965

            
966
12
    return _cairo_path_create_flat (cr->path, &cr->base);
967
}
968

            
969
static cairo_status_t
970
466
_cairo_default_context_append_path (void *abstract_cr,
971
				    const cairo_path_t *path)
972
{
973
466
    cairo_default_context_t *cr = abstract_cr;
974

            
975
466
    return _cairo_path_append_to_context (path, &cr->base);
976
}
977

            
978
static cairo_status_t
979
341779
_cairo_default_context_paint (void *abstract_cr)
980
{
981
341779
    cairo_default_context_t *cr = abstract_cr;
982

            
983
341779
    return _cairo_gstate_paint (cr->gstate);
984
}
985

            
986
static cairo_status_t
987
387
_cairo_default_context_paint_with_alpha (void *abstract_cr,
988
					 double alpha)
989
{
990
387
    cairo_default_context_t *cr = abstract_cr;
991
    cairo_solid_pattern_t pattern;
992
    cairo_status_t status;
993
    cairo_color_t color;
994

            
995
387
    if (CAIRO_ALPHA_IS_OPAQUE (alpha))
996
66
	return _cairo_gstate_paint (cr->gstate);
997

            
998
321
    if (CAIRO_ALPHA_IS_ZERO (alpha) &&
999
21
        _cairo_operator_bounded_by_mask (cr->gstate->op)) {
15
	return CAIRO_STATUS_SUCCESS;
    }
306
    _cairo_color_init_rgba (&color, 0., 0., 0., alpha);
306
    _cairo_pattern_init_solid (&pattern, &color);
306
    status = _cairo_gstate_mask (cr->gstate, &pattern.base);
306
    _cairo_pattern_fini (&pattern.base);
306
    return status;
}
static cairo_status_t
34098
_cairo_default_context_mask (void *abstract_cr,
			     cairo_pattern_t *mask)
{
34098
    cairo_default_context_t *cr = abstract_cr;
34098
    return _cairo_gstate_mask (cr->gstate, mask);
}
static cairo_status_t
651
_cairo_default_context_stroke_preserve (void *abstract_cr)
{
651
    cairo_default_context_t *cr = abstract_cr;
651
    return _cairo_gstate_stroke (cr->gstate, cr->path);
}
static cairo_status_t
39079
_cairo_default_context_stroke (void *abstract_cr)
{
39079
    cairo_default_context_t *cr = abstract_cr;
    cairo_status_t status;
39079
    status = _cairo_gstate_stroke (cr->gstate, cr->path);
39079
    if (unlikely (status))
6
	return status;
39073
    return _cairo_default_context_new_path (cr);
}
static cairo_status_t
15
_cairo_default_context_in_stroke (void *abstract_cr,
				  double x, double y,
				  cairo_bool_t *inside)
{
15
    cairo_default_context_t *cr = abstract_cr;
30
    return _cairo_gstate_in_stroke (cr->gstate,
15
				    cr->path,
				    x, y,
				    inside);
}
static cairo_status_t
120
_cairo_default_context_stroke_extents (void *abstract_cr,
				       double *x1, double *y1, double *x2, double *y2)
{
120
    cairo_default_context_t *cr = abstract_cr;
240
    return _cairo_gstate_stroke_extents (cr->gstate,
120
					 cr->path,
					 x1, y1, x2, y2);
}
static cairo_status_t
1269
_cairo_default_context_fill_preserve (void *abstract_cr)
{
1269
    cairo_default_context_t *cr = abstract_cr;
1269
    return _cairo_gstate_fill (cr->gstate, cr->path);
}
static cairo_status_t
392069
_cairo_default_context_fill (void *abstract_cr)
{
392069
    cairo_default_context_t *cr = abstract_cr;
    cairo_status_t status;
392069
    status = _cairo_gstate_fill (cr->gstate, cr->path);
392069
    if (unlikely (status))
3
	return status;
392066
    return _cairo_default_context_new_path (cr);
}
static cairo_status_t
145
_cairo_default_context_in_fill (void *abstract_cr,
				double x, double y,
				cairo_bool_t *inside)
{
145
    cairo_default_context_t *cr = abstract_cr;
290
    *inside = _cairo_gstate_in_fill (cr->gstate,
145
				     cr->path,
				     x, y);
145
    return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
78
_cairo_default_context_fill_extents (void *abstract_cr,
				     double *x1, double *y1, double *x2, double *y2)
{
78
    cairo_default_context_t *cr = abstract_cr;
156
    return _cairo_gstate_fill_extents (cr->gstate,
78
				       cr->path,
				       x1, y1, x2, y2);
}
static cairo_status_t
327
_cairo_default_context_clip_preserve (void *abstract_cr)
{
327
    cairo_default_context_t *cr = abstract_cr;
327
    return _cairo_gstate_clip (cr->gstate, cr->path);
}
static cairo_status_t
305136
_cairo_default_context_clip (void *abstract_cr)
{
305136
    cairo_default_context_t *cr = abstract_cr;
    cairo_status_t status;
305136
    status = _cairo_gstate_clip (cr->gstate, cr->path);
305136
    if (unlikely (status))
	return status;
305136
    return _cairo_default_context_new_path (cr);
}
static cairo_status_t
6
_cairo_default_context_in_clip (void *abstract_cr,
				double x, double y,
				cairo_bool_t *inside)
{
6
    cairo_default_context_t *cr = abstract_cr;
6
    *inside = _cairo_gstate_in_clip (cr->gstate, x, y);
6
    return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
300435
_cairo_default_context_reset_clip (void *abstract_cr)
{
300435
    cairo_default_context_t *cr = abstract_cr;
300435
    return _cairo_gstate_reset_clip (cr->gstate);
}
static cairo_status_t
32
_cairo_default_context_clip_extents (void *abstract_cr,
				     double *x1, double *y1, double *x2, double *y2)
{
32
    cairo_default_context_t *cr = abstract_cr;
32
    if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) {
	*x1 = -INFINITY;
	*y1 = -INFINITY;
	*x2 = +INFINITY;
	*y2 = +INFINITY;
    }
32
    return CAIRO_STATUS_SUCCESS;
}
static cairo_rectangle_list_t *
15
_cairo_default_context_copy_clip_rectangle_list (void *abstract_cr)
{
15
    cairo_default_context_t *cr = abstract_cr;
15
    return _cairo_gstate_copy_clip_rectangle_list (cr->gstate);
}
static cairo_status_t
6
_cairo_default_context_copy_page (void *abstract_cr)
{
6
    cairo_default_context_t *cr = abstract_cr;
6
    return _cairo_gstate_copy_page (cr->gstate);
}
static cairo_status_t
3
_cairo_default_context_tag_begin (void *abstract_cr,
				  const char *tag_name, const char *attributes)
{
3
    cairo_default_context_t *cr = abstract_cr;
3
    return _cairo_gstate_tag_begin (cr->gstate, tag_name, attributes);
}
static cairo_status_t
3
_cairo_default_context_tag_end (void *abstract_cr,
				const char *tag_name)
{
3
    cairo_default_context_t *cr = abstract_cr;
3
    return _cairo_gstate_tag_end (cr->gstate, tag_name);
}
static cairo_status_t
6
_cairo_default_context_show_page (void *abstract_cr)
{
6
    cairo_default_context_t *cr = abstract_cr;
6
    return _cairo_gstate_show_page (cr->gstate);
}
static cairo_status_t
114008
_cairo_default_context_set_font_face (void *abstract_cr,
				      cairo_font_face_t *font_face)
{
114008
    cairo_default_context_t *cr = abstract_cr;
114008
    return _cairo_gstate_set_font_face (cr->gstate, font_face);
}
static cairo_font_face_t *
34
_cairo_default_context_get_font_face (void *abstract_cr)
{
34
    cairo_default_context_t *cr = abstract_cr;
    cairo_font_face_t *font_face;
    cairo_status_t status;
34
    status = _cairo_gstate_get_font_face (cr->gstate, &font_face);
34
    if (unlikely (status)) {
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
	return (cairo_font_face_t *) &_cairo_font_face_nil;
    }
34
    return font_face;
}
static cairo_status_t
110793
_cairo_default_context_font_extents (void *abstract_cr,
				     cairo_font_extents_t *extents)
{
110793
    cairo_default_context_t *cr = abstract_cr;
110793
    return _cairo_gstate_get_font_extents (cr->gstate, extents);
}
static cairo_status_t
2745
_cairo_default_context_set_font_size (void *abstract_cr,
				      double size)
{
2745
    cairo_default_context_t *cr = abstract_cr;
2745
    return _cairo_gstate_set_font_size (cr->gstate, size);
}
static cairo_status_t
189
_cairo_default_context_set_font_matrix (void *abstract_cr,
					const cairo_matrix_t *matrix)
{
189
    cairo_default_context_t *cr = abstract_cr;
189
    return _cairo_gstate_set_font_matrix (cr->gstate, matrix);
}
static void
51
_cairo_default_context_get_font_matrix (void *abstract_cr,
					cairo_matrix_t *matrix)
{
51
    cairo_default_context_t *cr = abstract_cr;
51
    _cairo_gstate_get_font_matrix (cr->gstate, matrix);
51
}
static cairo_status_t
3084
_cairo_default_context_set_font_options (void *abstract_cr,
					 const cairo_font_options_t *options)
{
3084
    cairo_default_context_t *cr = abstract_cr;
3084
    _cairo_gstate_set_font_options (cr->gstate, options);
3084
    return CAIRO_STATUS_SUCCESS;
}
static void
81
_cairo_default_context_get_font_options (void *abstract_cr,
					 cairo_font_options_t *options)
{
81
    cairo_default_context_t *cr = abstract_cr;
81
    _cairo_gstate_get_font_options (cr->gstate, options);
81
}
static cairo_status_t
32475
_cairo_default_context_set_scaled_font (void *abstract_cr,
					cairo_scaled_font_t *scaled_font)
{
32475
    cairo_default_context_t *cr = abstract_cr;
    cairo_bool_t was_previous;
    cairo_status_t status;
32475
    if (scaled_font == cr->gstate->scaled_font)
5406
	return CAIRO_STATUS_SUCCESS;
27069
    was_previous = scaled_font == cr->gstate->previous_scaled_font;
27069
    status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
27069
    if (unlikely (status))
	return status;
27069
    status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
27069
    if (unlikely (status))
	return status;
27069
    _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
27069
    if (was_previous)
	cr->gstate->scaled_font = cairo_scaled_font_reference (scaled_font);
27069
    return CAIRO_STATUS_SUCCESS;
}
static cairo_scaled_font_t *
67990
_cairo_default_context_get_scaled_font (void *abstract_cr)
{
67990
    cairo_default_context_t *cr = abstract_cr;
    cairo_scaled_font_t *scaled_font;
    cairo_status_t status;
67990
    status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font);
67990
    if (unlikely (status))
9
	return _cairo_scaled_font_create_in_error (status);
67981
    return scaled_font;
}
static cairo_status_t
34944
_cairo_default_context_glyphs (void *abstract_cr,
			       const cairo_glyph_t *glyphs,
			       int num_glyphs,
			       cairo_glyph_text_info_t *info)
{
34944
    cairo_default_context_t *cr = abstract_cr;
34944
    return _cairo_gstate_show_text_glyphs (cr->gstate, glyphs, num_glyphs, info);
}
static cairo_status_t
165
_cairo_default_context_glyph_path (void *abstract_cr,
				   const cairo_glyph_t *glyphs,
				   int num_glyphs)
{
165
    cairo_default_context_t *cr = abstract_cr;
330
    return _cairo_gstate_glyph_path (cr->gstate,
				     glyphs, num_glyphs,
165
				     cr->path);
}
static cairo_status_t
68310
_cairo_default_context_glyph_extents (void                *abstract_cr,
				      const cairo_glyph_t    *glyphs,
				      int                    num_glyphs,
				      cairo_text_extents_t   *extents)
{
68310
    cairo_default_context_t *cr = abstract_cr;
68310
    return _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
}
static const cairo_backend_t _cairo_default_context_backend = {
    CAIRO_TYPE_DEFAULT,
    _cairo_default_context_destroy,
    _cairo_default_context_get_original_target,
    _cairo_default_context_get_current_target,
    _cairo_default_context_save,
    _cairo_default_context_restore,
    _cairo_default_context_push_group,
    _cairo_default_context_pop_group,
    _cairo_default_context_set_source_rgba,
    _cairo_default_context_set_source_surface,
    _cairo_default_context_set_source,
    _cairo_default_context_get_source,
    _cairo_default_context_set_antialias,
    _cairo_default_context_set_dash,
    _cairo_default_context_set_fill_rule,
    _cairo_default_context_set_line_cap,
    _cairo_default_context_set_line_join,
    _cairo_default_context_set_line_width,
    _cairo_default_context_set_hairline,
    _cairo_default_context_set_miter_limit,
    _cairo_default_context_set_opacity,
    _cairo_default_context_set_operator,
    _cairo_default_context_set_tolerance,
    _cairo_default_context_get_antialias,
    _cairo_default_context_get_dash,
    _cairo_default_context_get_fill_rule,
    _cairo_default_context_get_line_cap,
    _cairo_default_context_get_line_join,
    _cairo_default_context_get_line_width,
    _cairo_default_context_get_hairline,
    _cairo_default_context_get_miter_limit,
    _cairo_default_context_get_opacity,
    _cairo_default_context_get_operator,
    _cairo_default_context_get_tolerance,
    _cairo_default_context_translate,
    _cairo_default_context_scale,
    _cairo_default_context_rotate,
    _cairo_default_context_transform,
    _cairo_default_context_set_matrix,
    _cairo_default_context_set_identity_matrix,
    _cairo_default_context_get_matrix,
    _cairo_default_context_user_to_device,
    _cairo_default_context_user_to_device_distance,
    _cairo_default_context_device_to_user,
    _cairo_default_context_device_to_user_distance,
    _cairo_default_context_user_to_backend,
    _cairo_default_context_user_to_backend_distance,
    _cairo_default_context_backend_to_user,
    _cairo_default_context_backend_to_user_distance,
    _cairo_default_context_new_path,
    _cairo_default_context_new_sub_path,
    _cairo_default_context_move_to,
    _cairo_default_context_rel_move_to,
    _cairo_default_context_line_to,
    _cairo_default_context_rel_line_to,
    _cairo_default_context_curve_to,
    _cairo_default_context_rel_curve_to,
    NULL, /* arc-to */
    NULL, /* rel-arc-to */
    _cairo_default_context_close_path,
    _cairo_default_context_arc,
    _cairo_default_context_rectangle,
    _cairo_default_context_path_extents,
    _cairo_default_context_has_current_point,
    _cairo_default_context_get_current_point,
    _cairo_default_context_copy_path,
    _cairo_default_context_copy_path_flat,
    _cairo_default_context_append_path,
    NULL, /* stroke-to-path */
    _cairo_default_context_clip,
    _cairo_default_context_clip_preserve,
    _cairo_default_context_in_clip,
    _cairo_default_context_clip_extents,
    _cairo_default_context_reset_clip,
    _cairo_default_context_copy_clip_rectangle_list,
    _cairo_default_context_paint,
    _cairo_default_context_paint_with_alpha,
    _cairo_default_context_mask,
    _cairo_default_context_stroke,
    _cairo_default_context_stroke_preserve,
    _cairo_default_context_in_stroke,
    _cairo_default_context_stroke_extents,
    _cairo_default_context_fill,
    _cairo_default_context_fill_preserve,
    _cairo_default_context_in_fill,
    _cairo_default_context_fill_extents,
    _cairo_default_context_set_font_face,
    _cairo_default_context_get_font_face,
    _cairo_default_context_set_font_size,
    _cairo_default_context_set_font_matrix,
    _cairo_default_context_get_font_matrix,
    _cairo_default_context_set_font_options,
    _cairo_default_context_get_font_options,
    _cairo_default_context_set_scaled_font,
    _cairo_default_context_get_scaled_font,
    _cairo_default_context_font_extents,
    _cairo_default_context_glyphs,
    _cairo_default_context_glyph_path,
    _cairo_default_context_glyph_extents,
    _cairo_default_context_copy_page,
    _cairo_default_context_show_page,
    _cairo_default_context_tag_begin,
    _cairo_default_context_tag_end,
};
cairo_status_t
34933
_cairo_default_context_init (cairo_default_context_t *cr, void *target)
{
34933
    _cairo_init (&cr->base, &_cairo_default_context_backend);
34933
    _cairo_path_fixed_init (cr->path);
34933
    cr->gstate = &cr->gstate_tail[0];
34933
    cr->gstate_freelist = &cr->gstate_tail[1];
34933
    cr->gstate_tail[1].next = NULL;
34933
    return _cairo_gstate_init (cr->gstate, target);
}
cairo_t *
34933
_cairo_default_context_create (void *target)
{
    cairo_default_context_t *cr;
    cairo_status_t status;
34933
    cr = _freed_pool_get (&context_pool);
34933
    if (unlikely (cr == NULL)) {
3634
	cr = _cairo_calloc (sizeof (cairo_default_context_t));
3634
	if (unlikely (cr == NULL))
	    return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
    }
34933
    status = _cairo_default_context_init (cr, target);
34933
    if (unlikely (status)) {
	_freed_pool_put (&context_pool, cr);
	return _cairo_create_in_error (status);
    }
34933
    return &cr->base;
}