summaryrefslogtreecommitdiff
path: root/gs/base/gxpath.h
diff options
context:
space:
mode:
authorRalph Giles <ralph.giles@artifex.com>2008-08-29 18:46:21 +0000
committerRalph Giles <ralph.giles@artifex.com>2008-08-29 18:46:21 +0000
commit6ff2582d038f99b79178082b200bdfe73f734456 (patch)
tree6db04fc72813760fdc6912a15875ad83d57943df /gs/base/gxpath.h
parent9d36ee856e41244d3cf0469fc0004d21e6911994 (diff)
downloadghostpdl-6ff2582d038f99b79178082b200bdfe73f734456.tar.gz
Split the source tree into two new directories.
PSSRC files are now in 'gs/psi'. GLSRC files are now in 'gs/base'. This is to facilitate build modularization and merging in the ghostpdl tree. NOTE: msvc32.mak is now in psi, not src. git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@9048 a1074d23-0009-0410-80fe-cf8c14f379e6
Diffstat (limited to 'gs/base/gxpath.h')
-rw-r--r--gs/base/gxpath.h361
1 files changed, 361 insertions, 0 deletions
diff --git a/gs/base/gxpath.h b/gs/base/gxpath.h
new file mode 100644
index 000000000..c7c11153a
--- /dev/null
+++ b/gs/base/gxpath.h
@@ -0,0 +1,361 @@
+/* Copyright (C) 2001-2006 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* $Id$ */
+/* Fixed-point path procedures */
+/* Requires gxfixed.h */
+
+#ifndef gxpath_INCLUDED
+# define gxpath_INCLUDED
+
+#include "gscpm.h"
+#include "gslparam.h"
+#include "gspenum.h"
+#include "gsrect.h"
+
+/* The routines and types in this interface use */
+/* device, rather than user, coordinates, and fixed-point, */
+/* rather than floating, representation. */
+
+/* Opaque type for a path */
+#ifndef gx_path_DEFINED
+# define gx_path_DEFINED
+typedef struct gx_path_s gx_path;
+#endif
+
+/* Define the two insideness rules */
+#define gx_rule_winding_number (-1)
+#define gx_rule_even_odd 1
+
+/* Define 'notes' that describe the role of a path segment. */
+/* These are only for internal use; a normal segment's notes are 0. */
+typedef enum {
+ sn_none = 0,
+ sn_not_first = 1, /* segment is in curve/arc and not first */
+ sn_from_arc = 2 /* segment is part of an arc */
+} segment_notes;
+
+/* Debugging routines */
+#ifdef DEBUG
+void gx_dump_path(const gx_path *, const char *);
+void gx_path_print(const gx_path *);
+#endif
+
+/* Path memory management */
+
+/*
+ * Path memory management is unfortunately a little tricky. The
+ * implementation details are in gzpath.h: we only present the API here.
+ *
+ * Path objects per se may be allocated in 3 different ways: on the
+ * C stack, as separate objects in the heap, or (for the graphics state
+ * only) contained in a larger heap-allocated object.
+ *
+ * Any number of paths may share segments. The segments are stored in
+ * their own, reference-counted object, and are freed when there are no
+ * more references to that object.
+ */
+
+/*
+ * Allocate a path on the heap, and initialize it. If shared is NULL,
+ * allocate a segments object; if shared is an existing path, share its
+ * segments.
+ */
+gx_path *gx_path_alloc_shared(const gx_path * shared, gs_memory_t * mem,
+ client_name_t cname);
+
+#define gx_path_alloc(mem, cname)\
+ gx_path_alloc_shared(NULL, mem, cname)
+/*
+ * Initialize a path contained in an already-heap-allocated object,
+ * optionally allocating its segments.
+ */
+int gx_path_init_contained_shared(gx_path * ppath, const gx_path * shared,
+ gs_memory_t * mem, client_name_t cname);
+
+#define gx_path_alloc_contained(ppath, mem, cname)\
+ gx_path_init_contained_shared(ppath, NULL, mem, cname)
+/*
+ * Initialize a stack-allocated path. This doesn't allocate anything,
+ * but may still share the segments. Note that it returns an error if
+ * asked to share the segments of another local path.
+ */
+int gx_path_init_local_shared(gx_path * ppath, const gx_path * shared,
+ gs_memory_t * mem);
+
+#define gx_path_init_local(ppath, mem)\
+ (void)gx_path_init_local_shared(ppath, NULL, mem) /* can't fail */
+
+/*
+ * Initialize a stack-allocated pseudo-path for computing a bbox
+ * for a dynamic path.
+ */
+void gx_path_init_bbox_accumulator(gx_path * ppath);
+
+/*
+ * Ensure that a path owns its segments, by copying the segments if
+ * they currently have multiple references.
+ */
+int gx_path_unshare(gx_path * ppath);
+
+/*
+ * Free a path by releasing its segments if they have no more references.
+ * This also frees the path object iff it was allocated by gx_path_alloc.
+ */
+void gx_path_free(gx_path * ppath, client_name_t cname);
+
+/*
+ * Assign one path to another, adjusting reference counts appropriately.
+ * Note that this requires that segments of the two paths (but not the path
+ * objects themselves) were allocated with the same allocator. Note also
+ * that if ppfrom is stack-allocated, ppto is not, and ppto's segments are
+ * currently shared, gx_path_assign must do the equivalent of a
+ * gx_path_new(ppto), which allocates a new segments object for ppto.
+ */
+int gx_path_assign_preserve(gx_path * ppto, gx_path * ppfrom);
+
+/*
+ * Assign one path to another and free the first path at the same time.
+ * (This may do less work than assign_preserve + free.)
+ */
+int gx_path_assign_free(gx_path * ppto, gx_path * ppfrom);
+
+/* Path constructors */
+/* Note that all path constructors have an implicit initial gx_path_unshare. */
+
+int gx_path_new(gx_path *),
+ gx_path_add_point(gx_path *, fixed, fixed),
+ gx_path_add_relative_point(gx_path *, fixed, fixed),
+ gx_path_add_line_notes(gx_path *, fixed, fixed, segment_notes),
+ gx_path_add_dash_notes(gx_path * ppath, fixed x, fixed y, fixed dx, fixed dy, segment_notes notes),
+ gx_path_add_lines_notes(gx_path *, const gs_fixed_point *, int, segment_notes),
+ gx_path_add_rectangle(gx_path *, fixed, fixed, fixed, fixed),
+ gx_path_add_char_path(gx_path *, gx_path *, gs_char_path_mode),
+ gx_path_add_curve_notes(gx_path *, fixed, fixed, fixed, fixed, fixed, fixed, segment_notes),
+ gx_path_add_partial_arc_notes(gx_path *, fixed, fixed, fixed, fixed, floatp, segment_notes),
+ gx_path_add_path(gx_path *, gx_path *),
+ gx_path_close_subpath_notes(gx_path *, segment_notes),
+ /* We have to remove the 'subpath' from the following name */
+ /* to keep it unique in the first 23 characters. */
+ gx_path_pop_close_notes(gx_path *, segment_notes);
+
+/* Access path state flags */
+byte gx_path_get_state_flags(gx_path *ppath);
+void gx_path_set_state_flags(gx_path *ppath, byte flags);
+bool gx_path_is_drawing(gx_path *ppath);
+
+/*
+ * The last argument to gx_path_add_partial_arc is a fraction for computing
+ * the curve parameters. Here is the correct value for quarter-circles.
+ * (stroke uses this to draw round caps and joins.)
+ */
+#define quarter_arc_fraction 0.55228474983079334
+/*
+ * Backward-compatible constructors that don't take a notes argument.
+ */
+#define gx_path_add_line(ppath, x, y)\
+ gx_path_add_line_notes(ppath, x, y, sn_none)
+#define gx_path_add_lines(ppath, pts, count)\
+ gx_path_add_lines_notes(ppath, pts, count, sn_none)
+#define gx_path_add_curve(ppath, x1, y1, x2, y2, x3, y3)\
+ gx_path_add_curve_notes(ppath, x1, y1, x2, y2, x3, y3, sn_none)
+#define gx_path_add_partial_arc(ppath, x3, y3, xt, yt, fraction)\
+ gx_path_add_partial_arc_notes(ppath, x3, y3, xt, yt, fraction, sn_none)
+#define gx_path_close_subpath(ppath)\
+ gx_path_close_subpath_notes(ppath, sn_none)
+#define gx_path_pop_close_subpath(ppath)\
+ gx_path_pop_close_notes(ppath, sn_none)
+
+typedef enum {
+ pco_none = 0,
+ pco_monotonize = 1, /* make curves monotonic */
+ pco_accurate = 2, /* flatten with accurate tangents at ends */
+ pco_for_stroke = 4, /* flatten taking line width into account */
+ pco_small_curves = 8 /* make curves small */
+} gx_path_copy_options;
+
+/* Path accessors */
+
+gx_path *gx_current_path(const gs_state *);
+int gx_path_current_point(const gx_path *, gs_fixed_point *),
+ gx_path_bbox(gx_path *, gs_fixed_rect *),
+ gx_path_bbox_set(gx_path *, gs_fixed_rect *);
+int gx_path_subpath_start_point(const gx_path *, gs_fixed_point *);
+bool gx_path_has_curves(const gx_path *),
+ gx_path_is_void(const gx_path *), /* no segments */
+ gx_path_is_null(const gx_path *), /* nothing at all */
+ gx_path__check_curves(const gx_path * ppath, gx_path_copy_options options, fixed fixed_flat),
+ gx_path_has_long_segments(const gx_path * ppath);
+typedef enum {
+ prt_none = 0,
+ prt_open = 1, /* only 3 sides */
+ prt_fake_closed = 2, /* 4 lines, no closepath */
+ prt_closed = 3 /* 3 or 4 lines + closepath */
+} gx_path_rectangular_type;
+
+gx_path_rectangular_type
+gx_path_is_rectangular(const gx_path *, gs_fixed_rect *);
+
+#define gx_path_is_rectangle(ppath, pbox)\
+ (gx_path_is_rectangular(ppath, pbox) != prt_none)
+/* Inline versions of the above */
+#define gx_path_is_null_inline(ppath)\
+ (gx_path_is_void(ppath) && !path_position_valid(ppath))
+
+/* Path transformers */
+
+/* The imager state is only needed when flattening for stroke. */
+#ifndef gs_imager_state_DEFINED
+# define gs_imager_state_DEFINED
+typedef struct gs_imager_state_s gs_imager_state;
+#endif
+int gx_path_copy_reducing(const gx_path * ppath_old, gx_path * ppath_new,
+ fixed fixed_flatness, const gs_imager_state *pis,
+ gx_path_copy_options options);
+
+#define gx_path_copy(old, new)\
+ gx_path_copy_reducing(old, new, max_fixed, NULL, pco_none)
+#define gx_path_add_flattened(old, new, flatness)\
+ gx_path_copy_reducing(old, new, float2fixed(flatness), NULL, pco_none)
+#define gx_path_add_flattened_accurate(old, new, flatness, accurate)\
+ gx_path_copy_reducing(old, new, float2fixed(flatness), NULL,\
+ (accurate ? pco_accurate : pco_none))
+#define gx_path_add_flattened_for_stroke(old, new, flatness, pis)\
+ gx_path_copy_reducing(old, new, float2fixed(flatness), pis,\
+ (pis->accurate_curves ?\
+ pco_accurate | pco_for_stroke : pco_for_stroke))
+#define gx_path_add_monotonized(old, new)\
+ gx_path_copy_reducing(old, new, max_fixed, NULL, pco_monotonize)
+int gx_path_add_dash_expansion(const gx_path * /*old*/, gx_path * /*new*/,
+ const gs_imager_state *),
+ gx_path_copy_reversed(const gx_path * /*old*/, gx_path * /*new*/),
+ gx_path_translate(gx_path *, fixed, fixed),
+ gx_path_scale_exp2_shared(gx_path *ppath, int log2_scale_x,
+ int log2_scale_y, bool segments_shared);
+void gx_point_scale_exp2(gs_fixed_point *, int, int),
+ gx_rect_scale_exp2(gs_fixed_rect *, int, int);
+
+/* Path enumerator */
+
+/* This interface does not make a copy of the path. */
+/* Do not use gs_path_enum_cleanup with this interface! */
+int gx_path_enum_init(gs_path_enum *, const gx_path *);
+int gx_path_enum_next(gs_path_enum *, gs_fixed_point[3]); /* 0 when done */
+
+segment_notes
+gx_path_enum_notes(const gs_path_enum *);
+bool gx_path_enum_backup(gs_path_enum *);
+
+/* An auxiliary function to add a path point with a specified transformation. */
+int gs_moveto_aux(gs_imager_state *pis, gx_path *ppath, floatp x, floatp y);
+int gx_setcurrentpoint_from_path(gs_imager_state *pis, gx_path *path);
+
+/* Path optimization for the filling algorithm. */
+
+int gx_path_merge_contacting_contours(gx_path *ppath);
+
+/* ------ Clipping paths ------ */
+
+/* Opaque type for a clipping path */
+#ifndef gx_clip_path_DEFINED
+# define gx_clip_path_DEFINED
+typedef struct gx_clip_path_s gx_clip_path;
+#endif
+
+/* Graphics state clipping */
+int gx_clip_to_rectangle(gs_state *, gs_fixed_rect *);
+int gx_clip_to_path(gs_state *);
+int gx_default_clip_box(const gs_state *, gs_fixed_rect *);
+int gx_effective_clip_path(gs_state *, gx_clip_path **);
+
+/* Opaque type for a clip list. */
+#ifndef gx_clip_list_DEFINED
+# define gx_clip_list_DEFINED
+typedef struct gx_clip_list_s gx_clip_list;
+#endif
+
+/* Opaque type for fill parameters. */
+#ifndef gx_fill_params_DEFINED
+# define gx_fill_params_DEFINED
+typedef struct gx_fill_params_s gx_fill_params;
+#endif
+
+
+/* Opaque type for a clipping path enumerator. */
+typedef struct gs_cpath_enum_s gs_cpath_enum;
+
+/*
+ * Provide similar memory management for clip paths to what we have for
+ * paths (see above for details).
+ */
+gx_clip_path *gx_cpath_alloc_shared(const gx_clip_path * shared,
+ gs_memory_t * mem, client_name_t cname);
+
+#define gx_cpath_alloc(mem, cname)\
+ gx_cpath_alloc_shared(NULL, mem, cname)
+int gx_cpath_init_contained_shared(gx_clip_path * pcpath,
+ const gx_clip_path * shared,
+ gs_memory_t * mem,
+ client_name_t cname);
+
+#define gx_cpath_alloc_contained(pcpath, mem, cname)\
+ gx_cpath_init_contained_shared(pcpath, NULL, mem, cname)
+int gx_cpath_init_local_shared(gx_clip_path * pcpath,
+ const gx_clip_path * shared,
+ gs_memory_t * mem);
+
+#define gx_cpath_init_local(pcpath, mem)\
+ (void)gx_cpath_init_local_shared(pcpath, NULL, mem) /* can't fail */
+int gx_cpath_unshare(gx_clip_path * pcpath);
+void gx_cpath_free(gx_clip_path * pcpath, client_name_t cname);
+int gx_cpath_assign_preserve(gx_clip_path * pcpto, gx_clip_path * pcpfrom);
+int gx_cpath_assign_free(gx_clip_path * pcpto, gx_clip_path * pcpfrom);
+
+/* Clip path constructors and accessors */
+
+int
+ gx_cpath_reset(gx_clip_path *), /* from_rectangle ((0,0),(0,0)) */
+ gx_cpath_from_rectangle(gx_clip_path *, gs_fixed_rect *),
+ gx_cpath_clip(gs_state *, gx_clip_path *, /*const*/ gx_path *, int),
+ gx_cpath_intersect(gx_clip_path *, /*const*/ gx_path *, int,
+ gs_imager_state *),
+ gx_cpath_intersect_with_params(gx_clip_path *pcpath, /*const*/ gx_path *ppath_orig,
+ int rule, gs_imager_state *pis, const gx_fill_params * params),
+ gx_cpath_scale_exp2_shared(gx_clip_path *pcpath, int log2_scale_x,
+ int log2_scale_y, bool list_shared,
+ bool segments_shared),
+ gx_cpath_to_path(gx_clip_path *, gx_path *),
+ gx_cpath_to_path_synthesize(const gx_clip_path * pcpath, gx_path * ppath);
+bool
+ gx_cpath_inner_box(const gx_clip_path *, gs_fixed_rect *),
+ gx_cpath_outer_box(const gx_clip_path *, gs_fixed_rect *),
+ gx_cpath_includes_rectangle(const gx_clip_path *, fixed, fixed,
+ fixed, fixed);
+const gs_fixed_rect *cpath_is_rectangle(const gx_clip_path * pcpath);
+bool gx_cpath_rect_visible(gx_clip_path * pcpath, gs_int_rect *prect);
+int gx_cpath_copy(const gx_clip_path * from, gx_clip_path * pcpath);
+
+/* Enumerate a clipping path. This interface does not copy the path. */
+/* However, it does write into the path's "visited" flags. */
+int gx_cpath_enum_init(gs_cpath_enum *, const gx_clip_path *);
+int gx_cpath_enum_next(gs_cpath_enum *, gs_fixed_point[3]); /* 0 when done */
+
+segment_notes
+gx_cpath_enum_notes(const gs_cpath_enum *);
+
+#ifdef DEBUG
+void gx_cpath_print(const gx_clip_path *);
+#endif
+
+
+#endif /* gxpath_INCLUDED */