diff options
author | Ray Johnston <ray.johnston@artifex.com> | 2021-03-16 18:00:13 -0700 |
---|---|---|
committer | Ray Johnston <ray.johnston@artifex.com> | 2021-05-03 08:43:18 -0700 |
commit | 032cb22e6d63e2e81b86ae6ba1cbd04d7798bae7 (patch) | |
tree | 384383fb28c5e38380019437c026087ac99d2196 /base | |
parent | 2b5118c3fcb8e5cc58c9a3d87ad9fe327eece117 (diff) | |
download | ghostpdl-032cb22e6d63e2e81b86ae6ba1cbd04d7798bae7.tar.gz |
Add object type specific device halftones to the graphics state.
PostScript 'sethalftone' has an optional parameter "ObjectType" that allows
one of the three object specific types to be set: Vector, Image or Text.
Also add a new PostScript operator to set the current halftone (dev_ht,
set by sethalftone) as the device halftone to be used for an object type:
path, image and text.
For non-PostScript clients, the gs_halftone structure adds a 'objtype'
element (enum) that can be set prior to calling gs_sethalftone.
The gs_gstate_s dev_ht is now an array of HT_OBJTYPE_COUNT elements,
indexed by the gs_HT_objtype_t enum, with HT_OBJTYPE_DEFAULT (value 0)
used for prior sethalftone/setscreen/setcolorscreen operations.
NOTE: adding object types beyond the default+3 entries will require modification
of gx_select_dev_ht since it only uses 3 bits of the 'tag' to get the index
for the dev_ht[] array.
For code style, change to use != NULL instead of != 0 in most places that
this commit touched (but we may want a general cleanup of this everywhere).
TBD: Command line options for all PDL's will need a method to take a
halftone specification -- most likely a file that may be "PS-lite" syntax
and may be limited to a threshold array. Discussions are in progress.
Diffstat (limited to 'base')
-rw-r--r-- | base/gsgstate.c | 26 | ||||
-rw-r--r-- | base/gsht.c | 72 | ||||
-rw-r--r-- | base/gsht.h | 9 | ||||
-rw-r--r-- | base/gsht1.c | 2 | ||||
-rw-r--r-- | base/gshtscr.c | 1 | ||||
-rw-r--r-- | base/gshtx.c | 1 | ||||
-rw-r--r-- | base/gsptype2.c | 5 | ||||
-rw-r--r-- | base/gsstate.c | 2 | ||||
-rw-r--r-- | base/gxcht.c | 6 | ||||
-rw-r--r-- | base/gxclimag.c | 2 | ||||
-rw-r--r-- | base/gxclrast.c | 10 | ||||
-rw-r--r-- | base/gxcmap.c | 62 | ||||
-rw-r--r-- | base/gxcmap.h | 4 | ||||
-rw-r--r-- | base/gxdhtserial.c | 2 | ||||
-rw-r--r-- | base/gxgstate.h | 38 | ||||
-rw-r--r-- | base/gxht.c | 8 | ||||
-rw-r--r-- | base/gxht.h | 1 | ||||
-rw-r--r-- | base/gxht_thresh.c | 23 | ||||
-rw-r--r-- | base/gxicolor.c | 14 | ||||
-rw-r--r-- | base/gximono.c | 16 | ||||
-rw-r--r-- | base/gxshade.c | 2 | ||||
-rw-r--r-- | base/gzht.h | 9 |
22 files changed, 206 insertions, 109 deletions
diff --git a/base/gsgstate.c b/base/gsgstate.c index 6eb9b8178..0f7d182a5 100644 --- a/base/gsgstate.c +++ b/base/gsgstate.c @@ -112,7 +112,8 @@ gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem) for (i = 0; i < gs_color_select_count; ++i) pgs->screen_phase[i].x = pgs->screen_phase[i].y = 0; } - pgs->dev_ht = 0; + for (i=0; i < HT_OBJTYPE_COUNT; i++) + pgs->dev_ht[i] = NULL; pgs->cie_render = 0; pgs->cie_to_xyz = false; pgs->black_generation = 0; @@ -159,8 +160,11 @@ gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem) void gs_gstate_copied(gs_gstate * pgs) { + int i; + rc_increment(pgs->halftone); - rc_increment(pgs->dev_ht); + for (i=0; i < HT_OBJTYPE_COUNT; i++) + rc_increment(pgs->dev_ht[i]); rc_increment(pgs->cie_render); rc_increment(pgs->black_generation); rc_increment(pgs->undercolor_removal); @@ -183,6 +187,7 @@ void gs_gstate_pre_assign(gs_gstate *pto, const gs_gstate *pfrom) { const char *const cname = "gs_gstate_pre_assign"; + int i; #define RCCOPY(element)\ rc_pre_assign(pto->element, pfrom->element, cname) @@ -196,7 +201,8 @@ gs_gstate_pre_assign(gs_gstate *pto, const gs_gstate *pfrom) RCCOPY(undercolor_removal); RCCOPY(black_generation); RCCOPY(cie_render); - RCCOPY(dev_ht); + for (i=0; i < HT_OBJTYPE_COUNT; i++) + RCCOPY(dev_ht[i]); RCCOPY(halftone); RCCOPY(devicergb_cs); RCCOPY(devicecmyk_cs); @@ -212,7 +218,8 @@ void gs_gstate_release(gs_gstate * pgs) { const char *const cname = "gs_gstate_release"; - gx_device_halftone *pdht = pgs->dev_ht; + gx_device_halftone *pdht; + int i; #define RCDECR(element)\ rc_decrement(pgs->element, cname);\ @@ -227,13 +234,16 @@ gs_gstate_release(gs_gstate * pgs) RCDECR(black_generation); RCDECR(cie_render); /* - * If we're going to free the device halftone, make sure we free the + * If we're going to free a device halftone, make sure we free the * dependent structures as well. */ - if (pdht != 0 && pdht->rc.ref_count == 1) { - gx_device_halftone_release(pdht, pdht->rc.memory); + for (i=0; i < HT_OBJTYPE_COUNT; i++) { + pdht = pgs->dev_ht[i]; + if (pdht != NULL && pdht->rc.ref_count == 1) { + gx_device_halftone_release(pdht, pdht->rc.memory); + } + RCDECR(dev_ht[i]); } - RCDECR(dev_ht); RCDECR(halftone); RCDECR(devicergb_cs); RCDECR(devicecmyk_cs); diff --git a/base/gsht.c b/base/gsht.c index bc72f0e17..20c92e125 100644 --- a/base/gsht.c +++ b/base/gsht.c @@ -17,6 +17,7 @@ /* setscreen operator for Ghostscript library */ #include "memory_.h" #include "string_.h" +#include "assert_.h" #include <stdlib.h> /* for qsort */ #include "gx.h" #include "gserrors.h" @@ -168,12 +169,12 @@ gs_currentscreenlevels(const gs_gstate * pgs) { int gi = 0; - if (pgs->device != 0) + if (pgs->device != NULL) gi = pgs->device->color_info.gray_index; if (gi != GX_CINFO_COMP_NO_INDEX) - return pgs->dev_ht->components[gi].corder.num_levels; + return pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[gi].corder.num_levels; else - return pgs->dev_ht->components[0].corder.num_levels; + return pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[0].corder.num_levels; } /* .setscreenphase */ @@ -321,9 +322,9 @@ gx_ht_copy_ht_order(gx_ht_order * pdest, gx_ht_order * psrc, gs_memory_t * mem) psrc->procs, mem); if (code < 0) return code; - if (pdest->levels != 0) + if (pdest->levels != NULL) memcpy(pdest->levels, psrc->levels, psrc->num_levels * sizeof(uint)); - if (pdest->bit_data != 0) + if (pdest->bit_data != NULL) memcpy(pdest->bit_data, psrc->bit_data, (size_t)psrc->num_bits * psrc->procs->bit_data_elt_size); pdest->transfer = psrc->transfer; @@ -576,13 +577,13 @@ gx_ht_order_release(gx_ht_order * porder, gs_memory_t * mem, bool free_cache) { /* "free cache" is a proxy for "differs from default" */ if (free_cache) { - if (porder->cache != 0) + if (porder->cache != NULL) gx_ht_free_cache(mem, porder->cache); } porder->cache = 0; rc_decrement(porder->transfer, "gx_ht_order_release(transfer)"); porder->transfer = 0; - if (porder->data_memory != 0) { + if (porder->data_memory != NULL) { gs_free_object(porder->data_memory, porder->bit_data, "gx_ht_order_release(bit_data)"); gs_free_object(porder->data_memory, porder->levels, @@ -949,7 +950,8 @@ gx_gstate_dev_ht_install( gs_gstate * pgs, gx_device_halftone * pdht, gs_halftone_type type, - const gx_device * dev ) + const gx_device * dev, + gs_HT_objtype_t objtype ) { gx_device_halftone dht; int num_comps = pdht->num_dev_comp; @@ -960,6 +962,8 @@ gx_gstate_dev_ht_install( uint w, h; int dw, dh; + assert(objtype < HT_OBJTYPE_COUNT); + /* construct the new device halftone structure */ memset(&dht.order, 0, sizeof(dht.order)); /* the rc field is filled in later */ @@ -988,7 +992,7 @@ gx_gstate_dev_ht_install( * by clearing the corresponding pointers in the operand halftone's * orders. */ - if (pdht->components != 0) { + if (pdht->components != NULL) { int input_ncomps = pdht->num_comp; for (i = 0; i < input_ncomps && code >= 0; i++) { @@ -1101,27 +1105,28 @@ gx_gstate_dev_ht_install( * we still need. */ if (code >= 0) { - gx_device_halftone * pgsdht = pgs->dev_ht; - rc_header tmp_rc; - - if (pgsdht != 0 && pgsdht->rc.ref_count == 1) { - if (pdht != pgsdht) - gx_device_halftone_release(pgsdht, pgsdht->rc.memory); + gx_device_halftone **ppgsdht; + rc_header tmp_rc; + + /* The pgsdht corresponds to the one we will be installing according to 'objtype' */ + ppgsdht = &(pgs->dev_ht[objtype]); + if (*ppgsdht != NULL && (*ppgsdht)->rc.ref_count == 1) { + if (pdht != *ppgsdht) + gx_device_halftone_release(*ppgsdht, (*ppgsdht)->rc.memory); } else { - rc_unshare_struct( pgs->dev_ht, + rc_unshare_struct( *ppgsdht, gx_device_halftone, &st_device_halftone, pgs->memory, BEGIN code = gs_error_VMerror; goto err; END, "gx_gstate_dev_ht_install" ); - pgsdht = pgs->dev_ht; } /* * Everything worked. "Assume ownership" of the appropriate * portions of the source device halftone by clearing the * associated references. Since we might have - * pdht == pgs->dev_ht, this must done before updating pgs->dev_ht. + * pdht == pgs->dev_ht[], this must done before updating pgs->dev_ht[]. * * If the default order has been used for a device component, and * any of the source component orders share their levels or bit_data @@ -1130,7 +1135,7 @@ gx_gstate_dev_ht_install( * be cleared immediately below, so subsequently it will not be * possible to tell if that this information is being shared. */ - if (pdht->components != 0) { + if (pdht->components != NULL) { int input_ncomps = pdht->num_comp; for (i = 0; i < input_ncomps; i++) { @@ -1150,9 +1155,9 @@ gx_gstate_dev_ht_install( memset(&pdht->order, 0, sizeof(pdht->order)); } - tmp_rc = pgsdht->rc; - *pgsdht = dht; - pgsdht->rc = tmp_rc; + tmp_rc = (*ppgsdht)->rc; + **ppgsdht = dht; + (*ppgsdht)->rc = tmp_rc; /* update the effective transfer function array */ gx_gstate_set_effective_xfer(pgs); @@ -1180,6 +1185,22 @@ gx_gstate_dev_ht_install( } /* + * Copy the dev_ht[HT_OBJTYPE_DEFAULT] to the dev_ht[] for the specified object type. + */ +int +gx_gstate_dev_ht_copy_to_objtype(gs_gstate *pgs, gs_HT_objtype_t objtype) +{ + gx_device_halftone *pdht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; /* the current dev_ht */ + + if (objtype >= HT_OBJTYPE_COUNT) { + return_error(gs_error_undefined); + } + rc_increment(pdht); + pgs->dev_ht[objtype] = pdht; + return 0; +} + +/* * Install a new halftone in the graphics state. Note that we copy the top * level of the gs_halftone and the gx_device_halftone, and take ownership * of any substructures. @@ -1194,7 +1215,7 @@ gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, int code; pdht->num_dev_comp = pgs->device->color_info.num_components; - if (old_ht != 0 && old_ht->rc.memory == mem && + if (old_ht != NULL && old_ht->rc.memory == mem && old_ht->rc.ref_count == 1 ) new_ht = old_ht; @@ -1203,7 +1224,8 @@ gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, mem, return_error(gs_error_VMerror), "gx_ht_install(new halftone)"); code = gx_gstate_dev_ht_install(pgs, - pdht, pht->type, gs_currentdevice_inline(pgs)); + pdht, pht->type, gs_currentdevice_inline(pgs), + pht->objtype); if (code < 0) { if (new_ht != old_ht) gs_free_object(mem, new_ht, "gx_ht_install(new halftone)"); @@ -1242,7 +1264,7 @@ gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, void gx_gstate_set_effective_xfer(gs_gstate * pgs) { - gx_device_halftone *pdht = pgs->dev_ht; + gx_device_halftone *pdht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; gx_transfer_map *pmap; gx_ht_order *porder; int i, component_num, non_id_count; diff --git a/base/gsht.h b/base/gsht.h index 05857f9fc..f52808524 100644 --- a/base/gsht.h +++ b/base/gsht.h @@ -23,6 +23,15 @@ #include "gsgstate.h" #include "gstypes.h" +/* Define the ObjectType enum for Halftones */ +typedef enum { + HT_OBJTYPE_DEFAULT = 0, + HT_OBJTYPE_VECTOR, + HT_OBJTYPE_IMAGE, + HT_OBJTYPE_TEXT, + HT_OBJTYPE_COUNT /* Must be last */ +} gs_HT_objtype_t; + /* Client definition of (Type 1) halftones */ typedef struct gs_screen_halftone_s { float frequency; diff --git a/base/gsht1.c b/base/gsht1.c index 05fceb54b..90f7e51b4 100644 --- a/base/gsht1.c +++ b/base/gsht1.c @@ -169,6 +169,8 @@ gs_sethalftone_prepare(gs_gstate * pgs, gs_halftone * pht, gx_ht_order_component *pocs = 0; int code = 0; + if (pht->objtype >= HT_OBJTYPE_COUNT) + return_error(gs_error_limitcheck); switch (pht->type) { case ht_type_colorscreen: { diff --git a/base/gshtscr.c b/base/gshtscr.c index 34ca12405..6807a9f37 100644 --- a/base/gshtscr.c +++ b/base/gshtscr.c @@ -627,6 +627,7 @@ gs_screen_install(gs_screen_enum * penum) dev_ht.rc.memory = penum->halftone.rc.memory; dev_ht.order = penum->order; dev_ht.components = 0; + penum->halftone.objtype = HT_OBJTYPE_DEFAULT; if ((code = gx_ht_install(penum->pgs, &penum->halftone, &dev_ht)) < 0) gx_device_halftone_release(&dev_ht, dev_ht.rc.memory); return code; diff --git a/base/gshtx.c b/base/gshtx.c index c42f19ba1..bf01fb247 100644 --- a/base/gshtx.c +++ b/base/gshtx.c @@ -95,6 +95,7 @@ gs_ht_build( /* initialize the halftone */ pht->type = ht_type_multiple; pht->rc.free = free_comps; + pht->objtype = HT_OBJTYPE_DEFAULT; pht->params.ht_multiple.components = phtc; pht->params.ht_multiple.num_comp = num_comps; diff --git a/base/gsptype2.c b/base/gsptype2.c index 878fbe644..b9ef6a05c 100644 --- a/base/gsptype2.c +++ b/base/gsptype2.c @@ -158,13 +158,14 @@ gx_dc_is_pattern2_color(const gx_device_color *pdevc) } /* - * The device halftone used by a PatternType 2 patter is that current in + * The device halftone used by a PatternType 2 pattern is that current in * the graphic state at the time of the makepattern call. */ static const gx_device_halftone * gx_dc_pattern2_get_dev_halftone(const gx_device_color * pdevc) { - return ((gs_pattern2_instance_t *)pdevc->ccolor.pattern)->saved->dev_ht; + /* FIXME: Do we need to be objtype specific w.r.t. to the dev_ht ??? */ + return ((gs_pattern2_instance_t *)pdevc->ccolor.pattern)->saved->dev_ht[HT_OBJTYPE_DEFAULT]; } /* Load a PatternType 2 color into the cache. (No effect.) */ diff --git a/base/gsstate.c b/base/gsstate.c index 7a279201a..f9c06e605 100644 --- a/base/gsstate.c +++ b/base/gsstate.c @@ -76,7 +76,7 @@ static void clip_stack_rc_adjust(gx_clip_stack_t *cs, int delta, client_name_t c * * (3a) Objects that are logically connected to individual gstates. * We use reference counting to manage these. Currently these are: - * halftone, dev_ht, cie_render, black_generation, + * halftone, dev_ht(4), cie_render, black_generation, * undercolor_removal, set_transfer.*, cie_joint_caches, * clip_stack, {opacity,shape}.mask * effective_transfer.* may point to some of the same objects as diff --git a/base/gxcht.c b/base/gxcht.c index 6625601aa..fa40565a3 100644 --- a/base/gxcht.c +++ b/base/gxcht.c @@ -379,7 +379,7 @@ gx_dc_ht_colored_read( /* the number of components is determined by the color model */ devc.colors.colored.num_components = num_comps; - devc.colors.colored.c_ht = pgs->dev_ht; + devc.colors.colored.c_ht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; /* * Verify that we have at least the flag bits. For performance @@ -462,8 +462,8 @@ gx_dc_ht_colored_read( color_set_phase_mod( &devc, pgs->screen_phase[0].x, pgs->screen_phase[0].y, - pgs->dev_ht->lcm_width, - pgs->dev_ht->lcm_height ); + pgs->dev_ht[HT_OBJTYPE_DEFAULT]->lcm_width, + pgs->dev_ht[HT_OBJTYPE_DEFAULT]->lcm_height ); /* everything looks OK */ *pdevc = devc; diff --git a/base/gxclimag.c b/base/gxclimag.c index 68ab81f54..3958e3728 100644 --- a/base/gxclimag.c +++ b/base/gxclimag.c @@ -1585,7 +1585,7 @@ cmd_put_color_mapping(gx_device_clist_writer * cldev, const gs_gstate * pgs) { int code; - const gx_device_halftone *pdht = pgs->dev_ht; + const gx_device_halftone *pdht = gx_select_dev_ht(pgs); /* Put out the halftone, if present. */ if (pdht && pdht->id != cldev->device_halftone_id) { diff --git a/base/gxclrast.c b/base/gxclrast.c index ce683a94f..bfed7ddbb 100644 --- a/base/gxclrast.c +++ b/base/gxclrast.c @@ -809,7 +809,7 @@ in: /* Initialize for a new page. */ halftone_type, num_comp); #endif code = cmd_resize_halftone( - &gs_gstate.dev_ht, + &gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT], num_comp, mem); if (code < 0) goto out; @@ -1209,10 +1209,10 @@ set_phase: /* if (state_tile.size.x) tile_phase.x = (state.tile_phase.x + x0) % state_tile.size.x; - if (gs_gstate.dev_ht && gs_gstate.dev_ht->lcm_width) + if (gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT] && gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT]->lcm_width) color_phase.x = (state.tile_phase.x + x0) % - gs_gstate.dev_ht->lcm_width; + gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT]->lcm_width; /* * The true tile height for shifted tiles is not * size.y: see gxbitmap.h for the computation. @@ -1230,10 +1230,10 @@ set_phase: /* tile_phase.y = (state.tile_phase.y + y0) % full_height; } - if (gs_gstate.dev_ht && gs_gstate.dev_ht->lcm_height) + if (gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT] && gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT]->lcm_height) color_phase.y = (state.tile_phase.y + y0) % - gs_gstate.dev_ht->lcm_height; + gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT]->lcm_height; gx_gstate_setscreenphase(&gs_gstate, -(state.tile_phase.x + x0), -(state.tile_phase.y + y0), diff --git a/base/gxcmap.c b/base/gxcmap.c index cba4908e9..d8344773a 100644 --- a/base/gxcmap.c +++ b/base/gxcmap.c @@ -15,6 +15,7 @@ /* Color mapping for Ghostscript */ +#include "assert_.h" #include "gx.h" #include "gserrors.h" #include "gsccolor.h" @@ -27,6 +28,7 @@ #include "gxcmap.h" #include "gxlum.h" #include "gzstate.h" +#include "gzht.h" #include "gxdither.h" #include "gxcdevn.h" #include "string_.h" @@ -888,6 +890,32 @@ gx_remap_DeviceCMYK(const gs_client_color * pc, const gs_color_space * pcs, return 0; } +/* ------ Utility for selecting the dev_ht from the pgs using the dev->graphics_type_tag ----- */ + +static gs_HT_objtype_t +tag_to_HT_objtype[8] = { HT_OBJTYPE_DEFAULT, + HT_OBJTYPE_TEXT, /* GS_TEXT_TAG = 0x1 */ + HT_OBJTYPE_IMAGE, /* GS_IMAGE_TAG = 0x2 */ + HT_OBJTYPE_DEFAULT, + HT_OBJTYPE_VECTOR, /* GS_VECTOR_TAG = 0x4 */ + HT_OBJTYPE_DEFAULT, HT_OBJTYPE_DEFAULT, HT_OBJTYPE_DEFAULT + }; + +/* Return the selected dev_ht[] or the pgs->dev_ht[HT_OBJTYPE_DEFAULT] */ +gx_device_halftone * +gx_select_dev_ht(const gs_gstate *pgs) +{ + gs_HT_objtype_t objtype; + + /* This function only works with 3 bits currently. Flag here in case we add object types */ + assert(HT_OBJTYPE_COUNT == 4); + + objtype = tag_to_HT_objtype[pgs->device->graphics_type_tag & 7]; + if (pgs->dev_ht[objtype] == NULL) + objtype = HT_OBJTYPE_DEFAULT; + return pgs->dev_ht[objtype]; +} + /* ------ Render Gray color. ------ */ static void @@ -924,7 +952,7 @@ cmap_gray_halftoned(frac gray, gx_device_color * pdc, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -981,7 +1009,7 @@ cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1012,7 +1040,7 @@ cmap_rgb_halftoned(frac r, frac g, frac b, gx_device_color * pdc, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1056,7 +1084,7 @@ cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1115,7 +1143,7 @@ cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, /* duplicating most of the code of this procedure. */ if (gx_device_must_halftone(dev)) { if (gx_render_device_DeviceN(cm_comps, pdc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); return; } @@ -1133,7 +1161,7 @@ cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, color_set_pure(pdc, color); else { if (gx_render_device_DeviceN(cm_comps, pdc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } } @@ -1177,7 +1205,7 @@ cmap_rgb_alpha_halftoned(frac r, frac g, frac b, frac alpha, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1233,7 +1261,7 @@ cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1447,7 +1475,7 @@ cmap_separation_halftoned(frac all, gx_device_color * pdc, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1572,7 +1600,7 @@ cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs, return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1618,7 +1646,7 @@ cmap_devicen_halftoned(const frac * pcc, } /* We need to finish halftoning */ - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -1713,7 +1741,7 @@ cmap_devicen_direct(const frac * pcc, color_set_pure(pdc, color); return; } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } @@ -2093,7 +2121,7 @@ cmapper_transfer_halftone_add(gx_cmapper_t *data) } /* Halftoning */ if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2122,7 +2150,7 @@ cmapper_transfer_halftone_op(gx_cmapper_t *data) } /* Halftoning */ if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2146,7 +2174,7 @@ cmapper_transfer_halftone_sub(gx_cmapper_t *data) } /* Halftoning */ if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2242,7 +2270,7 @@ cmapper_halftone(gx_cmapper_t *data) cv_frac[i] = cv2frac(pconc[i]); } if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(&data->devc, pgs, dev, select); } @@ -2371,7 +2399,7 @@ cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, /* Halftoning */ if (has_halftone) { if (gx_render_device_DeviceN(&(cv_frac[0]), pdc, dev, - pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1) gx_color_load_select(pdc, pgs, dev, select); } else { /* We have a frac value from the transfer function. Do the encode. diff --git a/base/gxcmap.h b/base/gxcmap.h index b626e632b..3c7cdb47f 100644 --- a/base/gxcmap.h +++ b/base/gxcmap.h @@ -290,4 +290,8 @@ void gx_get_cmapper(gx_cmapper_t *cmapper, const gs_gstate *pgs, gx_device *dev, bool has_transfer, bool has_halftone, gs_color_select_t select); +/* Return the dev_ht[] selected by the pgs->device->graphics_tag */ +/* or the pgs->dev_ht[HT_OBJTYPE_DEFAULT] */ +gx_device_halftone *gx_select_dev_ht(const gs_gstate *pgs); + #endif /* gxcmap_INCLUDED */ diff --git a/base/gxdhtserial.c b/base/gxdhtserial.c index 6f8bb18f3..cd851951a 100644 --- a/base/gxdhtserial.c +++ b/base/gxdhtserial.c @@ -584,7 +584,7 @@ gx_ht_read_and_install( /* save since the 'install' copies the order, but then clears the source order */ for (i = 0; i < num_dev_comps; i++) components_save[i] = components[i]; - code = gx_gstate_dev_ht_install(pgs, &dht, dht.type, dev); + code = gx_gstate_dev_ht_install(pgs, &dht, dht.type, dev, HT_OBJTYPE_DEFAULT); if (code >= 0) { for (i = 0; i < num_dev_comps; i++) gx_ht_order_release(&components_save[i].corder, mem, false); diff --git a/base/gxgstate.h b/base/gxgstate.h index a6309d899..c81dfc49e 100644 --- a/base/gxgstate.h +++ b/base/gxgstate.h @@ -81,7 +81,7 @@ typedef struct gx_transfer_s { gs_halftone *halftone; /* (RC) */\ gs_int_point screen_phase[gs_color_select_count];\ /* dev_ht depends on halftone and device resolution. */\ - gx_device_halftone *dev_ht; /* (RC) */\ + gx_device_halftone *dev_ht[HT_OBJTYPE_COUNT]; /* (RC) */\ \ /* Color (device-dependent): */\ \ @@ -139,7 +139,10 @@ typedef struct gs_gstate_color_s { */ #define gs_cr_state_do_rc_ptrs(m)\ m(halftone) \ - m(dev_ht) \ + m(dev_ht[HT_OBJTYPE_DEFAULT]) \ + m(dev_ht[HT_OBJTYPE_VECTOR]) \ + m(dev_ht[HT_OBJTYPE_IMAGE]) \ + m(dev_ht[HT_OBJTYPE_TEXT]) \ m(cie_render) \ m(black_generation) \ m(undercolor_removal) \ @@ -155,19 +158,22 @@ typedef struct gs_gstate_color_s { /* Enumerate the pointers in a c.r. state. */ #define gs_cr_state_do_ptrs(m)\ m(0,halftone) \ - m(1,dev_ht) \ - m(2,cie_render) \ - m(3,black_generation) \ - m(4,undercolor_removal) \ - m(5,set_transfer.red) \ - m(6,set_transfer.green) \ - m(7,set_transfer.blue) \ - m(8,set_transfer.gray)\ - m(9,cie_joint_caches) \ - m(10,pattern_cache) \ - m(11,devicergb_cs) \ - m(12,devicecmyk_cs)\ - m(13,cie_joint_caches_alt) + m(1,dev_ht[HT_OBJTYPE_DEFAULT]) \ + m(2, dev_ht[HT_OBJTYPE_VECTOR]) \ + m(3, dev_ht[HT_OBJTYPE_IMAGE]) \ + m(4, dev_ht[HT_OBJTYPE_TEXT]) \ + m(5,cie_render) \ + m(6,black_generation) \ + m(7,undercolor_removal) \ + m(8,set_transfer.red) \ + m(9,set_transfer.green) \ + m(10,set_transfer.blue) \ + m(11,set_transfer.gray)\ + m(12,cie_joint_caches) \ + m(13,pattern_cache) \ + m(14,devicergb_cs) \ + m(15,devicecmyk_cs)\ + m(16,cie_joint_caches_alt) /* * We handle effective_transfer specially in gsistate.c since its pointers * are not enumerated for garbage collection but they are are relocated. @@ -176,7 +182,7 @@ typedef struct gs_gstate_color_s { * This count does not include the effective_transfer pointers since they * are not enumerated for GC. */ -#define st_cr_state_num_ptrs 14 +#define st_cr_state_num_ptrs 17 struct gs_devicen_color_map_s { bool use_alt_cspace; diff --git a/base/gxht.c b/base/gxht.c index b2322a237..a57662cee 100644 --- a/base/gxht.c +++ b/base/gxht.c @@ -545,7 +545,7 @@ gx_dc_ht_binary_read( devc.type = gx_dc_type_ht_binary; /* the halftone is always taken from the gs_gstate */ - devc.colors.binary.b_ht = pgs->dev_ht; + devc.colors.binary.b_ht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; /* cache is not porvided until the device color is used */ devc.colors.binary.b_tile = 0; @@ -592,14 +592,14 @@ gx_dc_ht_binary_read( devc.colors.binary.b_index = *pdata++; } - if (pgs->dev_ht == NULL) + if (pgs->dev_ht[HT_OBJTYPE_DEFAULT] == NULL) return_error(gs_error_unregistered); /* Must not happen. */ /* set the phase as required (select value is arbitrary) */ color_set_phase_mod( &devc, pgs->screen_phase[0].x, pgs->screen_phase[0].y, - pgs->dev_ht->lcm_width, - pgs->dev_ht->lcm_height ); + pgs->dev_ht[HT_OBJTYPE_DEFAULT]->lcm_width, + pgs->dev_ht[HT_OBJTYPE_DEFAULT]->lcm_height ); /* everything looks good */ *pdevc = devc; diff --git a/base/gxht.h b/base/gxht.h index b2743a5a8..e22f4f9ab 100644 --- a/base/gxht.h +++ b/base/gxht.h @@ -182,6 +182,7 @@ typedef struct gs_multiple_halftone_s { struct gs_halftone_s { gs_halftone_type type; rc_header rc; + gs_HT_objtype_t objtype; union { gs_screen_halftone screen; /* setscreen */ gs_colorscreen_halftone colorscreen; /* setcolorscreen */ diff --git a/base/gxht_thresh.c b/base/gxht_thresh.c index 348307ec4..c981f81b9 100644 --- a/base/gxht_thresh.c +++ b/base/gxht_thresh.c @@ -585,9 +585,11 @@ gxht_thresh_image_init(gx_image_enum *penum) gx_dda_fixed dda_ht; if (gx_device_must_halftone(penum->dev)) { - if (penum->pgs != NULL && penum->pgs->dev_ht != NULL) { - for (k = 0; k < penum->pgs->dev_ht->num_comp; k++) { - d_order = &(penum->pgs->dev_ht->components[k].corder); + if (penum->pgs != NULL && penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT] != NULL) { + gx_device_halftone *pdht = gx_select_dev_ht(penum->pgs); + + for (k = 0; k < pdht->num_comp; k++) { + d_order = &(pdht->components[k].corder); code = gx_ht_construct_threshold(d_order, penum->dev, penum->pgs, k); if (code < 0 ) { @@ -871,6 +873,7 @@ gxht_thresh_planes(gx_image_enum *penum, fixed xrun, gx_color_index dev_black = gx_device_black(dev); int spp_out = dev->color_info.num_components; byte *contone_align = NULL; /* Init to silence compiler warnings */ + gx_device_halftone *pdht = gx_select_dev_ht(penum->pgs); /* Go ahead and fill the threshold line buffer with tiled threshold values. First just grab the row or column that we are going to tile with and @@ -883,10 +886,10 @@ gxht_thresh_planes(gx_image_enum *penum, fixed xrun, /* Iterate over the vdi and fill up our threshold buffer. We also need to loop across the planes of data */ for (j = 0; j < spp_out; j++) { - bool threshold_inverted = penum->pgs->dev_ht->components[j].corder.threshold_inverted; + bool threshold_inverted = pdht->components[j].corder.threshold_inverted; - thresh_width = penum->pgs->dev_ht->components[j].corder.width; - thresh_height = penum->pgs->dev_ht->components[j].corder.full_height; + thresh_width = pdht->components[j].corder.width; + thresh_height = pdht->components[j].corder.full_height; halftone = penum->ht_buffer + j * vdi * dithered_stride; /* Compute the tiling positions with dest_width */ dx = (fixed2int_var_rounded(xrun) + penum->pgs->screen_phase[0].x) % thresh_width; @@ -901,7 +904,7 @@ gxht_thresh_planes(gx_image_enum *penum, fixed xrun, right_tile_width = dest_width - num_full_tiles * thresh_width - left_width; /* Get the proper threshold for the colorant count */ - threshold = penum->pgs->dev_ht->components[j].corder.threshold; + threshold = pdht->components[j].corder.threshold; /* Point to the proper contone data */ contone_align = penum->line + contone_stride * j + offset_contone[j]; @@ -995,11 +998,11 @@ gxht_thresh_planes(gx_image_enum *penum, fixed xrun, for (j = 0; j < spp_out; j++) { halftone = penum->ht_buffer + j * penum->ht_plane_height * (LAND_BITS>>3); - thresh_width = penum->pgs->dev_ht->components[j].corder.width; + thresh_width = pdht->components[j].corder.width; thresh_height = - penum->pgs->dev_ht->components[j].corder.full_height; + pdht->components[j].corder.full_height; /* Get the proper threshold for the colorant count */ - threshold = penum->pgs->dev_ht->components[j].corder.threshold; + threshold = pdht->components[j].corder.threshold; /* Point to the proper contone data */ contone_align = penum->line + offset_contone[j] + LAND_BITS * j * contone_stride; diff --git a/base/gxicolor.c b/base/gxicolor.c index 05820695b..4785ab4f0 100644 --- a/base/gxicolor.c +++ b/base/gxicolor.c @@ -108,7 +108,7 @@ color_halftone_init(gx_image_enum *penum) if (!gx_device_must_halftone(penum->dev)) return NULL; - if (penum->pgs == NULL || penum->pgs->dev_ht == NULL) + if (penum->pgs == NULL || penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT] == NULL) return NULL; dda_ht = penum->dda.pixel0.x; if (penum->dxx > 0) @@ -136,20 +136,20 @@ color_halftone_init(gx_image_enum *penum) if (cal_ht == NULL) goto fail; - for (k = 0; k < penum->pgs->dev_ht->num_comp; k++) { - d_order = &(penum->pgs->dev_ht->components[k].corder); + for (k = 0; k < penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->num_comp; k++) { + d_order = &(penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder); code = gx_ht_construct_threshold(d_order, penum->dev, penum->pgs, k); if (code < 0) goto fail; if (cal_halftone_add_screen(ctx, penum->memory->non_gc_memory, cal_ht, - penum->pgs->dev_ht->components[k].corder.threshold_inverted, - penum->pgs->dev_ht->components[k].corder.width, - penum->pgs->dev_ht->components[k].corder.full_height, + penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder.threshold_inverted, + penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder.width, + penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder.full_height, -penum->pgs->screen_phase[k].x, -penum->pgs->screen_phase[k].y, - penum->pgs->dev_ht->components[k].corder.threshold) < 0) + penum->pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[k].corder.threshold) < 0) goto fail; } diff --git a/base/gximono.c b/base/gximono.c index 659a6ccb9..7b40f3de7 100644 --- a/base/gximono.c +++ b/base/gximono.c @@ -96,12 +96,14 @@ halftone_init(gx_image_enum *penum) byte *cache = (penum->color_cache != NULL ? penum->color_cache->device_contone : NULL); cal_matrix matrix; int clip_x, clip_y; + gx_device_halftone *pdht = gx_select_dev_ht(penum->pgs); if (!gx_device_must_halftone(penum->dev)) return NULL; - if (penum->pgs == NULL || penum->pgs->dev_ht == NULL) + if (penum->pgs == NULL || pdht == NULL) return NULL; + dda_ht = penum->dda.pixel0.x; if (penum->dxx > 0) dda_translate(dda_ht, -fixed_epsilon); @@ -129,20 +131,20 @@ halftone_init(gx_image_enum *penum) if (cal_ht == NULL) goto fail; - for (k = 0; k < penum->pgs->dev_ht->num_comp; k++) { - d_order = &(penum->pgs->dev_ht->components[k].corder); + for (k = 0; k < pdht->num_comp; k++) { + d_order = &(pdht->components[k].corder); code = gx_ht_construct_threshold(d_order, penum->dev, penum->pgs, k); if (code < 0) goto fail; if (cal_halftone_add_screen(penum->memory->gs_lib_ctx->core->cal_ctx, penum->memory->non_gc_memory, cal_ht, - penum->pgs->dev_ht->components[k].corder.threshold_inverted, - penum->pgs->dev_ht->components[k].corder.width, - penum->pgs->dev_ht->components[k].corder.full_height, + pdht->components[k].corder.threshold_inverted, + pdht->components[k].corder.width, + pdht->components[k].corder.full_height, penum->pgs->screen_phase[k].x, -penum->pgs->screen_phase[k].y, - penum->pgs->dev_ht->components[k].corder.threshold) < 0) + pdht->components[k].corder.threshold) < 0) goto fail; } diff --git a/base/gxshade.c b/base/gxshade.c index a0ddf2900..08b9edcc2 100644 --- a/base/gxshade.c +++ b/base/gxshade.c @@ -365,7 +365,7 @@ top: } if (num_colors <= 32) { /****** WRONG FOR MULTI-PLANE HALFTONES ******/ - num_colors *= pgs->dev_ht->components[0].corder.num_levels; + num_colors *= pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[0].corder.num_levels; } if (psh->head.type == 2 || psh->head.type == 3) { max_error *= 0.25; diff --git a/base/gzht.h b/base/gzht.h index 9c1e0fe8a..358bd350f 100644 --- a/base/gzht.h +++ b/base/gzht.h @@ -196,7 +196,14 @@ void gx_ht_order_release(gx_ht_order * porder, gs_memory_t * mem, bool free_cach int gx_gstate_dev_ht_install(gs_gstate * pgs, gx_device_halftone * pdht, gs_halftone_type type, - const gx_device * dev); + const gx_device * dev, + gs_HT_objtype_t objtype); + +/* + * Copy the current dev_ht[HT_OBJTYPE_DEFAULT] to the dev_ht[] for the specified object type. + */ +int +gx_gstate_dev_ht_copy_to_objtype(gs_gstate *pgs, gs_HT_objtype_t objtype); /* * Install a new halftone in the graphics state. Note that we copy the top |