tizen 2.3.1 release
[framework/graphics/cairo.git] / src / cairo-path-stroke-polygon.c
1 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2 /* cairo - a vector graphics library with display and print output
3  *
4  * Copyright © 2002 University of Southern California
5  * Copyright © 2011 Intel Corporation
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it either under the terms of the GNU Lesser General Public
9  * License version 2.1 as published by the Free Software Foundation
10  * (the "LGPL") or, at your option, under the terms of the Mozilla
11  * Public License Version 1.1 (the "MPL"). If you do not alter this
12  * notice, a recipient may use your version of this file under either
13  * the MPL or the LGPL.
14  *
15  * You should have received a copy of the LGPL along with this library
16  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18  * You should have received a copy of the MPL along with this library
19  * in the file COPYING-MPL-1.1
20  *
21  * The contents of this file are subject to the Mozilla Public License
22  * Version 1.1 (the "License"); you may not use this file except in
23  * compliance with the License. You may obtain a copy of the License at
24  * http://www.mozilla.org/MPL/
25  *
26  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28  * the specific language governing rights and limitations.
29  *
30  * The Original Code is the cairo graphics library.
31  *
32  * The Initial Developer of the Original Code is University of Southern
33  * California.
34  *
35  * Contributor(s):
36  *      Carl D. Worth <cworth@cworth.org>
37  *      Chris Wilson <chris@chris-wilson.co.uk>
38  */
39
40 #define _BSD_SOURCE /* for hypot() */
41 #include "cairoint.h"
42
43 #include "cairo-box-inline.h"
44 #include "cairo-boxes-private.h"
45 #include "cairo-contour-inline.h"
46 #include "cairo-contour-private.h"
47 #include "cairo-error-private.h"
48 #include "cairo-path-fixed-private.h"
49 #include "cairo-slope-private.h"
50
51 #define DEBUG 0
52
53 struct stroker {
54     cairo_stroke_style_t style;
55
56 #if DEBUG
57     cairo_contour_t path;
58 #endif
59
60     struct stroke_contour {
61         /* Note that these are not strictly contours as they may intersect */
62         cairo_contour_t contour;
63     } cw, ccw;
64     cairo_uint64_t contour_tolerance;
65     cairo_polygon_t *polygon;
66
67     const cairo_matrix_t *ctm;
68     const cairo_matrix_t *ctm_inverse;
69     double tolerance;
70     double spline_cusp_tolerance;
71     double half_line_width;
72     cairo_bool_t ctm_det_positive;
73
74     cairo_pen_t pen;
75
76     cairo_point_t first_point;
77
78     cairo_bool_t has_initial_sub_path;
79
80     cairo_bool_t has_current_face;
81     cairo_stroke_face_t current_face;
82
83     cairo_bool_t has_first_face;
84     cairo_stroke_face_t first_face;
85
86     cairo_bool_t has_bounds;
87     cairo_box_t bounds;
88 };
89
90 static inline double
91 normalize_slope (double *dx, double *dy);
92
93 static void
94 compute_face (const cairo_point_t *point,
95               const cairo_slope_t *dev_slope,
96               struct stroker *stroker,
97               cairo_stroke_face_t *face);
98
99 static cairo_uint64_t
100 point_distance_sq (const cairo_point_t *p1,
101                         const cairo_point_t *p2)
102 {
103     int32_t dx = p1->x - p2->x;
104     int32_t dy = p1->y - p2->y;
105     return _cairo_int32x32_64_mul (dx, dx) + _cairo_int32x32_64_mul (dy, dy);
106 }
107
108 static cairo_bool_t
109 within_tolerance (const cairo_point_t *p1,
110               const cairo_point_t *p2,
111               cairo_uint64_t tolerance)
112 {
113     return FALSE;
114     return _cairo_int64_lt (point_distance_sq (p1, p2), tolerance);
115 }
116
117 static void
118 contour_add_point (struct stroker *stroker,
119                    struct stroke_contour *c,
120                    const cairo_point_t *point)
121 {
122     if (! within_tolerance (point, _cairo_contour_last_point (&c->contour),
123                         stroker->contour_tolerance))
124         _cairo_contour_add_point (&c->contour, point);
125     //*_cairo_contour_last_point (&c->contour) = *point;
126 }
127
128 static void
129 translate_point (cairo_point_t *point, const cairo_point_t *offset)
130 {
131     point->x += offset->x;
132     point->y += offset->y;
133 }
134
135 static int
136 slope_compare_sgn (double dx1, double dy1, double dx2, double dy2)
137 {
138     double  c = (dx1 * dy2 - dx2 * dy1);
139
140     if (c > 0) return 1;
141     if (c < 0) return -1;
142     return 0;
143 }
144
145 static inline int
146 range_step (int i, int step, int max)
147 {
148     i += step;
149     if (i < 0)
150         i = max - 1;
151     if (i >= max)
152         i = 0;
153     return i;
154 }
155
156 /*
157  * Construct a fan around the midpoint using the vertices from pen between
158  * inpt and outpt.
159  */
160 static void
161 add_fan (struct stroker *stroker,
162          const cairo_slope_t *in_vector,
163          const cairo_slope_t *out_vector,
164          const cairo_point_t *midpt,
165          cairo_bool_t clockwise,
166          struct stroke_contour *c)
167 {
168     cairo_pen_t *pen = &stroker->pen;
169     int start, stop;
170
171     if (stroker->has_bounds &&
172         ! _cairo_box_contains_point (&stroker->bounds, midpt))
173         return;
174
175     assert (stroker->pen.num_vertices);
176
177     if (clockwise) {
178         _cairo_pen_find_active_cw_vertices (pen,
179                                             in_vector, out_vector,
180                                             &start, &stop);
181         while (start != stop) {
182             cairo_point_t p = *midpt;
183             translate_point (&p, &pen->vertices[start].point);
184             contour_add_point (stroker, c, &p);
185
186             if (++start == pen->num_vertices)
187                 start = 0;
188         }
189     } else {
190         _cairo_pen_find_active_ccw_vertices (pen,
191                                              in_vector, out_vector,
192                                              &start, &stop);
193         while (start != stop) {
194             cairo_point_t p = *midpt;
195             translate_point (&p, &pen->vertices[start].point);
196             contour_add_point (stroker, c, &p);
197
198             if (start-- == 0)
199                 start += pen->num_vertices;
200         }
201     }
202 }
203
204 static int
205 join_is_clockwise (const cairo_stroke_face_t *in,
206                    const cairo_stroke_face_t *out)
207 {
208     return _cairo_slope_compare (&in->dev_vector, &out->dev_vector) < 0;
209 }
210
211 static void
212 inner_join (struct stroker *stroker,
213             const cairo_stroke_face_t *in,
214             const cairo_stroke_face_t *out,
215             int clockwise)
216 {
217 #if 0
218     cairo_point_t last;
219     const cairo_point_t *p, *outpt;
220     struct stroke_contour *inner;
221     cairo_int64_t d_p, d_last;
222     cairo_int64_t half_line_width;
223     cairo_bool_t negate;
224
225     /* XXX line segments shorter than line-width */
226
227     if (clockwise) {
228         inner = &stroker->ccw;
229         outpt = &out->ccw;
230         negate = 1;
231     } else {
232         inner = &stroker->cw;
233         outpt = &out->cw;
234         negate = 0;
235     }
236
237     half_line_width = CAIRO_FIXED_ONE*CAIRO_FIXED_ONE/2 * stroker->style.line_width * out->length + .5;
238
239     /* On the inside, the previous end-point is always
240      * closer to the new face by definition.
241      */
242     last = *_cairo_contour_last_point (&inner->contour);
243     d_last = distance_from_face (out, &last, negate);
244     _cairo_contour_remove_last_point (&inner->contour);
245
246 prev:
247     if (inner->contour.chain.num_points == 0) {
248         contour_add_point (stroker, inner, outpt);
249         return;
250     }
251     p = _cairo_contour_last_point (&inner->contour);
252     d_p = distance_from_face (out, p, negate);
253     if (_cairo_int64_lt (d_p, half_line_width) &&
254         !_cairo_int64_negative (distance_along_face (out, p)))
255     {
256         last = *p;
257         d_last = d_p;
258         _cairo_contour_remove_last_point (&inner->contour);
259         goto prev;
260     }
261
262     compute_inner_joint (&last, d_last, p, d_p, half_line_width);
263     contour_add_point (stroker, inner, &last);
264 #else
265     const cairo_point_t *outpt;
266     struct stroke_contour *inner;
267
268     if (clockwise) {
269         inner = &stroker->ccw;
270         outpt = &out->ccw;
271     } else {
272         inner = &stroker->cw;
273         outpt = &out->cw;
274     }
275     contour_add_point (stroker, inner, &in->point);
276     contour_add_point (stroker, inner, outpt);
277 #endif
278 }
279
280 static void
281 inner_close (struct stroker *stroker,
282              const cairo_stroke_face_t *in,
283              cairo_stroke_face_t *out)
284 {
285 #if 0
286     cairo_point_t last;
287     const cairo_point_t *p, *outpt, *inpt;
288     struct stroke_contour *inner;
289     struct _cairo_contour_chain *chain;
290
291     /* XXX line segments shorter than line-width */
292
293     if (join_is_clockwise (in, out)) {
294         inner = &stroker->ccw;
295         outpt = &in->ccw;
296         inpt = &out->ccw;
297     } else {
298         inner = &stroker->cw;
299         outpt = &in->cw;
300         inpt = &out->cw;
301     }
302
303     if (inner->contour.chain.num_points == 0) {
304         contour_add_point (stroker, inner, &in->point);
305         contour_add_point (stroker, inner, inpt);
306         *_cairo_contour_first_point (&inner->contour) =
307             *_cairo_contour_last_point (&inner->contour);
308         return;
309     }
310
311     line_width = stroker->style.line_width/2;
312     line_width *= CAIRO_FIXED_ONE;
313
314     d_last = sign * distance_from_face (out, outpt);
315     last = *outpt;
316
317     for (chain = &inner->contour.chain; chain; chain = chain->next) {
318         for (i = 0; i < chain->num_points; i++) {
319             p = &chain->points[i];
320             if ((d_p = sign * distance_from_face (in, p)) >= line_width &&
321                 distance_from_edge (stroker, inpt, &last, p) < line_width)
322             {
323                 goto out;
324             }
325
326             if (p->x != last.x || p->y != last.y) {
327                 last = *p;
328                 d_last = d_p;
329             }
330         }
331     }
332 out:
333
334     if (d_p != d_last) {
335         double dot = (line_width - d_last) / (d_p - d_last);
336         last.x += dot * (p->x - last.x);
337         last.y += dot * (p->y - last.y);
338     }
339     *_cairo_contour_last_point (&inner->contour) = last;
340
341     for (chain = &inner->contour.chain; chain; chain = chain->next) {
342         for (i = 0; i < chain->num_points; i++) {
343             cairo_point_t *pp = &chain->points[i];
344             if (pp == p)
345                 return;
346             *pp = last;
347         }
348     }
349 #else
350     const cairo_point_t *inpt;
351     struct stroke_contour *inner;
352
353     if (join_is_clockwise (in, out)) {
354         inner = &stroker->ccw;
355         inpt = &out->ccw;
356     } else {
357         inner = &stroker->cw;
358         inpt = &out->cw;
359     }
360
361     contour_add_point (stroker, inner, &in->point);
362     contour_add_point (stroker, inner, inpt);
363     *_cairo_contour_first_point (&inner->contour) =
364         *_cairo_contour_last_point (&inner->contour);
365 #endif
366 }
367
368 static void
369 outer_close (struct stroker *stroker,
370              const cairo_stroke_face_t *in,
371              const cairo_stroke_face_t *out)
372 {
373     const cairo_point_t *inpt, *outpt;
374     struct stroke_contour *outer;
375     int clockwise;
376
377     if (in->cw.x == out->cw.x && in->cw.y == out->cw.y &&
378         in->ccw.x == out->ccw.x && in->ccw.y == out->ccw.y)
379     {
380         return;
381     }
382
383     clockwise = join_is_clockwise (in, out);
384     if (clockwise) {
385         inpt = &in->cw;
386         outpt = &out->cw;
387         outer = &stroker->cw;
388     } else {
389         inpt = &in->ccw;
390         outpt = &out->ccw;
391         outer = &stroker->ccw;
392     }
393
394     if (within_tolerance (inpt, outpt, stroker->contour_tolerance)) {
395         *_cairo_contour_first_point (&outer->contour) =
396             *_cairo_contour_last_point (&outer->contour);
397         return;
398     }
399
400     switch (stroker->style.line_join) {
401     case CAIRO_LINE_JOIN_ROUND:
402         /* construct a fan around the common midpoint */
403         if ((in->dev_slope.x * out->dev_slope.x +
404              in->dev_slope.y * out->dev_slope.y) < stroker->spline_cusp_tolerance)
405         {
406             add_fan (stroker,
407                      &in->dev_vector, &out->dev_vector, &in->point,
408                      clockwise, outer);
409             break;
410         }
411
412     case CAIRO_LINE_JOIN_MITER:
413     default: {
414         /* dot product of incoming slope vector with outgoing slope vector */
415         double  in_dot_out = in->dev_slope.x * out->dev_slope.x +
416                              in->dev_slope.y * out->dev_slope.y;
417         double  ml = stroker->style.miter_limit;
418
419         /* Check the miter limit -- lines meeting at an acute angle
420          * can generate long miters, the limit converts them to bevel
421          *
422          * Consider the miter join formed when two line segments
423          * meet at an angle psi:
424          *
425          *         /.\
426          *        /. .\
427          *       /./ \.\
428          *      /./psi\.\
429          *
430          * We can zoom in on the right half of that to see:
431          *
432          *          |\
433          *          | \ psi/2
434          *          |  \
435          *          |   \
436          *          |    \
437          *          |     \
438          *        miter    \
439          *       length     \
440          *          |        \
441          *          |        .\
442          *          |    .     \
443          *          |.   line   \
444          *           \    width  \
445          *            \           \
446          *
447          *
448          * The right triangle in that figure, (the line-width side is
449          * shown faintly with three '.' characters), gives us the
450          * following expression relating miter length, angle and line
451          * width:
452          *
453          *      1 /sin (psi/2) = miter_length / line_width
454          *
455          * The right-hand side of this relationship is the same ratio
456          * in which the miter limit (ml) is expressed. We want to know
457          * when the miter length is within the miter limit. That is
458          * when the following condition holds:
459          *
460          *      1/sin(psi/2) <= ml
461          *      1 <= ml sin(psi/2)
462          *      1 <= ml² sin²(psi/2)
463          *      2 <= ml² 2 sin²(psi/2)
464          *                              2·sin²(psi/2) = 1-cos(psi)
465          *      2 <= ml² (1-cos(psi))
466          *
467          *                              in · out = |in| |out| cos (psi)
468          *
469          * in and out are both unit vectors, so:
470          *
471          *                              in · out = cos (psi)
472          *
473          *      2 <= ml² (1 - in · out)
474          *
475          */
476         if (2 <= ml * ml * (1 + in_dot_out)) {
477             double              x1, y1, x2, y2;
478             double              mx, my;
479             double              dx1, dx2, dy1, dy2;
480             double              ix, iy;
481             double              fdx1, fdy1, fdx2, fdy2;
482             double              mdx, mdy;
483
484             /*
485              * we've got the points already transformed to device
486              * space, but need to do some computation with them and
487              * also need to transform the slope from user space to
488              * device space
489              */
490             /* outer point of incoming line face */
491             x1 = _cairo_fixed_to_double (inpt->x);
492             y1 = _cairo_fixed_to_double (inpt->y);
493             dx1 = in->dev_slope.x;
494             dy1 = in->dev_slope.y;
495
496             /* outer point of outgoing line face */
497             x2 = _cairo_fixed_to_double (outpt->x);
498             y2 = _cairo_fixed_to_double (outpt->y);
499             dx2 = out->dev_slope.x;
500             dy2 = out->dev_slope.y;
501
502             /*
503              * Compute the location of the outer corner of the miter.
504              * That's pretty easy -- just the intersection of the two
505              * outer edges.  We've got slopes and points on each
506              * of those edges.  Compute my directly, then compute
507              * mx by using the edge with the larger dy; that avoids
508              * dividing by values close to zero.
509              */
510             my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) /
511                   (dx1 * dy2 - dx2 * dy1));
512             if (fabs (dy1) >= fabs (dy2))
513                 mx = (my - y1) * dx1 / dy1 + x1;
514             else
515                 mx = (my - y2) * dx2 / dy2 + x2;
516
517             /*
518              * When the two outer edges are nearly parallel, slight
519              * perturbations in the position of the outer points of the lines
520              * caused by representing them in fixed point form can cause the
521              * intersection point of the miter to move a large amount. If
522              * that moves the miter intersection from between the two faces,
523              * then draw a bevel instead.
524              */
525
526             ix = _cairo_fixed_to_double (in->point.x);
527             iy = _cairo_fixed_to_double (in->point.y);
528
529             /* slope of one face */
530             fdx1 = x1 - ix; fdy1 = y1 - iy;
531
532             /* slope of the other face */
533             fdx2 = x2 - ix; fdy2 = y2 - iy;
534
535             /* slope from the intersection to the miter point */
536             mdx = mx - ix; mdy = my - iy;
537
538             /*
539              * Make sure the miter point line lies between the two
540              * faces by comparing the slopes
541              */
542             if (slope_compare_sgn (fdx1, fdy1, mdx, mdy) !=
543                 slope_compare_sgn (fdx2, fdy2, mdx, mdy))
544             {
545                 cairo_point_t p;
546
547                 p.x = _cairo_fixed_from_double (mx);
548                 p.y = _cairo_fixed_from_double (my);
549
550                 *_cairo_contour_last_point (&outer->contour) = p;
551                 *_cairo_contour_first_point (&outer->contour) = p;
552                 return;
553             }
554         }
555         break;
556     }
557
558     case CAIRO_LINE_JOIN_BEVEL:
559         break;
560     }
561     contour_add_point (stroker, outer, outpt);
562 }
563
564 static void
565 outer_join (struct stroker *stroker,
566             const cairo_stroke_face_t *in,
567             const cairo_stroke_face_t *out,
568             int clockwise)
569 {
570     const cairo_point_t *inpt, *outpt;
571     struct stroke_contour *outer;
572
573     if (in->cw.x == out->cw.x && in->cw.y == out->cw.y &&
574         in->ccw.x == out->ccw.x && in->ccw.y == out->ccw.y)
575     {
576         return;
577     }
578     if (clockwise) {
579         inpt = &in->cw;
580         outpt = &out->cw;
581         outer = &stroker->cw;
582     } else {
583         inpt = &in->ccw;
584         outpt = &out->ccw;
585         outer = &stroker->ccw;
586     }
587
588     switch (stroker->style.line_join) {
589     case CAIRO_LINE_JOIN_ROUND:
590         /* construct a fan around the common midpoint */
591         add_fan (stroker,
592                  &in->dev_vector, &out->dev_vector, &in->point,
593                  clockwise, outer);
594         break;
595
596     case CAIRO_LINE_JOIN_MITER:
597     default: {
598         /* dot product of incoming slope vector with outgoing slope vector */
599         double  in_dot_out = in->dev_slope.x * out->dev_slope.x +
600                              in->dev_slope.y * out->dev_slope.y;
601         double  ml = stroker->style.miter_limit;
602
603         /* Check the miter limit -- lines meeting at an acute angle
604          * can generate long miters, the limit converts them to bevel
605          *
606          * Consider the miter join formed when two line segments
607          * meet at an angle psi:
608          *
609          *         /.\
610          *        /. .\
611          *       /./ \.\
612          *      /./psi\.\
613          *
614          * We can zoom in on the right half of that to see:
615          *
616          *          |\
617          *          | \ psi/2
618          *          |  \
619          *          |   \
620          *          |    \
621          *          |     \
622          *        miter    \
623          *       length     \
624          *          |        \
625          *          |        .\
626          *          |    .     \
627          *          |.   line   \
628          *           \    width  \
629          *            \           \
630          *
631          *
632          * The right triangle in that figure, (the line-width side is
633          * shown faintly with three '.' characters), gives us the
634          * following expression relating miter length, angle and line
635          * width:
636          *
637          *      1 /sin (psi/2) = miter_length / line_width
638          *
639          * The right-hand side of this relationship is the same ratio
640          * in which the miter limit (ml) is expressed. We want to know
641          * when the miter length is within the miter limit. That is
642          * when the following condition holds:
643          *
644          *      1/sin(psi/2) <= ml
645          *      1 <= ml sin(psi/2)
646          *      1 <= ml² sin²(psi/2)
647          *      2 <= ml² 2 sin²(psi/2)
648          *                              2·sin²(psi/2) = 1-cos(psi)
649          *      2 <= ml² (1-cos(psi))
650          *
651          *                              in · out = |in| |out| cos (psi)
652          *
653          * in and out are both unit vectors, so:
654          *
655          *                              in · out = cos (psi)
656          *
657          *      2 <= ml² (1 - in · out)
658          *
659          */
660         if (2 <= ml * ml * (1 + in_dot_out)) {
661             double              x1, y1, x2, y2;
662             double              mx, my;
663             double              dx1, dx2, dy1, dy2;
664             double              ix, iy;
665             double              fdx1, fdy1, fdx2, fdy2;
666             double              mdx, mdy;
667
668             /*
669              * we've got the points already transformed to device
670              * space, but need to do some computation with them and
671              * also need to transform the slope from user space to
672              * device space
673              */
674             /* outer point of incoming line face */
675             x1 = _cairo_fixed_to_double (inpt->x);
676             y1 = _cairo_fixed_to_double (inpt->y);
677             dx1 = in->dev_slope.x;
678             dy1 = in->dev_slope.y;
679
680             /* outer point of outgoing line face */
681             x2 = _cairo_fixed_to_double (outpt->x);
682             y2 = _cairo_fixed_to_double (outpt->y);
683             dx2 = out->dev_slope.x;
684             dy2 = out->dev_slope.y;
685
686             /*
687              * Compute the location of the outer corner of the miter.
688              * That's pretty easy -- just the intersection of the two
689              * outer edges.  We've got slopes and points on each
690              * of those edges.  Compute my directly, then compute
691              * mx by using the edge with the larger dy; that avoids
692              * dividing by values close to zero.
693              */
694             my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) /
695                   (dx1 * dy2 - dx2 * dy1));
696             if (fabs (dy1) >= fabs (dy2))
697                 mx = (my - y1) * dx1 / dy1 + x1;
698             else
699                 mx = (my - y2) * dx2 / dy2 + x2;
700
701             /*
702              * When the two outer edges are nearly parallel, slight
703              * perturbations in the position of the outer points of the lines
704              * caused by representing them in fixed point form can cause the
705              * intersection point of the miter to move a large amount. If
706              * that moves the miter intersection from between the two faces,
707              * then draw a bevel instead.
708              */
709
710             ix = _cairo_fixed_to_double (in->point.x);
711             iy = _cairo_fixed_to_double (in->point.y);
712
713             /* slope of one face */
714             fdx1 = x1 - ix; fdy1 = y1 - iy;
715
716             /* slope of the other face */
717             fdx2 = x2 - ix; fdy2 = y2 - iy;
718
719             /* slope from the intersection to the miter point */
720             mdx = mx - ix; mdy = my - iy;
721
722             /*
723              * Make sure the miter point line lies between the two
724              * faces by comparing the slopes
725              */
726             if (slope_compare_sgn (fdx1, fdy1, mdx, mdy) !=
727                 slope_compare_sgn (fdx2, fdy2, mdx, mdy))
728             {
729                 cairo_point_t p;
730
731                 p.x = _cairo_fixed_from_double (mx);
732                 p.y = _cairo_fixed_from_double (my);
733
734                 *_cairo_contour_last_point (&outer->contour) = p;
735                 return;
736             }
737         }
738         break;
739     }
740
741     case CAIRO_LINE_JOIN_BEVEL:
742         break;
743     }
744     contour_add_point (stroker,outer, outpt);
745 }
746
747 static void
748 add_cap (struct stroker *stroker,
749          const cairo_stroke_face_t *f,
750          struct stroke_contour *c)
751 {
752     switch (stroker->style.line_cap) {
753     case CAIRO_LINE_CAP_ROUND: {
754         cairo_slope_t slope;
755
756         slope.dx = -f->dev_vector.dx;
757         slope.dy = -f->dev_vector.dy;
758
759         add_fan (stroker, &f->dev_vector, &slope, &f->point, FALSE, c);
760         break;
761     }
762
763     case CAIRO_LINE_CAP_SQUARE: {
764         cairo_slope_t fvector;
765         cairo_point_t p;
766         double dx, dy;
767
768         dx = f->usr_vector.x;
769         dy = f->usr_vector.y;
770         dx *= stroker->half_line_width;
771         dy *= stroker->half_line_width;
772         cairo_matrix_transform_distance (stroker->ctm, &dx, &dy);
773         fvector.dx = _cairo_fixed_from_double (dx);
774         fvector.dy = _cairo_fixed_from_double (dy);
775
776         p.x = f->ccw.x + fvector.dx;
777         p.y = f->ccw.y + fvector.dy;
778         contour_add_point (stroker, c, &p);
779
780         p.x = f->cw.x + fvector.dx;
781         p.y = f->cw.y + fvector.dy;
782         contour_add_point (stroker, c, &p);
783     }
784
785     case CAIRO_LINE_CAP_BUTT:
786     default:
787         break;
788     }
789     contour_add_point (stroker, c, &f->cw);
790 }
791
792 static void
793 add_leading_cap (struct stroker *stroker,
794                  const cairo_stroke_face_t *face,
795                  struct stroke_contour *c)
796 {
797     cairo_stroke_face_t reversed;
798     cairo_point_t t;
799
800     reversed = *face;
801
802     /* The initial cap needs an outward facing vector. Reverse everything */
803     reversed.usr_vector.x = -reversed.usr_vector.x;
804     reversed.usr_vector.y = -reversed.usr_vector.y;
805     reversed.dev_vector.dx = -reversed.dev_vector.dx;
806     reversed.dev_vector.dy = -reversed.dev_vector.dy;
807
808     t = reversed.cw;
809     reversed.cw = reversed.ccw;
810     reversed.ccw = t;
811
812     add_cap (stroker, &reversed, c);
813 }
814
815 static void
816 add_trailing_cap (struct stroker *stroker,
817                   const cairo_stroke_face_t *face,
818                   struct stroke_contour *c)
819 {
820     add_cap (stroker, face, c);
821 }
822
823 static inline double
824 normalize_slope (double *dx, double *dy)
825 {
826     double dx0 = *dx, dy0 = *dy;
827     double mag;
828
829     assert (dx0 != 0.0 || dy0 != 0.0);
830
831     if (dx0 == 0.0) {
832         *dx = 0.0;
833         if (dy0 > 0.0) {
834             mag = dy0;
835             *dy = 1.0;
836         } else {
837             mag = -dy0;
838             *dy = -1.0;
839         }
840     } else if (dy0 == 0.0) {
841         *dy = 0.0;
842         if (dx0 > 0.0) {
843             mag = dx0;
844             *dx = 1.0;
845         } else {
846             mag = -dx0;
847             *dx = -1.0;
848         }
849     } else {
850         mag = hypot (dx0, dy0);
851         *dx = dx0 / mag;
852         *dy = dy0 / mag;
853     }
854
855     return mag;
856 }
857
858 static void
859 compute_face (const cairo_point_t *point,
860               const cairo_slope_t *dev_slope,
861               struct stroker *stroker,
862               cairo_stroke_face_t *face)
863 {
864     double face_dx, face_dy;
865     cairo_point_t offset_ccw, offset_cw;
866     double slope_dx, slope_dy;
867
868     slope_dx = _cairo_fixed_to_double (dev_slope->dx);
869     slope_dy = _cairo_fixed_to_double (dev_slope->dy);
870     face->length = normalize_slope (&slope_dx, &slope_dy);
871     face->dev_slope.x = slope_dx;
872     face->dev_slope.y = slope_dy;
873
874     /*
875      * rotate to get a line_width/2 vector along the face, note that
876      * the vector must be rotated the right direction in device space,
877      * but by 90° in user space. So, the rotation depends on
878      * whether the ctm reflects or not, and that can be determined
879      * by looking at the determinant of the matrix.
880      */
881     if (! _cairo_matrix_is_identity (stroker->ctm_inverse)) {
882         /* Normalize the matrix! */
883         cairo_matrix_transform_distance (stroker->ctm_inverse,
884                                          &slope_dx, &slope_dy);
885         normalize_slope (&slope_dx, &slope_dy);
886
887         if (stroker->ctm_det_positive) {
888             face_dx = - slope_dy * stroker->half_line_width;
889             face_dy = slope_dx * stroker->half_line_width;
890         } else {
891             face_dx = slope_dy * stroker->half_line_width;
892             face_dy = - slope_dx * stroker->half_line_width;
893         }
894
895         /* back to device space */
896         cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy);
897     } else {
898         face_dx = - slope_dy * stroker->half_line_width;
899         face_dy = slope_dx * stroker->half_line_width;
900     }
901
902     offset_ccw.x = _cairo_fixed_from_double (face_dx);
903     offset_ccw.y = _cairo_fixed_from_double (face_dy);
904     offset_cw.x = -offset_ccw.x;
905     offset_cw.y = -offset_ccw.y;
906
907     face->ccw = *point;
908     translate_point (&face->ccw, &offset_ccw);
909
910     face->point = *point;
911
912     face->cw = *point;
913     translate_point (&face->cw, &offset_cw);
914
915     face->usr_vector.x = slope_dx;
916     face->usr_vector.y = slope_dy;
917
918     face->dev_vector = *dev_slope;
919 }
920
921 static void
922 add_caps (struct stroker *stroker)
923 {
924     /* check for a degenerative sub_path */
925     if (stroker->has_initial_sub_path &&
926         ! stroker->has_first_face &&
927         ! stroker->has_current_face &&
928         stroker->style.line_cap == CAIRO_LINE_CAP_ROUND)
929     {
930         /* pick an arbitrary slope to use */
931         cairo_slope_t slope = { CAIRO_FIXED_ONE, 0 };
932         cairo_stroke_face_t face;
933
934         /* arbitrarily choose first_point */
935         compute_face (&stroker->first_point, &slope, stroker, &face);
936
937         add_leading_cap (stroker, &face, &stroker->ccw);
938         add_trailing_cap (stroker, &face, &stroker->ccw);
939
940         /* ensure the circle is complete */
941         _cairo_contour_add_point (&stroker->ccw.contour,
942                                   _cairo_contour_first_point (&stroker->ccw.contour));
943
944         _cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour);
945         _cairo_contour_reset (&stroker->ccw.contour);
946     } else {
947         if (stroker->has_current_face)
948             add_trailing_cap (stroker, &stroker->current_face, &stroker->ccw);
949
950 #if DEBUG
951         {
952             FILE *file = fopen ("contours.txt", "a");
953             _cairo_debug_print_contour (file, &stroker->path);
954             _cairo_debug_print_contour (file, &stroker->cw.contour);
955             _cairo_debug_print_contour (file, &stroker->ccw.contour);
956             fclose (file);
957             _cairo_contour_reset (&stroker->path);
958         }
959 #endif
960
961         _cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour);
962         _cairo_contour_reset (&stroker->ccw.contour);
963
964         if (stroker->has_first_face) {
965             _cairo_contour_add_point (&stroker->ccw.contour,
966                                       &stroker->first_face.cw);
967             add_leading_cap (stroker, &stroker->first_face, &stroker->ccw);
968 #if DEBUG
969             {
970                 FILE *file = fopen ("contours.txt", "a");
971                 _cairo_debug_print_contour (file, &stroker->ccw.contour);
972                 fclose (file);
973             }
974 #endif
975
976             _cairo_polygon_add_contour (stroker->polygon,
977                                         &stroker->ccw.contour);
978             _cairo_contour_reset (&stroker->ccw.contour);
979         }
980
981         _cairo_polygon_add_contour (stroker->polygon, &stroker->cw.contour);
982         _cairo_contour_reset (&stroker->cw.contour);
983     }
984 }
985
986 static cairo_status_t
987 close_path (void *closure);
988
989 static cairo_status_t
990 move_to (void *closure,
991          const cairo_point_t *point)
992 {
993     struct stroker *stroker = closure;
994
995     /* Cap the start and end of the previous sub path as needed */
996     add_caps (stroker);
997
998     stroker->has_first_face = FALSE;
999     stroker->has_current_face = FALSE;
1000     stroker->has_initial_sub_path = FALSE;
1001
1002     stroker->first_point = *point;
1003
1004 #if DEBUG
1005     _cairo_contour_add_point (&stroker->path, point);
1006 #endif
1007
1008     stroker->current_face.point = *point;
1009
1010     return CAIRO_STATUS_SUCCESS;
1011 }
1012
1013 static cairo_status_t
1014 line_to (void *closure,
1015          const cairo_point_t *point)
1016 {
1017     struct stroker *stroker = closure;
1018     cairo_stroke_face_t start;
1019     cairo_point_t *p1 = &stroker->current_face.point;
1020     cairo_slope_t dev_slope;
1021
1022     stroker->has_initial_sub_path = TRUE;
1023
1024     if (p1->x == point->x && p1->y == point->y)
1025         return CAIRO_STATUS_SUCCESS;
1026
1027 #if DEBUG
1028     _cairo_contour_add_point (&stroker->path, point);
1029 #endif
1030
1031     _cairo_slope_init (&dev_slope, p1, point);
1032     compute_face (p1, &dev_slope, stroker, &start);
1033
1034     if (stroker->has_current_face) {
1035         int clockwise = _cairo_slope_compare (&stroker->current_face.dev_vector,
1036                                               &start.dev_vector);
1037         if (clockwise) {
1038             clockwise = clockwise < 0;
1039             /* Join with final face from previous segment */
1040             if (! within_tolerance (&stroker->current_face.ccw, &start.ccw,
1041                                     stroker->contour_tolerance) ||
1042                 ! within_tolerance (&stroker->current_face.cw, &start.cw,
1043                                     stroker->contour_tolerance))
1044             {
1045                 outer_join (stroker, &stroker->current_face, &start, clockwise);
1046                 inner_join (stroker, &stroker->current_face, &start, clockwise);
1047             }
1048         }
1049     } else {
1050         if (! stroker->has_first_face) {
1051             /* Save sub path's first face in case needed for closing join */
1052             stroker->first_face = start;
1053             stroker->has_first_face = TRUE;
1054         }
1055         stroker->has_current_face = TRUE;
1056
1057         contour_add_point (stroker, &stroker->cw, &start.cw);
1058         contour_add_point (stroker, &stroker->ccw, &start.ccw);
1059     }
1060
1061     stroker->current_face = start;
1062     stroker->current_face.point = *point;
1063     stroker->current_face.ccw.x += dev_slope.dx;
1064     stroker->current_face.ccw.y += dev_slope.dy;
1065     stroker->current_face.cw.x += dev_slope.dx;
1066     stroker->current_face.cw.y += dev_slope.dy;
1067
1068     contour_add_point (stroker, &stroker->cw, &stroker->current_face.cw);
1069     contour_add_point (stroker, &stroker->ccw, &stroker->current_face.ccw);
1070
1071     return CAIRO_STATUS_SUCCESS;
1072 }
1073
1074 static cairo_status_t
1075 spline_to (void *closure,
1076            const cairo_point_t *point,
1077            const cairo_slope_t *tangent)
1078 {
1079     struct stroker *stroker = closure;
1080     cairo_stroke_face_t face;
1081
1082 #if DEBUG
1083     _cairo_contour_add_point (&stroker->path, point);
1084 #endif
1085     if ((tangent->dx | tangent->dy) == 0) {
1086         const cairo_point_t *inpt, *outpt;
1087         struct stroke_contour *outer;
1088         cairo_point_t t;
1089         int clockwise;
1090
1091         face = stroker->current_face;
1092
1093         face.usr_vector.x = -face.usr_vector.x;
1094         face.usr_vector.y = -face.usr_vector.y;
1095         face.dev_vector.dx = -face.dev_vector.dx;
1096         face.dev_vector.dy = -face.dev_vector.dy;
1097
1098         t = face.cw;
1099         face.cw = face.ccw;
1100         face.ccw = t;
1101
1102         clockwise = join_is_clockwise (&stroker->current_face, &face);
1103         if (clockwise) {
1104             inpt = &stroker->current_face.cw;
1105             outpt = &face.cw;
1106             outer = &stroker->cw;
1107         } else {
1108             inpt = &stroker->current_face.ccw;
1109             outpt = &face.ccw;
1110             outer = &stroker->ccw;
1111         }
1112
1113         add_fan (stroker,
1114                  &stroker->current_face.dev_vector,
1115                  &face.dev_vector,
1116                  &stroker->current_face.point,
1117                  clockwise, outer);
1118     } else {
1119         compute_face (point, tangent, stroker, &face);
1120
1121         if ((face.dev_slope.x * stroker->current_face.dev_slope.x +
1122              face.dev_slope.y * stroker->current_face.dev_slope.y) < stroker->spline_cusp_tolerance)
1123         {
1124             const cairo_point_t *inpt, *outpt;
1125             struct stroke_contour *outer;
1126             int clockwise = join_is_clockwise (&stroker->current_face, &face);
1127
1128             stroker->current_face.cw.x += face.point.x - stroker->current_face.point.x;
1129             stroker->current_face.cw.y += face.point.y - stroker->current_face.point.y;
1130             contour_add_point (stroker, &stroker->cw, &stroker->current_face.cw);
1131
1132             stroker->current_face.ccw.x += face.point.x - stroker->current_face.point.x;
1133             stroker->current_face.ccw.y += face.point.y - stroker->current_face.point.y;
1134             contour_add_point (stroker, &stroker->ccw, &stroker->current_face.ccw);
1135
1136             if (clockwise) {
1137                 inpt = &stroker->current_face.cw;
1138                 outpt = &face.cw;
1139                 outer = &stroker->cw;
1140             } else {
1141                 inpt = &stroker->current_face.ccw;
1142                 outpt = &face.ccw;
1143                 outer = &stroker->ccw;
1144             }
1145             add_fan (stroker,
1146                      &stroker->current_face.dev_vector,
1147                      &face.dev_vector,
1148                      &stroker->current_face.point,
1149                      clockwise, outer);
1150         }
1151
1152         contour_add_point (stroker, &stroker->cw, &face.cw);
1153         contour_add_point (stroker, &stroker->ccw, &face.ccw);
1154     }
1155
1156     stroker->current_face = face;
1157
1158     return CAIRO_STATUS_SUCCESS;
1159 }
1160
1161 static cairo_status_t
1162 curve_to (void *closure,
1163           const cairo_point_t *b,
1164           const cairo_point_t *c,
1165           const cairo_point_t *d)
1166 {
1167     struct stroker *stroker = closure;
1168     cairo_spline_t spline;
1169     cairo_stroke_face_t face;
1170
1171     if (stroker->has_bounds &&
1172         ! _cairo_spline_intersects (&stroker->current_face.point, b, c, d,
1173                                     &stroker->bounds))
1174         return line_to (closure, d);
1175
1176     if (! _cairo_spline_init (&spline, spline_to, stroker,
1177                               &stroker->current_face.point, b, c, d))
1178         return line_to (closure, d);
1179
1180     compute_face (&stroker->current_face.point, &spline.initial_slope,
1181                   stroker, &face);
1182
1183     if (stroker->has_current_face) {
1184         int clockwise = join_is_clockwise (&stroker->current_face, &face);
1185         /* Join with final face from previous segment */
1186         outer_join (stroker, &stroker->current_face, &face, clockwise);
1187         inner_join (stroker, &stroker->current_face, &face, clockwise);
1188     } else {
1189         if (! stroker->has_first_face) {
1190             /* Save sub path's first face in case needed for closing join */
1191             stroker->first_face = face;
1192             stroker->has_first_face = TRUE;
1193         }
1194         stroker->has_current_face = TRUE;
1195
1196         contour_add_point (stroker, &stroker->cw, &face.cw);
1197         contour_add_point (stroker, &stroker->ccw, &face.ccw);
1198     }
1199     stroker->current_face = face;
1200
1201     return _cairo_spline_decompose (&spline, stroker->tolerance);
1202 }
1203
1204 static cairo_status_t
1205 close_path (void *closure)
1206 {
1207     struct stroker *stroker = closure;
1208     cairo_status_t status;
1209
1210     status = line_to (stroker, &stroker->first_point);
1211     if (unlikely (status))
1212         return status;
1213
1214     if (stroker->has_first_face && stroker->has_current_face) {
1215         /* Join first and final faces of sub path */
1216         outer_close (stroker, &stroker->current_face, &stroker->first_face);
1217         inner_close (stroker, &stroker->current_face, &stroker->first_face);
1218 #if 0
1219         *_cairo_contour_first_point (&stroker->ccw.contour) =
1220             *_cairo_contour_last_point (&stroker->ccw.contour);
1221
1222         *_cairo_contour_first_point (&stroker->cw.contour) =
1223             *_cairo_contour_last_point (&stroker->cw.contour);
1224 #endif
1225
1226         _cairo_polygon_add_contour (stroker->polygon, &stroker->cw.contour);
1227         _cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour);
1228
1229 #if DEBUG
1230         {
1231             FILE *file = fopen ("contours.txt", "a");
1232             _cairo_debug_print_contour (file, &stroker->path);
1233             _cairo_debug_print_contour (file, &stroker->cw.contour);
1234             _cairo_debug_print_contour (file, &stroker->ccw.contour);
1235             fclose (file);
1236
1237             _cairo_contour_reset (&stroker->path);
1238         }
1239 #endif
1240         _cairo_contour_reset (&stroker->cw.contour);
1241         _cairo_contour_reset (&stroker->ccw.contour);
1242     } else {
1243         /* Cap the start and end of the sub path as needed */
1244         add_caps (stroker);
1245     }
1246
1247     stroker->has_initial_sub_path = FALSE;
1248     stroker->has_first_face = FALSE;
1249     stroker->has_current_face = FALSE;
1250
1251     return CAIRO_STATUS_SUCCESS;
1252 }
1253
1254 cairo_status_t
1255 _cairo_path_fixed_stroke_to_polygon (const cairo_path_fixed_t   *path,
1256                                      const cairo_stroke_style_t *style,
1257                                      const cairo_matrix_t       *ctm,
1258                                      const cairo_matrix_t       *ctm_inverse,
1259                                      double              tolerance,
1260                                      cairo_polygon_t *polygon)
1261 {
1262     struct stroker stroker;
1263     cairo_status_t status;
1264
1265     if (style->num_dashes) {
1266         return _cairo_path_fixed_stroke_dashed_to_polygon (path,
1267                                                            style,
1268                                                            ctm,
1269                                                            ctm_inverse,
1270                                                            tolerance,
1271                                                            polygon);
1272     }
1273
1274     stroker.has_bounds = polygon->num_limits;
1275     if (stroker.has_bounds) {
1276         /* Extend the bounds in each direction to account for the maximum area
1277          * we might generate trapezoids, to capture line segments that are
1278          * outside of the bounds but which might generate rendering that's
1279          * within bounds.
1280          */
1281         double dx, dy;
1282         cairo_fixed_t fdx, fdy;
1283         int i;
1284
1285         stroker.bounds = polygon->limits[0];
1286         for (i = 1; i < polygon->num_limits; i++)
1287              _cairo_box_add_box (&stroker.bounds, &polygon->limits[i]);
1288
1289         _cairo_stroke_style_max_distance_from_path (style, path, ctm, &dx, &dy);
1290         fdx = _cairo_fixed_from_double (dx);
1291         fdy = _cairo_fixed_from_double (dy);
1292
1293         stroker.bounds.p1.x -= fdx;
1294         stroker.bounds.p2.x += fdx;
1295         stroker.bounds.p1.y -= fdy;
1296         stroker.bounds.p2.y += fdy;
1297     }
1298
1299     stroker.style = *style;
1300     stroker.ctm = ctm;
1301     stroker.ctm_inverse = ctm_inverse;
1302     stroker.tolerance = tolerance;
1303     stroker.half_line_width = style->line_width / 2.;
1304     /* To test whether we need to join two segments of a spline using
1305      * a round-join or a bevel-join, we can inspect the angle between the
1306      * two segments. If the difference between the chord distance
1307      * (half-line-width times the cosine of the bisection angle) and the
1308      * half-line-width itself is greater than tolerance then we need to
1309      * inject a point.
1310      */
1311     stroker.spline_cusp_tolerance = 1 - tolerance / stroker.half_line_width;
1312     stroker.spline_cusp_tolerance *= stroker.spline_cusp_tolerance;
1313     stroker.spline_cusp_tolerance *= 2;
1314     stroker.spline_cusp_tolerance -= 1;
1315     stroker.ctm_det_positive =
1316         _cairo_matrix_compute_determinant (ctm) >= 0.0;
1317
1318     stroker.pen.num_vertices = 0;
1319     if (path->has_curve_to ||
1320         style->line_join == CAIRO_LINE_JOIN_ROUND ||
1321         style->line_cap == CAIRO_LINE_CAP_ROUND) {
1322         status = _cairo_pen_init (&stroker.pen,
1323                                   stroker.half_line_width,
1324                                   tolerance, ctm);
1325         if (unlikely (status))
1326             return status;
1327
1328         /* If the line width is so small that the pen is reduced to a
1329            single point, then we have nothing to do. */
1330         if (stroker.pen.num_vertices <= 1) {
1331             if (stroker.pen.num_vertices)
1332                 _cairo_pen_fini (&stroker.pen);
1333             return CAIRO_STATUS_SUCCESS;
1334         }
1335     }
1336
1337     stroker.has_current_face = FALSE;
1338     stroker.has_first_face = FALSE;
1339     stroker.has_initial_sub_path = FALSE;
1340
1341 #if DEBUG
1342     remove ("contours.txt");
1343     remove ("polygons.txt");
1344     _cairo_contour_init (&stroker.path, 0);
1345 #endif
1346     _cairo_contour_init (&stroker.cw.contour, 1);
1347     _cairo_contour_init (&stroker.ccw.contour, -1);
1348     tolerance *= CAIRO_FIXED_ONE;
1349     tolerance *= tolerance;
1350     stroker.contour_tolerance = tolerance;
1351     stroker.polygon = polygon;
1352
1353     status = _cairo_path_fixed_interpret (path,
1354                                           move_to,
1355                                           line_to,
1356                                           curve_to,
1357                                           close_path,
1358                                           &stroker);
1359     /* Cap the start and end of the final sub path as needed */
1360     if (likely (status == CAIRO_STATUS_SUCCESS))
1361         add_caps (&stroker);
1362
1363     _cairo_contour_fini (&stroker.cw.contour);
1364     _cairo_contour_fini (&stroker.ccw.contour);
1365     if (stroker.pen.num_vertices)
1366         _cairo_pen_fini (&stroker.pen);
1367
1368 #if DEBUG
1369     {
1370         FILE *file = fopen ("polygons.txt", "a");
1371         _cairo_debug_print_polygon (file, polygon);
1372         fclose (file);
1373     }
1374 #endif
1375
1376     return status;
1377 }