1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Mask clipping device and interface */
18 /* Requires gxdevice.h, gxdevmem.h */
19 
20 #ifndef gxmclip_INCLUDED
21 #  define gxmclip_INCLUDED
22 
23 #include "gxclip.h"
24 #include "gxdevmem.h"
25 
26 /*
27  * ImageType 3 images and Patterns that don't completely fill their
28  * bounding box require the ability to clip against a mask.
29  * The interface declared here doesn't take a position on whether
30  * the mask will be used only in one position (ImageType 3) or in
31  * multiple positions for tiling (Patterns).
32  *
33  * All the information in this file is logically private, but we must expose
34  * the structure definition so that clients can allocate instances in the
35  * stack frame.
36  */
37 
38 #define tile_clip_buffer_request 32768	/* enough for 2400 dpi up to 109" wide */
39 #define tile_clip_buffer_size\
40   ((tile_clip_buffer_request / ARCH_SIZEOF_LONG) * ARCH_SIZEOF_LONG)
41 typedef struct gx_device_mask_clip_s {
42     gx_device_forward_common;	/* target is set by client */
43     gx_strip_bitmap tiles;
44     gx_device_memory mdev;	/* for tile buffer for copy_mono */
45     gs_int_point phase;		/* device space origin relative */
46                                 /* to tile (backwards from gstate phase) */
47     /* Ensure that the buffer is long-aligned. */
48     union _b {
49         byte bytes[tile_clip_buffer_size];
50         ulong longs[tile_clip_buffer_size / ARCH_SIZEOF_LONG];
51     } buffer;
52 } gx_device_mask_clip;
53 
54 extern_st(st_device_mask_clip);
55 #define public_st_device_mask_clip()	/* in gxmclip.c */\
56   gs_public_st_composite_use_final(st_device_mask_clip, gx_device_mask_clip,\
57     "gx_device_mask_clip", device_mask_clip_enum_ptrs,\
58     device_mask_clip_reloc_ptrs, gx_device_finalize)
59 
60 /*
61  * Internal routine to initialize a mask clipping device.
62  * We supply an explicit device space origin or phase.
63  * Note that this procedure does not set cdev->tiles.
64  * If mem is sent as NULL, then the initialised device structure will not be
65  * freed when the refcount reaches 0 (suitable for devices on stack, or within
66  * other structures).
67  */
68 int gx_mask_clip_initialize(gx_device_mask_clip * cdev,
69                             const gx_device_mask_clip * proto,
70                             const gx_bitmap * bits, gx_device * tdev,
71                             int tx, int ty, gs_memory_t *mem);
72 
73 /*
74  * Prepare colors for a copy_mono operation.
75  * The arguments of copy_mono are free variables:
76  *   dev, data, sourcex, raster, id, x, y, w, y, color0, color1.
77  */
78 #define setup_mask_copy_mono(cdev, color, mcolor0, mcolor1)\
79         BEGIN\
80           if ( cdev->mdev.base == 0 ) {\
81             /*\
82              * The tile was too large for us to buffer even one scan line.\
83              * Punt to the very, very slow default implementation of\
84              * copy_mono.\
85              */\
86             return gx_default_copy_mono(dev, data, sourcex, raster, id,\
87                                         x, y, w, h, color0, color1);\
88           }\
89           if ( color1 != gx_no_color_index ) {\
90             if ( color0 != gx_no_color_index ) {\
91               /* Pre-fill with color0. */\
92               code =\
93                 (*dev_proc(dev, fill_rectangle))(dev, x, y, w, h, color0);\
94               if ( code < 0 )\
95                 return code;\
96             }\
97             color = color1;\
98             mcolor0 = 0, mcolor1 = gx_no_color_index;\
99           } else if ( color0 != gx_no_color_index ) {\
100             color = color0;\
101             mcolor0 = gx_no_color_index, mcolor1 = 0;\
102           } else\
103             return 0;\
104         END
105 
106 #endif /* gxmclip_INCLUDED */
107