1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 /*
24  * This code is based on Libart_LGPL - library of basic graphic primitives
25  *
26  * Copyright (c) 1998 Raph Levien
27  *
28  * Licensed under GNU LGPL v2
29  *
30  */
31 
32 /* Simple macros to set up storage allocation and basic types for libart
33    functions. */
34 
35 #ifndef __ART_H__
36 #define __ART_H__
37 
38 #include "common/scummsys.h"
39 
40 namespace Sword25 {
41 
42 /* These aren't, strictly speaking, configuration macros, but they're
43    damn handy to have around, and may be worth playing with for
44    debugging. */
45 #define art_new(type, n) ((type *)malloc ((n) * sizeof(type)))
46 
47 #define art_renew(p, type, n) ((type *)realloc (p, (n) * sizeof(type)))
48 
49 /* This one must be used carefully - in particular, p and max should
50    be variables. They can also be pstruct->el lvalues. */
51 #define art_expand(p, type, max) \
52 			do { \
53 				if (max) {\
54 					type *tmp = art_renew(p, type, max <<= 1); \
55 					if (!tmp) error("Cannot reallocate memory for art data"); \
56 					p = tmp; \
57 				} else { \
58 					max = 1; \
59 					p = art_new(type, 1); \
60 					if (!p) error("Cannot allocate memory for art data"); \
61 				} \
62 			} while (0)
63 
64 struct ArtDRect {
65 	/*< public >*/
66 	double x0, y0, x1, y1;
67 };
68 
69 struct ArtPoint {
70 	/*< public >*/
71 	double x, y;
72 };
73 
74 /* Basic data structures and constructors for sorted vector paths */
75 
76 struct ArtSVPSeg {
77 	int n_points;
78 	int dir; /* == 0 for "up", 1 for "down" */
79 	ArtDRect bbox;
80 	ArtPoint *points;
81 };
82 
83 struct ArtSVP {
84 	int n_segs;
85 	ArtSVPSeg segs[1];
86 };
87 
88 void art_svp_free(ArtSVP *svp);
89 
90 int art_svp_seg_compare(const void *s1, const void *s2);
91 
92 /* Basic data structures and constructors for bezier paths */
93 
94 enum ArtPathcode {
95 	ART_MOVETO,
96 	ART_MOVETO_OPEN,
97 	ART_CURVETO,
98 	ART_LINETO,
99 	ART_END
100 };
101 
102 struct ArtBpath {
103 	/*< public >*/
104 	ArtPathcode code;
105 	double x1;
106 	double y1;
107 	double x2;
108 	double y2;
109 	double x3;
110 	double y3;
111 };
112 
113 /* Basic data structures and constructors for simple vector paths */
114 
115 /* CURVETO is not allowed! */
116 struct ArtVpath {
117 	ArtPathcode code;
118 	double x;
119 	double y;
120 };
121 
122 /* Some of the functions need to go into their own modules */
123 
124 void art_vpath_add_point(ArtVpath **p_vpath, int *pn_points, int *pn_points_max,
125                     ArtPathcode code, double x, double y);
126 
127 ArtVpath *art_bez_path_to_vec(const ArtBpath *bez, double flatness);
128 
129 /* The funky new SVP intersector. */
130 
131 #ifndef ART_WIND_RULE_DEFINED
132 #define ART_WIND_RULE_DEFINED
133 enum ArtWindRule {
134 	ART_WIND_RULE_NONZERO,
135 	ART_WIND_RULE_INTERSECT,
136 	ART_WIND_RULE_ODDEVEN,
137 	ART_WIND_RULE_POSITIVE
138 };
139 #endif
140 
141 struct ArtSvpWriter {
142 	int (*add_segment)(ArtSvpWriter *self, int wind_left, int delta_wind,
143 	                   double x, double y);
144 	void (*add_point)(ArtSvpWriter *self, int seg_id, double x, double y);
145 	void (*close_segment)(ArtSvpWriter *self, int seg_id);
146 };
147 
148 ArtSvpWriter *art_svp_writer_rewind_new(ArtWindRule rule);
149 
150 ArtSVP *art_svp_writer_rewind_reap(ArtSvpWriter *self);
151 
152 int art_svp_seg_compare(const void *s1, const void *s2);
153 
154 void art_svp_intersector(const ArtSVP *in, ArtSvpWriter *out);
155 
156 
157 /* Sort vector paths into sorted vector paths. */
158 
159 ArtSVP *art_svp_from_vpath(ArtVpath *vpath);
160 
161 /* Sort vector paths into sorted vector paths. */
162 
163 enum ArtPathStrokeJoinType {
164 	ART_PATH_STROKE_JOIN_MITER,
165 	ART_PATH_STROKE_JOIN_ROUND,
166 	ART_PATH_STROKE_JOIN_BEVEL
167 };
168 
169 enum ArtPathStrokeCapType {
170 	ART_PATH_STROKE_CAP_BUTT,
171 	ART_PATH_STROKE_CAP_ROUND,
172 	ART_PATH_STROKE_CAP_SQUARE
173 };
174 
175 ArtSVP *art_svp_vpath_stroke(ArtVpath *vpath,
176                      ArtPathStrokeJoinType join,
177                      ArtPathStrokeCapType cap,
178                      double line_width,
179                      double miter_limit,
180                      double flatness);
181 
182 /* This version may have winding numbers exceeding 1. */
183 ArtVpath *art_svp_vpath_stroke_raw(ArtVpath *vpath,
184                          ArtPathStrokeJoinType join,
185                          ArtPathStrokeCapType cap,
186                          double line_width,
187                          double miter_limit,
188                          double flatness);
189 
190 
191 /* The spiffy antialiased renderer for sorted vector paths. */
192 
193 struct ArtSVPRenderAAStep {
194 	int x;
195 	int delta; /* stored with 16 fractional bits */
196 };
197 
198 struct ArtSVPRenderAAIter;
199 
200 ArtSVPRenderAAIter *art_svp_render_aa_iter(const ArtSVP *svp,
201                        int x0, int y0, int x1, int y1);
202 
203 void art_svp_render_aa_iter_step(ArtSVPRenderAAIter *iter, int *p_start,
204                             ArtSVPRenderAAStep **p_steps, int *p_n_steps);
205 
206 void art_svp_render_aa_iter_done(ArtSVPRenderAAIter *iter);
207 
208 void art_svp_render_aa(const ArtSVP *svp,
209                   int x0, int y0, int x1, int y1,
210                   void (*callback)(void *callback_data,
211                                    int y,
212                                    int start,
213                                    ArtSVPRenderAAStep *steps, int n_steps),
214                   void *callback_data);
215 
216 } // End of namespace Sword25
217 
218 #endif /* __ART_H__ */
219