Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1989, 1991, 1993, 1994, 1997, 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: zht.c,v 1.8 2005/10/11 10:04:28 leonardo Exp $ */
18
/* Halftone definition operators */
19
#include "ghost.h"
20
#include "memory_.h"
21
#include "oper.h"
22
#include "estack.h"
23
#include "gsstruct.h"		/* must precede igstate.h, */
24
					/* because of #ifdef in gsht.h */
25
#include "ialloc.h"
26
#include "igstate.h"
27
#include "gsmatrix.h"
28
#include "gxdevice.h"		/* for gzht.h */
29
#include "gzht.h"
30
#include "gsstate.h"
31
#include "iht.h"		/* prototypes */
32
#include "store.h"
33
 
34
/* Forward references */
35
private int screen_sample(i_ctx_t *);
36
private int set_screen_continue(i_ctx_t *);
37
private int screen_cleanup(i_ctx_t *);
38
 
39
/* - .currenthalftone <dict> 0 */
40
/* - .currenthalftone <frequency> <angle> <proc> 1 */
41
/* - .currenthalftone <red_freq> ... <gray_proc> 2 */
42
private int
43
zcurrenthalftone(i_ctx_t *i_ctx_p)
44
{
45
    os_ptr op = osp;
46
    gs_halftone ht;
47
 
48
    gs_currenthalftone(igs, &ht);
49
    switch (ht.type) {
50
	case ht_type_screen:
51
	    push(4);
52
	    make_real(op - 3, ht.params.screen.frequency);
53
	    make_real(op - 2, ht.params.screen.angle);
54
	    op[-1] = istate->screen_procs.gray;
55
	    make_int(op, 1);
56
	    break;
57
	case ht_type_colorscreen:
58
	    push(13);
59
	    {
60
		os_ptr opc = op - 12;
61
		gs_screen_halftone *pht = 
62
		    &ht.params.colorscreen.screens.colored.red;
63
 
64
		make_real(opc, pht->frequency);
65
		make_real(opc + 1, pht->angle);
66
		opc[2] = istate->screen_procs.red;
67
 
68
		opc = op - 9;
69
		pht = &ht.params.colorscreen.screens.colored.green;
70
		make_real(opc, pht->frequency);
71
		make_real(opc + 1, pht->angle);
72
		opc[2] = istate->screen_procs.green;
73
 
74
		opc = op - 6;
75
		pht = &ht.params.colorscreen.screens.colored.blue;
76
		make_real(opc, pht->frequency);
77
		make_real(opc + 1, pht->angle);
78
		opc[2] = istate->screen_procs.blue;
79
 
80
		opc = op - 3;
81
		pht = &ht.params.colorscreen.screens.colored.gray;
82
		make_real(opc, pht->frequency);
83
		make_real(opc + 1, pht->angle);
84
		opc[2] = istate->screen_procs.gray;
85
	    }
86
	    make_int(op, 2);
87
	    break;
88
	default:		/* Screen was set by sethalftone. */
89
	    push(2);
90
	    op[-1] = istate->halftone;
91
	    make_int(op, 0);
92
	    break;
93
    }
94
    return 0;
95
}
96
 
97
/* - .currentscreenlevels <int> */
98
private int
99
zcurrentscreenlevels(i_ctx_t *i_ctx_p)
100
{
101
    os_ptr op = osp;
102
 
103
    push(1);
104
    make_int(op, gs_currentscreenlevels(igs));
105
    return 0;
106
}
107
 
108
/* The setscreen operator is complex because it has to sample */
109
/* each pixel in the pattern cell, calling a procedure, and then */
110
/* sort the result into a whitening order. */
111
 
112
/* Layout of stuff pushed on estack: */
113
/*      Control mark, */
114
/*      [other stuff for other screen-setting operators], */
115
/*      finishing procedure (or 0), */
116
/*      spot procedure, */
117
/*      enumeration structure (as bytes). */
118
#define snumpush 4
119
#define sproc esp[-1]
120
#define senum r_ptr(esp, gs_screen_enum)
121
 
122
/* Forward references */
123
private int setscreen_finish(i_ctx_t *);
124
 
125
/* <frequency> <angle> <proc> setscreen - */
126
private int
127
zsetscreen(i_ctx_t *i_ctx_p)
128
{
129
    os_ptr op = osp;
130
    gs_screen_halftone screen;
131
    gx_ht_order order;
132
    int code = zscreen_params(op, &screen);
133
    gs_memory_t *mem;
134
    int space_index = r_space_index(op);
135
 
136
    if (code < 0)
137
	return code;
138
    mem = (gs_memory_t *)idmemory->spaces_indexed[space_index];
139
    /*
140
     * Allocate the halftone in the same VM space as the procedure.
141
     * This keeps the space relationships consistent.
142
     */
143
    code = gs_screen_order_init_memory(&order, igs, &screen,
144
				       gs_currentaccuratescreens(), mem);
145
    if (code < 0)
146
	return code;
147
    return zscreen_enum_init(i_ctx_p, &order, &screen, op, 3,
148
			     setscreen_finish, space_index);
149
}
150
/* We break out the body of this operator so it can be shared with */
151
/* the code for Type 1 halftones in sethalftone. */
152
int
153
zscreen_enum_init(i_ctx_t *i_ctx_p, const gx_ht_order * porder,
154
		  gs_screen_halftone * psp, ref * pproc, int npop,
155
		  int (*finish_proc)(i_ctx_t *), int space_index)
