xref: /plan9/sys/src/cmd/gs/src/gsropt.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1995, 2000 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: gsropt.h,v 1.7 2002/06/16 08:45:42 lpd Exp $ */
18 /* RasterOp / transparency type definitions */
19 
20 #ifndef gsropt_INCLUDED
21 #  define gsropt_INCLUDED
22 
23 /*
24  * This file defines the types for some library extensions that are
25  * motivated by PCL5 and also made available for PostScript:
26  * RasterOp, source and pattern white-pixel transparency, and
27  * per-pixel "render algorithm" information.
28  */
29 
30 /*
31  * Define whether we implement transparency correctly, or whether we
32  * implement it as documented in the H-P manuals.
33  */
34 #define TRANSPARENCY_PER_H_P
35 
36 /*
37  * By the magic of Boolean algebra, we can operate on the rop codes using
38  * Boolean operators and get the right result.  E.g., the value of
39  * (rop3_S & rop3_D) is the rop3 code for S & D.  We just have to remember
40  * to mask results with rop2_1 or rop3_1 if necessary.
41  */
42 
43 /* 2-input RasterOp */
44 typedef enum {
45     rop2_0 = 0,
46     rop2_S = 0xc,		/* source */
47 #define rop2_S_shift 2
48     rop2_D = 0xa,		/* destination */
49 #define rop2_D_shift 1
50     rop2_1 = 0xf,
51 #define rop2_operand(shift, d, s)\
52   ((shift) == 2 ? (s) : (d))
53     rop2_default = rop2_S
54 } gs_rop2_t;
55 
56 /*
57  * For the 3-input case, we follow H-P's inconsistent terminology:
58  * the transparency mode is called pattern transparency, but the third
59  * RasterOp operand is called texture, not pattern.
60  */
61 
62 /* 3-input RasterOp */
63 typedef enum {
64     rop3_0 = 0,
65     rop3_T = 0xf0,		/* texture */
66 #define rop3_T_shift 4
67     rop3_S = 0xcc,		/* source */
68 #define rop3_S_shift 2
69     rop3_D = 0xaa,		/* destination */
70 #define rop3_D_shift 1
71     rop3_1 = 0xff,
72     rop3_default = rop3_T | rop3_S
73 } gs_rop3_t;
74 
75 /* All the transformations on rop3s are designed so that */
76 /* they can also be used on lops.  The only place this costs anything */
77 /* is in rop3_invert. */
78 
79 /*
80  * Invert an operand.
81  */
82 #define rop3_invert_(op, mask, shift)\
83   ( (((op) & mask) >> shift) | (((op) & (rop3_1 - mask)) << shift) |\
84     ((op) & ~rop3_1) )
85 #define rop3_invert_D(op) rop3_invert_(op, rop3_D, rop3_D_shift)
86 #define rop3_invert_S(op) rop3_invert_(op, rop3_S, rop3_S_shift)
87 #define rop3_invert_T(op) rop3_invert_(op, rop3_T, rop3_T_shift)
88 /*
89  * Pin an operand to 0.
90  */
91 #define rop3_know_0_(op, mask, shift)\
92   ( (((op) & (rop3_1 - mask)) << shift) | ((op) & ~mask) )
93 #define rop3_know_D_0(op) rop3_know_0_(op, rop3_D, rop3_D_shift)
94 #define rop3_know_S_0(op) rop3_know_0_(op, rop3_S, rop3_S_shift)
95 #define rop3_know_T_0(op) rop3_know_0_(op, rop3_T, rop3_T_shift)
96 /*
97  * Pin an operand to 1.
98  */
99 #define rop3_know_1_(op, mask, shift)\
100   ( (((op) & mask) >> shift) | ((op) & ~(rop3_1 - mask)) )
101 #define rop3_know_D_1(op) rop3_know_1_(op, rop3_D, rop3_D_shift)
102 #define rop3_know_S_1(op) rop3_know_1_(op, rop3_S, rop3_S_shift)
103 #define rop3_know_T_1(op) rop3_know_1_(op, rop3_T, rop3_T_shift)
104 /*
105  * Swap S and T.
106  */
107 #define rop3_swap_S_T(op)\
108   ( (((op) & rop3_S & ~rop3_T) << (rop3_T_shift - rop3_S_shift)) |\
109     (((op) & ~rop3_S & rop3_T) >> (rop3_T_shift - rop3_S_shift)) |\
110     ((op) & (~rop3_1 | (rop3_S ^ rop3_T))) )
111 /*
112  * Account for transparency.
113  */
114 #define rop3_use_D_when_0_(op, mask)\
115   (((op) & ~(rop3_1 - mask)) | (rop3_D & ~mask))
116 #define rop3_use_D_when_1_(op, mask)\
117   (((op) & ~mask) | (rop3_D & mask))
118 #define rop3_use_D_when_S_0(op) rop3_use_D_when_0_(op, rop3_S)
119 #define rop3_use_D_when_S_1(op) rop3_use_D_when_1_(op, rop3_S)
120 #define rop3_use_D_when_T_0(op) rop3_use_D_when_0_(op, rop3_T)
121 #define rop3_use_D_when_T_1(op) rop3_use_D_when_1_(op, rop3_T)
122 /*
123  * Invert the result.
124  */
125 #define rop3_not(op) ((op) ^ rop3_1)
126 /*
127  * Test whether an operand is used.
128  */
129 #define rop3_uses_(op, mask, shift)\
130   ( ((((op) << shift) ^ (op)) & mask) != 0 )
131 #define rop3_uses_D(op) rop3_uses_(op, rop3_D, rop3_D_shift)
132 #define rop3_uses_S(op) rop3_uses_(op, rop3_S, rop3_S_shift)
133 #define rop3_uses_T(op) rop3_uses_(op, rop3_T, rop3_T_shift)
134 /*
135  * Test whether an operation is idempotent, i.e., whether
136  * f(D, S, T) = f(f(D, S, T), S, T).  This is equivalent to the condition that
137  * for all values s and t, !( f(0,s,t) == 1 && f(1,s,t) == 0 ).
138  */
139 #define rop3_is_idempotent(op)\
140   !( (op) & ~((op) << rop3_D_shift) & rop3_D )
141 
142 /* Transparency */
143 #define source_transparent_default false
144 #define pattern_transparent_default false
145 
146 /*
147  * We define a logical operation as a RasterOp, transparency flags,
148  * and render algorithm all packed into a single integer.
149  * In principle, we should use a structure, but most C implementations
150  * implement structure values very inefficiently.
151  *
152  * In addition, we define a "pdf14" flag which indicates that PDF
153  * transparency is in effect. This doesn't change rendering in any way,
154  * but does force the lop to be considered non-idempotent.
155  */
156 #define lop_rop(lop) ((gs_rop3_t)((lop) & 0xff))	/* must be low-order bits */
157 #define lop_S_transparent 0x100
158 #define lop_T_transparent 0x200
159 #define lop_pdf14 0x4000
160 #define lop_ral_shift 10
161 #define lop_ral_mask 0xf
162 typedef uint gs_logical_operation_t;
163 
164 #define lop_default\
165   (rop3_default |\
166    (source_transparent_default ? lop_S_transparent : 0) |\
167    (pattern_transparent_default ? lop_T_transparent : 0))
168 
169      /* Test whether a logical operation uses S or T. */
170 #ifdef TRANSPARENCY_PER_H_P	/* bizarre but necessary definition */
171 #define lop_uses_S(lop)\
172   (rop3_uses_S(lop) || ((lop) & (lop_S_transparent | lop_T_transparent)))
173 #else				/* reasonable definition */
174 #define lop_uses_S(lop)\
175   (rop3_uses_S(lop) || ((lop) & lop_S_transparent))
176 #endif
177 #define lop_uses_T(lop)\
178   (rop3_uses_T(lop) || ((lop) & lop_T_transparent))
179 /* Test whether a logical operation just sets D = x if y = 0. */
180 #define lop_no_T_is_S(lop)\
181   (((lop) & (lop_S_transparent | (rop3_1 - rop3_T))) == (rop3_S & ~rop3_T))
182 #define lop_no_S_is_T(lop)\
183   (((lop) & (lop_T_transparent | (rop3_1 - rop3_S))) == (rop3_T & ~rop3_S))
184 /* Test whether a logical operation is idempotent. */
185 #define lop_is_idempotent(lop) (rop3_is_idempotent(lop) && !(lop & lop_pdf14))
186 
187 /*
188  * Define the logical operation versions of some RasterOp transformations.
189  * Note that these also affect the transparency flags.
190  */
191 #define lop_know_S_0(lop)\
192   (rop3_know_S_0(lop) & ~lop_S_transparent)
193 #define lop_know_T_0(lop)\
194   (rop3_know_T_0(lop) & ~lop_T_transparent)
195 #define lop_know_S_1(lop)\
196   (lop & lop_S_transparent ? rop3_D : rop3_know_S_1(lop))
197 #define lop_know_T_1(lop)\
198   (lop & lop_T_transparent ? rop3_D : rop3_know_T_1(lop))
199 
200 /* Define the interface to the table of 256 RasterOp procedures. */
201 typedef unsigned long rop_operand;
202 typedef rop_operand (*rop_proc)(rop_operand D, rop_operand S, rop_operand T);
203 
204 /* Define the table of operand usage by the 256 RasterOp operations. */
205 typedef enum {
206     rop_usage_none = 0,
207     rop_usage_D = 1,
208     rop_usage_S = 2,
209     rop_usage_DS = 3,
210     rop_usage_T = 4,
211     rop_usage_DT = 5,
212     rop_usage_ST = 6,
213     rop_usage_DST = 7
214 } rop_usage_t;
215 
216 /* Define the table of RasterOp implementation procedures. */
217 extern const rop_proc rop_proc_table[256];
218 
219 /* Define the table of RasterOp operand usage. */
220 extern const byte /*rop_usage_t*/ rop_usage_table[256];
221 
222 #endif /* gsropt_INCLUDED */
223