1 /* Copyright (C) 2001-2012 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.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* RasterOp source device */
18 #include "gx.h"
19 #include "gserrors.h"
20 #include "gxdcolor.h"
21 #include "gxdevice.h"
22 #include "gdevmrop.h"
23 
24 /* GC procedures */
25 private_st_device_rop_texture();
ENUM_PTRS_BEGIN(device_rop_texture_enum_ptrs)26 static ENUM_PTRS_BEGIN(device_rop_texture_enum_ptrs) {
27     if (index < st_device_color_max_ptrs) {
28         gs_ptr_type_t ptype =
29             ENUM_SUPER_ELT(gx_device_rop_texture, st_device_color, texture, 0);
30 
31         if (ptype)
32             return ptype;
33         return ENUM_OBJ(NULL);	/* don't stop early */
34     }
35     ENUM_PREFIX(st_device_forward, st_device_color_max_ptrs);
36 } ENUM_PTRS_END
RELOC_PTRS_BEGIN(device_rop_texture_reloc_ptrs)37 static RELOC_PTRS_BEGIN(device_rop_texture_reloc_ptrs) {
38     RELOC_PREFIX(st_device_forward);
39     RELOC_SUPER(gx_device_rop_texture, st_device_color, texture);
40 } RELOC_PTRS_END
41 
42 /* Device for providing source data for RasterOp. */
43 static dev_proc_fill_rectangle(rop_texture_fill_rectangle);
44 static dev_proc_copy_mono(rop_texture_copy_mono);
45 static dev_proc_copy_color(rop_texture_copy_color);
46 static dev_proc_copy_planes(rop_texture_copy_planes);
47 
48 /* The device descriptor. */
49 static const gx_device_rop_texture gs_rop_texture_device = {
50     std_device_std_body(gx_device_rop_texture, 0, "rop source",
51                         0, 0, 1, 1),
52     {NULL,				/* open_device */
53      gx_forward_get_initial_matrix,
54      NULL,				/* default_sync_output */
55      NULL,				/* output_page */
56      NULL,				/* close_device */
57      gx_forward_map_rgb_color,
58      gx_forward_map_color_rgb,
59      rop_texture_fill_rectangle,
60      NULL,				/* tile_rectangle */
61      rop_texture_copy_mono,
62      rop_texture_copy_color,
63      NULL,				/* draw_line */
64      NULL,				/* get_bits */
65      gx_forward_get_params,
66      gx_forward_put_params,
67      gx_forward_map_cmyk_color,
68      gx_forward_get_xfont_procs,
69      gx_forward_get_xfont_device,
70      gx_forward_map_rgb_alpha_color,
71      gx_forward_get_page_device,
72      NULL,				/* get_alpha_bits (no alpha) */
73      gx_no_copy_alpha,		/* shouldn't be called */
74      gx_forward_get_band,
75      gx_no_copy_rop,		/* shouldn't be called */
76      NULL,				/* fill_path */
77      NULL,				/* stroke_path */
78      NULL,				/* fill_mask */
79      NULL,				/* fill_trapezoid */
80      NULL,				/* fill_parallelogram */
81      NULL,				/* fill_triangle */
82      NULL,				/* draw_thin_line */
83      NULL,				/* begin_image */
84      NULL,				/* image_data */
85      NULL,				/* end_image */
86      NULL,				/* strip_tile_rectangle */
87      NULL,				/* strip_copy_rop */
88      gx_forward_get_clipping_box,
89      NULL,				/* begin_typed_image */
90      NULL,				/* get_bits_rectangle */
91      gx_forward_map_color_rgb_alpha,
92      NULL,				/* create_compositor */
93      gx_forward_get_hardware_params,
94      NULL,				/* text_begin */
95      NULL,				/* finish_copydevice */
96      NULL,				/* begin_transparency_group */
97      NULL,				/* end_transparency_group */
98      NULL,				/* begin_transparency_mask */
99      NULL,				/* end_transparency_mask */
100      NULL,				/* discard_transparency_layer */
101      gx_forward_get_color_mapping_procs,
102      gx_forward_get_color_comp_index,
103      gx_forward_encode_color,
104      gx_forward_decode_color,
105      NULL,                              /* dev_spec_op */
106      gx_forward_fill_rectangle_hl_color,
107      gx_forward_include_color_space,
108      gx_forward_fill_linear_color_scanline,
109      gx_forward_fill_linear_color_trapezoid,
110      gx_forward_fill_linear_color_triangle,
111      gx_forward_update_spot_equivalent_colors,
112      gx_forward_ret_devn_params,
113      gx_forward_fillpage,
114      NULL,                              /* push_transparency_state */
115      NULL,                              /* pop_transparency_state */
116      NULL,                              /* put_image */
117      gx_forward_dev_spec_op,
118      rop_texture_copy_planes,           /* copy planes */
119      gx_forward_get_profile,
120      gx_forward_set_graphics_type_tag
121     },
122     0,				/* target */
123     lop_default			/* log_op */
124     /* */				/* texture */
125 };
126 
127 /* Create a RasterOp source device. */
128 int
gx_alloc_rop_texture_device(gx_device_rop_texture ** prsdev,gs_memory_t * mem,client_name_t cname)129 gx_alloc_rop_texture_device(gx_device_rop_texture ** prsdev, gs_memory_t * mem,
130                             client_name_t cname)
131 {
132     *prsdev = gs_alloc_struct(mem, gx_device_rop_texture,
133                               &st_device_rop_texture, cname);
134     return (*prsdev == 0 ? gs_note_error(gs_error_VMerror) : 0);
135 }
136 
137 /* Initialize a RasterOp source device. */
138 void
gx_make_rop_texture_device(gx_device_rop_texture * dev,gx_device * target,gs_logical_operation_t log_op,const gx_device_color * texture)139 gx_make_rop_texture_device(gx_device_rop_texture * dev, gx_device * target,
140              gs_logical_operation_t log_op, const gx_device_color * texture)
141 {
142     gx_device_init((gx_device *) dev,
143                    (const gx_device *)&gs_rop_texture_device,
144                    (target ? target->memory : NULL), true);
145     gx_device_set_target((gx_device_forward *)dev, target);
146     /* Drawing operations are defaulted, non-drawing are forwarded. */
147     check_device_separable((gx_device *) dev);
148     gx_device_fill_in_procs((gx_device *) dev);
149     gx_device_copy_params((gx_device *)dev, target);
150     dev->graphics_type_tag = target->graphics_type_tag;	/* Init from device */
151     dev->log_op = log_op;
152     dev->texture = *texture;
153 }
154 
155 /* Fill a rectangle */
156 static int
rop_texture_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)157 rop_texture_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
158                            gx_color_index color)
159 {
160     gx_device_rop_texture *const rtdev = (gx_device_rop_texture *)dev;
161     gx_rop_source_t source;
162 
163     source.sdata = NULL;
164     source.sourcex = 0;
165     source.sraster = 0;
166     source.id = gx_no_bitmap_id;
167     source.scolors[0] = source.scolors[1] = color;
168     source.planar_height = 0;
169     source.use_scolors = true;
170     return gx_device_color_fill_rectangle(&rtdev->texture,
171                                           x, y, w, h, rtdev->target,
172                                           rtdev->log_op, &source);
173 }
174 
175 /* Copy a monochrome rectangle */
176 static int
rop_texture_copy_mono(gx_device * dev,const byte * data,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index color0,gx_color_index color1)177 rop_texture_copy_mono(gx_device * dev,
178                 const byte * data, int sourcex, int raster, gx_bitmap_id id,
179                       int x, int y, int w, int h,
180                       gx_color_index color0, gx_color_index color1)
181 {
182     gx_device_rop_texture *const rtdev = (gx_device_rop_texture *)dev;
183     gx_rop_source_t source;
184     gs_logical_operation_t lop = rtdev->log_op;
185 
186     source.sdata = data;
187     source.sourcex = sourcex;
188     source.sraster = raster;
189     source.id = id;
190     source.scolors[0] = color0;
191     source.scolors[1] = color1;
192     source.planar_height = 0;
193     source.use_scolors = true;
194     /* Adjust the logical operation per transparent colors. */
195     if (color0 == gx_no_color_index)
196         lop = rop3_use_D_when_S_0(lop);
197     else if (color1 == gx_no_color_index)
198         lop = rop3_use_D_when_S_1(lop);
199     return gx_device_color_fill_rectangle(&rtdev->texture,
200                                           x, y, w, h, rtdev->target,
201                                           lop, &source);
202 }
203 
204 /* Copy a color rectangle */
205 static int
rop_texture_copy_color(gx_device * dev,const byte * data,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)206 rop_texture_copy_color(gx_device * dev,
207                 const byte * data, int sourcex, int raster, gx_bitmap_id id,
208                        int x, int y, int w, int h)
209 {
210     gx_device_rop_texture *const rtdev = (gx_device_rop_texture *)dev;
211     gx_rop_source_t source;
212 
213     source.sdata = data;
214     source.sourcex = sourcex;
215     source.sraster = raster;
216     source.id = id;
217     source.scolors[0] = source.scolors[1] = gx_no_color_index;
218     source.planar_height = 0;
219     source.use_scolors = false;
220     return gx_device_color_fill_rectangle(&rtdev->texture,
221                                           x, y, w, h, rtdev->target,
222                                           rtdev->log_op, &source);
223 }
224 
225 /* Copy a color rectangle */
226 static int
rop_texture_copy_planes(gx_device * dev,const byte * data,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,int plane_height)227 rop_texture_copy_planes(gx_device * dev,
228                         const byte * data, int sourcex, int raster,
229                         gx_bitmap_id id, int x, int y, int w, int h,
230                         int plane_height)
231 {
232     gx_device_rop_texture *const rtdev = (gx_device_rop_texture *)dev;
233     gx_rop_source_t source;
234 
235     source.sdata = data;
236     source.sourcex = sourcex;
237     source.sraster = raster;
238     source.id = id;
239     source.scolors[0] = source.scolors[1] = gx_no_color_index;
240     source.planar_height = plane_height;
241     source.use_scolors = false;
242     return gx_device_color_fill_rectangle(&rtdev->texture,
243                                           x, y, w, h, rtdev->target,
244                                           rtdev->log_op,
245                                           &source);
246 }
247