1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
14
/* $Id: zht.c 9043 2008-08-28 22:48:19Z giles $ */
15
/* Halftone definition operators */
20
#include "gsstruct.h" /* must precede igstate.h, */
21
/* because of #ifdef in gsht.h */
25
#include "gxdevice.h" /* for gzht.h */
28
#include "iht.h" /* prototypes */
31
/* Forward references */
32
static int screen_sample(i_ctx_t *);
33
static int set_screen_continue(i_ctx_t *);
34
static int screen_cleanup(i_ctx_t *);
36
/* - .currenthalftone <dict> 0 */
37
/* - .currenthalftone <frequency> <angle> <proc> 1 */
38
/* - .currenthalftone <red_freq> ... <gray_proc> 2 */
40
zcurrenthalftone(i_ctx_t *i_ctx_p)
45
gs_currenthalftone(igs, &ht);
49
make_real(op - 3, ht.params.screen.frequency);
50
make_real(op - 2, ht.params.screen.angle);
51
op[-1] = istate->screen_procs.gray;
54
case ht_type_colorscreen:
58
gs_screen_halftone *pht =
59
&ht.params.colorscreen.screens.colored.red;
61
make_real(opc, pht->frequency);
62
make_real(opc + 1, pht->angle);
63
opc[2] = istate->screen_procs.red;
66
pht = &ht.params.colorscreen.screens.colored.green;
67
make_real(opc, pht->frequency);
68
make_real(opc + 1, pht->angle);
69
opc[2] = istate->screen_procs.green;
72
pht = &ht.params.colorscreen.screens.colored.blue;
73
make_real(opc, pht->frequency);
74
make_real(opc + 1, pht->angle);
75
opc[2] = istate->screen_procs.blue;
78
pht = &ht.params.colorscreen.screens.colored.gray;
79
make_real(opc, pht->frequency);
80
make_real(opc + 1, pht->angle);
81
opc[2] = istate->screen_procs.gray;
85
default: /* Screen was set by sethalftone. */
87
op[-1] = istate->halftone;
94
/* - .currentscreenlevels <int> */
96
zcurrentscreenlevels(i_ctx_t *i_ctx_p)
101
make_int(op, gs_currentscreenlevels(igs));
105
/* The setscreen operator is complex because it has to sample */
106
/* each pixel in the pattern cell, calling a procedure, and then */
107
/* sort the result into a whitening order. */
109
/* Layout of stuff pushed on estack: */
111
/* [other stuff for other screen-setting operators], */
112
/* finishing procedure (or 0), */
113
/* spot procedure, */
114
/* enumeration structure (as bytes). */
116
#define sproc esp[-1]
117
#define senum r_ptr(esp, gs_screen_enum)
119
/* Forward references */
120
static int setscreen_finish(i_ctx_t *);
122
/* <frequency> <angle> <proc> setscreen - */
124
zsetscreen(i_ctx_t *i_ctx_p)
127
gs_screen_halftone screen;
129
int code = zscreen_params(op, &screen);
131
int space_index = r_space_index(op);
135
mem = (gs_memory_t *)idmemory->spaces_indexed[space_index];
137
* Allocate the halftone in the same VM space as the procedure.
138
* This keeps the space relationships consistent.
140
code = gs_screen_order_init_memory(&order, igs, &screen,
141
gs_currentaccuratescreens(), mem);
144
return zscreen_enum_init(i_ctx_p, &order, &screen, op, 3,
145
setscreen_finish, space_index);
147
/* We break out the body of this operator so it can be shared with */
148
/* the code for Type 1 halftones in sethalftone. */
150
zscreen_enum_init(i_ctx_t *i_ctx_p, const gx_ht_order * porder,
151
gs_screen_halftone * psp, ref * pproc, int npop,
152
int (*finish_proc)(i_ctx_t *), int space_index)
154
gs_screen_enum *penum;
155
gs_memory_t * mem = (gs_memory_t *)idmemory->spaces_indexed[space_index];
158
check_estack(snumpush + 1);
159
penum = gs_screen_enum_alloc(mem, "setscreen");
161
return_error(e_VMerror);
162
make_struct(esp + snumpush, space_index << r_space_shift, penum); /* do early for screen_cleanup in case of error */
163
code = gs_screen_enum_init_memory(penum, porder, igs, psp, mem);
165
screen_cleanup(i_ctx_p);
168
/* Push everything on the estack */
169
make_mark_estack(esp + 1, es_other, screen_cleanup);
171
make_op_estack(esp - 2, finish_proc);
173
push_op_estack(screen_sample);
175
return o_push_estack;
177
/* Set up the next sample */
179
screen_sample(i_ctx_t *i_ctx_p)
182
gs_screen_enum *penum = senum;
184
int code = gs_screen_currentpoint(penum, &pt);
192
if (real_opproc(esp - 2) != 0)
193
code = (*real_opproc(esp - 2)) (i_ctx_p);
195
screen_cleanup(i_ctx_p);
196
return (code < 0 ? code : o_pop_estack);
201
make_real(op - 1, pt.x);
204
push_op_estack(set_screen_continue);
206
return o_push_estack;
208
/* Continuation procedure for processing sampled pixels. */
210
set_screen_continue(i_ctx_t *i_ctx_p)
214
int code = real_param(op, &value);
218
code = gs_screen_next(senum, value);
222
return screen_sample(i_ctx_p);
224
/* Finish setscreen. */
226
setscreen_finish(i_ctx_t *i_ctx_p)
228
gs_screen_install(senum);
229
istate->screen_procs.red = sproc;
230
istate->screen_procs.green = sproc;
231
istate->screen_procs.blue = sproc;
232
istate->screen_procs.gray = sproc;
233
make_null(&istate->halftone);
236
/* Clean up after screen enumeration */
238
screen_cleanup(i_ctx_t *i_ctx_p)
240
gs_screen_enum *penum = r_ptr(esp + snumpush, gs_screen_enum);
242
gs_free_object(penum->halftone.rc.memory, penum, "screen_cleanup");
246
/* ------ Utility procedures ------ */
248
/* Get parameters for a single screen. */
250
zscreen_params(os_ptr op, gs_screen_halftone * phs)
253
int code = num_params(op - 1, 2, fa);
258
phs->frequency = fa[0];
263
/* ------ Initialization procedure ------ */
265
const op_def zht_op_defs[] =
267
{"0.currenthalftone", zcurrenthalftone},
268
{"0.currentscreenlevels", zcurrentscreenlevels},
269
{"3setscreen", zsetscreen},
270
/* Internal operators */
271
{"0%screen_sample", screen_sample},
272
{"1%set_screen_continue", set_screen_continue},
273
{"0%setscreen_finish", setscreen_finish},