1 #ifndef MUPDF_FITZ_PATH_H
2 #define MUPDF_FITZ_PATH_H
3 
4 #include "mupdf/fitz/system.h"
5 #include "mupdf/fitz/context.h"
6 #include "mupdf/fitz/geometry.h"
7 
8 /**
9  * Vector path buffer.
10  * It can be stroked and dashed, or be filled.
11  * It has a fill rule (nonzero or even_odd).
12  *
13  * When rendering, they are flattened, stroked and dashed straight
14  * into the Global Edge List.
15  */
16 
17 typedef struct fz_path fz_path;
18 
19 typedef enum
20 {
21 	FZ_LINECAP_BUTT = 0,
22 	FZ_LINECAP_ROUND = 1,
23 	FZ_LINECAP_SQUARE = 2,
24 	FZ_LINECAP_TRIANGLE = 3
25 } fz_linecap;
26 
27 typedef enum
28 {
29 	FZ_LINEJOIN_MITER = 0,
30 	FZ_LINEJOIN_ROUND = 1,
31 	FZ_LINEJOIN_BEVEL = 2,
32 	FZ_LINEJOIN_MITER_XPS = 3
33 } fz_linejoin;
34 
35 typedef struct
36 {
37 	int refs;
38 	fz_linecap start_cap, dash_cap, end_cap;
39 	fz_linejoin linejoin;
40 	float linewidth;
41 	float miterlimit;
42 	float dash_phase;
43 	int dash_len;
44 	float dash_list[32];
45 } fz_stroke_state;
46 
47 typedef struct
48 {
49 	/* Compulsory ones */
50 	void (*moveto)(fz_context *ctx, void *arg, float x, float y);
51 	void (*lineto)(fz_context *ctx, void *arg, float x, float y);
52 	void (*curveto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2, float x3, float y3);
53 	void (*closepath)(fz_context *ctx, void *arg);
54 	/* Optional ones */
55 	void (*quadto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2);
56 	void (*curvetov)(fz_context *ctx, void *arg, float x2, float y2, float x3, float y3);
57 	void (*curvetoy)(fz_context *ctx, void *arg, float x1, float y1, float x3, float y3);
58 	void (*rectto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2);
59 } fz_path_walker;
60 
61 /**
62 	Walk the segments of a path, calling the
63 	appropriate callback function from a given set for each
64 	segment of the path.
65 
66 	path: The path to walk.
67 
68 	walker: The set of callback functions to use. The first
69 	4 callback pointers in the set must be non-NULL. The
70 	subsequent ones can either be supplied, or can be left
71 	as NULL, in which case the top 4 functions will be
72 	called as appropriate to simulate them.
73 
74 	arg: An opaque argument passed in to each callback.
75 
76 	Exceptions will only be thrown if the underlying callback
77 	functions throw them.
78 */
79 void fz_walk_path(fz_context *ctx, const fz_path *path, const fz_path_walker *walker, void *arg);
80 
81 /**
82 	Create a new (empty) path structure.
83 */
84 fz_path *fz_new_path(fz_context *ctx);
85 
86 /**
87 	Increment the reference count. Returns the same pointer.
88 
89 	All paths can be kept, regardless of their packing type.
90 
91 	Never throws exceptions.
92 */
93 fz_path *fz_keep_path(fz_context *ctx, const fz_path *path);
94 
95 /**
96 	Decrement the reference count. When the reference count hits
97 	zero, free the path.
98 
99 	All paths can be dropped, regardless of their packing type.
100 	Packed paths do not own the blocks into which they are packed
101 	so dropping them does not free those blocks.
102 
103 	Never throws exceptions.
104 */
105 void fz_drop_path(fz_context *ctx, const fz_path *path);
106 
107 /**
108 	Minimise the internal storage used by a path.
109 
110 	As paths are constructed, the internal buffers
111 	grow. To avoid repeated reallocations they
112 	grow with some spare space. Once a path has
113 	been fully constructed, this call allows the
114 	excess space to be trimmed.
115 */
116 void fz_trim_path(fz_context *ctx, fz_path *path);
117 
118 /**
119 	Return the number of bytes required to pack a path.
120 */
121 int fz_packed_path_size(const fz_path *path);
122 
123 /**
124 	Pack a path into the given block.
125 	To minimise the size of paths, this function allows them to be
126 	packed into a buffer with other information. Paths can be used
127 	interchangeably regardless of how they are packed.
128 
129 	pack: Pointer to a block of data to pack the path into. Should
130 	be aligned by the caller to the same alignment as required for
131 	a fz_path pointer.
132 
133 	max: The number of bytes available in the block.
134 	If max < sizeof(fz_path) then an exception will
135 	be thrown. If max >= the value returned by
136 	fz_packed_path_size, then this call will never
137 	fail, except in low memory situations with large
138 	paths.
139 
140 	path: The path to pack.
141 
142 	Returns the number of bytes within the block used. Callers can
143 	access the packed path data by casting the value of pack on
144 	entry to be a fz_path *.
145 
146 	Throws exceptions on failure to allocate, or if
147 	max < sizeof(fz_path).
148 
149 	Implementation details: Paths can be 'unpacked', 'flat', or
150 	'open'. Standard paths, as created are 'unpacked'. Paths that
151 	will pack into less than max bytes will be packed as 'flat',
152 	unless they are too large (where large indicates that they
153 	exceed some private implementation defined limits, currently
154 	including having more than 256 coordinates or commands).
155 
156 	Large paths are 'open' packed as a header into the given block,
157 	plus pointers to other data blocks.
158 
159 	Users should not have to care about whether paths are 'open'
160 	or 'flat' packed. Simply pack a path (if required), and then
161 	forget about the details.
162 */
163 size_t fz_pack_path(fz_context *ctx, uint8_t *pack, size_t max, const fz_path *path);
164 
165 /**
166 	Clone the data for a path.
167 
168 	This is used in preference to fz_keep_path when a whole
169 	new copy of a path is required, rather than just a shared
170 	pointer. This probably indicates that the path is about to
171 	be modified.
172 
173 	path: path to clone.
174 
175 	Throws exceptions on failure to allocate.
176 */
177 fz_path *fz_clone_path(fz_context *ctx, fz_path *path);
178 
179 /**
180 	Return the current point that a path has
181 	reached or (0,0) if empty.
182 
183 	path: path to return the current point of.
184 */
185 fz_point fz_currentpoint(fz_context *ctx, fz_path *path);
186 
187 /**
188 	Append a 'moveto' command to a path.
189 	This 'opens' a path.
190 
191 	path: The path to modify.
192 
193 	x, y: The coordinate to move to.
194 
195 	Throws exceptions on failure to allocate, or attempting to
196 	modify a packed path.
197 */
198 void fz_moveto(fz_context *ctx, fz_path *path, float x, float y);
199 
200 /**
201 	Append a 'lineto' command to an open path.
202 
203 	path: The path to modify.
204 
205 	x, y: The coordinate to line to.
206 
207 	Throws exceptions on failure to allocate, or attempting to
208 	modify a packed path.
209 */
210 void fz_lineto(fz_context *ctx, fz_path *path, float x, float y);
211 
212 /**
213 	Append a 'rectto' command to an open path.
214 
215 	The rectangle is equivalent to:
216 		moveto x0 y0
217 		lineto x1 y0
218 		lineto x1 y1
219 		lineto x0 y1
220 		closepath
221 
222 	path: The path to modify.
223 
224 	x0, y0: First corner of the rectangle.
225 
226 	x1, y1: Second corner of the rectangle.
227 
228 	Throws exceptions on failure to allocate, or attempting to
229 	modify a packed path.
230 */
231 void fz_rectto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
232 
233 /**
234 	Append a 'quadto' command to an open path. (For a
235 	quadratic bezier).
236 
237 	path: The path to modify.
238 
239 	x0, y0: The control coordinates for the quadratic curve.
240 
241 	x1, y1: The end coordinates for the quadratic curve.
242 
243 	Throws exceptions on failure to allocate, or attempting to
244 	modify a packed path.
245 */
246 void fz_quadto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
247 
248 /**
249 	Append a 'curveto' command to an open path. (For a
250 	cubic bezier).
251 
252 	path: The path to modify.
253 
254 	x0, y0: The coordinates of the first control point for the
255 	curve.
256 
257 	x1, y1: The coordinates of the second control point for the
258 	curve.
259 
260 	x2, y2: The end coordinates for the curve.
261 
262 	Throws exceptions on failure to allocate, or attempting to
263 	modify a packed path.
264 */
265 void fz_curveto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1, float x2, float y2);
266 
267 /**
268 	Append a 'curvetov' command to an open path. (For a
269 	cubic bezier with the first control coordinate equal to
270 	the start point).
271 
272 	path: The path to modify.
273 
274 	x1, y1: The coordinates of the second control point for the
275 	curve.
276 
277 	x2, y2: The end coordinates for the curve.
278 
279 	Throws exceptions on failure to allocate, or attempting to
280 	modify a packed path.
281 */
282 void fz_curvetov(fz_context *ctx, fz_path *path, float x1, float y1, float x2, float y2);
283 
284 /**
285 	Append a 'curvetoy' command to an open path. (For a
286 	cubic bezier with the second control coordinate equal to
287 	the end point).
288 
289 	path: The path to modify.
290 
291 	x0, y0: The coordinates of the first control point for the
292 	curve.
293 
294 	x2, y2: The end coordinates for the curve (and the second
295 	control coordinate).
296 
297 	Throws exceptions on failure to allocate, or attempting to
298 	modify a packed path.
299 */
300 void fz_curvetoy(fz_context *ctx, fz_path *path, float x0, float y0, float x2, float y2);
301 
302 /**
303 	Close the current subpath.
304 
305 	path: The path to modify.
306 
307 	Throws exceptions on failure to allocate, attempting to modify
308 	a packed path, and illegal path closes (i.e. closing a non open
309 	path).
310 */
311 void fz_closepath(fz_context *ctx, fz_path *path);
312 
313 /**
314 	Transform a path by a given
315 	matrix.
316 
317 	path: The path to modify (must not be a packed path).
318 
319 	transform: The transform to apply.
320 
321 	Throws exceptions if the path is packed, or on failure
322 	to allocate.
323 */
324 void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform);
325 
326 /**
327 	Return a bounding rectangle for a path.
328 
329 	path: The path to bound.
330 
331 	stroke: If NULL, the bounding rectangle given is for
332 	the filled path. If non-NULL the bounding rectangle
333 	given is for the path stroked with the given attributes.
334 
335 	ctm: The matrix to apply to the path during stroking.
336 
337 	r: Pointer to a fz_rect which will be used to hold
338 	the result.
339 
340 	Returns r, updated to contain the bounding rectangle.
341 */
342 fz_rect fz_bound_path(fz_context *ctx, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm);
343 
344 /**
345 	Given a rectangle (assumed to be the bounding box for a path),
346 	expand it to allow for the expansion of the bbox that would be
347 	seen by stroking the path with the given stroke state and
348 	transform.
349 */
350 fz_rect fz_adjust_rect_for_stroke(fz_context *ctx, fz_rect rect, const fz_stroke_state *stroke, fz_matrix ctm);
351 
352 /**
353 	A sane 'default' stroke state.
354 */
355 extern const fz_stroke_state fz_default_stroke_state;
356 
357 /**
358 	Create a new (empty) stroke state structure (with no dash
359 	data) and return a reference to it.
360 
361 	Throws exception on failure to allocate.
362 */
363 fz_stroke_state *fz_new_stroke_state(fz_context *ctx);
364 
365 /**
366 	Create a new (empty) stroke state structure, with room for
367 	dash data of the given length, and return a reference to it.
368 
369 	len: The number of dash elements to allow room for.
370 
371 	Throws exception on failure to allocate.
372 */
373 fz_stroke_state *fz_new_stroke_state_with_dash_len(fz_context *ctx, int len);
374 
375 /**
376 	Take an additional reference to a stroke state structure.
377 
378 	No modifications should be carried out on a stroke
379 	state to which more than one reference is held, as
380 	this can cause race conditions.
381 */
382 fz_stroke_state *fz_keep_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
383 
384 /**
385 	Drop a reference to a stroke state structure, destroying the
386 	structure if it is the last reference.
387 */
388 void fz_drop_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
389 
390 /**
391 	Given a reference to a (possibly) shared stroke_state structure,
392 	return a reference to an equivalent stroke_state structure
393 	that is guaranteed to be unshared (i.e. one that can
394 	safely be modified).
395 
396 	shared: The reference to a (possibly) shared structure
397 	to unshare. Ownership of this reference is passed in
398 	to this function, even in the case of exceptions being
399 	thrown.
400 
401 	Exceptions may be thrown in the event of failure to
402 	allocate if required.
403 */
404 fz_stroke_state *fz_unshare_stroke_state(fz_context *ctx, fz_stroke_state *shared);
405 
406 /**
407 	Given a reference to a (possibly) shared stroke_state structure,
408 	return a reference to a stroke_state structure (with room for a
409 	given amount of dash data) that is guaranteed to be unshared
410 	(i.e. one that can safely be modified).
411 
412 	shared: The reference to a (possibly) shared structure
413 	to unshare. Ownership of this reference is passed in
414 	to this function, even in the case of exceptions being
415 	thrown.
416 
417 	Exceptions may be thrown in the event of failure to
418 	allocate if required.
419 */
420 fz_stroke_state *fz_unshare_stroke_state_with_dash_len(fz_context *ctx, fz_stroke_state *shared, int len);
421 
422 /**
423 	Create an identical stroke_state structure and return a
424 	reference to it.
425 
426 	stroke: The stroke state reference to clone.
427 
428 	Exceptions may be thrown in the event of a failure to
429 	allocate.
430 */
431 fz_stroke_state *fz_clone_stroke_state(fz_context *ctx, fz_stroke_state *stroke);
432 
433 #endif
434