1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//----------------------------------------------------------------------------
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Anti-Grain Geometry - Version 2.3
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Permission to copy, use, modify, sell and distribute this software
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// is granted provided this copyright notice appears in all copies.
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This software is provided "as is" without express or implied
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// warranty, and with no claim as to its suitability for any purpose.
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//----------------------------------------------------------------------------
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Contact: mcseem@antigrain.com
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//          mcseemagg@yahoo.com
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//          http://www.antigrain.com
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//----------------------------------------------------------------------------
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_BASICS_INCLUDED
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_BASICS_INCLUDED
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_INT8
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_INT8 signed char
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_INT8U
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_INT8U unsigned char
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_INT16
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_INT16 short
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_INT16U
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_INT16U unsigned short
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_INT32
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_INT32 int
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_INT32U
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_INT32U unsigned
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_INT64
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_INT64 signed long long
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef AGG_INT64U
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_INT64U unsigned long long
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AGG_INLINE inline
43ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcrt/fx_system.h"  // For FX_FLOAT
45ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovnamespace agg
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef AGG_INT8   int8;
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef AGG_INT8U  int8u;
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef AGG_INT16  int16;
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef AGG_INT16U int16u;
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef AGG_INT32  int32;
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef AGG_INT32U int32u;
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef AGG_INT64  int64;
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef AGG_INT64U int64u;
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef unsigned char cover_type;
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovenum cover_scale_e {
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cover_shift = 8,
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cover_size  = 1 << cover_shift,
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cover_mask  = cover_size - 1,
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cover_none  = 0,
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cover_full  = cover_mask
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtemplate<class T> struct rect_base  {
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    typedef rect_base<T> self_type;
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T x1;
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T y1;
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T x2;
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    T y2;
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rect_base() {}
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rect_base(T x1_, T y1_, T x2_, T y2_) :
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const self_type& normalize()
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        T t;
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(x1 > x2) {
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            t = x1;
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            x1 = x2;
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            x2 = t;
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(y1 > y2) {
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            t = y1;
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            y1 = y2;
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            y2 = t;
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return *this;
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bool clip(const self_type& r)
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(x2 > r.x2) {
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            x2 = r.x2;
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(y2 > r.y2) {
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            y2 = r.y2;
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(x1 < r.x1) {
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            x1 = r.x1;
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(y1 < r.y1) {
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            y1 = r.y1;
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return x1 <= x2 && y1 <= y2;
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bool is_valid() const
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return x1 <= x2 && y1 <= y2;
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtemplate<class Rect>
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline Rect intersect_rectangles(const Rect& r1, const Rect& r2)
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Rect r = r1;
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(r.x2 > r2.x2) {
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        r.x2 = r2.x2;
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(r.y2 > r2.y2) {
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        r.y2 = r2.y2;
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(r.x1 < r2.x1) {
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        r.x1 = r2.x1;
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(r.y1 < r2.y1) {
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        r.y1 = r2.y1;
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return r;
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtemplate<class Rect>
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline Rect unite_rectangles(const Rect& r1, const Rect& r2)
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Rect r = r1;
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(r.x2 < r2.x2) {
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        r.x2 = r2.x2;
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(r.y2 < r2.y2) {
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        r.y2 = r2.y2;
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(r.x1 > r2.x1) {
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        r.x1 = r2.x1;
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(r.y1 > r2.y1) {
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        r.y1 = r2.y1;
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return r;
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef rect_base<int>    rect;
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef rect_base<FX_FLOAT> rect_d;
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovenum path_commands_e {
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_stop     = 0,
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_move_to  = 1,
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_line_to  = 2,
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_curve3   = 3,
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_curve4   = 4,
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_curveN   = 5,
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_catrom   = 6,
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_ubspline = 7,
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_end_poly = 0x0F,
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_cmd_mask     = 0x0F
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovenum path_flags_e {
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_flags_none  = 0,
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_flags_ccw   = 0x10,
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_flags_cw    = 0x20,
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_flags_close = 0x40,
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_flags_jr	 = 0x80,
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_flags_mask  = 0xF0
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_vertex(unsigned c)
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c >= path_cmd_move_to && c < path_cmd_end_poly;
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_drawing(unsigned c)
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c >= path_cmd_line_to && c < path_cmd_end_poly;
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_stop(unsigned c)
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c == path_cmd_stop;
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_move_to(unsigned c)
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c == path_cmd_move_to;
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_line_to(unsigned c)
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c == path_cmd_line_to;
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_curve(unsigned c)
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c == path_cmd_curve3 || c == path_cmd_curve4;
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_curve3(unsigned c)
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c == path_cmd_curve3;
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_curve4(unsigned c)
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c == path_cmd_curve4;
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_end_poly(unsigned c)
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (c & path_cmd_mask) == path_cmd_end_poly;
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_close(unsigned c)
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (c & ~(path_flags_cw | path_flags_ccw)) ==
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           (path_cmd_end_poly | path_flags_close);
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_next_poly(unsigned c)
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return is_stop(c) || is_move_to(c) || is_end_poly(c);
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_cw(unsigned c)
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (c & path_flags_cw) != 0;
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_ccw(unsigned c)
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (c & path_flags_ccw) != 0;
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_oriented(unsigned c)
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (c & (path_flags_cw | path_flags_ccw)) != 0;
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline bool is_closed(unsigned c)
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (c & path_flags_close) != 0;
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline unsigned get_close_flag(unsigned c)
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c & path_flags_close;
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline unsigned clear_orientation(unsigned c)
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c & ~(path_flags_cw | path_flags_ccw);
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline unsigned get_orientation(unsigned c)
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return c & (path_flags_cw | path_flags_ccw);
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline unsigned set_orientation(unsigned c, unsigned o)
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    c &= ~path_flags_jr;
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return clear_orientation(c) | o;
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
263e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstruct point_type  {
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT x, y;
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned flag;
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    point_type() {}
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    point_type(FX_FLOAT x_, FX_FLOAT y_, unsigned flag_ = 0) : x(x_), y(y_), flag(flag_) {}
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct point_type_flag : public point_type {
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned flag;
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    point_type_flag()
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flag = 0;
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    point_type_flag(FX_FLOAT x_, FX_FLOAT y_, unsigned flag_ = 0) : point_type(x_, y_), flag(flag_) {}
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
277e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstruct vertex_type  {
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT   x, y;
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned cmd;
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    vertex_type() {}
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    vertex_type(FX_FLOAT x_, FX_FLOAT y_, unsigned cmd_) :
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        x(x_), y(y_), cmd(cmd_) {}
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
286