xref: /plan9/sys/src/cmd/gs/src/gxcpath.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1991, 1995, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gxcpath.h,v 1.5 2002/06/16 08:45:43 lpd Exp $ */
18 /* Definitions for clipping lists and devices */
19 /* Requires gxdevice.h */
20 
21 #ifndef gxcpath_INCLUDED
22 #  define gxcpath_INCLUDED
23 
24 /* We expose the implementation of clipping lists so that clients */
25 /* can allocate clipping lists or devices on the stack. */
26 
27 /*
28  * For clipping, a path is represented as a list of rectangles.
29  * Normally, a path is created as a list of segments;
30  * installing it as a clipping path creates the rectangle list.
31  * However, when the clipping path originates in some other way
32  * (e.g., from initclip, or for clipping a cached character),
33  * or if it is a non-trivial intersection of two paths,
34  * the resulting clipping path exists only as a rectangle list;
35  * clippath constructs the segment representation if needed.
36  * Note that even if the path only exists as a rectangle list,
37  * its bounding box (path.bbox) is still correct.
38  */
39 
40 /*
41  * Rectangle list structure.
42  * Consecutive gx_clip_rect entries either have the same Y values,
43  * or ymin of this entry >= ymax of the previous entry.
44  */
45 typedef struct gx_clip_rect_s gx_clip_rect;
46 struct gx_clip_rect_s {
47     gx_clip_rect *next, *prev;
48     int ymin, ymax;		/* ymax > ymin */
49     int xmin, xmax;		/* xmax > xmin */
50     byte to_visit;		/* bookkeeping for gs_clippath */
51 };
52 
53 /* The descriptor is public only for gxacpath.c. */
54 extern_st(st_clip_rect);
55 #define public_st_clip_rect()	/* in gxcpath.c */\
56   gs_public_st_ptrs2(st_clip_rect, gx_clip_rect, "clip_rect",\
57     clip_rect_enum_ptrs, clip_rect_reloc_ptrs, next, prev)
58 #define st_clip_rect_max_ptrs 2
59 
60 /*
61  * A clip list may consist either of a single rectangle,
62  * with null head and tail, or a list of rectangles.  In the latter case,
63  * there is a dummy head entry with p.x = q.x to cover Y values
64  * starting at min_int, and a dummy tail entry to cover Y values
65  * ending at max_int.  This eliminates the need for end tests.
66  */
67 #ifndef gx_clip_list_DEFINED
68 #  define gx_clip_list_DEFINED
69 typedef struct gx_clip_list_s gx_clip_list;
70 #endif
71 struct gx_clip_list_s {
72     gx_clip_rect single;	/* (has next = prev = 0) */
73     gx_clip_rect *head;
74     gx_clip_rect *tail;
75     int xmin, xmax;		/* min and max X over all but head/tail */
76     int count;			/* # of rectangles not counting */
77 				/* head or tail */
78 };
79 
80 #define private_st_clip_list()	/* in gxcpath.c */\
81   gs_private_st_ptrs2(st_clip_list, gx_clip_list, "clip_list",\
82     clip_list_enum_ptrs, clip_list_reloc_ptrs, head, tail)
83 #define st_clip_list_max_ptrs 2	/* head, tail */
84 #define clip_list_is_rectangle(clp) ((clp)->count <= 1)
85 
86 /*
87  * Clipping devices provide for translation before clipping.
88  * This ability, a late addition, currently is used only in a few
89  * situations that require breaking up a transfer into pieces,
90  * but we suspect it could be used more widely.
91  *
92  * Note that clipping devices cache their clipping box, so the target's
93  * clipping box and the clip list must be const after the clipping device
94  * is opened.
95  */
96 #ifndef gx_device_clip_DEFINED
97 #  define gx_device_clip_DEFINED
98 typedef struct gx_device_clip_s gx_device_clip;
99 #endif
100 struct gx_device_clip_s {
101     gx_device_forward_common;	/* target is set by client */
102     gx_clip_list list;		/* set by client */
103     gx_clip_rect *current;	/* cursor in list */
104     gs_int_point translation;
105     gs_fixed_rect clipping_box;
106     bool clipping_box_set;
107 };
108 
109 extern_st(st_device_clip);
110 #define public_st_device_clip()	/* in gxcpath.c */\
111   gs_public_st_composite_use_final(st_device_clip, gx_device_clip,\
112     "gx_device_clip", device_clip_enum_ptrs, device_clip_reloc_ptrs,\
113     gx_device_finalize)
114 void gx_make_clip_translate_device(gx_device_clip * dev,
115 				   const gx_clip_list * list,
116 				   int tx, int ty, gs_memory_t *mem);
117 
118 #define gx_make_clip_device(dev, list)\
119   gx_make_clip_translate_device(dev, list, 0, 0, NULL)
120 void gx_make_clip_path_device(gx_device_clip *, const gx_clip_path *);
121 
122 #define clip_rect_print(ch, str, ar)\
123   if_debug7(ch, "[%c]%s 0x%lx: (%d,%d),(%d,%d)\n", ch, str, (ulong)ar,\
124 	    (ar)->xmin, (ar)->ymin, (ar)->xmax, (ar)->ymax)
125 
126 /* Exported by gxcpath.c for gxacpath.c */
127 
128 /* Initialize a clip list. */
129 void gx_clip_list_init(gx_clip_list *);
130 
131 /* Free a clip list. */
132 void gx_clip_list_free(gx_clip_list *, gs_memory_t *);
133 
134 /* Set the outer box for a clipping path from its bounding box. */
135 void gx_cpath_set_outer_box(gx_clip_path *);
136 
137 /* Exported by gxcpath.c for gxclip.c */
138 
139 /* Return the rectangle list of a clipping path (for local use only). */
140 const gx_clip_list *gx_cpath_list(const gx_clip_path *pcpath);
141 
142 #endif /* gxcpath_INCLUDED */
143