1 /* Copyright (C) 1991, 1995, 1998, 1999 artofcode LLC.  All rights reserved.
2 
3   This program is free software; you can redistribute it and/or modify it
4   under the terms of the GNU General Public License as published by the
5   Free Software Foundation; either version 2 of the License, or (at your
6   option) any later version.
7 
8   This program is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   General Public License for more details.
12 
13   You should have received a copy of the GNU General Public License along
14   with this program; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16 
17 */
18 
19 /*$Id: gxcpath.h,v 1.2.6.1.2.1 2003/01/17 00:49:03 giles Exp $ */
20 /* Definitions for clipping lists and devices */
21 /* Requires gxdevice.h */
22 
23 #ifndef gxcpath_INCLUDED
24 #  define gxcpath_INCLUDED
25 
26 /* We expose the implementation of clipping lists so that clients */
27 /* can allocate clipping lists or devices on the stack. */
28 
29 /*
30  * For clipping, a path is represented as a list of rectangles.
31  * Normally, a path is created as a list of segments;
32  * installing it as a clipping path creates the rectangle list.
33  * However, when the clipping path originates in some other way
34  * (e.g., from initclip, or for clipping a cached character),
35  * or if it is a non-trivial intersection of two paths,
36  * the resulting clipping path exists only as a rectangle list;
37  * clippath constructs the segment representation if needed.
38  * Note that even if the path only exists as a rectangle list,
39  * its bounding box (path.bbox) is still correct.
40  */
41 
42 /*
43  * Rectangle list structure.
44  * Consecutive gx_clip_rect entries either have the same Y values,
45  * or ymin of this entry >= ymax of the previous entry.
46  */
47 typedef struct gx_clip_rect_s gx_clip_rect;
48 struct gx_clip_rect_s {
49     gx_clip_rect *next, *prev;
50     int ymin, ymax;		/* ymax > ymin */
51     int xmin, xmax;		/* xmax > xmin */
52     byte to_visit;		/* bookkeeping for gs_clippath */
53 };
54 
55 /* The descriptor is public only for gxacpath.c. */
56 extern_st(st_clip_rect);
57 #define public_st_clip_rect()	/* in gxcpath.c */\
58   gs_public_st_ptrs2(st_clip_rect, gx_clip_rect, "clip_rect",\
59     clip_rect_enum_ptrs, clip_rect_reloc_ptrs, next, prev)
60 #define st_clip_rect_max_ptrs 2
61 
62 /*
63  * A clip list may consist either of a single rectangle,
64  * with null head and tail, or a list of rectangles.  In the latter case,
65  * there is a dummy head entry with p.x = q.x to cover Y values
66  * starting at min_int, and a dummy tail entry to cover Y values
67  * ending at max_int.  This eliminates the need for end tests.
68  */
69 #ifndef gx_clip_list_DEFINED
70 #  define gx_clip_list_DEFINED
71 typedef struct gx_clip_list_s gx_clip_list;
72 #endif
73 struct gx_clip_list_s {
74     gx_clip_rect single;	/* (has next = prev = 0) */
75     gx_clip_rect *head;
76     gx_clip_rect *tail;
77     int xmin, xmax;		/* min and max X over all but head/tail */
78     int count;			/* # of rectangles not counting */
79 				/* head or tail */
80 };
81 
82 #define private_st_clip_list()	/* in gxcpath.c */\
83   gs_private_st_ptrs2(st_clip_list, gx_clip_list, "clip_list",\
84     clip_list_enum_ptrs, clip_list_reloc_ptrs, head, tail)
85 #define st_clip_list_max_ptrs 2	/* head, tail */
86 #define clip_list_is_rectangle(clp) ((clp)->count <= 1)
87 
88 /*
89  * Clipping devices provide for translation before clipping.
90  * This ability, a late addition, currently is used only in a few
91  * situations that require breaking up a transfer into pieces,
92  * but we suspect it could be used more widely.
93  *
94  * Note that clipping devices cache their clipping box, so the target's
95  * clipping box and the clip list must be const after the clipping device
96  * is opened.
97  */
98 #ifndef gx_device_clip_DEFINED
99 #  define gx_device_clip_DEFINED
100 typedef struct gx_device_clip_s gx_device_clip;
101 #endif
102 struct gx_device_clip_s {
103     gx_device_forward_common;	/* target is set by client */
104     gx_clip_list list;		/* set by client */
105     gx_clip_rect *current;	/* cursor in list */
106     gs_int_point translation;
107     gs_fixed_rect clipping_box;
108     bool clipping_box_set;
109 };
110 
111 extern_st(st_device_clip);
112 #define public_st_device_clip()	/* in gxcpath.c */\
113   gs_public_st_composite_use_final(st_device_clip, gx_device_clip,\
114     "gx_device_clip", device_clip_enum_ptrs, device_clip_reloc_ptrs,\
115     gx_device_finalize)
116 void gx_make_clip_translate_device(P5(gx_device_clip * dev,
117 				      const gx_clip_list * list,
118 				      int tx, int ty, gs_memory_t *mem));
119 
120 #define gx_make_clip_device(dev, list)\
121   gx_make_clip_translate_device(dev, list, 0, 0, NULL)
122 void gx_make_clip_path_device(P2(gx_device_clip *, const gx_clip_path *));
123 
124 #define clip_rect_print(ch, str, ar)\
125   if_debug7(ch, "[%c]%s 0x%lx: (%d,%d),(%d,%d)\n", ch, str, (ulong)ar,\
126 	    (ar)->xmin, (ar)->ymin, (ar)->xmax, (ar)->ymax)
127 
128 /* Exported by gxcpath.c for gxacpath.c */
129 
130 /* Initialize a clip list. */
131 void gx_clip_list_init(P1(gx_clip_list *));
132 
133 /* Free a clip list. */
134 void gx_clip_list_free(P2(gx_clip_list *, gs_memory_t *));
135 
136 /* Set the outer box for a clipping path from its bounding box. */
137 void gx_cpath_set_outer_box(P1(gx_clip_path *));
138 
139 /* Exported by gxcpath.c for gxclip.c */
140 
141 /* Return the rectangle list of a clipping path (for local use only). */
142 const gx_clip_list *gx_cpath_list(P1(const gx_clip_path *pcpath));
143 
144 #endif /* gxcpath_INCLUDED */
145