Tizen 2.0 Release
[profile/ivi/cairo.git] / src / cairo-gstate.c
1 /* cairo - a vector graphics library with display and print output
2  *
3  * Copyright © 2002 University of Southern California
4  * Copyright © 2005 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it either under the terms of the GNU Lesser General Public
8  * License version 2.1 as published by the Free Software Foundation
9  * (the "LGPL") or, at your option, under the terms of the Mozilla
10  * Public License Version 1.1 (the "MPL"). If you do not alter this
11  * notice, a recipient may use your version of this file under either
12  * the MPL or the LGPL.
13  *
14  * You should have received a copy of the LGPL along with this library
15  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17  * You should have received a copy of the MPL along with this library
18  * in the file COPYING-MPL-1.1
19  *
20  * The contents of this file are subject to the Mozilla Public License
21  * Version 1.1 (the "License"); you may not use this file except in
22  * compliance with the License. You may obtain a copy of the License at
23  * http://www.mozilla.org/MPL/
24  *
25  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27  * the specific language governing rights and limitations.
28  *
29  * The Original Code is the cairo graphics library.
30  *
31  * The Initial Developer of the Original Code is University of Southern
32  * California.
33  *
34  * Contributor(s):
35  *      Carl D. Worth <cworth@cworth.org>
36  */
37
38 #include "cairoint.h"
39
40 #include "cairo-clip-inline.h"
41 #include "cairo-clip-private.h"
42 #include "cairo-error-private.h"
43 #include "cairo-list-inline.h"
44 #include "cairo-gstate-private.h"
45 #include "cairo-pattern-private.h"
46 #include "cairo-traps-private.h"
47
48 #if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE)
49 #define ISFINITE(x) isfinite (x)
50 #else
51 #define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
52 #endif
53
54 static cairo_status_t
55 _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other);
56
57 static cairo_status_t
58 _cairo_gstate_ensure_font_face (cairo_gstate_t *gstate);
59
60 static cairo_status_t
61 _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate);
62
63 static void
64 _cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate);
65
66 static void
67 _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t      *gstate,
68                                            const cairo_glyph_t *glyphs,
69                                            int                  num_glyphs,
70                                            const cairo_text_cluster_t   *clusters,
71                                            int                   num_clusters,
72                                            cairo_text_cluster_flags_t cluster_flags,
73                                            cairo_glyph_t       *transformed_glyphs,
74                                            int                  *num_transformed_glyphs,
75                                            cairo_text_cluster_t *transformed_clusters);
76
77 static void
78 _cairo_gstate_update_device_transform (cairo_observer_t *observer,
79                                        void *arg)
80 {
81     cairo_gstate_t *gstate = cairo_container_of (observer,
82                                                  cairo_gstate_t,
83                                                  device_transform_observer);
84
85     gstate->is_identity = (_cairo_matrix_is_identity (&gstate->ctm) &&
86                            _cairo_matrix_is_identity (&gstate->target->device_transform));
87 }
88
89 cairo_status_t
90 _cairo_gstate_init (cairo_gstate_t  *gstate,
91                     cairo_surface_t *target)
92 {
93     VG (VALGRIND_MAKE_MEM_UNDEFINED (gstate, sizeof (cairo_gstate_t)));
94
95     gstate->next = NULL;
96
97     gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
98     gstate->opacity = 1.;
99
100     gstate->tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT;
101     gstate->antialias = CAIRO_ANTIALIAS_DEFAULT;
102
103     _cairo_stroke_style_init (&gstate->stroke_style);
104
105     gstate->fill_rule = CAIRO_GSTATE_FILL_RULE_DEFAULT;
106
107     gstate->font_face = NULL;
108     gstate->scaled_font = NULL;
109     gstate->previous_scaled_font = NULL;
110
111     cairo_matrix_init_scale (&gstate->font_matrix,
112                              CAIRO_GSTATE_DEFAULT_FONT_SIZE,
113                              CAIRO_GSTATE_DEFAULT_FONT_SIZE);
114
115     _cairo_font_options_init_default (&gstate->font_options);
116
117     gstate->clip = NULL;
118
119     gstate->target = cairo_surface_reference (target);
120     gstate->parent_target = NULL;
121     gstate->original_target = cairo_surface_reference (target);
122
123     gstate->device_transform_observer.callback = _cairo_gstate_update_device_transform;
124     cairo_list_add (&gstate->device_transform_observer.link,
125                     &gstate->target->device_transform_observers);
126
127     gstate->is_identity = _cairo_matrix_is_identity (&gstate->target->device_transform);
128     cairo_matrix_init_identity (&gstate->ctm);
129     gstate->ctm_inverse = gstate->ctm;
130     gstate->source_ctm_inverse = gstate->ctm;
131
132     gstate->source = (cairo_pattern_t *) &_cairo_pattern_black.base;
133
134     /* Now that the gstate is fully initialized and ready for the eventual
135      * _cairo_gstate_fini(), we can check for errors (and not worry about
136      * the resource deallocation). */
137     return target->status;
138 }
139
140 /**
141  * _cairo_gstate_init_copy:
142  *
143  * Initialize @gstate by performing a deep copy of state fields from
144  * @other. Note that gstate->next is not copied but is set to %NULL by
145  * this function.
146  **/
147 static cairo_status_t
148 _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
149 {
150     cairo_status_t status;
151
152     VG (VALGRIND_MAKE_MEM_UNDEFINED (gstate, sizeof (cairo_gstate_t)));
153
154     gstate->op = other->op;
155     gstate->opacity = other->opacity;
156
157     gstate->tolerance = other->tolerance;
158     gstate->antialias = other->antialias;
159
160     status = _cairo_stroke_style_init_copy (&gstate->stroke_style,
161                                             &other->stroke_style);
162     if (unlikely (status))
163         return status;
164
165     gstate->fill_rule = other->fill_rule;
166
167     gstate->font_face = cairo_font_face_reference (other->font_face);
168     gstate->scaled_font = cairo_scaled_font_reference (other->scaled_font);
169     gstate->previous_scaled_font = cairo_scaled_font_reference (other->previous_scaled_font);
170
171     gstate->font_matrix = other->font_matrix;
172
173     _cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
174
175     gstate->clip = _cairo_clip_copy (other->clip);
176
177     gstate->target = cairo_surface_reference (other->target);
178     /* parent_target is always set to NULL; it's only ever set by redirect_target */
179     gstate->parent_target = NULL;
180     gstate->original_target = cairo_surface_reference (other->original_target);
181
182     gstate->device_transform_observer.callback = _cairo_gstate_update_device_transform;
183     cairo_list_add (&gstate->device_transform_observer.link,
184                     &gstate->target->device_transform_observers);
185
186     gstate->is_identity = other->is_identity;
187     gstate->ctm = other->ctm;
188     gstate->ctm_inverse = other->ctm_inverse;
189     gstate->source_ctm_inverse = other->source_ctm_inverse;
190
191     gstate->source = cairo_pattern_reference (other->source);
192
193     gstate->next = NULL;
194
195     return CAIRO_STATUS_SUCCESS;
196 }
197
198 void
199 _cairo_gstate_fini (cairo_gstate_t *gstate)
200 {
201     _cairo_stroke_style_fini (&gstate->stroke_style);
202
203     cairo_font_face_destroy (gstate->font_face);
204     gstate->font_face = NULL;
205
206     cairo_scaled_font_destroy (gstate->previous_scaled_font);
207     gstate->previous_scaled_font = NULL;
208
209     cairo_scaled_font_destroy (gstate->scaled_font);
210     gstate->scaled_font = NULL;
211
212     _cairo_clip_destroy (gstate->clip);
213
214     cairo_list_del (&gstate->device_transform_observer.link);
215
216     cairo_surface_destroy (gstate->target);
217     gstate->target = NULL;
218
219     cairo_surface_destroy (gstate->parent_target);
220     gstate->parent_target = NULL;
221
222     cairo_surface_destroy (gstate->original_target);
223     gstate->original_target = NULL;
224
225     cairo_pattern_destroy (gstate->source);
226     gstate->source = NULL;
227
228     VG (VALGRIND_MAKE_MEM_NOACCESS (gstate, sizeof (cairo_gstate_t)));
229 }
230
231 /**
232  * _cairo_gstate_save:
233  * @gstate: input/output gstate pointer
234  *
235  * Makes a copy of the current state of @gstate and saves it
236  * to @gstate->next, then put the address of the newly allcated
237  * copy into @gstate.  _cairo_gstate_restore() reverses this.
238  **/
239 cairo_status_t
240 _cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
241 {
242     cairo_gstate_t *top;
243     cairo_status_t status;
244
245     if (CAIRO_INJECT_FAULT ())
246         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
247
248     top = *freelist;
249     if (top == NULL) {
250         top = malloc (sizeof (cairo_gstate_t));
251         if (unlikely (top == NULL))
252             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
253     } else
254         *freelist = top->next;
255
256     status = _cairo_gstate_init_copy (top, *gstate);
257     if (unlikely (status)) {
258         top->next = *freelist;
259         *freelist = top;
260         return status;
261     }
262
263     top->next = *gstate;
264     *gstate = top;
265
266     return CAIRO_STATUS_SUCCESS;
267 }
268
269 /**
270  * _cairo_gstate_restore:
271  * @gstate: input/output gstate pointer
272  *
273  * Reverses the effects of one _cairo_gstate_save() call.
274  **/
275 cairo_status_t
276 _cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
277 {
278     cairo_gstate_t *top;
279
280     top = *gstate;
281     if (top->next == NULL)
282         return _cairo_error (CAIRO_STATUS_INVALID_RESTORE);
283
284     *gstate = top->next;
285
286     _cairo_gstate_fini (top);
287     VG (VALGRIND_MAKE_MEM_UNDEFINED (&top->next, sizeof (cairo_gstate_t *)));
288     top->next = *freelist;
289     *freelist = top;
290
291     return CAIRO_STATUS_SUCCESS;
292 }
293
294 /**
295  * _cairo_gstate_redirect_target:
296  * @gstate: a #cairo_gstate_t
297  * @child: the new child target
298  *
299  * Redirect @gstate rendering to a "child" target. The original
300  * "parent" target with which the gstate was created will not be
301  * affected. See _cairo_gstate_get_target().
302  **/
303 cairo_status_t
304 _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
305 {
306     /* If this gstate is already redirected, this is an error; we need a
307      * new gstate to be able to redirect */
308     assert (gstate->parent_target == NULL);
309
310     /* Set up our new parent_target based on our current target;
311      * gstate->parent_target will take the ref that is held by gstate->target
312      */
313     gstate->parent_target = gstate->target;
314
315     /* Now set up our new target; we overwrite gstate->target directly,
316      * since its ref is now owned by gstate->parent_target */
317     gstate->target = cairo_surface_reference (child);
318     gstate->is_identity &= _cairo_matrix_is_identity (&child->device_transform);
319     cairo_list_move (&gstate->device_transform_observer.link,
320                      &gstate->target->device_transform_observers);
321
322     /* The clip is in surface backend coordinates for the previous target;
323      * translate it into the child's backend coordinates. */
324     _cairo_clip_destroy (gstate->clip);
325     gstate->clip = _cairo_clip_copy_with_translation (gstate->next->clip,
326                                                       child->device_transform.x0 - gstate->parent_target->device_transform.x0,
327                                                       child->device_transform.y0 - gstate->parent_target->device_transform.y0);
328
329     return CAIRO_STATUS_SUCCESS;
330 }
331
332 /**
333  * _cairo_gstate_is_group:
334  * @gstate: a #cairo_gstate_t
335  *
336  * Check if _cairo_gstate_redirect_target has been called on the head
337  * of the stack.
338  *
339  * Return value: %TRUE if @gstate is redirected to a target different
340  * than the previous state in the stack, %FALSE otherwise.
341  **/
342 cairo_bool_t
343 _cairo_gstate_is_group (cairo_gstate_t *gstate)
344 {
345     return gstate->parent_target != NULL;
346 }
347
348 /**
349  * _cairo_gstate_get_target:
350  * @gstate: a #cairo_gstate_t
351  *
352  * Return the current drawing target; if drawing is not redirected,
353  * this will be the same as _cairo_gstate_get_original_target().
354  *
355  * Return value: the current target surface
356  **/
357 cairo_surface_t *
358 _cairo_gstate_get_target (cairo_gstate_t *gstate)
359 {
360     return gstate->target;
361 }
362
363 /**
364  * _cairo_gstate_get_original_target:
365  * @gstate: a #cairo_gstate_t
366  *
367  * Return the original target with which @gstate was created. This
368  * function always returns the original target independent of any
369  * child target that may have been set with
370  * _cairo_gstate_redirect_target.
371  *
372  * Return value: the original target surface
373  **/
374 cairo_surface_t *
375 _cairo_gstate_get_original_target (cairo_gstate_t *gstate)
376 {
377     return gstate->original_target;
378 }
379
380 /**
381  * _cairo_gstate_get_clip:
382  * @gstate: a #cairo_gstate_t
383  *
384  * This space left intentionally blank.
385  *
386  * Return value: a pointer to the gstate's #cairo_clip_t structure.
387  **/
388 cairo_clip_t *
389 _cairo_gstate_get_clip (cairo_gstate_t *gstate)
390 {
391     return gstate->clip;
392 }
393
394 cairo_status_t
395 _cairo_gstate_set_source (cairo_gstate_t  *gstate,
396                           cairo_pattern_t *source)
397 {
398     if (source->status)
399         return source->status;
400
401     source = cairo_pattern_reference (source);
402     cairo_pattern_destroy (gstate->source);
403     gstate->source = source;
404     gstate->source_ctm_inverse = gstate->ctm_inverse;
405
406     return CAIRO_STATUS_SUCCESS;
407 }
408
409 cairo_pattern_t *
410 _cairo_gstate_get_source (cairo_gstate_t *gstate)
411 {
412     if (gstate->source == &_cairo_pattern_black.base) {
413         /* do not expose the static object to the user */
414         gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
415     }
416
417     return gstate->source;
418 }
419
420 cairo_status_t
421 _cairo_gstate_set_operator (cairo_gstate_t *gstate, cairo_operator_t op)
422 {
423     gstate->op = op;
424
425     return CAIRO_STATUS_SUCCESS;
426 }
427
428 cairo_operator_t
429 _cairo_gstate_get_operator (cairo_gstate_t *gstate)
430 {
431     return gstate->op;
432 }
433
434 cairo_status_t
435 _cairo_gstate_set_opacity (cairo_gstate_t *gstate, double op)
436 {
437     gstate->opacity = op;
438
439     return CAIRO_STATUS_SUCCESS;
440 }
441
442 double
443 _cairo_gstate_get_opacity (cairo_gstate_t *gstate)
444 {
445     return gstate->opacity;
446 }
447
448 cairo_status_t
449 _cairo_gstate_set_tolerance (cairo_gstate_t *gstate, double tolerance)
450 {
451     gstate->tolerance = tolerance;
452
453     return CAIRO_STATUS_SUCCESS;
454 }
455
456 double
457 _cairo_gstate_get_tolerance (cairo_gstate_t *gstate)
458 {
459     return gstate->tolerance;
460 }
461
462 cairo_status_t
463 _cairo_gstate_set_fill_rule (cairo_gstate_t *gstate, cairo_fill_rule_t fill_rule)
464 {
465     gstate->fill_rule = fill_rule;
466
467     return CAIRO_STATUS_SUCCESS;
468 }
469
470 cairo_fill_rule_t
471 _cairo_gstate_get_fill_rule (cairo_gstate_t *gstate)
472 {
473     return gstate->fill_rule;
474 }
475
476 cairo_status_t
477 _cairo_gstate_set_line_width (cairo_gstate_t *gstate, double width)
478 {
479     gstate->stroke_style.line_width = width;
480
481     return CAIRO_STATUS_SUCCESS;
482 }
483
484 double
485 _cairo_gstate_get_line_width (cairo_gstate_t *gstate)
486 {
487     return gstate->stroke_style.line_width;
488 }
489
490 cairo_status_t
491 _cairo_gstate_set_line_cap (cairo_gstate_t *gstate, cairo_line_cap_t line_cap)
492 {
493     gstate->stroke_style.line_cap = line_cap;
494
495     return CAIRO_STATUS_SUCCESS;
496 }
497
498 cairo_line_cap_t
499 _cairo_gstate_get_line_cap (cairo_gstate_t *gstate)
500 {
501     return gstate->stroke_style.line_cap;
502 }
503
504 cairo_status_t
505 _cairo_gstate_set_line_join (cairo_gstate_t *gstate, cairo_line_join_t line_join)
506 {
507     gstate->stroke_style.line_join = line_join;
508
509     return CAIRO_STATUS_SUCCESS;
510 }
511
512 cairo_line_join_t
513 _cairo_gstate_get_line_join (cairo_gstate_t *gstate)
514 {
515     return gstate->stroke_style.line_join;
516 }
517
518 cairo_status_t
519 _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dashes, double offset)
520 {
521     double dash_total, on_total, off_total;
522     int i, j;
523
524     free (gstate->stroke_style.dash);
525
526     gstate->stroke_style.num_dashes = num_dashes;
527
528     if (gstate->stroke_style.num_dashes == 0) {
529         gstate->stroke_style.dash = NULL;
530         gstate->stroke_style.dash_offset = 0.0;
531         return CAIRO_STATUS_SUCCESS;
532     }
533
534     gstate->stroke_style.dash = _cairo_malloc_ab (gstate->stroke_style.num_dashes, sizeof (double));
535     if (unlikely (gstate->stroke_style.dash == NULL)) {
536         gstate->stroke_style.num_dashes = 0;
537         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
538     }
539
540     on_total = off_total = dash_total = 0.0;
541     for (i = j = 0; i < num_dashes; i++) {
542         if (dash[i] < 0)
543             return _cairo_error (CAIRO_STATUS_INVALID_DASH);
544
545         if (dash[i] == 0 && i > 0 && i < num_dashes - 1) {
546             if (dash[++i] < 0)
547                 return _cairo_error (CAIRO_STATUS_INVALID_DASH);
548
549             gstate->stroke_style.dash[j-1] += dash[i];
550             gstate->stroke_style.num_dashes -= 2;
551         } else
552             gstate->stroke_style.dash[j++] = dash[i];
553
554         if (dash[i]) {
555             dash_total += dash[i];
556             if ((i & 1) == 0)
557                 on_total += dash[i];
558             else
559                 off_total += dash[i];
560         }
561     }
562
563     if (dash_total == 0.0)
564         return _cairo_error (CAIRO_STATUS_INVALID_DASH);
565
566     /* An odd dash value indicate symmetric repeating, so the total
567      * is twice as long. */
568     if (gstate->stroke_style.num_dashes & 1) {
569         dash_total *= 2;
570         on_total += off_total;
571     }
572
573     if (dash_total - on_total < CAIRO_FIXED_ERROR_DOUBLE) {
574         /* Degenerate dash -> solid line */
575         free (gstate->stroke_style.dash);
576         gstate->stroke_style.dash = NULL;
577         gstate->stroke_style.num_dashes = 0;
578         gstate->stroke_style.dash_offset = 0.0;
579         return CAIRO_STATUS_SUCCESS;
580     }
581
582     /* The dashing code doesn't like a negative offset or a big positive
583      * offset, so we compute an equivalent offset which is guaranteed to be
584      * positive and less than twice the pattern length. */
585     offset = fmod (offset, dash_total);
586     if (offset < 0.0)
587         offset += dash_total;
588     if (offset <= 0.0)          /* Take care of -0 */
589         offset = 0.0;
590     gstate->stroke_style.dash_offset = offset;
591
592     return CAIRO_STATUS_SUCCESS;
593 }
594
595 void
596 _cairo_gstate_get_dash (cairo_gstate_t *gstate,
597                         double         *dashes,
598                         int            *num_dashes,
599                         double         *offset)
600 {
601     if (dashes) {
602         memcpy (dashes,
603                 gstate->stroke_style.dash,
604                 sizeof (double) * gstate->stroke_style.num_dashes);
605     }
606
607     if (num_dashes)
608         *num_dashes = gstate->stroke_style.num_dashes;
609
610     if (offset)
611         *offset = gstate->stroke_style.dash_offset;
612 }
613
614 cairo_status_t
615 _cairo_gstate_set_miter_limit (cairo_gstate_t *gstate, double limit)
616 {
617     gstate->stroke_style.miter_limit = limit;
618
619     return CAIRO_STATUS_SUCCESS;
620 }
621
622 double
623 _cairo_gstate_get_miter_limit (cairo_gstate_t *gstate)
624 {
625     return gstate->stroke_style.miter_limit;
626 }
627
628 void
629 _cairo_gstate_get_matrix (cairo_gstate_t *gstate, cairo_matrix_t *matrix)
630 {
631     *matrix = gstate->ctm;
632 }
633
634 cairo_status_t
635 _cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty)
636 {
637     cairo_matrix_t tmp;
638
639     if (! ISFINITE (tx) || ! ISFINITE (ty))
640         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
641
642     _cairo_gstate_unset_scaled_font (gstate);
643
644     cairo_matrix_init_translate (&tmp, tx, ty);
645     cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
646     gstate->is_identity = FALSE;
647
648     /* paranoid check against gradual numerical instability */
649     if (! _cairo_matrix_is_invertible (&gstate->ctm))
650         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
651
652     cairo_matrix_init_translate (&tmp, -tx, -ty);
653     cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
654
655     return CAIRO_STATUS_SUCCESS;
656 }
657
658 cairo_status_t
659 _cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy)
660 {
661     cairo_matrix_t tmp;
662
663     if (sx * sy == 0.) /* either sx or sy is 0, or det == 0 due to underflow */
664         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
665     if (! ISFINITE (sx) || ! ISFINITE (sy))
666         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
667
668     _cairo_gstate_unset_scaled_font (gstate);
669
670     cairo_matrix_init_scale (&tmp, sx, sy);
671     cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
672     gstate->is_identity = FALSE;
673
674     /* paranoid check against gradual numerical instability */
675     if (! _cairo_matrix_is_invertible (&gstate->ctm))
676         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
677
678     cairo_matrix_init_scale (&tmp, 1/sx, 1/sy);
679     cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
680
681     return CAIRO_STATUS_SUCCESS;
682 }
683
684 cairo_status_t
685 _cairo_gstate_rotate (cairo_gstate_t *gstate, double angle)
686 {
687     cairo_matrix_t tmp;
688
689     if (angle == 0.)
690         return CAIRO_STATUS_SUCCESS;
691
692     if (! ISFINITE (angle))
693         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
694
695     _cairo_gstate_unset_scaled_font (gstate);
696
697     cairo_matrix_init_rotate (&tmp, angle);
698     cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
699     gstate->is_identity = FALSE;
700
701     /* paranoid check against gradual numerical instability */
702     if (! _cairo_matrix_is_invertible (&gstate->ctm))
703         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
704
705     cairo_matrix_init_rotate (&tmp, -angle);
706     cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
707
708     return CAIRO_STATUS_SUCCESS;
709 }
710
711 cairo_status_t
712 _cairo_gstate_transform (cairo_gstate_t       *gstate,
713                          const cairo_matrix_t *matrix)
714 {
715     cairo_matrix_t tmp;
716     cairo_status_t status;
717
718     if (! _cairo_matrix_is_invertible (matrix))
719         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
720
721     if (_cairo_matrix_is_identity (matrix))
722         return CAIRO_STATUS_SUCCESS;
723
724     tmp = *matrix;
725     status = cairo_matrix_invert (&tmp);
726     if (unlikely (status))
727         return status;
728
729     _cairo_gstate_unset_scaled_font (gstate);
730
731     cairo_matrix_multiply (&gstate->ctm, matrix, &gstate->ctm);
732     cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
733     gstate->is_identity = FALSE;
734
735     /* paranoid check against gradual numerical instability */
736     if (! _cairo_matrix_is_invertible (&gstate->ctm))
737         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
738
739     return CAIRO_STATUS_SUCCESS;
740 }
741
742 cairo_status_t
743 _cairo_gstate_set_matrix (cairo_gstate_t       *gstate,
744                           const cairo_matrix_t *matrix)
745 {
746     cairo_status_t status;
747
748     if (memcmp (matrix, &gstate->ctm, sizeof (cairo_matrix_t)) == 0)
749         return CAIRO_STATUS_SUCCESS;
750
751     if (! _cairo_matrix_is_invertible (matrix))
752         return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
753
754     if (_cairo_matrix_is_identity (matrix)) {
755         _cairo_gstate_identity_matrix (gstate);
756         return CAIRO_STATUS_SUCCESS;
757     }
758
759     _cairo_gstate_unset_scaled_font (gstate);
760
761     gstate->ctm = *matrix;
762     gstate->ctm_inverse = *matrix;
763     status = cairo_matrix_invert (&gstate->ctm_inverse);
764     assert (status == CAIRO_STATUS_SUCCESS);
765     gstate->is_identity = FALSE;
766
767     return CAIRO_STATUS_SUCCESS;
768 }
769
770 void
771 _cairo_gstate_identity_matrix (cairo_gstate_t *gstate)
772 {
773     if (_cairo_matrix_is_identity (&gstate->ctm))
774         return;
775
776     _cairo_gstate_unset_scaled_font (gstate);
777
778     cairo_matrix_init_identity (&gstate->ctm);
779     cairo_matrix_init_identity (&gstate->ctm_inverse);
780     gstate->is_identity = _cairo_matrix_is_identity (&gstate->target->device_transform);
781 }
782
783 void
784 _cairo_gstate_user_to_device (cairo_gstate_t *gstate, double *x, double *y)
785 {
786     cairo_matrix_transform_point (&gstate->ctm, x, y);
787 }
788
789 void
790 _cairo_gstate_user_to_device_distance (cairo_gstate_t *gstate,
791                                        double *dx, double *dy)
792 {
793     cairo_matrix_transform_distance (&gstate->ctm, dx, dy);
794 }
795
796 void
797 _cairo_gstate_device_to_user (cairo_gstate_t *gstate, double *x, double *y)
798 {
799     cairo_matrix_transform_point (&gstate->ctm_inverse, x, y);
800 }
801
802 void
803 _cairo_gstate_device_to_user_distance (cairo_gstate_t *gstate,
804                                        double *dx, double *dy)
805 {
806     cairo_matrix_transform_distance (&gstate->ctm_inverse, dx, dy);
807 }
808
809 void
810 _do_cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y)
811 {
812     cairo_matrix_transform_point (&gstate->ctm, x, y);
813     cairo_matrix_transform_point (&gstate->target->device_transform, x, y);
814 }
815
816 void
817 _do_cairo_gstate_user_to_backend_distance (cairo_gstate_t *gstate, double *x, double *y)
818 {
819     cairo_matrix_transform_distance (&gstate->ctm, x, y);
820     cairo_matrix_transform_distance (&gstate->target->device_transform, x, y);
821 }
822
823 void
824 _do_cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y)
825 {
826     cairo_matrix_transform_point (&gstate->target->device_transform_inverse, x, y);
827     cairo_matrix_transform_point (&gstate->ctm_inverse, x, y);
828 }
829
830 void
831 _do_cairo_gstate_backend_to_user_distance (cairo_gstate_t *gstate, double *x, double *y)
832 {
833     cairo_matrix_transform_distance (&gstate->target->device_transform_inverse, x, y);
834     cairo_matrix_transform_distance (&gstate->ctm_inverse, x, y);
835 }
836
837 void
838 _cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate,
839                                          double *x1, double *y1,
840                                          double *x2, double *y2,
841                                          cairo_bool_t *is_tight)
842 {
843     cairo_matrix_t matrix_inverse;
844
845     if (! _cairo_matrix_is_identity (&gstate->target->device_transform_inverse) ||
846     ! _cairo_matrix_is_identity (&gstate->ctm_inverse))
847     {
848         cairo_matrix_multiply (&matrix_inverse,
849                                &gstate->target->device_transform_inverse,
850                                &gstate->ctm_inverse);
851         _cairo_matrix_transform_bounding_box (&matrix_inverse,
852                                               x1, y1, x2, y2, is_tight);
853     }
854
855     else
856     {
857         if (is_tight)
858             *is_tight = TRUE;
859     }
860 }
861
862 /* XXX: NYI
863 cairo_status_t
864 _cairo_gstate_stroke_to_path (cairo_gstate_t *gstate)
865 {
866     cairo_status_t status;
867
868     _cairo_pen_init (&gstate);
869     return CAIRO_STATUS_SUCCESS;
870 }
871 */
872
873 void
874 _cairo_gstate_path_extents (cairo_gstate_t     *gstate,
875                             cairo_path_fixed_t *path,
876                             double *x1, double *y1,
877                             double *x2, double *y2)
878 {
879     cairo_box_t box;
880     double px1, py1, px2, py2;
881
882     if (_cairo_path_fixed_extents (path, &box)) {
883         px1 = _cairo_fixed_to_double (box.p1.x);
884         py1 = _cairo_fixed_to_double (box.p1.y);
885         px2 = _cairo_fixed_to_double (box.p2.x);
886         py2 = _cairo_fixed_to_double (box.p2.y);
887
888         _cairo_gstate_backend_to_user_rectangle (gstate,
889                                                  &px1, &py1, &px2, &py2,
890                                                  NULL);
891     } else {
892         px1 = 0.0;
893         py1 = 0.0;
894         px2 = 0.0;
895         py2 = 0.0;
896     }
897
898     if (x1)
899         *x1 = px1;
900     if (y1)
901         *y1 = py1;
902     if (x2)
903         *x2 = px2;
904     if (y2)
905         *y2 = py2;
906 }
907
908 static void
909 _cairo_gstate_copy_pattern (cairo_pattern_t *pattern,
910                             const cairo_pattern_t *original)
911 {
912     /* First check if the we can replace the original with a much simpler
913      * pattern. For example, gradients that are uniform or just have a single
914      * stop can sometimes be replaced with a solid.
915      */
916
917     if (_cairo_pattern_is_clear (original)) {
918         _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern,
919                                    CAIRO_COLOR_TRANSPARENT);
920         return;
921     }
922
923     if (original->type == CAIRO_PATTERN_TYPE_LINEAR ||
924         original->type == CAIRO_PATTERN_TYPE_RADIAL)
925     {
926         cairo_color_t color;
927         if (_cairo_gradient_pattern_is_solid ((cairo_gradient_pattern_t *) original,
928                                               NULL,
929                                               &color))
930         {
931             _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern,
932                                        &color);
933             return;
934         }
935     }
936
937     _cairo_pattern_init_static_copy (pattern, original);
938 }
939
940 static void
941 _cairo_gstate_copy_transformed_pattern (cairo_gstate_t  *gstate,
942                                         cairo_pattern_t *pattern,
943                                         const cairo_pattern_t *original,
944                                         const cairo_matrix_t  *ctm_inverse)
945 {
946     _cairo_gstate_copy_pattern (pattern, original);
947
948     /* apply device_transform first so that it is transformed by ctm_inverse */
949     if (original->type == CAIRO_PATTERN_TYPE_SURFACE) {
950         cairo_surface_pattern_t *surface_pattern;
951         cairo_surface_t *surface;
952
953         surface_pattern = (cairo_surface_pattern_t *) original;
954         surface = surface_pattern->surface;
955
956         if (_cairo_surface_has_device_transform (surface))
957             _cairo_pattern_transform (pattern, &surface->device_transform);
958     }
959
960     if (! _cairo_matrix_is_identity (ctm_inverse))
961         _cairo_pattern_transform (pattern, ctm_inverse);
962
963     if (_cairo_surface_has_device_transform (gstate->target)) {
964         _cairo_pattern_transform (pattern,
965                                   &gstate->target->device_transform_inverse);
966     }
967 }
968
969 static void
970 _cairo_gstate_copy_transformed_source (cairo_gstate_t   *gstate,
971                                        cairo_pattern_t  *pattern)
972 {
973     _cairo_gstate_copy_transformed_pattern (gstate, pattern,
974                                             gstate->source,
975                                             &gstate->source_ctm_inverse);
976 }
977
978 static void
979 _cairo_gstate_copy_transformed_mask (cairo_gstate_t   *gstate,
980                                      cairo_pattern_t  *pattern,
981                                      cairo_pattern_t  *mask)
982 {
983     _cairo_gstate_copy_transformed_pattern (gstate, pattern,
984                                             mask,
985                                             &gstate->ctm_inverse);
986 }
987
988 static cairo_operator_t
989 _reduce_op (cairo_gstate_t *gstate)
990 {
991     cairo_operator_t op;
992     const cairo_pattern_t *pattern;
993
994     op = gstate->op;
995     if (op != CAIRO_OPERATOR_SOURCE)
996         return op;
997
998     pattern = gstate->source;
999     if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
1000         const cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern;
1001         if (solid->color.alpha_short <= 0x00ff) {
1002             op = CAIRO_OPERATOR_CLEAR;
1003         } else if ((gstate->target->content & CAIRO_CONTENT_ALPHA) == 0) {
1004             if ((solid->color.red_short |
1005                  solid->color.green_short |
1006                  solid->color.blue_short) <= 0x00ff)
1007             {
1008                 op = CAIRO_OPERATOR_CLEAR;
1009             }
1010         }
1011     } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
1012         const cairo_surface_pattern_t *surface = (cairo_surface_pattern_t *) pattern;
1013         if (surface->surface->is_clear &&
1014             surface->surface->content & CAIRO_CONTENT_ALPHA)
1015         {
1016             op = CAIRO_OPERATOR_CLEAR;
1017         }
1018     } else {
1019         const cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t *) pattern;
1020         if (gradient->n_stops == 0)
1021             op = CAIRO_OPERATOR_CLEAR;
1022     }
1023
1024     return op;
1025 }
1026
1027 static cairo_status_t
1028 _cairo_gstate_get_pattern_status (const cairo_pattern_t *pattern)
1029 {
1030     if (unlikely (pattern->type == CAIRO_PATTERN_TYPE_MESH &&
1031                   ((const cairo_mesh_pattern_t *) pattern)->current_patch))
1032     {
1033         /* If current patch != NULL, the pattern is under construction
1034          * and cannot be used as a source */
1035         return CAIRO_STATUS_INVALID_MESH_CONSTRUCTION;
1036     }
1037
1038     return pattern->status;
1039 }
1040
1041 cairo_status_t
1042 _cairo_gstate_paint (cairo_gstate_t *gstate)
1043 {
1044     cairo_pattern_union_t source_pattern;
1045     const cairo_pattern_t *pattern;
1046     cairo_status_t status;
1047     cairo_operator_t op;
1048
1049     status = _cairo_gstate_get_pattern_status (gstate->source);
1050     if (unlikely (status))
1051         return status;
1052
1053     if (gstate->op == CAIRO_OPERATOR_DEST)
1054         return CAIRO_STATUS_SUCCESS;
1055
1056     if (_cairo_clip_is_all_clipped (gstate->clip))
1057         return CAIRO_STATUS_SUCCESS;
1058
1059     op = _reduce_op (gstate);
1060     if (op == CAIRO_OPERATOR_CLEAR) {
1061         pattern = &_cairo_pattern_clear.base;
1062     } else {
1063         _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
1064         pattern = &source_pattern.base;
1065     }
1066
1067     return _cairo_surface_paint (gstate->target,
1068                                  op, pattern,
1069                                  gstate->clip);
1070 }
1071
1072 cairo_status_t
1073 _cairo_gstate_mask (cairo_gstate_t  *gstate,
1074                     cairo_pattern_t *mask)
1075 {
1076     cairo_pattern_union_t source_pattern, mask_pattern;
1077     const cairo_pattern_t *source;
1078     cairo_operator_t op;
1079     cairo_status_t status;
1080
1081     status = _cairo_gstate_get_pattern_status (mask);
1082     if (unlikely (status))
1083         return status;
1084
1085     status = _cairo_gstate_get_pattern_status (gstate->source);
1086     if (unlikely (status))
1087         return status;
1088
1089     if (gstate->op == CAIRO_OPERATOR_DEST)
1090         return CAIRO_STATUS_SUCCESS;
1091
1092     if (_cairo_clip_is_all_clipped (gstate->clip))
1093         return CAIRO_STATUS_SUCCESS;
1094
1095     assert (gstate->opacity == 1.0);
1096
1097     if (_cairo_pattern_is_opaque (mask, NULL))
1098         return _cairo_gstate_paint (gstate);
1099
1100     if (_cairo_pattern_is_clear (mask) &&
1101         _cairo_operator_bounded_by_mask (gstate->op))
1102     {
1103         return CAIRO_STATUS_SUCCESS;
1104     }
1105
1106     op = _reduce_op (gstate);
1107     if (op == CAIRO_OPERATOR_CLEAR) {
1108         source = &_cairo_pattern_clear.base;
1109     } else {
1110         _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
1111         source = &source_pattern.base;
1112     }
1113     _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
1114
1115     if (source->type == CAIRO_PATTERN_TYPE_SOLID &&
1116         mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID &&
1117         _cairo_operator_bounded_by_source (op))
1118     {
1119         const cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
1120         cairo_color_t combined;
1121
1122         if (mask_pattern.base.has_component_alpha) {
1123 #define M(R, A, B, c) R.c = A.c * B.c
1124             M(combined, solid->color, mask_pattern.solid.color, red);
1125             M(combined, solid->color, mask_pattern.solid.color, green);
1126             M(combined, solid->color, mask_pattern.solid.color, blue);
1127             M(combined, solid->color, mask_pattern.solid.color, alpha);
1128 #undef M
1129         } else {
1130             combined = solid->color;
1131             _cairo_color_multiply_alpha (&combined, mask_pattern.solid.color.alpha);
1132         }
1133
1134         _cairo_pattern_init_solid (&source_pattern.solid, &combined);
1135
1136         status = _cairo_surface_paint (gstate->target, op,
1137                                        &source_pattern.base,
1138                                        gstate->clip);
1139     }
1140     else
1141     {
1142         status = _cairo_surface_mask (gstate->target, op,
1143                                       source,
1144                                       &mask_pattern.base,
1145                                       gstate->clip);
1146     }
1147
1148     return status;
1149 }
1150
1151 cairo_status_t
1152 _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
1153 {
1154     cairo_pattern_union_t source_pattern;
1155     cairo_stroke_style_t style;
1156     double dash[2];
1157     cairo_status_t status;
1158
1159     status = _cairo_gstate_get_pattern_status (gstate->source);
1160     if (unlikely (status))
1161         return status;
1162
1163     if (gstate->op == CAIRO_OPERATOR_DEST)
1164         return CAIRO_STATUS_SUCCESS;
1165
1166     if (gstate->stroke_style.line_width <= 0.0)
1167         return CAIRO_STATUS_SUCCESS;
1168
1169     if (_cairo_clip_is_all_clipped (gstate->clip))
1170         return CAIRO_STATUS_SUCCESS;
1171
1172     assert (gstate->opacity == 1.0);
1173
1174     memcpy (&style, &gstate->stroke_style, sizeof (gstate->stroke_style));
1175     if (_cairo_stroke_style_dash_can_approximate (&gstate->stroke_style, &gstate->ctm, gstate->tolerance)) {
1176         style.dash = dash;
1177         _cairo_stroke_style_dash_approximate (&gstate->stroke_style, &gstate->ctm, gstate->tolerance,
1178                                               &style.dash_offset,
1179                                               style.dash,
1180                                               &style.num_dashes);
1181     }
1182
1183     _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
1184
1185     return _cairo_surface_stroke (gstate->target,
1186                                   gstate->op,
1187                                   &source_pattern.base,
1188                                   path,
1189                                   &style,
1190                                   &gstate->ctm,
1191                                   &gstate->ctm_inverse,
1192                                   gstate->tolerance,
1193                                   gstate->antialias,
1194                                   gstate->clip);
1195 }
1196
1197 cairo_status_t
1198 _cairo_gstate_in_stroke (cairo_gstate_t     *gstate,
1199                          cairo_path_fixed_t *path,
1200                          double              x,
1201                          double              y,
1202                          cairo_bool_t       *inside_ret)
1203 {
1204     cairo_status_t status;
1205     cairo_rectangle_int_t extents;
1206     cairo_box_t limit;
1207     cairo_traps_t traps;
1208
1209     if (gstate->stroke_style.line_width <= 0.0) {
1210         *inside_ret = FALSE;
1211         return CAIRO_STATUS_SUCCESS;
1212     }
1213
1214     _cairo_gstate_user_to_backend (gstate, &x, &y);
1215
1216     /* Before we perform the expensive stroke analysis,
1217      * check whether the point is within the extents of the path.
1218      */
1219     _cairo_path_fixed_approximate_stroke_extents (path,
1220                                                   &gstate->stroke_style,
1221                                                   &gstate->ctm,
1222                                                   &extents);
1223     if (x < extents.x || x > extents.x + extents.width ||
1224         y < extents.y || y > extents.y + extents.height)
1225     {
1226         *inside_ret = FALSE;
1227         return CAIRO_STATUS_SUCCESS;
1228     }
1229
1230     limit.p1.x = _cairo_fixed_from_double (x) - 1;
1231     limit.p1.y = _cairo_fixed_from_double (y) - 1;
1232     limit.p2.x = limit.p1.x + 2;
1233     limit.p2.y = limit.p1.y + 2;
1234
1235     _cairo_traps_init (&traps);
1236     _cairo_traps_limit (&traps, &limit, 1);
1237
1238     status = _cairo_path_fixed_stroke_to_traps (path,
1239                                                 &gstate->stroke_style,
1240                                                 &gstate->ctm,
1241                                                 &gstate->ctm_inverse,
1242                                                 gstate->tolerance,
1243                                                 &traps);
1244     if (unlikely (status))
1245         goto BAIL;
1246
1247     *inside_ret = _cairo_traps_contain (&traps, x, y);
1248
1249 BAIL:
1250     _cairo_traps_fini (&traps);
1251
1252     return status;
1253 }
1254
1255 cairo_status_t
1256 _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
1257 {
1258     cairo_status_t status;
1259
1260     status = _cairo_gstate_get_pattern_status (gstate->source);
1261     if (unlikely (status))
1262         return status;
1263
1264     if (gstate->op == CAIRO_OPERATOR_DEST)
1265         return CAIRO_STATUS_SUCCESS;
1266
1267     if (_cairo_clip_is_all_clipped (gstate->clip))
1268         return CAIRO_STATUS_SUCCESS;
1269
1270     assert (gstate->opacity == 1.0);
1271
1272     if (_cairo_path_fixed_fill_is_empty (path)) {
1273         if (_cairo_operator_bounded_by_mask (gstate->op))
1274             return CAIRO_STATUS_SUCCESS;
1275
1276         status = _cairo_surface_paint (gstate->target,
1277                                        CAIRO_OPERATOR_CLEAR,
1278                                        &_cairo_pattern_clear.base,
1279                                        gstate->clip);
1280     } else {
1281         cairo_pattern_union_t source_pattern;
1282         const cairo_pattern_t *pattern;
1283         cairo_operator_t op;
1284         cairo_rectangle_int_t extents;
1285         cairo_box_t box;
1286
1287         op = _reduce_op (gstate);
1288         if (op == CAIRO_OPERATOR_CLEAR) {
1289             pattern = &_cairo_pattern_clear.base;
1290         } else {
1291             _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
1292             pattern = &source_pattern.base;
1293         }
1294
1295         /* Toolkits often paint the entire background with a fill */
1296         if (_cairo_surface_get_extents (gstate->target, &extents) &&
1297             _cairo_path_fixed_is_box (path, &box) &&
1298             box.p1.x <= _cairo_fixed_from_int (extents.x) &&
1299             box.p1.y <= _cairo_fixed_from_int (extents.y) &&
1300             box.p2.x >= _cairo_fixed_from_int (extents.x + extents.width) &&
1301             box.p2.y >= _cairo_fixed_from_int (extents.y + extents.height))
1302         {
1303             status = _cairo_surface_paint (gstate->target, op, pattern,
1304                                            gstate->clip);
1305         }
1306         else
1307         {
1308             status = _cairo_surface_fill (gstate->target, op, pattern,
1309                                           path,
1310                                           gstate->fill_rule,
1311                                           gstate->tolerance,
1312                                           gstate->antialias,
1313                                           gstate->clip);
1314         }
1315     }
1316
1317     return status;
1318 }
1319
1320 cairo_bool_t
1321 _cairo_gstate_in_fill (cairo_gstate_t     *gstate,
1322                        cairo_path_fixed_t *path,
1323                        double              x,
1324                        double              y)
1325 {
1326     _cairo_gstate_user_to_backend (gstate, &x, &y);
1327
1328     return _cairo_path_fixed_in_fill (path,
1329                                       gstate->fill_rule,
1330                                       gstate->tolerance,
1331                                       x, y);
1332 }
1333
1334 cairo_bool_t
1335 _cairo_gstate_in_clip (cairo_gstate_t     *gstate,
1336                        double              x,
1337                        double              y)
1338 {
1339     cairo_clip_t *clip = gstate->clip;
1340     int i;
1341
1342     if (_cairo_clip_is_all_clipped (clip))
1343         return FALSE;
1344
1345     if (clip == NULL)
1346         return TRUE;
1347
1348     _cairo_gstate_user_to_backend (gstate, &x, &y);
1349
1350     if (x <  clip->extents.x ||
1351         x >= clip->extents.x + clip->extents.width ||
1352         y <  clip->extents.y ||
1353         y >= clip->extents.y + clip->extents.height)
1354     {
1355         return FALSE;
1356     }
1357
1358     if (clip->num_boxes) {
1359         int fx, fy;
1360
1361         fx = _cairo_fixed_from_double (x);
1362         fy = _cairo_fixed_from_double (y);
1363         for (i = 0; i < clip->num_boxes; i++) {
1364             if (fx >= clip->boxes[i].p1.x && fx <= clip->boxes[i].p2.x &&
1365                 fy >= clip->boxes[i].p1.y && fy <= clip->boxes[i].p2.y)
1366                 break;
1367         }
1368         if (i == clip->num_boxes)
1369             return FALSE;
1370     }
1371
1372     if (clip->path) {
1373         cairo_clip_path_t *clip_path = clip->path;
1374         do {
1375             if (! _cairo_path_fixed_in_fill (&clip_path->path,
1376                                              clip_path->fill_rule,
1377                                              clip_path->tolerance,
1378                                              x, y))
1379                 return FALSE;
1380         } while ((clip_path = clip_path->prev) != NULL);
1381     }
1382
1383     return TRUE;
1384 }
1385
1386 cairo_status_t
1387 _cairo_gstate_copy_page (cairo_gstate_t *gstate)
1388 {
1389     cairo_surface_copy_page (gstate->target);
1390     return cairo_surface_status (gstate->target);
1391 }
1392
1393 cairo_status_t
1394 _cairo_gstate_show_page (cairo_gstate_t *gstate)
1395 {
1396     cairo_surface_show_page (gstate->target);
1397     return cairo_surface_status (gstate->target);
1398 }
1399
1400 static void
1401 _cairo_gstate_extents_to_user_rectangle (cairo_gstate_t   *gstate,
1402                                          const cairo_box_t *extents,
1403                                          double *x1, double *y1,
1404                                          double *x2, double *y2)
1405 {
1406     double px1, py1, px2, py2;
1407
1408     px1 = _cairo_fixed_to_double (extents->p1.x);
1409     py1 = _cairo_fixed_to_double (extents->p1.y);
1410     px2 = _cairo_fixed_to_double (extents->p2.x);
1411     py2 = _cairo_fixed_to_double (extents->p2.y);
1412
1413     _cairo_gstate_backend_to_user_rectangle (gstate,
1414                                              &px1, &py1, &px2, &py2,
1415                                              NULL);
1416     if (x1)
1417         *x1 = px1;
1418     if (y1)
1419         *y1 = py1;
1420     if (x2)
1421         *x2 = px2;
1422     if (y2)
1423         *y2 = py2;
1424 }
1425
1426 cairo_status_t
1427 _cairo_gstate_stroke_extents (cairo_gstate_t     *gstate,
1428                               cairo_path_fixed_t *path,
1429                               double *x1, double *y1,
1430                               double *x2, double *y2)
1431 {
1432     cairo_int_status_t status;
1433     cairo_box_t extents;
1434     cairo_bool_t empty;
1435
1436     if (x1)
1437         *x1 = 0.0;
1438     if (y1)
1439         *y1 = 0.0;
1440     if (x2)
1441         *x2 = 0.0;
1442     if (y2)
1443         *y2 = 0.0;
1444
1445     if (gstate->stroke_style.line_width <= 0.0)
1446         return CAIRO_STATUS_SUCCESS;
1447
1448     status = CAIRO_INT_STATUS_UNSUPPORTED;
1449     if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
1450         cairo_boxes_t boxes;
1451
1452         _cairo_boxes_init (&boxes);
1453         status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path,
1454                                                                 &gstate->stroke_style,
1455                                                                 &gstate->ctm,
1456                                                                 gstate->antialias,
1457                                                                 &boxes);
1458         empty = boxes.num_boxes == 0;
1459         if (! empty)
1460             _cairo_boxes_extents (&boxes, &extents);
1461         _cairo_boxes_fini (&boxes);
1462     }
1463
1464     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
1465         cairo_traps_t traps;
1466
1467         _cairo_traps_init (&traps);
1468         status = _cairo_path_fixed_stroke_to_traps (path,
1469                                                     &gstate->stroke_style,
1470                                                     &gstate->ctm,
1471                                                     &gstate->ctm_inverse,
1472                                                     gstate->tolerance,
1473                                                     &traps);
1474         empty = traps.num_traps == 0;
1475         if (! empty)
1476             _cairo_traps_extents (&traps, &extents);
1477         _cairo_traps_fini (&traps);
1478     }
1479     if (! empty) {
1480         _cairo_gstate_extents_to_user_rectangle (gstate, &extents,
1481                                                  x1, y1, x2, y2);
1482     }
1483
1484     return status;
1485 }
1486
1487 cairo_status_t
1488 _cairo_gstate_fill_extents (cairo_gstate_t     *gstate,
1489                             cairo_path_fixed_t *path,
1490                             double *x1, double *y1,
1491                             double *x2, double *y2)
1492 {
1493     cairo_status_t status;
1494     cairo_box_t extents;
1495     cairo_bool_t empty;
1496
1497     if (x1)
1498         *x1 = 0.0;
1499     if (y1)
1500         *y1 = 0.0;
1501     if (x2)
1502         *x2 = 0.0;
1503     if (y2)
1504         *y2 = 0.0;
1505
1506     if (_cairo_path_fixed_fill_is_empty (path))
1507         return CAIRO_STATUS_SUCCESS;
1508
1509     if (_cairo_path_fixed_fill_is_rectilinear (path)) {
1510         cairo_boxes_t boxes;
1511
1512         _cairo_boxes_init (&boxes);
1513         status = _cairo_path_fixed_fill_rectilinear_to_boxes (path,
1514                                                               gstate->fill_rule,
1515                                                               gstate->antialias,
1516                                                               &boxes);
1517         empty = boxes.num_boxes == 0;
1518         if (! empty)
1519             _cairo_boxes_extents (&boxes, &extents);
1520
1521         _cairo_boxes_fini (&boxes);
1522     } else {
1523         cairo_traps_t traps;
1524
1525         _cairo_traps_init (&traps);
1526
1527         status = _cairo_path_fixed_fill_to_traps (path,
1528                                                   gstate->fill_rule,
1529                                                   gstate->tolerance,
1530                                                   &traps);
1531         empty = traps.num_traps == 0;
1532         if (! empty)
1533             _cairo_traps_extents (&traps, &extents);
1534
1535         _cairo_traps_fini (&traps);
1536     }
1537
1538     if (! empty) {
1539         _cairo_gstate_extents_to_user_rectangle (gstate, &extents,
1540                                                  x1, y1, x2, y2);
1541     }
1542
1543     return status;
1544 }
1545
1546 cairo_status_t
1547 _cairo_gstate_reset_clip (cairo_gstate_t *gstate)
1548 {
1549     _cairo_clip_destroy (gstate->clip);
1550     gstate->clip = NULL;
1551
1552     return CAIRO_STATUS_SUCCESS;
1553 }
1554
1555 cairo_status_t
1556 _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
1557 {
1558     gstate->clip =
1559         _cairo_clip_intersect_path (gstate->clip,
1560                                     path,
1561                                     gstate->fill_rule,
1562                                     gstate->tolerance,
1563                                     gstate->antialias);
1564     /* XXX */
1565     return CAIRO_STATUS_SUCCESS;
1566 }
1567
1568 static cairo_bool_t
1569 _cairo_gstate_int_clip_extents (cairo_gstate_t        *gstate,
1570                                 cairo_rectangle_int_t *extents)
1571 {
1572     cairo_bool_t is_bounded;
1573
1574     is_bounded = _cairo_surface_get_extents (gstate->target, extents);
1575
1576     if (gstate->clip) {
1577         _cairo_rectangle_intersect (extents,
1578                                     _cairo_clip_get_extents (gstate->clip));
1579         is_bounded = TRUE;
1580     }
1581
1582     return is_bounded;
1583 }
1584
1585 cairo_bool_t
1586 _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
1587                             double         *x1,
1588                             double         *y1,
1589                             double         *x2,
1590                             double         *y2)
1591 {
1592     cairo_rectangle_int_t extents;
1593     double px1, py1, px2, py2;
1594
1595     if (! _cairo_gstate_int_clip_extents (gstate, &extents))
1596         return FALSE;
1597
1598     px1 = extents.x;
1599     py1 = extents.y;
1600     px2 = extents.x + (int) extents.width;
1601     py2 = extents.y + (int) extents.height;
1602
1603     _cairo_gstate_backend_to_user_rectangle (gstate,
1604                                              &px1, &py1, &px2, &py2,
1605                                              NULL);
1606
1607     if (x1)
1608         *x1 = px1;
1609     if (y1)
1610         *y1 = py1;
1611     if (x2)
1612         *x2 = px2;
1613     if (y2)
1614         *y2 = py2;
1615
1616     return TRUE;
1617 }
1618
1619 cairo_rectangle_list_t*
1620 _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
1621 {
1622     cairo_rectangle_int_t extents;
1623     cairo_rectangle_list_t *list;
1624     cairo_clip_t *clip;
1625
1626     if (_cairo_surface_get_extents (gstate->target, &extents))
1627         clip = _cairo_clip_copy_intersect_rectangle (gstate->clip, &extents);
1628     else
1629         clip = gstate->clip;
1630
1631     list = _cairo_clip_copy_rectangle_list (clip, gstate);
1632
1633     if (clip != gstate->clip)
1634         _cairo_clip_destroy (clip);
1635
1636     return list;
1637 }
1638
1639 static void
1640 _cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate)
1641 {
1642     if (gstate->scaled_font == NULL)
1643         return;
1644
1645     if (gstate->previous_scaled_font != NULL)
1646         cairo_scaled_font_destroy (gstate->previous_scaled_font);
1647
1648     gstate->previous_scaled_font = gstate->scaled_font;
1649     gstate->scaled_font = NULL;
1650 }
1651
1652 cairo_status_t
1653 _cairo_gstate_set_font_size (cairo_gstate_t *gstate,
1654                              double          size)
1655 {
1656     _cairo_gstate_unset_scaled_font (gstate);
1657
1658     cairo_matrix_init_scale (&gstate->font_matrix, size, size);
1659
1660     return CAIRO_STATUS_SUCCESS;
1661 }
1662
1663 cairo_status_t
1664 _cairo_gstate_set_font_matrix (cairo_gstate_t       *gstate,
1665                                const cairo_matrix_t *matrix)
1666 {
1667     if (memcmp (matrix, &gstate->font_matrix, sizeof (cairo_matrix_t)) == 0)
1668         return CAIRO_STATUS_SUCCESS;
1669
1670     _cairo_gstate_unset_scaled_font (gstate);
1671
1672     gstate->font_matrix = *matrix;
1673
1674     return CAIRO_STATUS_SUCCESS;
1675 }
1676
1677 void
1678 _cairo_gstate_get_font_matrix (cairo_gstate_t *gstate,
1679                                cairo_matrix_t *matrix)
1680 {
1681     *matrix = gstate->font_matrix;
1682 }
1683
1684 void
1685 _cairo_gstate_set_font_options (cairo_gstate_t             *gstate,
1686                                 const cairo_font_options_t *options)
1687 {
1688     if (memcmp (options, &gstate->font_options, sizeof (cairo_font_options_t)) == 0)
1689         return;
1690
1691     _cairo_gstate_unset_scaled_font (gstate);
1692
1693     _cairo_font_options_init_copy (&gstate->font_options, options);
1694 }
1695
1696 void
1697 _cairo_gstate_get_font_options (cairo_gstate_t       *gstate,
1698                                 cairo_font_options_t *options)
1699 {
1700     *options = gstate->font_options;
1701 }
1702
1703 cairo_status_t
1704 _cairo_gstate_get_font_face (cairo_gstate_t     *gstate,
1705                              cairo_font_face_t **font_face)
1706 {
1707     cairo_status_t status;
1708
1709     status = _cairo_gstate_ensure_font_face (gstate);
1710     if (unlikely (status))
1711         return status;
1712
1713     *font_face = gstate->font_face;
1714
1715     return CAIRO_STATUS_SUCCESS;
1716 }
1717
1718 cairo_status_t
1719 _cairo_gstate_get_scaled_font (cairo_gstate_t       *gstate,
1720                                cairo_scaled_font_t **scaled_font)
1721 {
1722     cairo_status_t status;
1723
1724     status = _cairo_gstate_ensure_scaled_font (gstate);
1725     if (unlikely (status))
1726         return status;
1727
1728     *scaled_font = gstate->scaled_font;
1729
1730     return CAIRO_STATUS_SUCCESS;
1731 }
1732
1733 /*
1734  * Like everything else in this file, fonts involve Too Many Coordinate Spaces;
1735  * it is easy to get confused about what's going on.
1736  *
1737  * The user's view
1738  * ---------------
1739  *
1740  * Users ask for things in user space. When cairo starts, a user space unit
1741  * is about 1/96 inch, which is similar to (but importantly different from)
1742  * the normal "point" units most users think in terms of. When a user
1743  * selects a font, its scale is set to "one user unit". The user can then
1744  * independently scale the user coordinate system *or* the font matrix, in
1745  * order to adjust the rendered size of the font.
1746  *
1747  * Metrics are returned in user space, whether they are obtained from
1748  * the currently selected font in a  #cairo_t or from a #cairo_scaled_font_t
1749  * which is a font specialized to a particular scale matrix, CTM, and target
1750  * surface.
1751  *
1752  * The font's view
1753  * ---------------
1754  *
1755  * Fonts are designed and stored (in say .ttf files) in "font space", which
1756  * describes an "EM Square" (a design tile) and has some abstract number
1757  * such as 1000, 1024, or 2048 units per "EM". This is basically an
1758  * uninteresting space for us, but we need to remember that it exists.
1759  *
1760  * Font resources (from libraries or operating systems) render themselves
1761  * to a particular device. Since they do not want to make most programmers
1762  * worry about the font design space, the scaling API is simplified to
1763  * involve just telling the font the required pixel size of the EM square
1764  * (that is, in device space).
1765  *
1766  *
1767  * Cairo's gstate view
1768  * -------------------
1769  *
1770  * In addition to the CTM and CTM inverse, we keep a matrix in the gstate
1771  * called the "font matrix" which describes the user's most recent
1772  * font-scaling or font-transforming request. This is kept in terms of an
1773  * abstract scale factor, composed with the CTM and used to set the font's
1774  * pixel size. So if the user asks to "scale the font by 12", the matrix
1775  * is:
1776  *
1777  *   [ 12.0, 0.0, 0.0, 12.0, 0.0, 0.0 ]
1778  *
1779  * It is an affine matrix, like all cairo matrices, where its tx and ty
1780  * components are used to "nudging" fonts around and are handled in gstate
1781  * and then ignored by the "scaled-font" layer.
1782  *
1783  * In order to perform any action on a font, we must build an object
1784  * called a #cairo_font_scale_t; this contains the central 2x2 matrix
1785  * resulting from "font matrix * CTM" (sans the font matrix translation
1786  * components as stated in the previous paragraph).
1787  *
1788  * We pass this to the font when making requests of it, which causes it to
1789  * reply for a particular [user request, device] combination, under the CTM
1790  * (to accommodate the "zoom in" == "bigger fonts" issue above).
1791  *
1792  * The other terms in our communication with the font are therefore in
1793  * device space. When we ask it to perform text->glyph conversion, it will
1794  * produce a glyph string in device space. Glyph vectors we pass to it for
1795  * measuring or rendering should be in device space. The metrics which we
1796  * get back from the font will be in device space. The contents of the
1797  * global glyph image cache will be in device space.
1798  *
1799  *
1800  * Cairo's public view
1801  * -------------------
1802  *
1803  * Since the values entering and leaving via public API calls are in user
1804  * space, the gstate functions typically need to multiply arguments by the
1805  * CTM (for user-input glyph vectors), and return values by the CTM inverse
1806  * (for font responses such as metrics or glyph vectors).
1807  *
1808  */
1809
1810 static cairo_status_t
1811 _cairo_gstate_ensure_font_face (cairo_gstate_t *gstate)
1812 {
1813     cairo_font_face_t *font_face;
1814
1815     if (gstate->font_face != NULL)
1816         return gstate->font_face->status;
1817
1818
1819     font_face = cairo_toy_font_face_create (CAIRO_FONT_FAMILY_DEFAULT,
1820                                             CAIRO_FONT_SLANT_DEFAULT,
1821                                             CAIRO_FONT_WEIGHT_DEFAULT);
1822     if (font_face->status)
1823         return font_face->status;
1824
1825     gstate->font_face = font_face;
1826
1827     return CAIRO_STATUS_SUCCESS;
1828 }
1829
1830 static cairo_status_t
1831 _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate)
1832 {
1833     cairo_status_t status;
1834     cairo_font_options_t options;
1835     cairo_scaled_font_t *scaled_font;
1836
1837     if (gstate->scaled_font != NULL)
1838         return gstate->scaled_font->status;
1839
1840     status = _cairo_gstate_ensure_font_face (gstate);
1841     if (unlikely (status))
1842         return status;
1843
1844     cairo_surface_get_font_options (gstate->target, &options);
1845     cairo_font_options_merge (&options, &gstate->font_options);
1846
1847     scaled_font = cairo_scaled_font_create (gstate->font_face,
1848                                             &gstate->font_matrix,
1849                                             &gstate->ctm,
1850                                             &options);
1851
1852     status = cairo_scaled_font_status (scaled_font);
1853     if (unlikely (status))
1854         return status;
1855
1856     gstate->scaled_font = scaled_font;
1857
1858     return CAIRO_STATUS_SUCCESS;
1859 }
1860
1861 cairo_status_t
1862 _cairo_gstate_get_font_extents (cairo_gstate_t *gstate,
1863                                 cairo_font_extents_t *extents)
1864 {
1865     cairo_status_t status = _cairo_gstate_ensure_scaled_font (gstate);
1866     if (unlikely (status))
1867         return status;
1868
1869     cairo_scaled_font_extents (gstate->scaled_font, extents);
1870
1871     return cairo_scaled_font_status (gstate->scaled_font);
1872 }
1873
1874 cairo_status_t
1875 _cairo_gstate_set_font_face (cairo_gstate_t    *gstate,
1876                              cairo_font_face_t *font_face)
1877 {
1878     if (font_face && font_face->status)
1879         return _cairo_error (font_face->status);
1880
1881     if (font_face == gstate->font_face)
1882         return CAIRO_STATUS_SUCCESS;
1883
1884     cairo_font_face_destroy (gstate->font_face);
1885     gstate->font_face = cairo_font_face_reference (font_face);
1886
1887     _cairo_gstate_unset_scaled_font (gstate);
1888
1889     return CAIRO_STATUS_SUCCESS;
1890 }
1891
1892 cairo_status_t
1893 _cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
1894                              const cairo_glyph_t *glyphs,
1895                              int num_glyphs,
1896                              cairo_text_extents_t *extents)
1897 {
1898     cairo_status_t status;
1899
1900     status = _cairo_gstate_ensure_scaled_font (gstate);
1901     if (unlikely (status))
1902         return status;
1903
1904     cairo_scaled_font_glyph_extents (gstate->scaled_font,
1905                                      glyphs, num_glyphs,
1906                                      extents);
1907
1908     return cairo_scaled_font_status (gstate->scaled_font);
1909 }
1910
1911 cairo_status_t
1912 _cairo_gstate_show_text_glyphs (cairo_gstate_t             *gstate,
1913                                 const cairo_glyph_t        *glyphs,
1914                                 int                         num_glyphs,
1915                                 cairo_glyph_text_info_t    *info)
1916 {
1917     cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)];
1918     cairo_text_cluster_t stack_transformed_clusters[CAIRO_STACK_ARRAY_LENGTH (cairo_text_cluster_t)];
1919     cairo_pattern_union_t source_pattern;
1920     cairo_glyph_t *transformed_glyphs;
1921     const cairo_pattern_t *pattern;
1922     cairo_text_cluster_t *transformed_clusters;
1923     cairo_operator_t op;
1924     cairo_status_t status;
1925
1926     status = _cairo_gstate_get_pattern_status (gstate->source);
1927     if (unlikely (status))
1928         return status;
1929
1930     if (gstate->op == CAIRO_OPERATOR_DEST)
1931         return CAIRO_STATUS_SUCCESS;
1932
1933     if (_cairo_clip_is_all_clipped (gstate->clip))
1934         return CAIRO_STATUS_SUCCESS;
1935
1936     status = _cairo_gstate_ensure_scaled_font (gstate);
1937     if (unlikely (status))
1938         return status;
1939
1940     transformed_glyphs = stack_transformed_glyphs;
1941     transformed_clusters = stack_transformed_clusters;
1942
1943     if (num_glyphs > ARRAY_LENGTH (stack_transformed_glyphs)) {
1944         transformed_glyphs = cairo_glyph_allocate (num_glyphs);
1945         if (unlikely (transformed_glyphs == NULL))
1946             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1947     }
1948
1949     if (info != NULL) {
1950         if (info->num_clusters > ARRAY_LENGTH (stack_transformed_clusters)) {
1951             transformed_clusters = cairo_text_cluster_allocate (info->num_clusters);
1952             if (unlikely (transformed_clusters == NULL)) {
1953                 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1954                 goto CLEANUP_GLYPHS;
1955             }
1956         }
1957
1958         _cairo_gstate_transform_glyphs_to_backend (gstate,
1959                                                    glyphs, num_glyphs,
1960                                                    info->clusters,
1961                                                    info->num_clusters,
1962                                                    info->cluster_flags,
1963                                                    transformed_glyphs,
1964                                                    &num_glyphs,
1965                                                    transformed_clusters);
1966     } else {
1967         _cairo_gstate_transform_glyphs_to_backend (gstate,
1968                                                    glyphs, num_glyphs,
1969                                                    NULL, 0, 0,
1970                                                    transformed_glyphs,
1971                                                    &num_glyphs,
1972                                                    NULL);
1973     }
1974
1975     if (num_glyphs == 0)
1976         goto CLEANUP_GLYPHS;
1977
1978     op = _reduce_op (gstate);
1979     if (op == CAIRO_OPERATOR_CLEAR) {
1980         pattern = &_cairo_pattern_clear.base;
1981     } else {
1982         _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
1983         pattern = &source_pattern.base;
1984     }
1985
1986     /* For really huge font sizes, we can just do path;fill instead of
1987      * show_glyphs, as show_glyphs would put excess pressure on the cache,
1988      * and moreover, not all components below us correctly handle huge font
1989      * sizes.  I wanted to set the limit at 256.  But alas, seems like cairo's
1990      * rasterizer is something like ten times slower than freetype's for huge
1991      * sizes.  So, no win just yet.  For now, do it for insanely-huge sizes,
1992      * just to make sure we don't make anyone unhappy.  When we get a really
1993      * fast rasterizer in cairo, we may want to readjust this.
1994      *
1995      * Needless to say, do this only if show_text_glyphs is not available. */
1996     if (cairo_surface_has_show_text_glyphs (gstate->target) ||
1997         _cairo_scaled_font_get_max_scale (gstate->scaled_font) <= 10240)
1998     {
1999         if (info != NULL) {
2000             status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern,
2001                                                       info->utf8, info->utf8_len,
2002                                                       transformed_glyphs, num_glyphs,
2003                                                       transformed_clusters, info->num_clusters,
2004                                                       info->cluster_flags,
2005                                                       gstate->scaled_font,
2006                                                       gstate->clip);
2007         } else {
2008             status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern,
2009                                                       NULL, 0,
2010                                                       transformed_glyphs, num_glyphs,
2011                                                       NULL, 0, 0,
2012                                                       gstate->scaled_font,
2013                                                       gstate->clip);
2014         }
2015     }
2016     else
2017     {
2018         cairo_path_fixed_t path;
2019
2020         _cairo_path_fixed_init (&path);
2021
2022         status = _cairo_scaled_font_glyph_path (gstate->scaled_font,
2023                                                 transformed_glyphs, num_glyphs,
2024                                                 &path);
2025
2026         if (status == CAIRO_STATUS_SUCCESS) {
2027             status = _cairo_surface_fill (gstate->target, op, pattern,
2028                                           &path,
2029                                           CAIRO_FILL_RULE_WINDING,
2030                                           gstate->tolerance,
2031                                           gstate->scaled_font->options.antialias,
2032                                           gstate->clip);
2033         }
2034
2035         _cairo_path_fixed_fini (&path);
2036     }
2037
2038 CLEANUP_GLYPHS:
2039     if (transformed_glyphs != stack_transformed_glyphs)
2040       cairo_glyph_free (transformed_glyphs);
2041     if (transformed_clusters != stack_transformed_clusters)
2042       cairo_text_cluster_free (transformed_clusters);
2043
2044     return status;
2045 }
2046
2047 cairo_status_t
2048 _cairo_gstate_glyph_path (cairo_gstate_t      *gstate,
2049                           const cairo_glyph_t *glyphs,
2050                           int                  num_glyphs,
2051                           cairo_path_fixed_t  *path)
2052 {
2053     cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)];
2054     cairo_glyph_t *transformed_glyphs;
2055     cairo_status_t status;
2056
2057     status = _cairo_gstate_ensure_scaled_font (gstate);
2058     if (unlikely (status))
2059         return status;
2060
2061     if (num_glyphs < ARRAY_LENGTH (stack_transformed_glyphs)) {
2062         transformed_glyphs = stack_transformed_glyphs;
2063     } else {
2064         transformed_glyphs = cairo_glyph_allocate (num_glyphs);
2065         if (unlikely (transformed_glyphs == NULL))
2066             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2067     }
2068
2069     _cairo_gstate_transform_glyphs_to_backend (gstate,
2070                                                glyphs, num_glyphs,
2071                                                NULL, 0, 0,
2072                                                transformed_glyphs,
2073                                                &num_glyphs, NULL);
2074
2075     status = _cairo_scaled_font_glyph_path (gstate->scaled_font,
2076                                             transformed_glyphs, num_glyphs,
2077                                             path);
2078
2079     if (transformed_glyphs != stack_transformed_glyphs)
2080       cairo_glyph_free (transformed_glyphs);
2081
2082     return status;
2083 }
2084
2085 cairo_status_t
2086 _cairo_gstate_set_antialias (cairo_gstate_t *gstate,
2087                              cairo_antialias_t antialias)
2088 {
2089     gstate->antialias = antialias;
2090
2091     return CAIRO_STATUS_SUCCESS;
2092 }
2093
2094 cairo_antialias_t
2095 _cairo_gstate_get_antialias (cairo_gstate_t *gstate)
2096 {
2097     return gstate->antialias;
2098 }
2099
2100 /**
2101  * _cairo_gstate_transform_glyphs_to_backend:
2102  * @gstate: a #cairo_gstate_t
2103  * @glyphs: the array of #cairo_glyph_t objects to be transformed
2104  * @num_glyphs: the number of elements in @glyphs
2105  * @transformed_glyphs: a pre-allocated array of at least @num_glyphs
2106  * #cairo_glyph_t objects
2107  * @num_transformed_glyphs: the number of elements in @transformed_glyphs
2108  * after dropping out of bounds glyphs, or %NULL if glyphs shouldn't be
2109  * dropped
2110  *
2111  * Transform an array of glyphs to backend space by first adding the offset
2112  * of the font matrix, then transforming from user space to backend space.
2113  * The result of the transformation is placed in @transformed_glyphs.
2114  *
2115  * This also uses information from the scaled font and the surface to
2116  * cull/drop glyphs that will not be visible.
2117  **/
2118 static void
2119 _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t       *gstate,
2120                                            const cairo_glyph_t  *glyphs,
2121                                            int                   num_glyphs,
2122                                            const cairo_text_cluster_t   *clusters,
2123                                            int                   num_clusters,
2124                                            cairo_text_cluster_flags_t cluster_flags,
2125                                            cairo_glyph_t        *transformed_glyphs,
2126                                            int                  *num_transformed_glyphs,
2127                                            cairo_text_cluster_t *transformed_clusters)
2128 {
2129     cairo_rectangle_int_t surface_extents;
2130     cairo_matrix_t *ctm = &gstate->ctm;
2131     cairo_matrix_t *font_matrix = &gstate->font_matrix;
2132     cairo_matrix_t *device_transform = &gstate->target->device_transform;
2133     cairo_bool_t drop = FALSE;
2134     double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
2135     int i, j, k;
2136
2137     drop = TRUE;
2138     if (! _cairo_gstate_int_clip_extents (gstate, &surface_extents)) {
2139         drop = FALSE; /* unbounded surface */
2140     } else {
2141         double scale10 = 10 * _cairo_scaled_font_get_max_scale (gstate->scaled_font);
2142         if (surface_extents.width == 0 || surface_extents.height == 0) {
2143           /* No visible area.  Don't draw anything */
2144           *num_transformed_glyphs = 0;
2145           return;
2146         }
2147         /* XXX We currently drop any glyphs that has its position outside
2148          * of the surface boundaries by a safety margin depending on the
2149          * font scale.  This however can fail in extreme cases where the
2150          * font has really long swashes for example...  We can correctly
2151          * handle that by looking the glyph up and using its device bbox
2152          * to device if it's going to be visible, but I'm not inclined to
2153          * do that now.
2154          */
2155         x1 = surface_extents.x - scale10;
2156         y1 = surface_extents.y - scale10;
2157         x2 = surface_extents.x + (int) surface_extents.width  + scale10;
2158         y2 = surface_extents.y + (int) surface_extents.height + scale10;
2159     }
2160
2161     if (!drop)
2162         *num_transformed_glyphs = num_glyphs;
2163
2164 #define KEEP_GLYPH(glyph) (x1 <= glyph.x && glyph.x <= x2 && y1 <= glyph.y && glyph.y <= y2)
2165
2166     j = 0;
2167     if (_cairo_matrix_is_identity (ctm) &&
2168         _cairo_matrix_is_identity (device_transform) &&
2169         font_matrix->x0 == 0 && font_matrix->y0 == 0)
2170     {
2171         if (! drop) {
2172             memcpy (transformed_glyphs, glyphs,
2173                     num_glyphs * sizeof (cairo_glyph_t));
2174             memcpy (transformed_clusters, clusters,
2175                     num_clusters * sizeof (cairo_text_cluster_t));
2176             j = num_glyphs;
2177         } else if (num_clusters == 0) {
2178             for (i = 0; i < num_glyphs; i++) {
2179                 transformed_glyphs[j].index = glyphs[i].index;
2180                 transformed_glyphs[j].x = glyphs[i].x;
2181                 transformed_glyphs[j].y = glyphs[i].y;
2182                 if (KEEP_GLYPH (transformed_glyphs[j]))
2183                     j++;
2184             }
2185         } else {
2186             const cairo_glyph_t *cur_glyph;
2187
2188             if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
2189                 cur_glyph = glyphs + num_glyphs - 1;
2190             else
2191                 cur_glyph = glyphs;
2192
2193             for (i = 0; i < num_clusters; i++) {
2194                 cairo_bool_t cluster_visible = FALSE;
2195
2196                 for (k = 0; k < clusters[i].num_glyphs; k++) {
2197                     transformed_glyphs[j+k].index = cur_glyph->index;
2198                     transformed_glyphs[j+k].x = cur_glyph->x;
2199                     transformed_glyphs[j+k].y = cur_glyph->y;
2200                     if (KEEP_GLYPH (transformed_glyphs[j+k]))
2201                         cluster_visible = TRUE;
2202
2203                     if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
2204                         cur_glyph--;
2205                     else
2206                         cur_glyph++;
2207                 }
2208
2209                 transformed_clusters[i] = clusters[i];
2210                 if (cluster_visible)
2211                     j += k;
2212                 else
2213                     transformed_clusters[i].num_glyphs = 0;
2214             }
2215         }
2216     }
2217     else if (_cairo_matrix_is_translation (ctm) &&
2218              _cairo_matrix_is_translation (device_transform))
2219     {
2220         double tx = font_matrix->x0 + ctm->x0 + device_transform->x0;
2221         double ty = font_matrix->y0 + ctm->y0 + device_transform->y0;
2222
2223         if (! drop || num_clusters == 0) {
2224             for (i = 0; i < num_glyphs; i++) {
2225                 transformed_glyphs[j].index = glyphs[i].index;
2226                 transformed_glyphs[j].x = glyphs[i].x + tx;
2227                 transformed_glyphs[j].y = glyphs[i].y + ty;
2228                 if (!drop || KEEP_GLYPH (transformed_glyphs[j]))
2229                     j++;
2230             }
2231             memcpy (transformed_clusters, clusters,
2232                     num_clusters * sizeof (cairo_text_cluster_t));
2233         } else {
2234             const cairo_glyph_t *cur_glyph;
2235
2236             if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
2237                 cur_glyph = glyphs + num_glyphs - 1;
2238             else
2239                 cur_glyph = glyphs;
2240
2241             for (i = 0; i < num_clusters; i++) {
2242                 cairo_bool_t cluster_visible = FALSE;
2243
2244                 for (k = 0; k < clusters[i].num_glyphs; k++) {
2245                     transformed_glyphs[j+k].index = cur_glyph->index;
2246                     transformed_glyphs[j+k].x = cur_glyph->x + tx;
2247                     transformed_glyphs[j+k].y = cur_glyph->y + ty;
2248                     if (KEEP_GLYPH (transformed_glyphs[j+k]))
2249                         cluster_visible = TRUE;
2250
2251                     if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
2252                         cur_glyph--;
2253                     else
2254                         cur_glyph++;
2255                 }
2256
2257                 transformed_clusters[i] = clusters[i];
2258                 if (cluster_visible)
2259                     j += k;
2260                 else
2261                     transformed_clusters[i].num_glyphs = 0;
2262             }
2263         }
2264     }
2265     else
2266     {
2267         cairo_matrix_t aggregate_transform;
2268
2269         cairo_matrix_init_translate (&aggregate_transform,
2270                                      gstate->font_matrix.x0,
2271                                      gstate->font_matrix.y0);
2272         cairo_matrix_multiply (&aggregate_transform,
2273                                &aggregate_transform, ctm);
2274         cairo_matrix_multiply (&aggregate_transform,
2275                                &aggregate_transform, device_transform);
2276
2277         if (! drop || num_clusters == 0) {
2278             for (i = 0; i < num_glyphs; i++) {
2279                 transformed_glyphs[j] = glyphs[i];
2280                 cairo_matrix_transform_point (&aggregate_transform,
2281                                               &transformed_glyphs[j].x,
2282                                               &transformed_glyphs[j].y);
2283                 if (! drop || KEEP_GLYPH (transformed_glyphs[j]))
2284                     j++;
2285             }
2286             memcpy (transformed_clusters, clusters,
2287                     num_clusters * sizeof (cairo_text_cluster_t));
2288         } else {
2289             const cairo_glyph_t *cur_glyph;
2290
2291             if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
2292                 cur_glyph = glyphs + num_glyphs - 1;
2293             else
2294                 cur_glyph = glyphs;
2295
2296             for (i = 0; i < num_clusters; i++) {
2297                 cairo_bool_t cluster_visible = FALSE;
2298                 for (k = 0; k < clusters[i].num_glyphs; k++) {
2299                     transformed_glyphs[j+k] = *cur_glyph;
2300                     cairo_matrix_transform_point (&aggregate_transform,
2301                                                   &transformed_glyphs[j+k].x,
2302                                                   &transformed_glyphs[j+k].y);
2303                     if (KEEP_GLYPH (transformed_glyphs[j+k]))
2304                         cluster_visible = TRUE;
2305
2306                     if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
2307                         cur_glyph--;
2308                     else
2309                         cur_glyph++;
2310                 }
2311
2312                 transformed_clusters[i] = clusters[i];
2313                 if (cluster_visible)
2314                     j += k;
2315                 else
2316                     transformed_clusters[i].num_glyphs = 0;
2317             }
2318         }
2319     }
2320     *num_transformed_glyphs = j;
2321
2322     if (num_clusters != 0 && cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) {
2323         for (i = 0; i < --j; i++) {
2324             cairo_glyph_t tmp;
2325
2326             tmp = transformed_glyphs[i];
2327             transformed_glyphs[i] = transformed_glyphs[j];
2328             transformed_glyphs[j] = tmp;
2329         }
2330     }
2331 }