123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688 |
- /* Copyright (C) 1993, 2000 Aladdin Enterprises. All rights reserved.
-
- This file is part of AFPL Ghostscript.
-
- AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
- distributor accepts any responsibility for the consequences of using it, or
- for whether it serves any particular purpose or works at all, unless he or
- she says so in writing. Refer to the Aladdin Free Public License (the
- "License") for full details.
-
- Every copy of AFPL Ghostscript must include a copy of the License, normally
- in a plain ASCII text file named PUBLIC. The License grants you the right
- to copy, modify and redistribute AFPL Ghostscript, but only under certain
- conditions described in the License. Among other things, the License
- requires that the copyright notice and this notice be preserved on all
- copies.
- */
- /*$Id: gxpcmap.c,v 1.3 2000/09/19 19:00:39 lpd Exp $ */
- /* Pattern color mapping for Ghostscript library */
- #include "math_.h"
- #include "memory_.h"
- #include "gx.h"
- #include "gserrors.h"
- #include "gsstruct.h"
- #include "gsutil.h" /* for gs_next_ids */
- #include "gxfixed.h"
- #include "gxmatrix.h"
- #include "gxcspace.h" /* for gscolor2.h */
- #include "gxcolor2.h"
- #include "gxdcolor.h"
- #include "gxdevice.h"
- #include "gxdevmem.h"
- #include "gxpcolor.h"
- #include "gzstate.h"
- /* Define the default size of the Pattern cache. */
- #define max_cached_patterns_LARGE 50
- #define max_pattern_bits_LARGE 100000
- #define max_cached_patterns_SMALL 5
- #define max_pattern_bits_SMALL 1000
- uint
- gx_pat_cache_default_tiles(void)
- {
- #if arch_small_memory
- return max_cached_patterns_SMALL;
- #else
- return (gs_debug_c('.') ? max_cached_patterns_SMALL :
- max_cached_patterns_LARGE);
- #endif
- }
- ulong
- gx_pat_cache_default_bits(void)
- {
- #if arch_small_memory
- return max_pattern_bits_SMALL;
- #else
- return (gs_debug_c('.') ? max_pattern_bits_SMALL :
- max_pattern_bits_LARGE);
- #endif
- }
- /* Define the structures for Pattern rendering and caching. */
- private_st_color_tile();
- private_st_color_tile_element();
- private_st_pattern_cache();
- private_st_device_pattern_accum();
- /* ------ Pattern rendering ------ */
- /* Device procedures */
- private dev_proc_open_device(pattern_accum_open);
- private dev_proc_close_device(pattern_accum_close);
- private dev_proc_fill_rectangle(pattern_accum_fill_rectangle);
- private dev_proc_copy_mono(pattern_accum_copy_mono);
- private dev_proc_copy_color(pattern_accum_copy_color);
- private dev_proc_get_bits_rectangle(pattern_accum_get_bits_rectangle);
- /* The device descriptor */
- private const gx_device_pattern_accum gs_pattern_accum_device =
- {std_device_std_body_open(gx_device_pattern_accum, 0,
- "pattern accumulator",
- 0, 0, 72, 72),
- {
- /* NOTE: all drawing procedures must be defaulted, not forwarded. */
- pattern_accum_open,
- NULL,
- NULL,
- NULL,
- pattern_accum_close,
- NULL,
- NULL,
- pattern_accum_fill_rectangle,
- gx_default_tile_rectangle,
- pattern_accum_copy_mono,
- pattern_accum_copy_color,
- NULL,
- gx_default_get_bits,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- gx_default_copy_alpha,
- NULL,
- gx_default_copy_rop,
- gx_default_fill_path,
- gx_default_stroke_path,
- gx_default_fill_mask,
- gx_default_fill_trapezoid,
- gx_default_fill_parallelogram,
- gx_default_fill_triangle,
- gx_default_draw_thin_line,
- gx_default_begin_image,
- gx_default_image_data,
- gx_default_end_image,
- gx_default_strip_tile_rectangle,
- gx_default_strip_copy_rop,
- gx_get_largest_clipping_box,
- gx_default_begin_typed_image,
- pattern_accum_get_bits_rectangle,
- NULL,
- NULL,
- NULL,
- gx_default_text_begin,
- gx_default_finish_copydevice
- },
- 0, /* target */
- 0, 0, 0, 0 /* bitmap_memory, bits, mask, instance */
- };
- /* Allocate a pattern accumulator, with an initial refct of 0. */
- gx_device_pattern_accum *
- gx_pattern_accum_alloc(gs_memory_t * mem, client_name_t cname)
- {
- gx_device_pattern_accum *adev =
- gs_alloc_struct(mem, gx_device_pattern_accum,
- &st_device_pattern_accum, cname);
- if (adev == 0)
- return 0;
- gx_device_init((gx_device *)adev,
- (const gx_device *)&gs_pattern_accum_device,
- mem, true);
- gx_device_forward_fill_in_procs((gx_device_forward *)adev);
- return adev;
- }
- /*
- * Initialize a pattern accumulator.
- * Client must already have set instance and bitmap_memory.
- *
- * Note that mask and bits accumulators are only created if necessary.
- */
- private int
- pattern_accum_open(gx_device * dev)
- {
- gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev;
- const gs_pattern1_instance_t *pinst = padev->instance;
- gs_memory_t *mem = padev->bitmap_memory;
- gx_device_memory *mask = 0;
- gx_device_memory *bits = 0;
- /*
- * The client should preset the target, because the device for which the
- * pattern is being rendered may not (in general, will not) be the same
- * as the one that was current when the pattern was instantiated.
- */
- gx_device *target =
- (padev->target == 0 ? gs_currentdevice(pinst->saved) :
- padev->target);
- int width = pinst->size.x;
- int height = pinst->size.y;
- int code = 0;
- bool mask_open = false;
- /*
- * C's bizarre coercion rules force us to copy HWResolution in pieces
- * rather than using a single assignment.
- */
- #define PDSET(dev)\
- ((dev)->width = width, (dev)->height = height,\
- /*(dev)->HWResolution = target->HWResolution*/\
- (dev)->HWResolution[0] = target->HWResolution[0],\
- (dev)->HWResolution[1] = target->HWResolution[1])
- PDSET(padev);
- padev->color_info = target->color_info;
- if (pinst->uses_mask) {
- mask = gs_alloc_struct( mem,
- gx_device_memory,
- &st_device_memory,
- "pattern_accum_open(mask)"
- );
- if (mask == 0)
- return_error(gs_error_VMerror);
- gs_make_mem_mono_device(mask, mem, 0);
- PDSET(mask);
- mask->bitmap_memory = mem;
- mask->base = 0;
- code = (*dev_proc(mask, open_device)) ((gx_device *) mask);
- if (code >= 0) {
- mask_open = true;
- memset(mask->base, 0, mask->raster * mask->height);
- }
- }
- if (code >= 0) {
- switch (pinst->template.PaintType) {
- case 2: /* uncolored */
- gx_device_set_target((gx_device_forward *)padev, target);
- break;
- case 1: /* colored */
- bits = gs_alloc_struct(mem, gx_device_memory,
- &st_device_memory,
- "pattern_accum_open(bits)");
- if (bits == 0)
- code = gs_note_error(gs_error_VMerror);
- else {
- gs_make_mem_device(bits,
- gdev_mem_device_for_bits(target->color_info.depth),
- mem, -1, target);
- PDSET(bits);
- #undef PDSET
- bits->color_info = target->color_info;
- bits->bitmap_memory = mem;
- code = (*dev_proc(bits, open_device)) ((gx_device *) bits);
- gx_device_set_target((gx_device_forward *)padev,
- (gx_device *)bits);
- }
- }
- }
- if (code < 0) {
- if (bits != 0)
- gs_free_object(mem, bits, "pattern_accum_open(bits)");
- if (mask != 0) {
- if (mask_open)
- (*dev_proc(mask, close_device)) ((gx_device *) mask);
- gs_free_object(mem, mask, "pattern_accum_open(mask)");
- }
- return code;
- }
- padev->mask = mask;
- padev->bits = bits;
- /* Retain the device, so it will survive anomalous grestores. */
- gx_device_retain(dev, true);
- return code;
- }
- /* Close an accumulator and free the bits. */
- private int
- pattern_accum_close(gx_device * dev)
- {
- gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev;
- gs_memory_t *mem = padev->bitmap_memory;
- /*
- * If bits != 0, it is the target of the device; reference counting
- * will close and free it.
- */
- gx_device_set_target((gx_device_forward *)padev, NULL);
- padev->bits = 0;
- if (padev->mask != 0) {
- (*dev_proc(padev->mask, close_device)) ((gx_device *) padev->mask);
- gs_free_object(mem, padev->mask, "pattern_accum_close(mask)");
- padev->mask = 0;
- }
- /* Un-retain the device now, so reference counting will free it. */
- gx_device_retain(dev, false);
- return 0;
- }
- /* Fill a rectangle */
- private int
- pattern_accum_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
- gx_color_index color)
- {
- gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev;
- if (padev->bits)
- (*dev_proc(padev->target, fill_rectangle))
- (padev->target, x, y, w, h, color);
- if (padev->mask)
- return (*dev_proc(padev->mask, fill_rectangle))
- ((gx_device *) padev->mask, x, y, w, h, (gx_color_index) 1);
- else
- return 0;
- }
- /* Copy a monochrome bitmap. */
- private int
- pattern_accum_copy_mono(gx_device * dev, const byte * data, int data_x,
- int raster, gx_bitmap_id id, int x, int y, int w, int h,
- gx_color_index color0, gx_color_index color1)
- {
- gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev;
- if (padev->bits)
- (*dev_proc(padev->target, copy_mono))
- (padev->target, data, data_x, raster, id, x, y, w, h,
- color0, color1);
- if (padev->mask) {
- if (color0 != gx_no_color_index)
- color0 = 1;
- if (color1 != gx_no_color_index)
- color1 = 1;
- if (color0 == 1 && color1 == 1)
- return (*dev_proc(padev->mask, fill_rectangle))
- ((gx_device *) padev->mask, x, y, w, h, (gx_color_index) 1);
- else
- return (*dev_proc(padev->mask, copy_mono))
- ((gx_device *) padev->mask, data, data_x, raster, id, x, y, w, h,
- color0, color1);
- } else
- return 0;
- }
- /* Copy a color bitmap. */
- private int
- pattern_accum_copy_color(gx_device * dev, const byte * data, int data_x,
- int raster, gx_bitmap_id id, int x, int y, int w, int h)
- {
- gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev;
- if (padev->bits)
- (*dev_proc(padev->target, copy_color))
- (padev->target, data, data_x, raster, id, x, y, w, h);
- if (padev->mask)
- return (*dev_proc(padev->mask, fill_rectangle))
- ((gx_device *) padev->mask, x, y, w, h, (gx_color_index) 1);
- else
- return 0;
- }
- /* Read back a rectangle of bits. */
- /****** SHOULD USE MASK TO DEFINE UNREAD AREA *****/
- private int
- pattern_accum_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
- gs_get_bits_params_t * params, gs_int_rect ** unread)
- {
- gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev;
- if (padev->bits)
- return (*dev_proc(padev->target, get_bits_rectangle))
- (padev->target, prect, params, unread);
- return_error(gs_error_Fatal); /* can't happen */
- }
- /* ------ Color space implementation ------ */
- /* Free all entries in a pattern cache. */
- private bool
- pattern_cache_choose_all(gx_color_tile * ctile, void *proc_data)
- {
- return true;
- }
- private void
- pattern_cache_free_all(gx_pattern_cache * pcache)
- {
- gx_pattern_cache_winnow(pcache, pattern_cache_choose_all, NULL);
- }
- /* Allocate a Pattern cache. */
- gx_pattern_cache *
- gx_pattern_alloc_cache(gs_memory_t * mem, uint num_tiles, ulong max_bits)
- {
- gx_pattern_cache *pcache =
- gs_alloc_struct(mem, gx_pattern_cache, &st_pattern_cache,
- "pattern_cache_alloc(struct)");
- gx_color_tile *tiles =
- gs_alloc_struct_array(mem, num_tiles, gx_color_tile,
- &st_color_tile_element,
- "pattern_cache_alloc(tiles)");
- uint i;
- if (pcache == 0 || tiles == 0) {
- gs_free_object(mem, tiles, "pattern_cache_alloc(tiles)");
- gs_free_object(mem, pcache, "pattern_cache_alloc(struct)");
- return 0;
- }
- pcache->memory = mem;
- pcache->tiles = tiles;
- pcache->num_tiles = num_tiles;
- pcache->tiles_used = 0;
- pcache->next = 0;
- pcache->bits_used = 0;
- pcache->max_bits = max_bits;
- pcache->free_all = pattern_cache_free_all;
- for (i = 0; i < num_tiles; tiles++, i++) {
- tiles->id = gx_no_bitmap_id;
- /* Clear the pointers to pacify the GC. */
- uid_set_invalid(&tiles->uid);
- tiles->tbits.data = 0;
- tiles->tmask.data = 0;
- tiles->index = i;
- }
- return pcache;
- }
- /* Ensure that an imager has a Pattern cache. */
- private int
- ensure_pattern_cache(gs_imager_state * pis)
- {
- if (pis->pattern_cache == 0) {
- gx_pattern_cache *pcache =
- gx_pattern_alloc_cache(pis->memory,
- gx_pat_cache_default_tiles(),
- gx_pat_cache_default_bits());
- if (pcache == 0)
- return_error(gs_error_VMerror);
- pis->pattern_cache = pcache;
- }
- return 0;
- }
- /* Get and set the Pattern cache in a gstate. */
- gx_pattern_cache *
- gstate_pattern_cache(gs_state * pgs)
- {
- return pgs->pattern_cache;
- }
- void
- gstate_set_pattern_cache(gs_state * pgs, gx_pattern_cache * pcache)
- {
- pgs->pattern_cache = pcache;
- }
- /* Free a Pattern cache entry. */
- private void
- gx_pattern_cache_free_entry(gx_pattern_cache * pcache, gx_color_tile * ctile)
- {
- if (ctile->id != gx_no_bitmap_id) {
- gs_memory_t *mem = pcache->memory;
- gx_device_memory mdev;
- /*
- * We must initialize the memory device properly, even though
- * we aren't using it for drawing.
- */
- gs_make_mem_mono_device(&mdev, mem, NULL);
- if (ctile->tmask.data != 0) {
- mdev.width = ctile->tmask.size.x;
- mdev.height = ctile->tmask.size.y;
- /*mdev.color_info.depth = 1;*/
- pcache->bits_used -= gdev_mem_bitmap_size(&mdev);
- gs_free_object(mem, ctile->tmask.data,
- "free_pattern_cache_entry(mask data)");
- ctile->tmask.data = 0; /* for GC */
- }
- if (ctile->tbits.data != 0) {
- mdev.width = ctile->tbits.size.x;
- mdev.height = ctile->tbits.size.y;
- mdev.color_info.depth = ctile->depth;
- pcache->bits_used -= gdev_mem_bitmap_size(&mdev);
- gs_free_object(mem, ctile->tbits.data,
- "free_pattern_cache_entry(bits data)");
- ctile->tbits.data = 0; /* for GC */
- }
- ctile->id = gx_no_bitmap_id;
- pcache->tiles_used--;
- }
- }
- /*
- * Add a Pattern cache entry. This is exported for the interpreter.
- * Note that this does not free any of the data in the accumulator
- * device, but it may zero out the bitmap_memory pointers to prevent
- * the accumulated bitmaps from being freed when the device is closed.
- */
- private void make_bitmap(P3(gx_strip_bitmap *, const gx_device_memory *, gx_bitmap_id));
- int
- gx_pattern_cache_add_entry(gs_imager_state * pis,
- gx_device_pattern_accum * padev, gx_color_tile ** pctile)
- {
- gx_device_memory *mbits = padev->bits;
- gx_device_memory *mmask = padev->mask;
- const gs_pattern1_instance_t *pinst = padev->instance;
- gx_pattern_cache *pcache;
- ulong used = 0;
- gx_bitmap_id id = pinst->id;
- gx_color_tile *ctile;
- int code = ensure_pattern_cache(pis);
- if (code < 0)
- return code;
- pcache = pis->pattern_cache;
- /*
- * Check whether the pattern completely fills its box.
- * If so, we can avoid the expensive masking operations
- * when using the pattern.
- */
- if (mmask != 0) {
- int y;
- for (y = 0; y < mmask->height; y++) {
- const byte *row = scan_line_base(mmask, y);
- int w;
- for (w = mmask->width; w > 8; w -= 8)
- if (*row++ != 0xff)
- goto keep;
- if ((*row | (0xff >> w)) != 0xff)
- goto keep;
- }
- /* We don't need a mask. */
- mmask = 0;
- keep:;
- }
- if (mbits != 0)
- used += gdev_mem_bitmap_size(mbits);
- if (mmask != 0)
- used += gdev_mem_bitmap_size(mmask);
- ctile = &pcache->tiles[id % pcache->num_tiles];
- gx_pattern_cache_free_entry(pcache, ctile);
- while (pcache->bits_used + used > pcache->max_bits &&
- pcache->bits_used != 0 /* allow 1 oversized entry (?) */
- ) {
- pcache->next = (pcache->next + 1) % pcache->num_tiles;
- gx_pattern_cache_free_entry(pcache, &pcache->tiles[pcache->next]);
- }
- ctile->id = id;
- ctile->depth = padev->color_info.depth;
- ctile->uid = pinst->template.uid;
- ctile->tiling_type = pinst->template.TilingType;
- ctile->step_matrix = pinst->step_matrix;
- ctile->bbox = pinst->bbox;
- ctile->is_simple = pinst->is_simple;
- if (mbits != 0) {
- make_bitmap(&ctile->tbits, mbits, gs_next_ids(1));
- mbits->bitmap_memory = 0; /* don't free the bits */
- } else
- ctile->tbits.data = 0;
- if (mmask != 0) {
- make_bitmap(&ctile->tmask, mmask, id);
- mmask->bitmap_memory = 0; /* don't free the bits */
- } else
- ctile->tmask.data = 0;
- pcache->bits_used += used;
- pcache->tiles_used++;
- *pctile = ctile;
- return 0;
- }
- private void
- make_bitmap(register gx_strip_bitmap * pbm, const gx_device_memory * mdev,
- gx_bitmap_id id)
- {
- pbm->data = mdev->base;
- pbm->raster = mdev->raster;
- pbm->rep_width = pbm->size.x = mdev->width;
- pbm->rep_height = pbm->size.y = mdev->height;
- pbm->id = id;
- pbm->rep_shift = pbm->shift = 0;
- }
- /* Purge selected entries from the pattern cache. */
- void
- gx_pattern_cache_winnow(gx_pattern_cache * pcache,
- bool(*proc) (P2(gx_color_tile * ctile, void *proc_data)), void *proc_data)
- {
- uint i;
- if (pcache == 0) /* no cache created yet */
- return;
- for (i = 0; i < pcache->num_tiles; ++i) {
- gx_color_tile *ctile = &pcache->tiles[i];
- if (ctile->id != gx_no_bitmap_id && (*proc) (ctile, proc_data))
- gx_pattern_cache_free_entry(pcache, ctile);
- }
- }
- /* Reload a (non-null) Pattern color into the cache. */
- /* *pdc is already set, except for colors.pattern.p_tile and mask.m_tile. */
- int
- gx_pattern_load(gx_device_color * pdc, const gs_imager_state * pis,
- gx_device * dev, gs_color_select_t select)
- {
- gx_device_pattern_accum *adev;
- gs_pattern1_instance_t *pinst =
- (gs_pattern1_instance_t *)pdc->ccolor.pattern;
- gs_state *saved;
- gx_color_tile *ctile;
- gs_memory_t *mem = pis->memory;
- int code;
- if (gx_pattern_cache_lookup(pdc, pis, dev, select))
- return 0;
- /* We REALLY don't like the following cast.... */
- code = ensure_pattern_cache((gs_imager_state *) pis);
- if (code < 0)
- return code;
- /*
- * Note that adev is an internal device, so it will be freed when the
- * last reference to it from a graphics state is deleted.
- */
- adev = gx_pattern_accum_alloc(mem, "gx_pattern_load");
- if (adev == 0)
- return_error(gs_error_VMerror);
- gx_device_set_target((gx_device_forward *)adev, dev);
- adev->instance = pinst;
- adev->bitmap_memory = mem;
- code = dev_proc(adev, open_device)((gx_device *)adev);
- if (code < 0)
- goto fail;
- saved = gs_gstate(pinst->saved);
- if (saved == 0) {
- code = gs_note_error(gs_error_VMerror);
- goto fail;
- }
- if (saved->pattern_cache == 0)
- saved->pattern_cache = pis->pattern_cache;
- gs_setdevice_no_init(saved, (gx_device *)adev);
- code = (*pinst->template.PaintProc)(&pdc->ccolor, saved);
- if (code < 0) {
- dev_proc(adev, close_device)((gx_device *)adev);
- /* Freeing the state will free the device. */
- gs_state_free(saved);
- return code;
- }
- /* We REALLY don't like the following cast.... */
- code = gx_pattern_cache_add_entry((gs_imager_state *)pis, adev, &ctile);
- if (code >= 0) {
- if (!gx_pattern_cache_lookup(pdc, pis, dev, select)) {
- lprintf("Pattern cache lookup failed after insertion!\n");
- code = gs_note_error(gs_error_Fatal);
- }
- }
- #ifdef DEBUG
- if (gs_debug_c('B')) {
- if (adev->mask)
- debug_dump_bitmap(adev->mask->base, adev->mask->raster,
- adev->mask->height, "[B]Pattern mask");
- if (adev->bits)
- debug_dump_bitmap(((gx_device_memory *) adev->target)->base,
- ((gx_device_memory *) adev->target)->raster,
- adev->target->height, "[B]Pattern bits");
- }
- #endif
- /* Free the bookkeeping structures, except for the bits and mask */
- /* data iff they are still needed. */
- dev_proc(adev, close_device)((gx_device *)adev);
- /* Freeing the state will free the device. */
- gs_state_free(saved);
- return code;
- fail:
- gs_free_object(mem, adev, "gx_pattern_load");
- return code;
- }
- /* Remap a PatternType 1 color. */
- cs_proc_remap_color(gx_remap_Pattern); /* check the prototype */
- int
- gs_pattern1_remap_color(const gs_client_color * pc, const gs_color_space * pcs,
- gx_device_color * pdc, const gs_imager_state * pis,
- gx_device * dev, gs_color_select_t select)
- {
- gs_pattern1_instance_t *pinst = (gs_pattern1_instance_t *)pc->pattern;
- int code;
- pdc->ccolor = *pc;
- if (pinst == 0) {
- /* Null pattern */
- color_set_null_pattern(pdc);
- return 0;
- }
- if (pinst->template.PaintType == 2) { /* uncolored */
- code = (*pcs->params.pattern.base_space.type->remap_color)
- (pc, (const gs_color_space *)&pcs->params.pattern.base_space,
- pdc, pis, dev, select);
- if (code < 0)
- return code;
- if (pdc->type == gx_dc_type_pure)
- pdc->type = &gx_dc_pure_masked;
- else if (pdc->type == gx_dc_type_ht_binary)
- pdc->type = &gx_dc_binary_masked;
- else if (pdc->type == gx_dc_type_ht_colored)
- pdc->type = &gx_dc_colored_masked;
- else
- return_error(gs_error_unregistered);
- } else
- color_set_null_pattern(pdc);
- pdc->mask.id = pinst->id;
- pdc->mask.m_tile = 0;
- return gx_pattern_load(pdc, pis, dev, select);
- }
|