| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 |
- // Copyright (C) 2004-2025 Artifex Software, Inc.
- //
- // This file is part of MuPDF.
- //
- // MuPDF is free software: you can redistribute it and/or modify it under the
- // terms of the GNU Affero General Public License as published by the Free
- // Software Foundation, either version 3 of the License, or (at your option)
- // any later version.
- //
- // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
- // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
- // details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
- //
- // Alternative licensing terms are available from the licensor.
- // For commercial licensing, see <https://www.artifex.com/> or contact
- // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
- // CA 94129, USA, for further information.
- #ifndef MUPDF_FITZ_PATH_H
- #define MUPDF_FITZ_PATH_H
- #include "mupdf/fitz/system.h"
- #include "mupdf/fitz/context.h"
- #include "mupdf/fitz/geometry.h"
- /**
- * Vector path buffer.
- * It can be stroked and dashed, or be filled.
- * It has a fill rule (nonzero or even_odd).
- *
- * When rendering, they are flattened, stroked and dashed straight
- * into the Global Edge List.
- */
- typedef struct fz_path fz_path;
- typedef enum
- {
- FZ_LINECAP_BUTT = 0,
- FZ_LINECAP_ROUND = 1,
- FZ_LINECAP_SQUARE = 2,
- FZ_LINECAP_TRIANGLE = 3
- } fz_linecap;
- typedef enum
- {
- FZ_LINEJOIN_MITER = 0,
- FZ_LINEJOIN_ROUND = 1,
- FZ_LINEJOIN_BEVEL = 2,
- FZ_LINEJOIN_MITER_XPS = 3
- } fz_linejoin;
- typedef struct
- {
- int refs;
- fz_linecap start_cap, dash_cap, end_cap;
- fz_linejoin linejoin;
- float linewidth;
- float miterlimit;
- float dash_phase;
- int dash_len;
- float dash_list[FZ_FLEXIBLE_ARRAY];
- } fz_stroke_state;
- typedef struct
- {
- /* Compulsory ones */
- void (*moveto)(fz_context *ctx, void *arg, float x, float y);
- void (*lineto)(fz_context *ctx, void *arg, float x, float y);
- void (*curveto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2, float x3, float y3);
- void (*closepath)(fz_context *ctx, void *arg);
- /* Optional ones */
- void (*quadto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2);
- void (*curvetov)(fz_context *ctx, void *arg, float x2, float y2, float x3, float y3);
- void (*curvetoy)(fz_context *ctx, void *arg, float x1, float y1, float x3, float y3);
- void (*rectto)(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2);
- } fz_path_walker;
- /**
- Walk the segments of a path, calling the
- appropriate callback function from a given set for each
- segment of the path.
- path: The path to walk.
- walker: The set of callback functions to use. The first
- 4 callback pointers in the set must be non-NULL. The
- subsequent ones can either be supplied, or can be left
- as NULL, in which case the top 4 functions will be
- called as appropriate to simulate them.
- arg: An opaque argument passed in to each callback.
- Exceptions will only be thrown if the underlying callback
- functions throw them.
- */
- void fz_walk_path(fz_context *ctx, const fz_path *path, const fz_path_walker *walker, void *arg);
- /**
- Create a new (empty) path structure.
- */
- fz_path *fz_new_path(fz_context *ctx);
- /**
- Increment the reference count. Returns the same pointer.
- All paths can be kept, regardless of their packing type.
- Never throws exceptions.
- */
- fz_path *fz_keep_path(fz_context *ctx, const fz_path *path);
- /**
- Decrement the reference count. When the reference count hits
- zero, free the path.
- All paths can be dropped, regardless of their packing type.
- Packed paths do not own the blocks into which they are packed
- so dropping them does not free those blocks.
- Never throws exceptions.
- */
- void fz_drop_path(fz_context *ctx, const fz_path *path);
- /**
- Minimise the internal storage used by a path.
- As paths are constructed, the internal buffers
- grow. To avoid repeated reallocations they
- grow with some spare space. Once a path has
- been fully constructed, this call allows the
- excess space to be trimmed.
- */
- void fz_trim_path(fz_context *ctx, fz_path *path);
- /**
- Return the number of bytes required to pack a path.
- */
- int fz_packed_path_size(const fz_path *path);
- /**
- Pack a path into the given block.
- To minimise the size of paths, this function allows them to be
- packed into a buffer with other information. Paths can be used
- interchangeably regardless of how they are packed.
- pack: Pointer to a block of data to pack the path into. Should
- be aligned by the caller to the same alignment as required for
- a fz_path pointer.
- path: The path to pack.
- Returns the number of bytes within the block used. Callers can
- access the packed path data by casting the value of pack on
- entry to be a fz_path *.
- Throws exceptions on failure to allocate.
- Implementation details: Paths can be 'unpacked', 'flat', or
- 'open'. Standard paths, as created are 'unpacked'. Paths
- will be packed as 'flat', unless they are too large
- (where large indicates that they exceed some private
- implementation defined limits, currently including having
- more than 256 coordinates or commands).
- Large paths are 'open' packed as a header into the given block,
- plus pointers to other data blocks.
- Users should not have to care about whether paths are 'open'
- or 'flat' packed. Simply pack a path (if required), and then
- forget about the details.
- */
- size_t fz_pack_path(fz_context *ctx, uint8_t *pack, const fz_path *path);
- /**
- Clone the data for a path.
- This is used in preference to fz_keep_path when a whole
- new copy of a path is required, rather than just a shared
- pointer. This probably indicates that the path is about to
- be modified.
- path: path to clone.
- Throws exceptions on failure to allocate.
- */
- fz_path *fz_clone_path(fz_context *ctx, fz_path *path);
- /**
- Return the current point that a path has
- reached or (0,0) if empty.
- path: path to return the current point of.
- */
- fz_point fz_currentpoint(fz_context *ctx, fz_path *path);
- /**
- Append a 'moveto' command to a path.
- This 'opens' a path.
- path: The path to modify.
- x, y: The coordinate to move to.
- Throws exceptions on failure to allocate, or attempting to
- modify a packed path.
- */
- void fz_moveto(fz_context *ctx, fz_path *path, float x, float y);
- /**
- Append a 'lineto' command to an open path.
- path: The path to modify.
- x, y: The coordinate to line to.
- Throws exceptions on failure to allocate, or attempting to
- modify a packed path.
- */
- void fz_lineto(fz_context *ctx, fz_path *path, float x, float y);
- /**
- Append a 'rectto' command to an open path.
- The rectangle is equivalent to:
- moveto x0 y0
- lineto x1 y0
- lineto x1 y1
- lineto x0 y1
- closepath
- path: The path to modify.
- x0, y0: First corner of the rectangle.
- x1, y1: Second corner of the rectangle.
- Throws exceptions on failure to allocate, or attempting to
- modify a packed path.
- */
- void fz_rectto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
- /**
- Append a 'quadto' command to an open path. (For a
- quadratic bezier).
- path: The path to modify.
- x0, y0: The control coordinates for the quadratic curve.
- x1, y1: The end coordinates for the quadratic curve.
- Throws exceptions on failure to allocate, or attempting to
- modify a packed path.
- */
- void fz_quadto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1);
- /**
- Append a 'curveto' command to an open path. (For a
- cubic bezier).
- path: The path to modify.
- x0, y0: The coordinates of the first control point for the
- curve.
- x1, y1: The coordinates of the second control point for the
- curve.
- x2, y2: The end coordinates for the curve.
- Throws exceptions on failure to allocate, or attempting to
- modify a packed path.
- */
- void fz_curveto(fz_context *ctx, fz_path *path, float x0, float y0, float x1, float y1, float x2, float y2);
- /**
- Append a 'curvetov' command to an open path. (For a
- cubic bezier with the first control coordinate equal to
- the start point).
- path: The path to modify.
- x1, y1: The coordinates of the second control point for the
- curve.
- x2, y2: The end coordinates for the curve.
- Throws exceptions on failure to allocate, or attempting to
- modify a packed path.
- */
- void fz_curvetov(fz_context *ctx, fz_path *path, float x1, float y1, float x2, float y2);
- /**
- Append a 'curvetoy' command to an open path. (For a
- cubic bezier with the second control coordinate equal to
- the end point).
- path: The path to modify.
- x0, y0: The coordinates of the first control point for the
- curve.
- x2, y2: The end coordinates for the curve (and the second
- control coordinate).
- Throws exceptions on failure to allocate, or attempting to
- modify a packed path.
- */
- void fz_curvetoy(fz_context *ctx, fz_path *path, float x0, float y0, float x2, float y2);
- /**
- Close the current subpath.
- path: The path to modify.
- Throws exceptions on failure to allocate, attempting to modify
- a packed path, and illegal path closes (i.e. closing a non open
- path).
- */
- void fz_closepath(fz_context *ctx, fz_path *path);
- /**
- Transform a path by a given
- matrix.
- path: The path to modify (must not be a packed path).
- transform: The transform to apply.
- Throws exceptions if the path is packed, or on failure
- to allocate.
- */
- void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform);
- /**
- Return a bounding rectangle for a path.
- path: The path to bound.
- stroke: If NULL, the bounding rectangle given is for
- the filled path. If non-NULL the bounding rectangle
- given is for the path stroked with the given attributes.
- ctm: The matrix to apply to the path during stroking.
- r: Pointer to a fz_rect which will be used to hold
- the result.
- Returns r, updated to contain the bounding rectangle.
- */
- fz_rect fz_bound_path(fz_context *ctx, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm);
- /**
- Given a rectangle (assumed to be the bounding box for a path),
- expand it to allow for the expansion of the bbox that would be
- seen by stroking the path with the given stroke state and
- transform.
- */
- fz_rect fz_adjust_rect_for_stroke(fz_context *ctx, fz_rect rect, const fz_stroke_state *stroke, fz_matrix ctm);
- /**
- A sane 'default' stroke state.
- */
- FZ_DATA extern const fz_stroke_state fz_default_stroke_state;
- /**
- Create a new (empty) stroke state structure (with no dash
- data) and return a reference to it.
- Throws exception on failure to allocate.
- */
- fz_stroke_state *fz_new_stroke_state(fz_context *ctx);
- /**
- Create a new (empty) stroke state structure, with room for
- dash data of the given length, and return a reference to it.
- len: The number of dash elements to allow room for.
- Throws exception on failure to allocate.
- */
- fz_stroke_state *fz_new_stroke_state_with_dash_len(fz_context *ctx, int len);
- /**
- Take an additional reference to a stroke state structure.
- No modifications should be carried out on a stroke
- state to which more than one reference is held, as
- this can cause race conditions.
- */
- fz_stroke_state *fz_keep_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
- int fz_stroke_state_eq(fz_context *ctx, const fz_stroke_state *a, const fz_stroke_state *b);
- /**
- Drop a reference to a stroke state structure, destroying the
- structure if it is the last reference.
- */
- void fz_drop_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
- /**
- Given a reference to a (possibly) shared stroke_state structure,
- return a reference to an equivalent stroke_state structure
- that is guaranteed to be unshared (i.e. one that can
- safely be modified).
- shared: The reference to a (possibly) shared structure
- to unshare. Ownership of this reference is passed in
- to this function, even in the case of exceptions being
- thrown.
- Exceptions may be thrown in the event of failure to
- allocate if required.
- */
- fz_stroke_state *fz_unshare_stroke_state(fz_context *ctx, fz_stroke_state *shared);
- /**
- Given a reference to a (possibly) shared stroke_state structure,
- return a reference to a stroke_state structure (with room for a
- given amount of dash data) that is guaranteed to be unshared
- (i.e. one that can safely be modified).
- shared: The reference to a (possibly) shared structure
- to unshare. Ownership of this reference is passed in
- to this function, even in the case of exceptions being
- thrown.
- Exceptions may be thrown in the event of failure to
- allocate if required.
- */
- fz_stroke_state *fz_unshare_stroke_state_with_dash_len(fz_context *ctx, fz_stroke_state *shared, int len);
- /**
- Create an identical stroke_state structure and return a
- reference to it.
- stroke: The stroke state reference to clone.
- Exceptions may be thrown in the event of a failure to
- allocate.
- */
- fz_stroke_state *fz_clone_stroke_state(fz_context *ctx, const fz_stroke_state *stroke);
- fz_linecap fz_linecap_from_string(const char *s);
- const char *fz_string_from_linecap(fz_linecap cap);
- fz_linejoin fz_linejoin_from_string(const char *s);
- const char *fz_string_from_linejoin(fz_linejoin join);
- /**
- Check whether a given path, under the given transform
- is an axis-aligned rectangle.
- We accept zero width or height rectangles, so
- "move 100, 100; line 200, 100" would count as
- a rectangle too.
- */
- int fz_path_is_rect(fz_context *ctx, const fz_path *path, fz_matrix ctm);
- /**
- Check whether a given path, under the given transform
- is an axis-aligned rectangle.
- We accept zero width or height rectangles, so
- "move 100, 100; line 200, 100" would count as
- a rectangle too.
- bounds = NULL, or place to return the rectangle
- bounds if the path is a rectangle.
- */
- int fz_path_is_rect_with_bounds(fz_context *ctx, const fz_path *path, fz_matrix ctm, fz_rect *bounds);
- #endif
|