xref: /plan9-contrib/sys/src/cmd/gs/src/gsropt.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /* Copyright (C) 1995, 2000 Aladdin Enterprises.  All rights reserved.
27dd7cddfSDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
57dd7cddfSDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: gsropt.h,v 1.7 2002/06/16 08:45:42 lpd Exp $ */
187dd7cddfSDavid du Colombier /* RasterOp / transparency type definitions */
197dd7cddfSDavid du Colombier 
207dd7cddfSDavid du Colombier #ifndef gsropt_INCLUDED
217dd7cddfSDavid du Colombier #  define gsropt_INCLUDED
227dd7cddfSDavid du Colombier 
237dd7cddfSDavid du Colombier /*
247dd7cddfSDavid du Colombier  * This file defines the types for some library extensions that are
257dd7cddfSDavid du Colombier  * motivated by PCL5 and also made available for PostScript:
267dd7cddfSDavid du Colombier  * RasterOp, source and pattern white-pixel transparency, and
277dd7cddfSDavid du Colombier  * per-pixel "render algorithm" information.
287dd7cddfSDavid du Colombier  */
297dd7cddfSDavid du Colombier 
307dd7cddfSDavid du Colombier /*
317dd7cddfSDavid du Colombier  * Define whether we implement transparency correctly, or whether we
327dd7cddfSDavid du Colombier  * implement it as documented in the H-P manuals.
337dd7cddfSDavid du Colombier  */
347dd7cddfSDavid du Colombier #define TRANSPARENCY_PER_H_P
357dd7cddfSDavid du Colombier 
367dd7cddfSDavid du Colombier /*
377dd7cddfSDavid du Colombier  * By the magic of Boolean algebra, we can operate on the rop codes using
387dd7cddfSDavid du Colombier  * Boolean operators and get the right result.  E.g., the value of
397dd7cddfSDavid du Colombier  * (rop3_S & rop3_D) is the rop3 code for S & D.  We just have to remember
407dd7cddfSDavid du Colombier  * to mask results with rop2_1 or rop3_1 if necessary.
417dd7cddfSDavid du Colombier  */
427dd7cddfSDavid du Colombier 
437dd7cddfSDavid du Colombier /* 2-input RasterOp */
447dd7cddfSDavid du Colombier typedef enum {
457dd7cddfSDavid du Colombier     rop2_0 = 0,
467dd7cddfSDavid du Colombier     rop2_S = 0xc,		/* source */
477dd7cddfSDavid du Colombier #define rop2_S_shift 2
487dd7cddfSDavid du Colombier     rop2_D = 0xa,		/* destination */
497dd7cddfSDavid du Colombier #define rop2_D_shift 1
507dd7cddfSDavid du Colombier     rop2_1 = 0xf,
517dd7cddfSDavid du Colombier #define rop2_operand(shift, d, s)\
527dd7cddfSDavid du Colombier   ((shift) == 2 ? (s) : (d))
537dd7cddfSDavid du Colombier     rop2_default = rop2_S
547dd7cddfSDavid du Colombier } gs_rop2_t;
557dd7cddfSDavid du Colombier 
567dd7cddfSDavid du Colombier /*
577dd7cddfSDavid du Colombier  * For the 3-input case, we follow H-P's inconsistent terminology:
587dd7cddfSDavid du Colombier  * the transparency mode is called pattern transparency, but the third
597dd7cddfSDavid du Colombier  * RasterOp operand is called texture, not pattern.
607dd7cddfSDavid du Colombier  */
617dd7cddfSDavid du Colombier 
627dd7cddfSDavid du Colombier /* 3-input RasterOp */
637dd7cddfSDavid du Colombier typedef enum {
647dd7cddfSDavid du Colombier     rop3_0 = 0,
657dd7cddfSDavid du Colombier     rop3_T = 0xf0,		/* texture */
667dd7cddfSDavid du Colombier #define rop3_T_shift 4
677dd7cddfSDavid du Colombier     rop3_S = 0xcc,		/* source */
687dd7cddfSDavid du Colombier #define rop3_S_shift 2
697dd7cddfSDavid du Colombier     rop3_D = 0xaa,		/* destination */
707dd7cddfSDavid du Colombier #define rop3_D_shift 1
717dd7cddfSDavid du Colombier     rop3_1 = 0xff,
727dd7cddfSDavid du Colombier     rop3_default = rop3_T | rop3_S
737dd7cddfSDavid du Colombier } gs_rop3_t;
747dd7cddfSDavid du Colombier 
757dd7cddfSDavid du Colombier /* All the transformations on rop3s are designed so that */
767dd7cddfSDavid du Colombier /* they can also be used on lops.  The only place this costs anything */
777dd7cddfSDavid du Colombier /* is in rop3_invert. */
787dd7cddfSDavid du Colombier 
797dd7cddfSDavid du Colombier /*
807dd7cddfSDavid du Colombier  * Invert an operand.
817dd7cddfSDavid du Colombier  */
827dd7cddfSDavid du Colombier #define rop3_invert_(op, mask, shift)\
837dd7cddfSDavid du Colombier   ( (((op) & mask) >> shift) | (((op) & (rop3_1 - mask)) << shift) |\
847dd7cddfSDavid du Colombier     ((op) & ~rop3_1) )
857dd7cddfSDavid du Colombier #define rop3_invert_D(op) rop3_invert_(op, rop3_D, rop3_D_shift)
867dd7cddfSDavid du Colombier #define rop3_invert_S(op) rop3_invert_(op, rop3_S, rop3_S_shift)
877dd7cddfSDavid du Colombier #define rop3_invert_T(op) rop3_invert_(op, rop3_T, rop3_T_shift)
887dd7cddfSDavid du Colombier /*
897dd7cddfSDavid du Colombier  * Pin an operand to 0.
907dd7cddfSDavid du Colombier  */
917dd7cddfSDavid du Colombier #define rop3_know_0_(op, mask, shift)\
927dd7cddfSDavid du Colombier   ( (((op) & (rop3_1 - mask)) << shift) | ((op) & ~mask) )
937dd7cddfSDavid du Colombier #define rop3_know_D_0(op) rop3_know_0_(op, rop3_D, rop3_D_shift)
947dd7cddfSDavid du Colombier #define rop3_know_S_0(op) rop3_know_0_(op, rop3_S, rop3_S_shift)
957dd7cddfSDavid du Colombier #define rop3_know_T_0(op) rop3_know_0_(op, rop3_T, rop3_T_shift)
967dd7cddfSDavid du Colombier /*
977dd7cddfSDavid du Colombier  * Pin an operand to 1.
987dd7cddfSDavid du Colombier  */
997dd7cddfSDavid du Colombier #define rop3_know_1_(op, mask, shift)\
1007dd7cddfSDavid du Colombier   ( (((op) & mask) >> shift) | ((op) & ~(rop3_1 - mask)) )
1017dd7cddfSDavid du Colombier #define rop3_know_D_1(op) rop3_know_1_(op, rop3_D, rop3_D_shift)
1027dd7cddfSDavid du Colombier #define rop3_know_S_1(op) rop3_know_1_(op, rop3_S, rop3_S_shift)
1037dd7cddfSDavid du Colombier #define rop3_know_T_1(op) rop3_know_1_(op, rop3_T, rop3_T_shift)
1047dd7cddfSDavid du Colombier /*
1057dd7cddfSDavid du Colombier  * Swap S and T.
1067dd7cddfSDavid du Colombier  */
1077dd7cddfSDavid du Colombier #define rop3_swap_S_T(op)\
1087dd7cddfSDavid du Colombier   ( (((op) & rop3_S & ~rop3_T) << (rop3_T_shift - rop3_S_shift)) |\
1097dd7cddfSDavid du Colombier     (((op) & ~rop3_S & rop3_T) >> (rop3_T_shift - rop3_S_shift)) |\
1107dd7cddfSDavid du Colombier     ((op) & (~rop3_1 | (rop3_S ^ rop3_T))) )
1117dd7cddfSDavid du Colombier /*
1127dd7cddfSDavid du Colombier  * Account for transparency.
1137dd7cddfSDavid du Colombier  */
1147dd7cddfSDavid du Colombier #define rop3_use_D_when_0_(op, mask)\
1157dd7cddfSDavid du Colombier   (((op) & ~(rop3_1 - mask)) | (rop3_D & ~mask))
1167dd7cddfSDavid du Colombier #define rop3_use_D_when_1_(op, mask)\
1177dd7cddfSDavid du Colombier   (((op) & ~mask) | (rop3_D & mask))
1187dd7cddfSDavid du Colombier #define rop3_use_D_when_S_0(op) rop3_use_D_when_0_(op, rop3_S)
1197dd7cddfSDavid du Colombier #define rop3_use_D_when_S_1(op) rop3_use_D_when_1_(op, rop3_S)
1207dd7cddfSDavid du Colombier #define rop3_use_D_when_T_0(op) rop3_use_D_when_0_(op, rop3_T)
1217dd7cddfSDavid du Colombier #define rop3_use_D_when_T_1(op) rop3_use_D_when_1_(op, rop3_T)
1227dd7cddfSDavid du Colombier /*
1237dd7cddfSDavid du Colombier  * Invert the result.
1247dd7cddfSDavid du Colombier  */
1257dd7cddfSDavid du Colombier #define rop3_not(op) ((op) ^ rop3_1)
1267dd7cddfSDavid du Colombier /*
1277dd7cddfSDavid du Colombier  * Test whether an operand is used.
1287dd7cddfSDavid du Colombier  */
1297dd7cddfSDavid du Colombier #define rop3_uses_(op, mask, shift)\
1307dd7cddfSDavid du Colombier   ( ((((op) << shift) ^ (op)) & mask) != 0 )
1317dd7cddfSDavid du Colombier #define rop3_uses_D(op) rop3_uses_(op, rop3_D, rop3_D_shift)
1327dd7cddfSDavid du Colombier #define rop3_uses_S(op) rop3_uses_(op, rop3_S, rop3_S_shift)
1337dd7cddfSDavid du Colombier #define rop3_uses_T(op) rop3_uses_(op, rop3_T, rop3_T_shift)
1347dd7cddfSDavid du Colombier /*
1357dd7cddfSDavid du Colombier  * Test whether an operation is idempotent, i.e., whether
1367dd7cddfSDavid du Colombier  * f(D, S, T) = f(f(D, S, T), S, T).  This is equivalent to the condition that
1377dd7cddfSDavid du Colombier  * for all values s and t, !( f(0,s,t) == 1 && f(1,s,t) == 0 ).
1387dd7cddfSDavid du Colombier  */
1397dd7cddfSDavid du Colombier #define rop3_is_idempotent(op)\
1407dd7cddfSDavid du Colombier   !( (op) & ~((op) << rop3_D_shift) & rop3_D )
1417dd7cddfSDavid du Colombier 
1427dd7cddfSDavid du Colombier /* Transparency */
1437dd7cddfSDavid du Colombier #define source_transparent_default false
1447dd7cddfSDavid du Colombier #define pattern_transparent_default false
1457dd7cddfSDavid du Colombier 
1467dd7cddfSDavid du Colombier /*
1477dd7cddfSDavid du Colombier  * We define a logical operation as a RasterOp, transparency flags,
1487dd7cddfSDavid du Colombier  * and render algorithm all packed into a single integer.
1497dd7cddfSDavid du Colombier  * In principle, we should use a structure, but most C implementations
1507dd7cddfSDavid du Colombier  * implement structure values very inefficiently.
1513ff48bf5SDavid du Colombier  *
1523ff48bf5SDavid du Colombier  * In addition, we define a "pdf14" flag which indicates that PDF
1533ff48bf5SDavid du Colombier  * transparency is in effect. This doesn't change rendering in any way,
1543ff48bf5SDavid du Colombier  * but does force the lop to be considered non-idempotent.
1557dd7cddfSDavid du Colombier  */
1567dd7cddfSDavid du Colombier #define lop_rop(lop) ((gs_rop3_t)((lop) & 0xff))	/* must be low-order bits */
1577dd7cddfSDavid du Colombier #define lop_S_transparent 0x100
1587dd7cddfSDavid du Colombier #define lop_T_transparent 0x200
1593ff48bf5SDavid du Colombier #define lop_pdf14 0x4000
1607dd7cddfSDavid du Colombier #define lop_ral_shift 10
1617dd7cddfSDavid du Colombier #define lop_ral_mask 0xf
1627dd7cddfSDavid du Colombier typedef uint gs_logical_operation_t;
1637dd7cddfSDavid du Colombier 
1647dd7cddfSDavid du Colombier #define lop_default\
1657dd7cddfSDavid du Colombier   (rop3_default |\
1667dd7cddfSDavid du Colombier    (source_transparent_default ? lop_S_transparent : 0) |\
1677dd7cddfSDavid du Colombier    (pattern_transparent_default ? lop_T_transparent : 0))
1687dd7cddfSDavid du Colombier 
1697dd7cddfSDavid du Colombier      /* Test whether a logical operation uses S or T. */
1707dd7cddfSDavid du Colombier #ifdef TRANSPARENCY_PER_H_P	/* bizarre but necessary definition */
1717dd7cddfSDavid du Colombier #define lop_uses_S(lop)\
1727dd7cddfSDavid du Colombier   (rop3_uses_S(lop) || ((lop) & (lop_S_transparent | lop_T_transparent)))
1737dd7cddfSDavid du Colombier #else				/* reasonable definition */
1747dd7cddfSDavid du Colombier #define lop_uses_S(lop)\
1757dd7cddfSDavid du Colombier   (rop3_uses_S(lop) || ((lop) & lop_S_transparent))
1767dd7cddfSDavid du Colombier #endif
1777dd7cddfSDavid du Colombier #define lop_uses_T(lop)\
1787dd7cddfSDavid du Colombier   (rop3_uses_T(lop) || ((lop) & lop_T_transparent))
1797dd7cddfSDavid du Colombier /* Test whether a logical operation just sets D = x if y = 0. */
1807dd7cddfSDavid du Colombier #define lop_no_T_is_S(lop)\
1817dd7cddfSDavid du Colombier   (((lop) & (lop_S_transparent | (rop3_1 - rop3_T))) == (rop3_S & ~rop3_T))
1827dd7cddfSDavid du Colombier #define lop_no_S_is_T(lop)\
1837dd7cddfSDavid du Colombier   (((lop) & (lop_T_transparent | (rop3_1 - rop3_S))) == (rop3_T & ~rop3_S))
1847dd7cddfSDavid du Colombier /* Test whether a logical operation is idempotent. */
1853ff48bf5SDavid du Colombier #define lop_is_idempotent(lop) (rop3_is_idempotent(lop) && !(lop & lop_pdf14))
1867dd7cddfSDavid du Colombier 
1877dd7cddfSDavid du Colombier /*
1887dd7cddfSDavid du Colombier  * Define the logical operation versions of some RasterOp transformations.
1897dd7cddfSDavid du Colombier  * Note that these also affect the transparency flags.
1907dd7cddfSDavid du Colombier  */
1917dd7cddfSDavid du Colombier #define lop_know_S_0(lop)\
1927dd7cddfSDavid du Colombier   (rop3_know_S_0(lop) & ~lop_S_transparent)
1937dd7cddfSDavid du Colombier #define lop_know_T_0(lop)\
1947dd7cddfSDavid du Colombier   (rop3_know_T_0(lop) & ~lop_T_transparent)
1957dd7cddfSDavid du Colombier #define lop_know_S_1(lop)\
1967dd7cddfSDavid du Colombier   (lop & lop_S_transparent ? rop3_D : rop3_know_S_1(lop))
1977dd7cddfSDavid du Colombier #define lop_know_T_1(lop)\
1987dd7cddfSDavid du Colombier   (lop & lop_T_transparent ? rop3_D : rop3_know_T_1(lop))
1997dd7cddfSDavid du Colombier 
2007dd7cddfSDavid du Colombier /* Define the interface to the table of 256 RasterOp procedures. */
2017dd7cddfSDavid du Colombier typedef unsigned long rop_operand;
202*593dc095SDavid du Colombier typedef rop_operand (*rop_proc)(rop_operand D, rop_operand S, rop_operand T);
2037dd7cddfSDavid du Colombier 
2047dd7cddfSDavid du Colombier /* Define the table of operand usage by the 256 RasterOp operations. */
2057dd7cddfSDavid du Colombier typedef enum {
2067dd7cddfSDavid du Colombier     rop_usage_none = 0,
2077dd7cddfSDavid du Colombier     rop_usage_D = 1,
2087dd7cddfSDavid du Colombier     rop_usage_S = 2,
2097dd7cddfSDavid du Colombier     rop_usage_DS = 3,
2107dd7cddfSDavid du Colombier     rop_usage_T = 4,
2117dd7cddfSDavid du Colombier     rop_usage_DT = 5,
2127dd7cddfSDavid du Colombier     rop_usage_ST = 6,
2137dd7cddfSDavid du Colombier     rop_usage_DST = 7
2147dd7cddfSDavid du Colombier } rop_usage_t;
2157dd7cddfSDavid du Colombier 
2167dd7cddfSDavid du Colombier /* Define the table of RasterOp implementation procedures. */
2177dd7cddfSDavid du Colombier extern const rop_proc rop_proc_table[256];
2187dd7cddfSDavid du Colombier 
2197dd7cddfSDavid du Colombier /* Define the table of RasterOp operand usage. */
2207dd7cddfSDavid du Colombier extern const byte /*rop_usage_t*/ rop_usage_table[256];
2217dd7cddfSDavid du Colombier 
2227dd7cddfSDavid du Colombier #endif /* gsropt_INCLUDED */
223