1 /* Copyright (C) 1999 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: gsptype1.c,v 1.23 2005/06/15 18:40:07 igor Exp $ */
18 /* PatternType 1 pattern implementation */
19 #include "math_.h"
20 #include "gx.h"
21 #include "gserrors.h"
22 #include "gsrop.h"
23 #include "gsstruct.h"
24 #include "gsutil.h" /* for gs_next_ids */
25 #include "gxarith.h"
26 #include "gxfixed.h"
27 #include "gxmatrix.h"
28 #include "gxcoord.h" /* for gs_concat, gx_tr'_to_fixed */
29 #include "gxcspace.h" /* for gscolor2.h */
30 #include "gxcolor2.h"
31 #include "gxdcolor.h"
32 #include "gxdevice.h"
33 #include "gxdevmem.h"
34 #include "gxclip2.h"
35 #include "gspath.h"
36 #include "gxpath.h"
37 #include "gxpcolor.h"
38 #include "gxp1impl.h" /* requires gxpcolor.h */
39 #include "gzstate.h"
40 #include "gsimage.h"
41 #include "gsiparm4.h"
42 #include "gsovrc.h"
43
44 /* Temporary switches for experimanting with Adobe compatibility. */
45 #define ADJUST_SCALE_FOR_THIN_LINES 0 /* Old code = 0 */
46 #define ADJUST_SCALE_BY_GS_TRADITION 0 /* Old code = 1 */
47 #define ADJUST_AS_ADOBE 1 /* Old code = 0 *//* This one is closer to Adobe. */
48
49 /* GC descriptors */
50 private_st_pattern1_template();
51 private_st_pattern1_instance();
52
53 /* GC procedures */
ENUM_PTRS_BEGIN(pattern1_instance_enum_ptrs)54 private ENUM_PTRS_BEGIN(pattern1_instance_enum_ptrs) {
55 if (index < st_pattern1_template_max_ptrs) {
56 gs_ptr_type_t ptype =
57 ENUM_SUPER_ELT(gs_pattern1_instance_t, st_pattern1_template,
58 template, 0);
59
60 if (ptype)
61 return ptype;
62 return ENUM_OBJ(NULL); /* don't stop early */
63 }
64 ENUM_PREFIX(st_pattern_instance, st_pattern1_template_max_ptrs);
65 } ENUM_PTRS_END
RELOC_PTRS_BEGIN(pattern1_instance_reloc_ptrs)66 private RELOC_PTRS_BEGIN(pattern1_instance_reloc_ptrs) {
67 RELOC_PREFIX(st_pattern_instance);
68 RELOC_SUPER(gs_pattern1_instance_t, st_pattern1_template, template);
69 } RELOC_PTRS_END
70
71 /* Define a PatternType 1 pattern. */
72 private pattern_proc_uses_base_space(gs_pattern1_uses_base_space);
73 private pattern_proc_make_pattern(gs_pattern1_make_pattern);
74 private pattern_proc_get_pattern(gs_pattern1_get_pattern);
75 private pattern_proc_set_color(gs_pattern1_set_color);
76 private const gs_pattern_type_t gs_pattern1_type = {
77 1, {
78 gs_pattern1_uses_base_space, gs_pattern1_make_pattern,
79 gs_pattern1_get_pattern, gs_pattern1_remap_color,
80 gs_pattern1_set_color
81 }
82 };
83
84 /*
85 * Build a PatternType 1 Pattern color space.
86 */
87 int
gs_cspace_build_Pattern1(gs_color_space ** ppcspace,const gs_color_space * pbase_cspace,gs_memory_t * pmem)88 gs_cspace_build_Pattern1(gs_color_space ** ppcspace,
89 const gs_color_space * pbase_cspace, gs_memory_t * pmem)
90 {
91 gs_color_space *pcspace = 0;
92 int code;
93
94 if (pbase_cspace != 0) {
95 if (gs_color_space_num_components(pcspace) < 0) /* Pattern space */
96 return_error(gs_error_rangecheck);
97 }
98 code = gs_cspace_alloc(&pcspace, &gs_color_space_type_Pattern, pmem);
99 if (code < 0)
100 return code;
101 if (pbase_cspace != 0) {
102 pcspace->params.pattern.has_base_space = true;
103 gs_cspace_init_from((gs_color_space *) & (pcspace->params.pattern.base_space),
104 pbase_cspace
105 );
106 } else
107 pcspace->params.pattern.has_base_space = false;
108 *ppcspace = pcspace;
109 return 0;
110 }
111
112 /* Initialize a PatternType 1 pattern template. */
113 void
gs_pattern1_init(gs_pattern1_template_t * ppat)114 gs_pattern1_init(gs_pattern1_template_t * ppat)
115 {
116 gs_pattern_common_init((gs_pattern_template_t *)ppat, &gs_pattern1_type);
117 }
118
119 /* Make an instance of a PatternType 1 pattern. */
120 private int compute_inst_matrix(gs_pattern1_instance_t * pinst,
121 const gs_state * saved, gs_rect * pbbox, int width, int height);
122 int
gs_makepattern(gs_client_color * pcc,const gs_pattern1_template_t * pcp,const gs_matrix * pmat,gs_state * pgs,gs_memory_t * mem)123 gs_makepattern(gs_client_color * pcc, const gs_pattern1_template_t * pcp,
124 const gs_matrix * pmat, gs_state * pgs, gs_memory_t * mem)
125 {
126 return gs_pattern1_make_pattern(pcc, (const gs_pattern_template_t *)pcp,
127 pmat, pgs, mem);
128 }
129 private int
gs_pattern1_make_pattern(gs_client_color * pcc,const gs_pattern_template_t * ptemp,const gs_matrix * pmat,gs_state * pgs,gs_memory_t * mem)130 gs_pattern1_make_pattern(gs_client_color * pcc,
131 const gs_pattern_template_t * ptemp,
132 const gs_matrix * pmat, gs_state * pgs,
133 gs_memory_t * mem)
134 {
135 const gs_pattern1_template_t *pcp = (const gs_pattern1_template_t *)ptemp;
136 gs_pattern1_instance_t inst;
137 gs_pattern1_instance_t *pinst;
138 gs_state *saved;
139 gs_rect bbox;
140 gs_fixed_rect cbox;
141 gx_device * pdev = pgs->device;
142 int dev_width = pdev->width;
143 int dev_height = pdev->height;
144 int code = gs_make_pattern_common(pcc, (const gs_pattern_template_t *)pcp,
145 pmat, pgs, mem,
146 &st_pattern1_instance);
147
148 if (code < 0)
149 return code;
150 if (mem == 0)
151 mem = gs_state_memory(pgs);
152 pinst = (gs_pattern1_instance_t *)pcc->pattern;
153 *(gs_pattern_instance_t *)&inst = *(gs_pattern_instance_t *)pinst;
154 saved = inst.saved;
155 switch (pcp->PaintType) {
156 case 1: /* colored */
157 gs_set_logical_op(saved, lop_default);
158 break;
159 case 2: /* uncolored */
160 gx_set_device_color_1(saved);
161 break;
162 default:
163 code = gs_note_error(gs_error_rangecheck);
164 goto fsaved;
165 }
166 inst.template = *pcp;
167 code = compute_inst_matrix(&inst, saved, &bbox, dev_width, dev_height);
168 if (code < 0)
169 goto fsaved;
170
171 #define mat inst.step_matrix
172 if_debug6('t', "[t]step_matrix=[%g %g %g %g %g %g]\n",
173 mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty);
174 if_debug4('t', "[t]bbox=(%g,%g),(%g,%g)\n",
175 bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
176 {
177 float bbw = bbox.q.x - bbox.p.x;
178 float bbh = bbox.q.y - bbox.p.y;
179
180 /* If the step and the size agree to within 1/2 pixel, */
181 /* make them the same. */
182 if (ADJUST_SCALE_BY_GS_TRADITION) {
183 inst.size.x = (int)(bbw + 0.8); /* 0.8 is arbitrary */
184 inst.size.y = (int)(bbh + 0.8);
185 } else {
186 inst.size.x = (int)ceil(bbw);
187 inst.size.y = (int)ceil(bbh);
188 }
189
190 if (inst.size.x == 0 || inst.size.y == 0) {
191 /*
192 * The pattern is empty: the stepping matrix doesn't matter.
193 */
194 gs_make_identity(&mat);
195 bbox.p.x = bbox.p.y = bbox.q.x = bbox.q.y = 0;
196 } else {
197 /* Check for singular stepping matrix. */
198 if (fabs(mat.xx * mat.yy - mat.xy * mat.yx) < 1.0e-6) {
199 code = gs_note_error(gs_error_rangecheck);
200 goto fsaved;
201 }
202 if (ADJUST_SCALE_BY_GS_TRADITION &&
203 mat.xy == 0 && mat.yx == 0 &&
204 fabs(fabs(mat.xx) - bbw) < 0.5 &&
205 fabs(fabs(mat.yy) - bbh) < 0.5
206 ) {
207 gs_scale(saved, fabs(inst.size.x / mat.xx),
208 fabs(inst.size.y / mat.yy));
209 code = compute_inst_matrix(&inst, saved, &bbox,
210 dev_width, dev_height);
211 if (code < 0)
212 goto fsaved;
213 if (ADJUST_SCALE_FOR_THIN_LINES) {
214 /* To allow thin lines at a cell boundary
215 to be painted inside the cell,
216 we adjust the scale so that
217 the scaled width is in fixed_1 smaller */
218 gs_scale(saved, (fabs(inst.size.x) - 1.0 / fixed_scale) / fabs(inst.size.x),
219 (fabs(inst.size.y) - 1.0 / fixed_scale) / fabs(inst.size.y));
220 }
221 if_debug2('t',
222 "[t]adjusted XStep & YStep to size=(%d,%d)\n",
223 inst.size.x, inst.size.y);
224 if_debug4('t', "[t]bbox=(%g,%g),(%g,%g)\n",
225 bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
226 } else if (ADJUST_AS_ADOBE) {
227 if (mat.xy == 0 && mat.yx == 0 &&
228 fabs(fabs(mat.xx) - bbw) < 0.5 &&
229 fabs(fabs(mat.yy) - bbh) < 0.5
230 ) {
231 if (inst.step_matrix.xx <= 2) {
232 /* Prevent a degradation - see -r72 mspro.pdf */
233 gs_scale(saved, fabs(inst.size.x / mat.xx), 1);
234 inst.step_matrix.xx = (float)inst.size.x;
235 } else {
236 inst.step_matrix.xx = (float)floor(inst.step_matrix.xx + 0.5);
237 /* To allow thin lines at a cell boundary
238 to be painted inside the cell,
239 we adjust the scale so that
240 the scaled width is in fixed_1 smaller */
241 if (bbw >= inst.size.x - 1.0 / fixed_scale)
242 gs_scale(saved, (fabs(inst.size.x) - 1.0 / fixed_scale) / fabs(inst.size.x), 1);
243 }
244 if (inst.step_matrix.yy <= 2) {
245 gs_scale(saved, 1, fabs(inst.size.y / mat.yy));
246 inst.step_matrix.yy = (float)inst.size.y;
247 } else {
248 inst.step_matrix.yy = (float)floor(inst.step_matrix.yy + 0.5);
249 if (bbh >= inst.size.y - 1.0 / fixed_scale)
250 gs_scale(saved, 1, (fabs(inst.size.y) - 1.0 / fixed_scale) / fabs(inst.size.y));
251 }
252 code = gs_bbox_transform(&inst.template.BBox, &ctm_only(saved), &bbox);
253 if (code < 0)
254 goto fsaved;
255 }
256 }
257 }
258 }
259 if ((code = gs_bbox_transform_inverse(&bbox, &mat, &inst.bbox)) < 0)
260 goto fsaved;
261 if_debug4('t', "[t]ibbox=(%g,%g),(%g,%g)\n",
262 inst.bbox.p.x, inst.bbox.p.y, inst.bbox.q.x, inst.bbox.q.y);
263 inst.is_simple = (fabs(mat.xx) == inst.size.x && mat.xy == 0 &&
264 mat.yx == 0 && fabs(mat.yy) == inst.size.y);
265 if_debug6('t',
266 "[t]is_simple? xstep=(%g,%g) ystep=(%g,%g) size=(%d,%d)\n",
267 inst.step_matrix.xx, inst.step_matrix.xy,
268 inst.step_matrix.yx, inst.step_matrix.yy,
269 inst.size.x, inst.size.y);
270 /* Absent other information, instances always require a mask. */
271 inst.uses_mask = true;
272 gx_translate_to_fixed(saved, float2fixed_rounded(mat.tx - bbox.p.x),
273 float2fixed_rounded(mat.ty - bbox.p.y));
274 mat.tx = bbox.p.x;
275 mat.ty = bbox.p.y;
276 #undef mat
277 cbox.p.x = fixed_0;
278 cbox.p.y = fixed_0;
279 cbox.q.x = int2fixed(inst.size.x);
280 cbox.q.y = int2fixed(inst.size.y);
281 code = gx_clip_to_rectangle(saved, &cbox);
282 if (code < 0)
283 goto fsaved;
284 inst.id = gs_next_ids(mem, 1);
285 *pinst = inst;
286 return 0;
287 #undef mat
288 fsaved:gs_state_free(saved);
289 gs_free_object(mem, pinst, "gs_makepattern");
290 return code;
291 }
292
293 /*
294 * Clamp the bound box for a pattern to the region of the pattern that will
295 * actually be on our page. We need to do this becuase some applications
296 * create patterns which specify a bounding box which is much larger than
297 * the page. We allocate a buffer for holding the pattern. We need to
298 * prevent this buffer from getting too large.
299 */
300 private int
clamp_pattern_bbox(gs_pattern1_instance_t * pinst,gs_rect * pbbox,int width,int height,const gs_matrix * pmat)301 clamp_pattern_bbox(gs_pattern1_instance_t * pinst, gs_rect * pbbox,
302 int width, int height, const gs_matrix * pmat)
303 {
304 double xstep = pinst->template.XStep;
305 double ystep = pinst->template.YStep;
306 double xmin = pbbox->q.x;
307 double xmax = pbbox->p.x;
308 double ymin = pbbox->q.y;
309 double ymax = pbbox->p.y;
310 int ixpat, iypat, iystart;
311 double xpat, ypat;
312 double xlower, xupper, ylower, yupper;
313 double xdev, ydev;
314 gs_rect dev_page, pat_page;
315 gs_point dev_pat_origin, dev_step;
316 int code;
317
318 /*
319 * Scan across the page. We determine the region to be scanned
320 * by working in the pattern coordinate space. This is logically
321 * simpler since XStep and YStep are on axis in the pattern space.
322 */
323 /*
324 * Convert the page dimensions from device coordinates into the
325 * pattern coordinate frame.
326 */
327 dev_page.p.x = dev_page.p.y = 0;
328 dev_page.q.x = width;
329 dev_page.q.y = height;
330 code = gs_bbox_transform_inverse(&dev_page, pmat, &pat_page);
331 if (code < 0)
332 return code;
333 /*
334 * Determine the location of the pattern origin in device coordinates.
335 */
336 gs_point_transform(0.0, 0.0, pmat, &dev_pat_origin);
337 /*
338 * Determine our starting point. We start with a postion that puts the
339 * pattern below and to the left of the page (in pattern space) and scan
340 * until the pattern is above and right of the page.
341 */
342 ixpat = (int) floor((pat_page.p.x - pinst->template.BBox.q.x) / xstep);
343 iystart = (int) floor((pat_page.p.y - pinst->template.BBox.q.y) / ystep);
344
345 /* Now do the scan */
346 for (; ; ixpat++) {
347 xpat = ixpat * xstep;
348 for (iypat = iystart; ; iypat++) {
349 ypat = iypat * ystep;
350 /*
351 * Calculate the shift in the pattern's location.
352 */
353 gs_point_transform(xpat, ypat, pmat, &dev_step);
354 xdev = dev_step.x - dev_pat_origin.x;
355 ydev = dev_step.y - dev_pat_origin.y;
356 /*
357 * Check if the pattern bounding box intersects the page.
358 */
359 xlower = (xdev + pbbox->p.x > 0) ? pbbox->p.x : -xdev;
360 xupper = (xdev + pbbox->q.x < width) ? pbbox->q.x : -xdev + width;
361 ylower = (ydev + pbbox->p.y > 0) ? pbbox->p.y : -ydev;
362 yupper = (ydev + pbbox->q.y < height) ? pbbox->q.y : -ydev + height;
363 if (xlower < xupper && ylower < yupper) {
364 /*
365 * The pattern intersects the page. Expand required area if
366 * needed.
367 */
368 if (xlower < xmin)
369 xmin = xlower;
370 if (xupper > xmax)
371 xmax = xupper;
372 if (ylower < ymin)
373 ymin = ylower;
374 if (yupper > ymax)
375 ymax = yupper;
376 }
377 if (ypat > pat_page.q.y - pinst->template.BBox.p.y)
378 break;
379 }
380 if (xpat > pat_page.q.x - pinst->template.BBox.p.x)
381 break;
382 }
383 /* Update the bounding box. */
384 if (xmin < xmax && ymin < ymax) {
385 pbbox->p.x = xmin;
386 pbbox->q.x = xmax;
387 pbbox->p.y = ymin;
388 pbbox->q.y = ymax;
389 } else {
390 /* The pattern is never on the page. Set bbox = 1, 1 */
391 pbbox->p.x = pbbox->p.y = 0;
392 pbbox->q.x = pbbox->q.y = 1;
393 }
394 return 0;
395 }
396
397 /* Compute the stepping matrix and device space instance bounding box */
398 /* from the step values and the saved matrix. */
399 private int
compute_inst_matrix(gs_pattern1_instance_t * pinst,const gs_state * saved,gs_rect * pbbox,int width,int height)400 compute_inst_matrix(gs_pattern1_instance_t * pinst, const gs_state * saved,
401 gs_rect * pbbox, int width, int height)
402 {
403 double xx = pinst->template.XStep * saved->ctm.xx;
404 double xy = pinst->template.XStep * saved->ctm.xy;
405 double yx = pinst->template.YStep * saved->ctm.yx;
406 double yy = pinst->template.YStep * saved->ctm.yy;
407 int code;
408
409 /* Adjust the stepping matrix so all coefficients are >= 0. */
410 if (xx == 0 || yy == 0) { /* We know that both xy and yx are non-zero. */
411 double temp;
412
413 temp = xx, xx = yx, yx = temp;
414 temp = xy, xy = yy, yy = temp;
415 }
416 if (xx < 0)
417 xx = -xx, xy = -xy;
418 if (yy < 0)
419 yx = -yx, yy = -yy;
420 /* Now xx > 0, yy > 0. */
421 pinst->step_matrix.xx = xx;
422 pinst->step_matrix.xy = xy;
423 pinst->step_matrix.yx = yx;
424 pinst->step_matrix.yy = yy;
425 pinst->step_matrix.tx = saved->ctm.tx;
426 pinst->step_matrix.ty = saved->ctm.ty;
427 code = gs_bbox_transform(&pinst->template.BBox, &ctm_only(saved), pbbox);
428 /*
429 * Some applications produce patterns that are larger than the page.
430 * If the bounding box for the pattern is larger than the page. clamp
431 * the pattern to the page size.
432 */
433 if (code >= 0 &&
434 (pbbox->q.x - pbbox->p.x > width || pbbox->q.y - pbbox->p.y > height))
435 code = clamp_pattern_bbox(pinst, pbbox, width,
436 height, &ctm_only(saved));
437
438 return code;
439 }
440
441 /* Test whether a PatternType 1 pattern uses a base space. */
442 private bool
gs_pattern1_uses_base_space(const gs_pattern_template_t * ptemp)443 gs_pattern1_uses_base_space(const gs_pattern_template_t *ptemp)
444 {
445 return ((const gs_pattern1_template_t *)ptemp)->PaintType == 2;
446 }
447
448 /* getpattern for PatternType 1 */
449 /* This is only intended for the benefit of pattern PaintProcs. */
450 private const gs_pattern_template_t *
gs_pattern1_get_pattern(const gs_pattern_instance_t * pinst)451 gs_pattern1_get_pattern(const gs_pattern_instance_t *pinst)
452 {
453 return (const gs_pattern_template_t *)
454 &((const gs_pattern1_instance_t *)pinst)->template;
455 }
456
457 /*
458 * Perform actions required at setcolor time. This procedure resets the
459 * overprint information (almost) as required by the pattern. The logic
460 * behind this operation is a bit convoluted:
461 *
462 * 1. Both PatternType 1 and 2 "colors" occur within the pattern color
463 * space.
464 *
465 * 2. Nominally, the set of drawn components is a property of the color
466 * space, and is set at the time setcolorspace is called. This is
467 * not the case for patterns, so overprint information must be set
468 * at setcolor time for them.
469 *
470 * 3. PatternType 2 color spaces incorporate their own color space, so
471 * the set of drawn components is determined by that color space.
472 * For PatternType 1 color spaces, the PaintType determines the
473 * appropriate color space to use. If PaintType is 2 (uncolored),
474 * the pattern makes use of the base color space of the current
475 * pattern color space, so overprint is set as appropriate for
476 * that color space.
477 *
478 * 4. For PatternType 1 color spaces with PaintType 1 (colored), the
479 * appropriate color space to use is determined by the pattern's
480 * PaintProc. This cannot be handled by the current graphic
481 * library mechanism, because color space information is lost when
482 * the pattern tile is cached (and the pattern tile is essentially
483 * always cached). We punt in this case and list all components
484 * as drawn components. (This feature could be support by retaining
485 * per-component pattern masks, but complete re-design of the
486 * pattern mechanism is probably more appropriate.)
487 *
488 * 5. Once overprint information has been set for a particular color,
489 * it must be reset to the proper value when that color is no
490 * longer in use. "Normal" (non-pattern) colors do not have a
491 * "set_color" action, both for performance and logical reasons.
492 * This does not, however, cause significant difficulty, as the
493 * change in color space required to set a normal color will
494 * reset the overprint information as required.
495 */
496 private int
gs_pattern1_set_color(const gs_client_color * pcc,gs_state * pgs)497 gs_pattern1_set_color(const gs_client_color * pcc, gs_state * pgs)
498 {
499 gs_pattern1_instance_t * pinst = (gs_pattern1_instance_t *)pcc->pattern;
500 gs_pattern1_template_t * ptmplt = &pinst->template;
501
502 if (ptmplt->PaintType == 2) {
503 const gs_color_space * pcs = pgs->color_space;
504
505 pcs = (const gs_color_space *)&(pcs->params.pattern.base_space);
506 return pcs->type->set_overprint(pcs, pgs);
507 } else {
508 gs_overprint_params_t params;
509
510 params.retain_any_comps = false;
511 pgs->effective_overprint_mode = 0;
512 return gs_state_update_overprint(pgs, ¶ms);
513 }
514 }
515
516
517 const gs_pattern1_template_t *
gs_getpattern(const gs_client_color * pcc)518 gs_getpattern(const gs_client_color * pcc)
519 {
520 const gs_pattern_instance_t *pinst = pcc->pattern;
521
522 return (pinst == 0 || pinst->type != &gs_pattern1_type ? 0 :
523 &((const gs_pattern1_instance_t *)pinst)->template);
524 }
525
526 /*
527 * Code for generating patterns from bitmaps and pixmaps.
528 */
529
530 /*
531 * The following structures are realized here only because this is the
532 * first location in which they were needed. Otherwise, there is nothing
533 * about them that is specific to patterns.
534 */
535 public_st_gs_bitmap();
536 public_st_gs_tile_bitmap();
537 public_st_gs_depth_bitmap();
538 public_st_gs_tile_depth_bitmap();
539 public_st_gx_strip_bitmap();
540
541 /*
542 * Structure for holding a gs_depth_bitmap and the corresponding depth and
543 * colorspace information.
544 *
545 * The free_proc pointer is needed to hold the original value of the pattern
546 * instance free structure. This pointer in the pattern instance will be
547 * overwritten with free_pixmap_pattern, which will free the pixmap info
548 * structure when it is freed.
549 */
550 typedef struct pixmap_info_s {
551 gs_depth_bitmap bitmap; /* must be first */
552 const gs_color_space *pcspace;
553 uint white_index;
554 void (*free_proc)(gs_memory_t *, void *, client_name_t);
555 } pixmap_info;
556
557 gs_private_st_suffix_add1(st_pixmap_info,
558 pixmap_info,
559 "pixmap info. struct",
560 pixmap_enum_ptr,
561 pixmap_reloc_ptr,
562 st_gs_depth_bitmap,
563 pcspace
564 );
565
566 #define st_pixmap_info_max_ptrs (1 + st_tile_bitmap_max_ptrs)
567
568 /*
569 * Free routine for pattern instances created from pixmaps. This overwrites
570 * the free procedure originally stored in the pattern instance, and stores
571 * the pointer to that procedure in the pixmap_info structure. This procedure
572 * will call the original procedure, then free the pixmap_info structure.
573 *
574 * Note that this routine does NOT release the data in the original pixmap;
575 * that remains the responsibility of the client.
576 */
577 private void
free_pixmap_pattern(gs_memory_t * pmem,void * pvpinst,client_name_t cname)578 free_pixmap_pattern(
579 gs_memory_t * pmem,
580 void * pvpinst,
581 client_name_t cname
582 )
583 {
584 gs_pattern1_instance_t *pinst = (gs_pattern1_instance_t *)pvpinst;
585 pixmap_info *ppmap = pinst->template.client_data;
586
587 ppmap->free_proc(pmem, pvpinst, cname);
588 gs_free_object(pmem, ppmap, cname);
589 }
590
591 /*
592 * PaintProcs for bitmap and pixmap patterns.
593 */
594 private int bitmap_paint(gs_image_enum * pen, gs_data_image_t * pim,
595 const gs_depth_bitmap * pbitmap, gs_state * pgs);
596 private int
mask_PaintProc(const gs_client_color * pcolor,gs_state * pgs)597 mask_PaintProc(const gs_client_color * pcolor, gs_state * pgs)
598 {
599 const pixmap_info *ppmap = gs_getpattern(pcolor)->client_data;
600 const gs_depth_bitmap *pbitmap = &(ppmap->bitmap);
601 gs_image_enum *pen =
602 gs_image_enum_alloc(gs_state_memory(pgs), "mask_PaintProc");
603 gs_image1_t mask;
604
605 if (pen == 0)
606 return_error(gs_error_VMerror);
607 gs_image_t_init_mask(&mask, true);
608 mask.Width = pbitmap->size.x;
609 mask.Height = pbitmap->size.y;
610 gs_image_init(pen, &mask, false, pgs);
611 return bitmap_paint(pen, (gs_data_image_t *) & mask, pbitmap, pgs);
612 }
613 private int
image_PaintProc(const gs_client_color * pcolor,gs_state * pgs)614 image_PaintProc(const gs_client_color * pcolor, gs_state * pgs)
615 {
616 const pixmap_info *ppmap = gs_getpattern(pcolor)->client_data;
617 const gs_depth_bitmap *pbitmap = &(ppmap->bitmap);
618 gs_image_enum *pen =
619 gs_image_enum_alloc(gs_state_memory(pgs), "image_PaintProc");
620 gs_color_space cs;
621 const gs_color_space *pcspace;
622 gx_image_enum_common_t *pie;
623 /*
624 * If the image is transparent then we want to do image type4 processing.
625 * Otherwise we want to use image type 1 processing.
626 */
627 int transparent = ppmap->white_index < (1 << (pbitmap->num_comps * pbitmap->pix_depth));
628
629 /*
630 * Note: gs_image1_t and gs_image4_t sre nearly identical structure
631 * definitions. From our point of view, the only significant difference
632 * is MaskColor in gs_image4_t. The fields are generally loaded using
633 * the gs_image1_t version of the union and then used for either type
634 * of image processing.
635 */
636 union {
637 gs_image1_t i1;
638 gs_image4_t i4;
639 } image;
640 int code;
641
642 if (pen == 0)
643 return_error(gs_error_VMerror);
644
645 if (ppmap->pcspace == 0) {
646 gs_cspace_init_DeviceGray(pgs->memory, &cs);
647 pcspace = &cs;
648 } else
649 pcspace = ppmap->pcspace;
650 gs_gsave(pgs);
651 gs_setcolorspace(pgs, pcspace);
652 if (transparent)
653 gs_image4_t_init( (gs_image4_t *) &image, pcspace);
654 else
655 gs_image_t_init_adjust( (gs_image_t *) &image, pcspace, 0);
656 image.i1.Width = pbitmap->size.x;
657 image.i1.Height = pbitmap->size.y;
658 if (transparent) {
659 image.i4.MaskColor_is_range = false;
660 image.i4.MaskColor[0] = ppmap->white_index;
661 }
662 image.i1.Decode[0] = 0.0;
663 image.i1.Decode[1] = (float)((1 << pbitmap->pix_depth) - 1);
664 image.i1.BitsPerComponent = pbitmap->pix_depth;
665 /* backwards compatibility */
666 if (ppmap->pcspace == 0) {
667 image.i1.Decode[0] = 1.0;
668 image.i1.Decode[1] = 0.0;
669 }
670
671 if ( (code = gs_image_begin_typed( (const gs_image_common_t *)&image,
672 pgs,
673 false,
674 &pie )) >= 0 &&
675 (code = gs_image_enum_init( pen,
676 pie,
677 (gs_data_image_t *)&image,
678 pgs )) >= 0 )
679 code = bitmap_paint(pen, (gs_data_image_t *) & image, pbitmap, pgs);
680 gs_grestore(pgs);
681 return code;
682 }
683 /* Finish painting any kind of bitmap pattern. */
684 private int
bitmap_paint(gs_image_enum * pen,gs_data_image_t * pim,const gs_depth_bitmap * pbitmap,gs_state * pgs)685 bitmap_paint(gs_image_enum * pen, gs_data_image_t * pim,
686 const gs_depth_bitmap * pbitmap, gs_state * pgs)
687 {
688 uint raster = pbitmap->raster;
689 uint nbytes = (pim->Width * pbitmap->pix_depth + 7) >> 3;
690 uint used;
691 const byte *dp = pbitmap->data;
692 int n;
693 int code = 0, code1;
694
695 if (nbytes == raster)
696 code = gs_image_next(pen, dp, nbytes * pim->Height, &used);
697 else
698 for (n = pim->Height; n > 0 && code >= 0; dp += raster, --n)
699 code = gs_image_next(pen, dp, nbytes, &used);
700 code1 = gs_image_cleanup_and_free_enum(pen);
701 if (code >= 0 && code1 < 0)
702 code = code1;
703 return code;
704 }
705
706 /*
707 * Make a pattern from a bitmap or pixmap. The pattern may be colored or
708 * uncolored, as determined by the mask operand. This code is intended
709 * primarily for use by PCL.
710 *
711 * See the comment prior to the declaration of this function in gscolor2.h
712 * for further information.
713 */
714 int
gs_makepixmappattern(gs_client_color * pcc,const gs_depth_bitmap * pbitmap,bool mask,const gs_matrix * pmat,long id,const gs_color_space * pcspace,uint white_index,gs_state * pgs,gs_memory_t * mem)715 gs_makepixmappattern(
716 gs_client_color * pcc,
717 const gs_depth_bitmap * pbitmap,
718 bool mask,
719 const gs_matrix * pmat,
720 long id,
721 const gs_color_space * pcspace,
722 uint white_index,
723 gs_state * pgs,
724 gs_memory_t * mem
725 )
726 {
727
728 gs_pattern1_template_t pat;
729 pixmap_info *ppmap;
730 gs_matrix mat, smat;
731 int code;
732
733 /* check that the data is legitimate */
734 if ((mask) || (pcspace == 0)) {
735 if (pbitmap->pix_depth != 1)
736 return_error(gs_error_rangecheck);
737 pcspace = 0;
738 } else if (gs_color_space_get_index(pcspace) != gs_color_space_index_Indexed)
739 return_error(gs_error_rangecheck);
740 if (pbitmap->num_comps != 1)
741 return_error(gs_error_rangecheck);
742
743 /* allocate and initialize a pixmap_info structure for the paint proc */
744 if (mem == 0)
745 mem = gs_state_memory(pgs);
746 ppmap = gs_alloc_struct(mem,
747 pixmap_info,
748 &st_pixmap_info,
749 "makepximappattern"
750 );
751 if (ppmap == 0)
752 return_error(gs_error_VMerror);
753 ppmap->bitmap = *pbitmap;
754 ppmap->pcspace = pcspace;
755 ppmap->white_index = white_index;
756
757 /* set up the client pattern structure */
758 gs_pattern1_init(&pat);
759 uid_set_UniqueID(&pat.uid, (id == no_UniqueID) ? gs_next_ids(mem, 1) : id);
760 pat.PaintType = (mask ? 2 : 1);
761 pat.TilingType = 1;
762 pat.BBox.p.x = 0;
763 pat.BBox.p.y = 0;
764 pat.BBox.q.x = pbitmap->size.x;
765 pat.BBox.q.y = pbitmap->size.y;
766 pat.XStep = (float)pbitmap->size.x;
767 pat.YStep = (float)pbitmap->size.y;
768 pat.PaintProc = (mask ? mask_PaintProc : image_PaintProc);
769 pat.client_data = ppmap;
770
771 /* set the ctm to be the identity */
772 gs_currentmatrix(pgs, &smat);
773 gs_make_identity(&mat);
774 gs_setmatrix(pgs, &mat);
775
776 /* build the pattern, restore the previous matrix */
777 if (pmat == NULL)
778 pmat = &mat;
779 if ((code = gs_makepattern(pcc, &pat, pmat, pgs, mem)) != 0)
780 gs_free_object(mem, ppmap, "makebitmappattern_xform");
781 else {
782 /*
783 * If this is not a masked pattern and if the white pixel index
784 * is outside of the representable range, we don't need to go to
785 * the trouble of accumulating a mask that will just be all 1s.
786 */
787 gs_pattern1_instance_t *pinst =
788 (gs_pattern1_instance_t *)pcc->pattern;
789
790 if (!mask && (white_index >= (1 << pbitmap->pix_depth)))
791 pinst->uses_mask = false;
792
793 /* overwrite the free procedure for the pattern instance */
794 ppmap->free_proc = pinst->rc.free;
795 pinst->rc.free = free_pixmap_pattern;
796
797 /*
798 * Since the PaintProcs don't reference the saved color space or
799 * color, clear these so that there isn't an extra retained
800 * reference to the Pattern object.
801 */
802 gs_setgray(pinst->saved, 0.0);
803
804 }
805 gs_setmatrix(pgs, &smat);
806 return code;
807 }
808
809 /*
810 * Backwards compatibility.
811 */
812 int
gs_makebitmappattern_xform(gs_client_color * pcc,const gx_tile_bitmap * ptile,bool mask,const gs_matrix * pmat,long id,gs_state * pgs,gs_memory_t * mem)813 gs_makebitmappattern_xform(
814 gs_client_color * pcc,
815 const gx_tile_bitmap * ptile,
816 bool mask,
817 const gs_matrix * pmat,
818 long id,
819 gs_state * pgs,
820 gs_memory_t * mem
821 )
822 {
823 gs_depth_bitmap bitmap;
824
825 /* build the bitmap the size of one repetition */
826 bitmap.data = ptile->data;
827 bitmap.raster = ptile->raster;
828 bitmap.size.x = ptile->rep_width;
829 bitmap.size.y = ptile->rep_height;
830 bitmap.id = ptile->id; /* shouldn't matter */
831 bitmap.pix_depth = 1;
832 bitmap.num_comps = 1;
833
834 return gs_makepixmappattern(pcc, &bitmap, mask, pmat, id, 0, 0, pgs, mem);
835 }
836
837
838 /* ------ Color space implementation ------ */
839
840 /*
841 * Defined the Pattern device color types. We need a masked analogue of
842 * each of the non-pattern types, to handle uncolored patterns. We use
843 * 'masked_fill_rect' instead of 'masked_fill_rectangle' in order to limit
844 * identifier lengths to 32 characters.
845 */
846 private dev_color_proc_get_dev_halftone(gx_dc_pattern_get_dev_halftone);
847 private dev_color_proc_load(gx_dc_pattern_load);
848 /*dev_color_proc_fill_rectangle(gx_dc_pattern_fill_rectangle); *//*gxp1fill.h */
849 private dev_color_proc_equal(gx_dc_pattern_equal);
850 private dev_color_proc_load(gx_dc_pure_masked_load);
851
852 private dev_color_proc_get_dev_halftone(gx_dc_pure_masked_get_dev_halftone);
853 /*dev_color_proc_fill_rectangle(gx_dc_pure_masked_fill_rect); *//*gxp1fill.h */
854 private dev_color_proc_equal(gx_dc_pure_masked_equal);
855 private dev_color_proc_load(gx_dc_binary_masked_load);
856
857 private dev_color_proc_get_dev_halftone(gx_dc_binary_masked_get_dev_halftone);
858 /*dev_color_proc_fill_rectangle(gx_dc_binary_masked_fill_rect); *//*gxp1fill.h */
859 private dev_color_proc_equal(gx_dc_binary_masked_equal);
860 private dev_color_proc_load(gx_dc_colored_masked_load);
861
862 private dev_color_proc_get_dev_halftone(gx_dc_colored_masked_get_dev_halftone);
863 /*dev_color_proc_fill_rectangle(gx_dc_colored_masked_fill_rect); *//*gxp1fill.h */
864 private dev_color_proc_equal(gx_dc_colored_masked_equal);
865
866 /* The device color types are exported for gxpcmap.c. */
867 gs_private_st_composite(st_dc_pattern, gx_device_color, "dc_pattern",
868 dc_pattern_enum_ptrs, dc_pattern_reloc_ptrs);
869 const gx_device_color_type_t gx_dc_pattern = {
870 &st_dc_pattern,
871 gx_dc_pattern_save_dc, gx_dc_pattern_get_dev_halftone,
872 gx_dc_ht_get_phase,
873 gx_dc_pattern_load, gx_dc_pattern_fill_rectangle,
874 gx_dc_default_fill_masked, gx_dc_pattern_equal,
875 gx_dc_pattern_write, gx_dc_pattern_read,
876 gx_dc_pattern_get_nonzero_comps
877 };
878
879 extern_st(st_dc_ht_binary);
880 gs_private_st_composite(st_dc_pure_masked, gx_device_color, "dc_pure_masked",
881 dc_masked_enum_ptrs, dc_masked_reloc_ptrs);
882 const gx_device_color_type_t gx_dc_pure_masked = {
883 &st_dc_pure_masked,
884 gx_dc_pattern_save_dc, gx_dc_pure_masked_get_dev_halftone,
885 gx_dc_no_get_phase,
886 gx_dc_pure_masked_load, gx_dc_pure_masked_fill_rect,
887 gx_dc_default_fill_masked, gx_dc_pure_masked_equal,
888 gx_dc_pattern_write, gx_dc_pattern_read,
889 gx_dc_pure_get_nonzero_comps
890 };
891
892 gs_private_st_composite(st_dc_binary_masked, gx_device_color,
893 "dc_binary_masked", dc_binary_masked_enum_ptrs,
894 dc_binary_masked_reloc_ptrs);
895 const gx_device_color_type_t gx_dc_binary_masked = {
896 &st_dc_binary_masked,
897 gx_dc_pattern_save_dc, gx_dc_binary_masked_get_dev_halftone,
898 gx_dc_ht_get_phase,
899 gx_dc_binary_masked_load, gx_dc_binary_masked_fill_rect,
900 gx_dc_default_fill_masked, gx_dc_binary_masked_equal,
901 gx_dc_pattern_write, gx_dc_pattern_read,
902 gx_dc_ht_binary_get_nonzero_comps
903 };
904
905 gs_private_st_composite_only(st_dc_colored_masked, gx_device_color,
906 "dc_colored_masked",
907 dc_masked_enum_ptrs, dc_masked_reloc_ptrs);
908 const gx_device_color_type_t gx_dc_colored_masked = {
909 &st_dc_colored_masked,
910 gx_dc_pattern_save_dc, gx_dc_colored_masked_get_dev_halftone,
911 gx_dc_ht_get_phase,
912 gx_dc_colored_masked_load, gx_dc_colored_masked_fill_rect,
913 gx_dc_default_fill_masked, gx_dc_colored_masked_equal,
914 gx_dc_pattern_write, gx_dc_pattern_read,
915 gx_dc_ht_colored_get_nonzero_comps
916 };
917
918 #undef gx_dc_type_pattern
919 const gx_device_color_type_t *const gx_dc_type_pattern = &gx_dc_pattern;
920 #define gx_dc_type_pattern (&gx_dc_pattern)
921
922 /* GC procedures */
923 private
ENUM_PTRS_WITH(dc_pattern_enum_ptrs,gx_device_color * cptr)924 ENUM_PTRS_WITH(dc_pattern_enum_ptrs, gx_device_color *cptr)
925 {
926 return ENUM_USING(st_dc_pure_masked, vptr, size, index - 1);
927 }
928 case 0:
929 {
930 gx_color_tile *tile = cptr->colors.pattern.p_tile;
931
932 ENUM_RETURN((tile == 0 ? tile : tile - tile->index));
933 }
934 ENUM_PTRS_END
RELOC_PTRS_WITH(dc_pattern_reloc_ptrs,gx_device_color * cptr)935 private RELOC_PTRS_WITH(dc_pattern_reloc_ptrs, gx_device_color *cptr)
936 {
937 gx_color_tile *tile = cptr->colors.pattern.p_tile;
938
939 if (tile != 0) {
940 uint index = tile->index;
941
942 RELOC_TYPED_OFFSET_PTR(gx_device_color, colors.pattern.p_tile, index);
943 }
944 RELOC_USING(st_dc_pure_masked, vptr, size);
945 }
946 RELOC_PTRS_END
947 private ENUM_PTRS_WITH(dc_masked_enum_ptrs, gx_device_color *cptr)
948 ENUM_SUPER(gx_device_color, st_client_color, ccolor, 1);
949 case 0:
950 {
951 gx_color_tile *mask = cptr->mask.m_tile;
952
953 ENUM_RETURN((mask == 0 ? mask : mask - mask->index));
954 }
955 ENUM_PTRS_END
RELOC_PTRS_WITH(dc_masked_reloc_ptrs,gx_device_color * cptr)956 private RELOC_PTRS_WITH(dc_masked_reloc_ptrs, gx_device_color *cptr)
957 {
958 gx_color_tile *mask = cptr->mask.m_tile;
959
960 RELOC_SUPER(gx_device_color, st_client_color, ccolor);
961 if (mask != 0) {
962 uint index = mask->index;
963
964 RELOC_TYPED_OFFSET_PTR(gx_device_color, mask.m_tile, index);
965 }
966 }
967 RELOC_PTRS_END
ENUM_PTRS_BEGIN(dc_binary_masked_enum_ptrs)968 private ENUM_PTRS_BEGIN(dc_binary_masked_enum_ptrs)
969 {
970 return ENUM_USING(st_dc_ht_binary, vptr, size, index - 2);
971 }
972 case 0:
973 case 1:
974 return ENUM_USING(st_dc_pure_masked, vptr, size, index);
975 ENUM_PTRS_END
RELOC_PTRS_BEGIN(dc_binary_masked_reloc_ptrs)976 private RELOC_PTRS_BEGIN(dc_binary_masked_reloc_ptrs)
977 {
978 RELOC_USING(st_dc_pure_masked, vptr, size);
979 RELOC_USING(st_dc_ht_binary, vptr, size);
980 }
981 RELOC_PTRS_END
982
983
984 /*
985 * Currently patterns cannot be passed through the command list,
986 * however vector devices need to save a color for comparing
987 * it with another color, which appears later.
988 * We provide a minimal support, which is necessary
989 * for the current implementation of pdfwrite.
990 * It is not sufficient for restoring the pattern from the saved color.
991 */
992 void
gx_dc_pattern_save_dc(const gx_device_color * pdevc,gx_device_color_saved * psdc)993 gx_dc_pattern_save_dc(
994 const gx_device_color * pdevc,
995 gx_device_color_saved * psdc )
996 {
997 psdc->type = pdevc->type;
998 if (pdevc->ccolor_valid) {
999 psdc->colors.pattern.id = pdevc->ccolor.pattern->pattern_id;
1000 psdc->colors.pattern.phase = pdevc->phase;
1001 } {
1002 /* The client color has been changed to a non-pattern color,
1003 but device color has not been created yet.
1004 */
1005 psdc->colors.pattern.id = gs_no_id;
1006 psdc->colors.pattern.phase.x = psdc->colors.pattern.phase.y = 0;
1007 }
1008 }
1009
1010 /*
1011 * Colored Type 1 patterns cannot provide a halftone, as multiple
1012 * halftones may be used by the PaintProc procedure. Hence, we can only
1013 * hope this is a contone device.
1014 */
1015 private const gx_device_halftone *
gx_dc_pattern_get_dev_halftone(const gx_device_color * pdevc)1016 gx_dc_pattern_get_dev_halftone(const gx_device_color * pdevc)
1017 {
1018 return 0;
1019 }
1020
1021 /*
1022 * Uncolored Type 1 halftones make use of the halftone impplied by their
1023 * base color. Ideally this would be returned via an inhereted method,
1024 * but the device color structure does not support such an arrangement.
1025 */
1026 private const gx_device_halftone *
gx_dc_pure_masked_get_dev_halftone(const gx_device_color * pdevc)1027 gx_dc_pure_masked_get_dev_halftone(const gx_device_color * pdevc)
1028 {
1029 return 0;
1030 }
1031
1032 private const gx_device_halftone *
gx_dc_binary_masked_get_dev_halftone(const gx_device_color * pdevc)1033 gx_dc_binary_masked_get_dev_halftone(const gx_device_color * pdevc)
1034 {
1035 return pdevc->colors.binary.b_ht;
1036 }
1037
1038 private const gx_device_halftone *
gx_dc_colored_masked_get_dev_halftone(const gx_device_color * pdevc)1039 gx_dc_colored_masked_get_dev_halftone(const gx_device_color * pdevc)
1040 {
1041 return pdevc->colors.colored.c_ht;
1042 }
1043
1044
1045 /* Macros for pattern loading */
1046 #define FINISH_PATTERN_LOAD\
1047 while ( !gx_pattern_cache_lookup(pdevc, pis, dev, select) )\
1048 { code = gx_pattern_load(pdevc, pis, dev, select);\
1049 if ( code < 0 ) break;\
1050 }\
1051 return code;
1052
1053 /* Ensure that a colored Pattern is loaded in the cache. */
1054 private int
gx_dc_pattern_load(gx_device_color * pdevc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)1055 gx_dc_pattern_load(gx_device_color * pdevc, const gs_imager_state * pis,
1056 gx_device * dev, gs_color_select_t select)
1057 {
1058 int code = 0;
1059
1060 FINISH_PATTERN_LOAD
1061 }
1062 /* Ensure that an uncolored Pattern is loaded in the cache. */
1063 private int
gx_dc_pure_masked_load(gx_device_color * pdevc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)1064 gx_dc_pure_masked_load(gx_device_color * pdevc, const gs_imager_state * pis,
1065 gx_device * dev, gs_color_select_t select)
1066 {
1067 int code = (*gx_dc_type_data_pure.load) (pdevc, pis, dev, select);
1068
1069 if (code < 0)
1070 return code;
1071 FINISH_PATTERN_LOAD
1072 }
1073 private int
gx_dc_binary_masked_load(gx_device_color * pdevc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)1074 gx_dc_binary_masked_load(gx_device_color * pdevc, const gs_imager_state * pis,
1075 gx_device * dev, gs_color_select_t select)
1076 {
1077 int code = (*gx_dc_type_data_ht_binary.load) (pdevc, pis, dev, select);
1078
1079 if (code < 0)
1080 return code;
1081 FINISH_PATTERN_LOAD
1082 }
1083 private int
gx_dc_colored_masked_load(gx_device_color * pdevc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)1084 gx_dc_colored_masked_load(gx_device_color * pdevc, const gs_imager_state * pis,
1085 gx_device * dev, gs_color_select_t select)
1086 {
1087 int code = (*gx_dc_type_data_ht_colored.load) (pdevc, pis, dev, select);
1088
1089 if (code < 0)
1090 return code;
1091 FINISH_PATTERN_LOAD
1092 }
1093
1094 /* Look up a pattern color in the cache. */
1095 bool
gx_pattern_cache_lookup(gx_device_color * pdevc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)1096 gx_pattern_cache_lookup(gx_device_color * pdevc, const gs_imager_state * pis,
1097 gx_device * dev, gs_color_select_t select)
1098 {
1099 gx_pattern_cache *pcache = pis->pattern_cache;
1100 gx_bitmap_id id = pdevc->mask.id;
1101
1102 if (id == gx_no_bitmap_id) {
1103 color_set_null_pattern(pdevc);
1104 return true;
1105 }
1106 if (pcache != 0) {
1107 gx_color_tile *ctile = &pcache->tiles[id % pcache->num_tiles];
1108 bool internal_accum = true;
1109 if (pis->have_pattern_streams) {
1110 int code = dev_proc(dev, pattern_manage)(dev, id, NULL, pattern_manage__load);
1111 internal_accum = (code == 0);
1112 if (code < 0)
1113 return false;
1114 }
1115 if (ctile->id == id &&
1116 ctile->is_dummy == !internal_accum &&
1117 (pdevc->type != &gx_dc_pattern ||
1118 ctile->depth == dev->color_info.depth)
1119 ) {
1120 int px = pis->screen_phase[select].x;
1121 int py = pis->screen_phase[select].y;
1122
1123 if (pdevc->type == &gx_dc_pattern) { /* colored */
1124 pdevc->colors.pattern.p_tile = ctile;
1125 color_set_phase_mod(pdevc, px, py,
1126 ctile->tbits.rep_width,
1127 ctile->tbits.rep_height);
1128 }
1129 pdevc->mask.m_tile =
1130 (ctile->tmask.data == 0 ? (gx_color_tile *) 0 :
1131 ctile);
1132 pdevc->mask.m_phase.x = -px;
1133 pdevc->mask.m_phase.y = -py;
1134 return true;
1135 }
1136 }
1137 return false;
1138 }
1139
1140 #undef FINISH_PATTERN_LOAD
1141
1142 /* Compare two Pattern colors for equality. */
1143 private bool
gx_dc_pattern_equal(const gx_device_color * pdevc1,const gx_device_color * pdevc2)1144 gx_dc_pattern_equal(const gx_device_color * pdevc1,
1145 const gx_device_color * pdevc2)
1146 {
1147 return pdevc2->type == pdevc1->type &&
1148 pdevc1->phase.x == pdevc2->phase.x &&
1149 pdevc1->phase.y == pdevc2->phase.y &&
1150 pdevc1->mask.id == pdevc2->mask.id;
1151 }
1152
1153 /*
1154 * For shading and colored tiling patterns, it is not possible to say
1155 * which color components have non-zero values. The following routine
1156 * indicates this by just returning 1. The procedure is exported for
1157 * the benefit of gsptype2.c.
1158 */
1159 int
gx_dc_pattern_get_nonzero_comps(const gx_device_color * pdevc_ignored,const gx_device * dev_ignored,gx_color_index * pcomp_bits_ignored)1160 gx_dc_pattern_get_nonzero_comps(
1161 const gx_device_color * pdevc_ignored,
1162 const gx_device * dev_ignored,
1163 gx_color_index * pcomp_bits_ignored )
1164 {
1165 return 1;
1166 }
1167
1168
1169 private bool
gx_dc_pure_masked_equal(const gx_device_color * pdevc1,const gx_device_color * pdevc2)1170 gx_dc_pure_masked_equal(const gx_device_color * pdevc1,
1171 const gx_device_color * pdevc2)
1172 {
1173 return (*gx_dc_type_pure->equal) (pdevc1, pdevc2) &&
1174 pdevc1->mask.id == pdevc2->mask.id;
1175 }
1176 private bool
gx_dc_binary_masked_equal(const gx_device_color * pdevc1,const gx_device_color * pdevc2)1177 gx_dc_binary_masked_equal(const gx_device_color * pdevc1,
1178 const gx_device_color * pdevc2)
1179 {
1180 return (*gx_dc_type_ht_binary->equal) (pdevc1, pdevc2) &&
1181 pdevc1->mask.id == pdevc2->mask.id;
1182 }
1183 private bool
gx_dc_colored_masked_equal(const gx_device_color * pdevc1,const gx_device_color * pdevc2)1184 gx_dc_colored_masked_equal(const gx_device_color * pdevc1,
1185 const gx_device_color * pdevc2)
1186 {
1187 return (*gx_dc_type_ht_colored->equal) (pdevc1, pdevc2) &&
1188 pdevc1->mask.id == pdevc2->mask.id;
1189 }
1190
1191 /* currently, patterns cannot be passed through the command list */
1192 int
gx_dc_pattern_write(const gx_device_color * pdevc,const gx_device_color_saved * psdc,const gx_device * dev,byte * data,uint * psize)1193 gx_dc_pattern_write(
1194 const gx_device_color * pdevc,
1195 const gx_device_color_saved * psdc,
1196 const gx_device * dev,
1197 byte * data,
1198 uint * psize )
1199 {
1200 return_error(gs_error_unknownerror);
1201 }
1202
1203 int
gx_dc_pattern_read(gx_device_color * pdevc,const gs_imager_state * pis,const gx_device_color * prior_devc,const gx_device * dev,const byte * data,uint size,gs_memory_t * mem)1204 gx_dc_pattern_read(
1205 gx_device_color * pdevc,
1206 const gs_imager_state * pis,
1207 const gx_device_color * prior_devc,
1208 const gx_device * dev,
1209 const byte * data,
1210 uint size,
1211 gs_memory_t * mem )
1212 {
1213 return_error(gs_error_unknownerror);
1214 }
1215