Tizen 2.0 Release
[framework/graphics/cairo.git] / src / cairo-path-fixed-private.h
1 /* cairo - a vector graphics library with display and print output
2  *
3  * Copyright © 2005 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it either under the terms of the GNU Lesser General Public
7  * License version 2.1 as published by the Free Software Foundation
8  * (the "LGPL") or, at your option, under the terms of the Mozilla
9  * Public License Version 1.1 (the "MPL"). If you do not alter this
10  * notice, a recipient may use your version of this file under either
11  * the MPL or the LGPL.
12  *
13  * You should have received a copy of the LGPL along with this library
14  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16  * You should have received a copy of the MPL along with this library
17  * in the file COPYING-MPL-1.1
18  *
19  * The contents of this file are subject to the Mozilla Public License
20  * Version 1.1 (the "License"); you may not use this file except in
21  * compliance with the License. You may obtain a copy of the License at
22  * http://www.mozilla.org/MPL/
23  *
24  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26  * the specific language governing rights and limitations.
27  *
28  * The Original Code is the cairo graphics library.
29  *
30  * The Initial Developer of the Original Code is Red Hat, Inc.
31  *
32  * Contributor(s):
33  *      Carl D. Worth <cworth@redhat.com>
34  */
35
36 #ifndef CAIRO_PATH_FIXED_PRIVATE_H
37 #define CAIRO_PATH_FIXED_PRIVATE_H
38
39 #include "cairo-types-private.h"
40 #include "cairo-compiler-private.h"
41 #include "cairo-list-private.h"
42
43 #define WATCH_PATH 0
44 #if WATCH_PATH
45 #include <stdio.h>
46 #endif
47
48 enum cairo_path_op {
49     CAIRO_PATH_OP_MOVE_TO = 0,
50     CAIRO_PATH_OP_LINE_TO = 1,
51     CAIRO_PATH_OP_CURVE_TO = 2,
52     CAIRO_PATH_OP_CLOSE_PATH = 3
53 };
54
55 /* we want to make sure a single byte is used for the enum */
56 typedef char cairo_path_op_t;
57
58 /* make _cairo_path_fixed fit into ~512 bytes -- about 50 items */
59 #define CAIRO_PATH_BUF_SIZE ((512 - sizeof (cairo_path_buf_t)) \
60                            / (2 * sizeof (cairo_point_t) + sizeof (cairo_path_op_t)))
61
62 typedef struct _cairo_path_buf {
63     cairo_list_t link;
64     unsigned int num_ops;
65     unsigned int size_ops;
66     unsigned int num_points;
67     unsigned int size_points;
68
69     cairo_path_op_t *op;
70     cairo_point_t *points;
71 } cairo_path_buf_t;
72
73 typedef struct _cairo_path_buf_fixed {
74     cairo_path_buf_t base;
75
76     cairo_path_op_t op[CAIRO_PATH_BUF_SIZE];
77     cairo_point_t points[2 * CAIRO_PATH_BUF_SIZE];
78 } cairo_path_buf_fixed_t;
79
80 /*
81   NOTES:
82   has_curve_to => !stroke_is_rectilinear
83   fill_is_rectilinear => stroke_is_rectilinear
84   fill_is_empty => fill_is_rectilinear
85   fill_maybe_region => fill_is_rectilinear
86 */
87 struct _cairo_path_fixed {
88     cairo_point_t last_move_point;
89     cairo_point_t current_point;
90     unsigned int has_current_point      : 1;
91     unsigned int needs_move_to          : 1;
92     unsigned int has_extents            : 1;
93     unsigned int has_curve_to           : 1;
94     unsigned int stroke_is_rectilinear  : 1;
95     unsigned int fill_is_rectilinear    : 1;
96     unsigned int fill_maybe_region      : 1;
97     unsigned int fill_is_empty          : 1;
98
99     cairo_box_t extents;
100
101     cairo_path_buf_fixed_t  buf;
102 };
103
104 cairo_private void
105 _cairo_path_fixed_translate (cairo_path_fixed_t *path,
106                              cairo_fixed_t offx,
107                              cairo_fixed_t offy);
108
109 cairo_private cairo_status_t
110 _cairo_path_fixed_append (cairo_path_fixed_t                *path,
111                           const cairo_path_fixed_t          *other,
112                           cairo_fixed_t                      tx,
113                           cairo_fixed_t                      ty);
114
115 cairo_private unsigned long
116 _cairo_path_fixed_hash (const cairo_path_fixed_t *path);
117
118 cairo_private unsigned long
119 _cairo_path_fixed_size (const cairo_path_fixed_t *path);
120
121 cairo_private cairo_bool_t
122 _cairo_path_fixed_equal (const cairo_path_fixed_t *a,
123                          const cairo_path_fixed_t *b);
124
125 typedef struct _cairo_path_fixed_iter {
126     const cairo_path_buf_t *first;
127     const cairo_path_buf_t *buf;
128     unsigned int n_op;
129     unsigned int n_point;
130 } cairo_path_fixed_iter_t;
131
132 cairo_private void
133 _cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter,
134                              const cairo_path_fixed_t *path);
135
136 cairo_private cairo_bool_t
137 _cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter,
138                                     cairo_box_t *box);
139
140 cairo_private cairo_bool_t
141 _cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter);
142
143 static inline cairo_bool_t
144 _cairo_path_fixed_fill_is_empty (const cairo_path_fixed_t *path)
145 {
146     return path->fill_is_empty;
147 }
148
149 static inline cairo_bool_t
150 _cairo_path_fixed_fill_is_rectilinear (const cairo_path_fixed_t *path)
151 {
152     if (! path->fill_is_rectilinear)
153         return 0;
154
155     if (! path->has_current_point || path->needs_move_to)
156         return 1;
157
158     /* check whether the implicit close preserves the rectilinear property */
159     return path->current_point.x == path->last_move_point.x ||
160            path->current_point.y == path->last_move_point.y;
161 }
162
163 static inline cairo_bool_t
164 _cairo_path_fixed_stroke_is_rectilinear (const cairo_path_fixed_t *path)
165 {
166     return path->stroke_is_rectilinear;
167 }
168
169 static inline cairo_bool_t
170 _cairo_path_fixed_fill_maybe_region (const cairo_path_fixed_t *path)
171 {
172     if (! path->fill_maybe_region)
173         return 0;
174
175     if (! path->has_current_point || path->needs_move_to)
176         return 1;
177
178     /* check whether the implicit close preserves the rectilinear property
179      * (the integer point property is automatically preserved)
180      */
181     return path->current_point.x == path->last_move_point.x ||
182            path->current_point.y == path->last_move_point.y;
183 }
184
185 cairo_private cairo_bool_t
186 _cairo_path_fixed_is_stroke_box (const cairo_path_fixed_t *path,
187                                  cairo_box_t *box);
188
189 #endif /* CAIRO_PATH_FIXED_PRIVATE_H */