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