comparison mupdf-source/include/mupdf/fitz/path.h @ 2:b50eed0cc0ef upstream

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