156
{
157
    gs_screen_enum *penum;
158
    gs_memory_t * mem = (gs_memory_t *)idmemory->spaces_indexed[space_index]; 
159
    int code;
160
 
161
    check_estack(snumpush + 1);
162
    penum = gs_screen_enum_alloc(mem, "setscreen");
163
    if (penum == 0)
164
	return_error(e_VMerror);
165
    make_struct(esp + snumpush, space_index << r_space_shift, penum);	/* do early for screen_cleanup in case of error */
166
    code = gs_screen_enum_init_memory(penum, porder, igs, psp, mem);
167
    if (code < 0) {
168
	screen_cleanup(i_ctx_p);
169
	return code;
170
    }
171
    /* Push everything on the estack */
172
    make_mark_estack(esp + 1, es_other, screen_cleanup);
173
    esp += snumpush;
174
    make_op_estack(esp - 2, finish_proc);
175
    sproc = *pproc;
176
    push_op_estack(screen_sample);
177
    pop(npop);
178
    return o_push_estack;
179
}
180
/* Set up the next sample */
181
private int
182
screen_sample(i_ctx_t *i_ctx_p)
183
{
184
    os_ptr op = osp;
185
    gs_screen_enum *penum = senum;
186
    gs_point pt;
187
    int code = gs_screen_currentpoint(penum, &pt);
188
    ref proc;
189
 
190
    switch (code) {
191
	default:
192
	    return code;
193
	case 1:
194
	    /* All done */
195
	    if (real_opproc(esp - 2) != 0)
196
		code = (*real_opproc(esp - 2)) (i_ctx_p);
197
	    esp -= snumpush;
198
	    screen_cleanup(i_ctx_p);
199
	    return (code < 0 ? code : o_pop_estack);
200
	case 0:
201
	    ;
202
    }
203
    push(2);
204
    make_real(op - 1, pt.x);
205
    make_real(op, pt.y);
206
    proc = sproc;
207
    push_op_estack(set_screen_continue);
208
    *++esp = proc;
209
    return o_push_estack;
210
}
211
/* Continuation procedure for processing sampled pixels. */
212
private int
213
set_screen_continue(i_ctx_t *i_ctx_p)
214
{
215
    os_ptr op = osp;
216
    double value;
217
    int code = real_param(op, &value);
218
 
219
    if (code < 0)
220
	return code;
221
    code = gs_screen_next(senum, value);
222
    if (code < 0)
223
	return code;
224
    pop(1);
225
    return screen_sample(i_ctx_p);
226
}
227
/* Finish setscreen. */
228
private int
229
setscreen_finish(i_ctx_t *i_ctx_p)
230
{
231
    gs_screen_install(senum);
232
    istate->screen_procs.red = sproc;
233
    istate->screen_procs.green = sproc;
234
    istate->screen_procs.blue = sproc;
235
    istate->screen_procs.gray = sproc;
236
    make_null(&istate->halftone);
237
    return 0;
238
}
239
/* Clean up after screen enumeration */
240
private int
241
screen_cleanup(i_ctx_t *i_ctx_p)
242
{
243
    gs_screen_enum *penum = r_ptr(esp + snumpush, gs_screen_enum);
244
 
245
    gs_free_object(penum->halftone.rc.memory, penum, "screen_cleanup");
246
    return 0;
247
}
248
 
249
/* ------ Utility procedures ------ */
250
 
251
/* Get parameters for a single screen. */
252
int
253
zscreen_params(os_ptr op, gs_screen_halftone * phs)
254
{
255
    double fa[2];
256
    int code = num_params(op - 1, 2, fa);
257
 
258
    if (code < 0)
259
	return code;
260
    check_proc(*op);
261
    phs->frequency = fa[0];
262
    phs->angle = fa[1];
263
    return 0;
264
}
265
 
266
/* ------ Initialization procedure ------ */
267
 
268
const op_def zht_op_defs[] =
269
{
270
    {"0.currenthalftone", zcurrenthalftone},
271
    {"0.currentscreenlevels", zcurrentscreenlevels},
272
    {"3setscreen", zsetscreen},
273
		/* Internal operators */
274
    {"0%screen_sample", screen_sample},
275
    {"1%set_screen_continue", set_screen_continue},
276
    {"0%setscreen_finish", setscreen_finish},
277
    op_def_end(0)
278
};