Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/gs/src/gslib.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1995, 2000 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: gslib.c,v 1.15 2004/09/16 08:03:56 igor Exp $ */
18
/* Test program for Ghostscript library */
19
/* Capture stdin/out/err before gsio.h redefines them. */
20
#include "stdio_.h"
21
static FILE *real_stdin, *real_stdout, *real_stderr;
22
static void
23
get_real(void)
24
{
25
    real_stdin = stdin, real_stdout = stdout, real_stderr = stderr;
26
}
27
#include "math_.h"
28
#include "string_.h"
29
#include "gx.h"
30
#include "gp.h"
31
#include "gsalloc.h"
32
#include "gscdefs.h"
33
#include "gserrors.h"
34
#include "gslib.h"
35
#include "gsmatrix.h"
36
#include "gsstate.h"
37
#include "gscspace.h"
38
#include "gscolor2.h"
39
#include "gscoord.h"
40
#include "gscie.h"
41
#include "gscrd.h"
42
#include "gsiparm3.h"
43
#include "gsiparm4.h"
44
#include "gsparam.h"
45
#include "gspaint.h"
46
#include "gspath.h"
47
#include "gspath2.h"
48
#include "gsrop.h"
49
#include "gsstruct.h"
50
#include "gsutil.h"
51
#include "gxalloc.h"
52
#include "gxdcolor.h"		/* for gx_device_white/black */
53
#include "gxdevice.h"
54
#include "gxht.h"		/* for gs_halftone */
55
#include "gdevbbox.h"
56
#include "gdevcmap.h"
57
#include "gshtx.h"
58
 
59
/* Define whether we are processing captured data. */
60
/*#define CAPTURE */
61
 
62
/* Test programs */
63
private int test1(gs_state *, gs_memory_t *);	/* kaleidoscope */
64
private int test2(gs_state *, gs_memory_t *);	/* pattern fill */
65
private int test3(gs_state *, gs_memory_t *);	/* RasterOp */
66
private int test4(gs_state *, gs_memory_t *);	/* set resolution */
67
private int test5(gs_state *, gs_memory_t *);	/* images */
68
private int test6(gs_state *, gs_memory_t *);	/* CIE API, snapping */
69
private int test7(gs_state *, gs_memory_t *);	/* non-monot HT */
70
private int test8(gs_state *, gs_memory_t *);	/* transp patterns */
71
 
72
#ifdef CAPTURE
73
#include "k/capture.c"
74
private int test10(gs_state *, gs_memory_t *);	/* captured data */
75
 
76
#endif
77
private int (*tests[]) (gs_state *, gs_memory_t *) =
78
{
79
    test1, test2, test3, test4, test5,
80
	test6, test7, test8, 0
81
#ifdef CAPTURE
82
	test10
83
#endif
84
};
85
 
86
/* Include the extern for the device list. */
87
extern_gs_lib_device_list();
88
 
89
/* Forward references */
90
private float odsf(floatp, floatp);
91
 
92
 
93
int
94
main(int argc, const char *argv[])
95
{
96
    char achar;
97
    gs_ref_memory_t *imem;
98
 
99
#define mem ((gs_memory_t *)imem)
100
    gs_state *pgs;
101
    const gx_device *const *list;
102
    gx_device *dev;
103
    gx_device_bbox *bbdev;
104
    int code;
105
 
106
    gp_init();
107
    get_real();
108
    gs_stdin = real_stdin;
109
    gs_stdout = real_stdout;
110
    gs_stderr = real_stderr;
111
    gs_lib_init(stdout);
112
    if (argc < 2 || (achar = argv[1][0]) < '1' ||
113
	achar > '0' + countof(tests)
114
	) {
115
	lprintf1("Usage: gslib 1..%c\n", '0' + countof(tests));
116
	exit(1);
117
    }
118
    gs_debug['@'] = 1;
119
    gs_debug['?'] = 1;
120
/*gs_debug['B'] = 1; *//****** PATCH ******/
121
/*gs_debug['L'] = 1; *//****** PATCH ******/
122
    imem = ialloc_alloc_state(&gs_memory_default, 20000);
123
    imem->space = 0;
124
    /*
125
     * gs_iodev_init must be called after the rest of the inits, for
126
     * obscure reasons that really should be documented!
127
     */
128
    gs_iodev_init(mem);
129
/****** WRONG ******/
130
    gs_lib_device_list(&list, NULL);
131
    gs_copydevice(&dev, list[0], mem);
132
    check_device_separable(dev);
133
    gx_device_fill_in_procs(dev);
134
    bbdev =
135
	gs_alloc_struct_immovable(mem, gx_device_bbox, &st_device_bbox,
136
				  "bbox");
137
    gx_device_bbox_init(bbdev, dev, mem);
138
    /* Print out the device name just to test the gsparam.c API. */
139
    {
140
	gs_c_param_list list;
141
	gs_param_string nstr;
142
 
143
	gs_c_param_list_write(&list, mem);
144
	code = gs_getdeviceparams(dev, (gs_param_list *) & list);
145
	if (code < 0) {
146
	    lprintf1("getdeviceparams failed! code = %d\n", code);
147
	    exit(1);
148
	}
149
	gs_c_param_list_read(&list);
150
	code = param_read_string((gs_param_list *) & list, "Name", &nstr);
151
	if (code < 0) {
152
	    lprintf1("reading Name failed! code = %d\n", code);
153
	    exit(1);
154
	}
155
	dputs("Device name = ");
156
	debug_print_string(nstr.data, nstr.size);
157
	dputs("\n");
158
	gs_c_param_list_release(&list);
159
    }
160
    /*
161
     * If this is a device that takes an OutputFile, set the OutputFile
162
     * to "-" in the copy.
163
     */
164
    {
165
	gs_c_param_list list;
166
	gs_param_string nstr;
167
 
168
	gs_c_param_list_write(&list, mem);
169
	param_string_from_string(nstr, "-");
170
	code = param_write_string((gs_param_list *)&list, "OutputFile", &nstr);
171
	if (code < 0) {
172
	    lprintf1("writing OutputFile failed! code = %d\n", code);
173
	    exit(1);
174
	}
175
	gs_c_param_list_read(&list);
176
	code = gs_putdeviceparams(dev, (gs_param_list *)&list);
177
	gs_c_param_list_release(&list);
178
	if (code < 0 && code != gs_error_undefined) {
179
	    lprintf1("putdeviceparams failed! code = %d\n", code);
180
	    exit(1);
181
	}
182
    }
183
    dev = (gx_device *) bbdev;
184
    pgs = gs_state_alloc(mem);
185
    gs_setdevice_no_erase(pgs, dev);	/* can't erase yet */
186
    {
187
	gs_point dpi;
188
	gs_screen_halftone ht;
189
 
190
	gs_dtransform(pgs, 72.0, 72.0, &dpi);
191
	ht.frequency = min(fabs(dpi.x), fabs(dpi.y)) / 16.001;
192
	ht.angle = 0;
193
	ht.spot_function = odsf;
194
	gs_setscreen(pgs, &ht);
195
    }
196
    /* gsave and grestore (among other places) assume that */
197
    /* there are at least 2 gstates on the graphics stack. */
198
    /* Ensure that now. */
199
    gs_gsave(pgs);
200
    gs_erasepage(pgs);
201
 
202
    code = (*tests[achar - '1']) (pgs, mem);
203
    gs_output_page(pgs, 1, 1);
204
    {
205
	gs_rect bbox;
206
 
207
	gx_device_bbox_bbox(bbdev, &bbox);
208
	dprintf4("Bounding box: [%g %g %g %g]\n",
209
		 bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
210
    }
211
    if (code)
212
	dprintf1("**** Test returned code = %d.\n", code);
213
    dputs("Done.  Press <enter> to exit.");
214
    fgetc(gs_stdin);
215
    gs_lib_finit(0, 0);
216
    return 0;
217
#undef mem
218
}
219
/* Ordered dither spot function */
220
private float
221
odsf(floatp x, floatp y)
222
{
223
    static const byte dither[256] =
224
    {
225
	0x0E, 0x8E, 0x2E, 0xAE, 0x06, 0x86, 0x26, 0xA6, 0x0C, 0x8C, 0x2C, 0xAC, 0x04, 0x84, 0x24, 0xA4,
226
	0xCE, 0x4E, 0xEE, 0x6E, 0xC6, 0x46, 0xE6, 0x66, 0xCC, 0x4C, 0xEC, 0x6C, 0xC4, 0x44, 0xE4, 0x64,
227
	0x3E, 0xBE, 0x1E, 0x9E, 0x36, 0xB6, 0x16, 0x96, 0x3C, 0xBC, 0x1C, 0x9C, 0x34, 0xB4, 0x14, 0x94,
228
	0xFE, 0x7E, 0xDE, 0x5E, 0xF6, 0x76, 0xD6, 0x56, 0xFC, 0x7C, 0xDC, 0x5C, 0xF4, 0x74, 0xD4, 0x54,
229
	0x01, 0x81, 0x21, 0xA1, 0x09, 0x89, 0x29, 0xA9, 0x03, 0x83, 0x23, 0xA3, 0x0B, 0x8B, 0x2B, 0xAB,
230
	0xC1, 0x41, 0xE1, 0x61, 0xC9, 0x49, 0xE9, 0x69, 0xC3, 0x43, 0xE3, 0x63, 0xCB, 0x4B, 0xEB, 0x6B,
231
	0x31, 0xB1, 0x11, 0x91, 0x39, 0xB9, 0x19, 0x99, 0x33, 0xB3, 0x13, 0x93, 0x3B, 0xBB, 0x1B, 0x9B,
232
	0xF1, 0x71, 0xD1, 0x51, 0xF9, 0x79, 0xD9, 0x59, 0xF3, 0x73, 0xD3, 0x53, 0xFB, 0x7B, 0xDB, 0x5B,
233
	0x0D, 0x8D, 0x2D, 0xAD, 0x05, 0x85, 0x25, 0xA5, 0x0F, 0x8F, 0x2F, 0xAF, 0x07, 0x87, 0x27, 0xA7,
234
	0xCD, 0x4D, 0xED, 0x6D, 0xC5, 0x45, 0xE5, 0x65, 0xCF, 0x4F, 0xEF, 0x6F, 0xC7, 0x47, 0xE7, 0x67,
235
	0x3D, 0xBD, 0x1D, 0x9D, 0x35, 0xB5, 0x15, 0x95, 0x3F, 0xBF, 0x1F, 0x9F, 0x37, 0xB7, 0x17, 0x97,
236
	0xFD, 0x7D, 0xDD, 0x5D, 0xF5, 0x75, 0xD5, 0x55, 0xFF, 0x7F, 0xDF, 0x5F, 0xF7, 0x77, 0xD7, 0x57,
237
	0x02, 0x82, 0x22, 0xA2, 0x0A, 0x8A, 0x2A, 0xAA, 0x00, 0x80, 0x20, 0xA0, 0x08, 0x88, 0x28, 0xA8,
238
	0xC2, 0x42, 0xE2, 0x62, 0xCA, 0x4A, 0xEA, 0x6A, 0xC0, 0x40, 0xE0, 0x60, 0xC8, 0x48, 0xE8, 0x68,
239
	0x32, 0xB2, 0x12, 0x92, 0x3A, 0xBA, 0x1A, 0x9A, 0x30, 0xB0, 0x10, 0x90, 0x38, 0xB8, 0x18, 0x98,
240
	0xF2, 0x72, 0xD2, 0x52, 0xFA, 0x7A, 0xDA, 0x5A, 0xF0, 0x70, 0xD0, 0x50, 0xF8, 0x78, 0xD8, 0x58
241
    };
242
    int i = (int)((x + 1) * 7.9999);
243
    int j = (int)((y + 1) * 7.9999);
244
 
245
    return dither[16 * i + j] / 256.0;
246
}
247
 
248
/* Fill a rectangle. */
249
private int
250
fill_rect1(gs_state * pgs, floatp x, floatp y, floatp w, floatp h)
251
{
252
    gs_rect r;
253
 
254
    r.q.x = (r.p.x = x) + w;
255
    r.q.y = (r.p.y = y) + h;
256
    return gs_rectfill(pgs, &r, 1);
257
}
258
 
259
/* Stubs for GC */
260
const gs_ptr_procs_t ptr_struct_procs =
261
{NULL, NULL, NULL};
262
const gs_ptr_procs_t ptr_string_procs =
263
{NULL, NULL, NULL};
264
const gs_ptr_procs_t ptr_const_string_procs =
265
{NULL, NULL, NULL};
266
void *				/* obj_header_t * */
267
gs_reloc_struct_ptr(const void * /* obj_header_t * */ obj, gc_state_t * gcst)
268
{
269
    return (void *)obj;
270
}
271
void
272
gs_reloc_string(gs_string * sptr, gc_state_t * gcst)
273
{
274
}
275
void
276
gs_reloc_const_string(gs_const_string * sptr, gc_state_t * gcst)
277
{
278
}
279
 
280
/* Other stubs */
281
void
282
gs_to_exit(const gs_memory_t *mem, int exit_status)
283
{
284
    gs_lib_finit(mem, exit_status, 0);
285
}
286
 
287
void
288
gs_abort(const gs_memory_t *mem)
289
{
290
    gs_to_exit(mem, 1); /* cleanup */
291
    gp_do_exit(1); /* system independent exit() */	
292
}
293
 
294
 
295
/* Return the number with the magnitude of x and the sign of y. */
296
/* This is a BSD addition to libm; not all compilers have it. */
297
private double
298
gs_copysign(floatp x, floatp y)
299
{
300
   return ( y >= 0  ? fabs(x) : -fabs(x) );
301
}
302
 
303
 
304
/* ---------------- Test program 1 ---------------- */
305
/* Draw a colored kaleidoscope. */
306
 
307
/* Random number generator */
308
private long rand_state = 1;
309
private long
310
rand(void)
311
{
312
#define A 16807
313
#define M 0x7fffffff
314
#define Q 127773		/* M / A */
315
#define R 2836			/* M % A */
316
    rand_state = A * (rand_state % Q) - R * (rand_state / Q);
317
    /* Note that rand_state cannot be 0 here. */
318
    if (rand_state <= 0)
319
	rand_state += M;
320
#undef A
321
#undef M
322
#undef Q
323
#undef R
324
    return rand_state;
325
}
326
private int
327
test1(gs_state * pgs, gs_memory_t * mem)
328
{
329
    int n;
330
 
331
    gs_scale(pgs, 72.0, 72.0);
332
    gs_translate(pgs, 4.25, 5.5);
333
    gs_scale(pgs, 4.0, 4.0);
334
    gs_newpath(pgs);
335
    for (n = 200; --n >= 0;) {
336
	int j;
337
 
338
#define rf() (rand() / (1.0 * 0x10000 * 0x8000))
339
	double r = rf(), g = rf(), b = rf();
340
	double x0 = rf(), y0 = rf(), x1 = rf(), y1 = rf(), x2 = rf(), y2 = rf();
341
 
342
	gs_setrgbcolor(pgs, r, g, b);
343
	for (j = 0; j < 6; j++) {
344
	    gs_gsave(pgs);
345
	    gs_rotate(pgs, 60.0 * j);
346
	    gs_moveto(pgs, x0, y0);
347
	    gs_lineto(pgs, x1, y1);
348
	    gs_lineto(pgs, x2, y2);
349
	    gs_fill(pgs);
350
	    gs_grestore(pgs);
351
	}
352
    }
353
#undef mem
354
    return 0;
355
}
356
 
357
/* ---------------- Test program 2 ---------------- */
358
/* Fill an area with a pattern. */
359
 
360
private int
361
test2(gs_state * pgs, gs_memory_t * mem)
362
{
363
    gs_client_color cc;
364
    gx_tile_bitmap tile;
365
    /*const */ byte tpdata[] =
366
    {
367
    /* Define a pattern that looks like this:
368
       ..xxxx
369
       .....x
370
       .....x
371
       ..xxxx
372
       .x....
373
       x.....
374
     */
375
	0x3c, 0, 0, 0, 0x04, 0, 0, 0, 0x04, 0, 0, 0, 0x3c, 0, 0, 0,
376
	0x40, 0, 0, 0, 0x80, 0, 0, 0
377
    };
378
 
379
    gs_newpath(pgs);
380
    gs_moveto(pgs, 100.0, 300.0);
381
    gs_lineto(pgs, 500.0, 500.0);
382
    gs_lineto(pgs, 200.0, 100.0);
383
    gs_lineto(pgs, 300.0, 500.0);
384
    gs_lineto(pgs, 500.0, 200.0);
385
    gs_closepath(pgs);
386
    gs_setrgbcolor(pgs, 0.0, 0.0, 0.0);
387
    gs_gsave(pgs);
388
    gs_fill(pgs);
389
    gs_grestore(pgs);
390
    tile.data = tpdata;
391
    tile.raster = 4;
392
    tile.size.x = tile.rep_width = 6;
393
    tile.size.y = tile.rep_height = 6;
394
    tile.id = gx_no_bitmap_id;
395
    gs_makebitmappattern(&cc, &tile, true, pgs, NULL);
396
    /* Note: color space is DeviceRGB */
397
    cc.paint.values[0] = 0.0;
398
    cc.paint.values[1] = 1.0;
399
    cc.paint.values[2] = 1.0;
400
    gs_setpattern(pgs, &cc);
401
    gs_eofill(pgs);
402
    gs_makebitmappattern(&cc, &tile, false, pgs, NULL);
403
    gs_setcolor(pgs, &cc);
404
    gs_moveto(pgs, 50.0, 50.0);
405
    gs_lineto(pgs, 300.0, 50.0);
406
    gs_lineto(pgs, 50.0, 300.0);
407
    gs_closepath(pgs);
408
    gs_setrgbcolor(pgs, 1.0, 0.0, 0.0);
409
    gs_gsave(pgs);
410
    gs_fill(pgs);
411
    gs_grestore(pgs);
412
    gs_setpattern(pgs, &cc);
413
    gs_eofill(pgs);
414
    return 0;
415
}
416
 
417
/* ---------------- Test program 3 ---------------- */
418
/* Exercise RasterOp a little. */
419
/* Currently, this only works with monobit devices. */
420
 
421
private int
422
test3(gs_state * pgs, gs_memory_t * mem)
423
{
424
    gx_device *dev = gs_currentdevice(pgs);
425
    gx_color_index black = gx_device_black(dev);
426
    gx_color_index white = gx_device_white(dev);
427
    gx_color_index black2[2];
428
    gx_color_index black_white[2];
429
    gx_color_index white_black[2];
430
    long pattern[max(align_bitmap_mod / sizeof(long), 1) * 4];
431
 
432
#define pbytes ((byte *)pattern)
433
    gx_tile_bitmap tile;
434
 
435
    black2[0] = black2[1] = black;
436
    black_white[0] = white_black[1] = black;
437
    black_white[1] = white_black[0] = white;
438
    pbytes[0] = 0xf0;
439
    pbytes[align_bitmap_mod] = 0x90;
440
    pbytes[align_bitmap_mod * 2] = 0x90;
441
    pbytes[align_bitmap_mod * 3] = 0xf0;
442
    tile.data = pbytes;
443
    tile.raster = align_bitmap_mod;
444
    tile.size.x = tile.size.y = 4;
445
    tile.id = gs_next_ids(1);
446
    tile.rep_width = tile.rep_height = 4;
447
    (*dev_proc(dev, copy_rop))
448
	(dev, NULL, 0, 0, gx_no_bitmap_id, black2,
449
	 &tile, white_black, 100, 100, 150, 150, 0, 0, rop3_T);
450
    (*dev_proc(dev, copy_rop))
451
	(dev, NULL, 0, 0, gx_no_bitmap_id, black2,
452
	 NULL, NULL, 120, 120, 110, 110, 0, 0, ~rop3_S & rop3_1);
453
    (*dev_proc(dev, copy_rop))
454
	(dev, NULL, 0, 0, gx_no_bitmap_id, black2,
455
	 &tile, white_black, 110, 110, 130, 130, 0, 0, rop3_T ^ rop3_D);
456
#undef pbytes
457
    return 0;
458
}
459
 
460
/* ---------------- Test program 4 ---------------- */
461
/* Set the resolution dynamically. */
462
 
463
private int
464
test4(gs_state * pgs, gs_memory_t * mem)
465
{
466
    gs_c_param_list list;
467
    float resv[2];
468
    gs_param_float_array ares;
469
    int code;
470
    gx_device *dev = gs_currentdevice(pgs);
471
 
472
    gs_c_param_list_write(&list, mem);
473
    resv[0] = resv[1] = 100;
474
    ares.data = resv;
475
    ares.size = 2;
476
    ares.persistent = true;
477
    code = param_write_float_array((gs_param_list *) & list,
478
				   "HWResolution", &ares);
479
    if (code < 0) {
480
	lprintf1("Writing HWResolution failed: %d\n", code);
481
	exit(1);
482
    }
483
    gs_c_param_list_read(&list);
484
    code = gs_putdeviceparams(dev, (gs_param_list *) & list);
485
    gs_c_param_list_release(&list);
486
    if (code < 0) {
487
	lprintf1("Setting HWResolution failed: %d\n", code);
488
	exit(1);
489
    }
490
    gs_initmatrix(pgs);
491
    gs_initclip(pgs);
492
    if (code == 1) {
493
	code = (*dev_proc(dev, open_device)) (dev);
494
	if (code < 0) {
495
	    lprintf1("Reopening device failed: %d\n", code);
496
	    exit(1);
497
	}
498
    }
499
    gs_moveto(pgs, 0.0, 72.0);
500
    gs_rlineto(pgs, 72.0, 0.0);
501
    gs_rlineto(pgs, 0.0, 72.0);
502
    gs_closepath(pgs);
503
    gs_stroke(pgs);
504
    return 0;
505
}
506
 
507
/* ---------------- Test program 5 ---------------- */
508
/* Test masked (and non-masked) images. */
509
 
510
private int
511
test5(gs_state * pgs, gs_memory_t * mem)
512
{
513
    gx_device *dev = gs_currentdevice(pgs);
514
    gx_image_enum_common_t *info;
515
    gx_image_plane_t planes[5];
516
    gx_drawing_color dcolor;
517
    int code;
518
    static const byte data3[] =
519
    {
520
	0x00, 0x44, 0x88, 0xcc,
521
	0x44, 0x88, 0xcc, 0x00,
522
	0x88, 0xcc, 0x00, 0x44,
523
	0xcc, 0x00, 0x44, 0x88
524
    };
525
    gs_color_space gray_cs;
526
 
527
    gs_cspace_init_DeviceGray(&gray_cs);
528
 
529
    /*
530
     * Neither ImageType 3 nor 4 needs a current color,
531
     * but some intermediate code assumes it's valid.
532
     */
533
    set_nonclient_dev_color(&dcolor, 0);
534
 
535
    /* Scale everything up, and fill the background. */
536
    {
537
	gs_matrix mat;
538
 
539
	gs_currentmatrix(pgs, &mat);
540
	mat.xx = gs_copysign(98.6, mat.xx);
541
	mat.yy = gs_copysign(98.6, mat.yy);
542
	mat.tx = floor(mat.tx) + 0.499;
543
	mat.ty = floor(mat.ty) + 0.499;
544
	gs_setmatrix(pgs, &mat);
545
    }
546
    gs_setrgbcolor(pgs, 1.0, 0.9, 0.9);
547
    fill_rect1(pgs, 0.25, 0.25, 4.0, 6.0);
548
    gs_setrgbcolor(pgs, 0.5, 1.0, 0.5);
549
 
550
#if 0
551
    /* Make things a little more interesting.... */
552
    gs_translate(pgs, 1.0, 1.0);
553
    gs_rotate(pgs, 10.0);
554
    gs_scale(pgs, 1.3, 0.9);
555
#endif
556
 
557
#define do_image(image, idata)\
558
  BEGIN\
559
  code = gx_device_begin_typed_image(dev, (gs_imager_state *)pgs, NULL,\
560
     (gs_image_common_t *)&image, NULL, &dcolor, NULL, mem, &info);\
561
  /****** TEST code >= 0 ******/\
562
  planes[0].data = idata;\
563
  planes[0].data_x = 0;\
564
  planes[0].raster = (image.Height * image.BitsPerComponent + 7) >> 3;\
565
  code = gx_image_plane_data(info, planes, image.Height);\
566
  /****** TEST code == 1 ******/\
567
  code = gx_image_end(info, true);\
568
  /****** TEST code >= 0 ******/\
569
  END
570
 
571
#define W 4
572
#define H 4
573
 
574
    /* Test an unmasked image. */
575
    gs_gsave(pgs);
576
    {
577
	gs_image1_t image1;
578
	void *info1;
579
        gs_color_space cs;
580
 
581
        gs_cspace_init_DeviceGray(&cs);
582
	gs_image_t_init(&image1, &cs);
583
	/* image */
584
	image1.ImageMatrix.xx = W;
585
	image1.ImageMatrix.yy = -H;
586
	image1.ImageMatrix.ty = H;
587
	/* data_image */
588
	image1.Width = W;
589
	image1.Height = H;
590
	image1.BitsPerComponent = 8;
591
 
592
	gs_translate(pgs, 0.5, 4.0);
593
	code = gx_device_begin_image(dev, (gs_imager_state *) pgs,
594
				     &image1, gs_image_format_chunky,
595
				     NULL, &dcolor, NULL, mem, &info1);
596
/****** TEST code >= 0 ******/
597
	planes[0].data = data3;
598
	planes[0].data_x = 0;
599
	planes[0].raster =
600
	    (image1.Height * image1.BitsPerComponent + 7) >> 3;
601
	/* Use the old image_data API. */
602
	code = gx_image_data(info1, &planes[0].data, 0,
603
			     planes[0].raster, image1.Height);
604
/****** TEST code == 1 ******/
605
	code = gx_image_end(info1, true);
606
/****** TEST code >= 0 ******/
607
    }
608
    gs_grestore(pgs);
609
 
610
    /* Test an explicitly masked image. */
611
    gs_gsave(pgs);
612
    {
613
	gs_image3_t image3;
614
	static const byte data3mask[] =
615
	{
616
	    0x60,
617
	    0x90,
618
	    0x90,
619
	    0x60
620
	};
621
	static const byte data3x2mask[] =
622
	{
623
	    0x66,
624
	    0x99,
625
	    0x99,
626
	    0x66,
627
	    0x66,
628
	    0x99,
629
	    0x99,
630
	    0x66
631
	};
632
 
633
	gs_image3_t_init(&image3, &gray_cs, interleave_scan_lines);
634
	/* image */
635
	image3.ImageMatrix.xx = W;
636
	image3.ImageMatrix.yy = -H;
637
	image3.ImageMatrix.ty = H;
638
	/* data_image */
639
	image3.Width = W;
640
	image3.Height = H;
641
	image3.BitsPerComponent = 8;
642
	/* MaskDict */
643
	image3.MaskDict.ImageMatrix = image3.ImageMatrix;
644
	image3.MaskDict.Width = image3.Width;
645
	image3.MaskDict.Height = image3.Height;
646
 
647
	/* Display with 1-for-1 mask and image. */
648
	gs_translate(pgs, 0.5, 2.0);
649
	code = gx_device_begin_typed_image(dev, (gs_imager_state *) pgs,
650
				       NULL, (gs_image_common_t *) & image3,
651
					   NULL, &dcolor, NULL, mem, &info);
652
/****** TEST code >= 0 ******/
653
	planes[0].data = data3mask;
654
	planes[0].data_x = 0;
655
	planes[0].raster = (image3.MaskDict.Height + 7) >> 3;
656
	planes[1].data = data3;
657
	planes[1].data_x = 0;
658
	planes[1].raster =
659
	    (image3.Height * image3.BitsPerComponent + 7) >> 3;
660
	code = gx_image_plane_data(info, planes, image3.Height);
661
/****** TEST code == 1 ******/
662
	code = gx_image_end(info, true);
663
/****** TEST code >= 0 ******/
664
 
665
	/* Display with 2-for-1 mask and image. */
666
	image3.MaskDict.ImageMatrix.xx *= 2;
667
	image3.MaskDict.ImageMatrix.yy *= 2;
668
	image3.MaskDict.ImageMatrix.ty *= 2;
669
	image3.MaskDict.Width *= 2;
670
	image3.MaskDict.Height *= 2;
671
	gs_translate(pgs, 1.5, 0.0);
672
	code = gx_device_begin_typed_image(dev, (gs_imager_state *) pgs,
673
				       NULL, (gs_image_common_t *) & image3,
674
					   NULL, &dcolor, NULL, mem, &info);
675
/****** TEST code >= 0 ******/
676
	planes[0].data = data3x2mask;
677
	planes[0].raster = (image3.MaskDict.Width + 7) >> 3;
678
	{
679
	    int i;
680
 
681
	    for (i = 0; i < H; ++i) {
682
		planes[1].data = 0;
683
		code = gx_image_plane_data(info, planes, 1);
684
		planes[0].data += planes[0].raster;
685
/****** TEST code == 0 ******/
686
		planes[1].data = data3 + i * planes[1].raster;
687
		code = gx_image_plane_data(info, planes, 1);
688
		planes[0].data += planes[0].raster;
689
/****** TEST code >= 0 ******/
690
	    }
691
	}
692
/****** TEST code == 1 ******/
693
	code = gx_image_end(info, true);
694
/****** TEST code >= 0 ******/
695
    }
696
    gs_grestore(pgs);
697
 
698
    /* Test a chroma-keyed masked image. */
699
    gs_gsave(pgs);
700
    {
701
	gs_image4_t image4;
702
	const byte *data4 = data3;
703
 
704
	gs_image4_t_init(&image4, &gray_cs);
705
	/* image */
706
	image4.ImageMatrix.xx = W;
707
	image4.ImageMatrix.yy = -H;
708
	image4.ImageMatrix.ty = H;
709
	/* data_image */
710
	image4.Width = W;
711
	image4.Height = H;
712
	image4.BitsPerComponent = 8;
713
 
714
	/* Display with a single mask color. */
715
	gs_translate(pgs, 0.5, 0.5);
716
	image4.MaskColor_is_range = false;
717
	image4.MaskColor[0] = 0xcc;
718
	do_image(image4, data4);
719
 
720
	/* Display a second time with a color range. */
721
	gs_translate(pgs, 1.5, 0.0);
722
	image4.MaskColor_is_range = true;
723
	image4.MaskColor[0] = 0x40;
724
	image4.MaskColor[1] = 0x90;
725
	do_image(image4, data4);
726
    }
727
    gs_grestore(pgs);
728
 
729
#undef W
730
#undef H
731
#undef do_image
732
    return 0;
733
}
734
 
735
/* ---------------- Test program 6 ---------------- */
736
/* Test the C API for CIE CRDs, and color snapping. */
737
 
738
private void
739
spectrum(gs_state * pgs, int n)
740
{
741
    float den = n;
742
    float den1 = n - 1;
743
    float den2 = (n * 2 - 1) * n;
744
    int a, b, c;
745
 
746
    for (a = 0; a < n; ++a)
747
	for (b = 0; b < n; ++b)
748
	    for (c = 0; c < n; ++c) {
749
		double size = (n * 2 - c * 2 - 1) / den2;
750
		gs_client_color cc;
751
 
752
		cc.paint.values[0] = a / den1;
753
		cc.paint.values[1] = b / den1;
754
		cc.paint.values[2] = c / den1;
755
		gs_setcolor(pgs, &cc);
756
		fill_rect1(pgs,
757
			   a / den + c / den2, b / den + c / den2,
758
			   size, size);
759
	    }
760
}
761
private float
762
render_abc(floatp v, const gs_cie_render * ignore_crd)
763
{
764
    return v / 2;
765
}
766
private int
767
set_cmap_method(gx_device_cmap *cmdev, gx_device_color_mapping_method_t method,
768
		gs_state *pgs, gs_memory_t *mem)
769
{
770
    gs_c_param_list list;
771
    int cmm = method;
772
 
773
    gs_c_param_list_write(&list, mem);
774
    param_write_int((gs_param_list *)&list, "ColorMappingMethod", &cmm);
775
    gs_c_param_list_read(&list);
776
    gs_putdeviceparams((gx_device *)cmdev, (gs_param_list *)&list);
777
    gs_c_param_list_release(&list);
778
    gs_setdevice_no_init(pgs, (gx_device *)cmdev);
779
    return 0;
780
}
781
private int
782
test6(gs_state * pgs, gs_memory_t * mem)
783
{
784
    gs_color_space *pcs;
785
    gs_cie_abc *pabc;
786
    gs_cie_render *pcrd;
787
    static const gs_vector3 white_point =
788
    {1, 1, 1};
789
    static const gs_cie_render_proc3 encode_abc =
790
    {
791
	{render_abc, render_abc, render_abc}
792
    };
793
    gx_device_cmap *cmdev;
794
    int code;
795
    gs_color_space rgb_cs;
796
 
797
    gs_cspace_init_DeviceRGB(&rgb_cs);
798
 
799
    gs_scale(pgs, 150.0, 150.0);
800
    gs_translate(pgs, 0.5, 0.5);
801
    gs_setcolorspace(pgs, &rgb_cs);
802
    spectrum(pgs, 5);
803
    gs_translate(pgs, 1.2, 0.0);
804
    /* We must set the CRD before the color space. */
805
    code = gs_cie_render1_build(&pcrd, mem, "test6");
806
    if (code < 0)
807
	return code;
808
    gs_cie_render1_initialize(pcrd, NULL, &white_point, NULL,
809
			      NULL, NULL, NULL,
810
			      NULL, NULL, NULL,
811
			      NULL, &encode_abc, NULL,
812
			      NULL);
813
    gs_setcolorrendering(pgs, pcrd);
814
    gs_cspace_build_CIEABC(&pcs, NULL, mem);
815
    /* There should be an API for initializing CIE color spaces too.... */
816
    pabc = pcs->params.abc;
817
    pabc->common.points.WhitePoint = white_point;
818
    gs_cie_abc_complete(pabc);
819
    /* End of initializing the color space. */
820
    gs_setcolorspace(pgs, pcs);
821
    spectrum(pgs, 5);
822
    /* Now test color snapping. */
823
    cmdev =
824
	gs_alloc_struct_immovable(mem, gx_device_cmap, &st_device_cmap,
825
				  "cmap device");
826
    gdev_cmap_init(cmdev, gs_currentdevice(pgs),
827
		   device_cmap_snap_to_primaries);
828
    gs_setdevice_no_init(pgs, (gx_device *) cmdev);
829
    gs_setrgbcolor(pgs, 0.0, 0.0, 0.0);		/* back to DeviceRGB space */
830
    gs_translate(pgs, -1.2, 1.2);
831
    spectrum(pgs, 5);
832
    gs_translate(pgs, 1.2, 0.0);
833
    set_cmap_method(cmdev, device_cmap_monochrome, pgs, mem);
834
    spectrum(pgs, 5);
835
    gs_translate(pgs, -1.2, 1.2);
836
    set_cmap_method(cmdev, device_cmap_color_to_black_over_white, pgs, mem);
837
    spectrum(pgs, 5);
838
    return 0;
839
}
840
 
841
/* ---------------- Test program 7 ---------------- */
842
/* Test the C API for non-monotonic halftones. */
843
 
844
private int
845
test7(gs_state * pgs, gs_memory_t * mem)
846
{
847
    /* Define a non-monotonic 4 x 4 halftone with 4 gray levels. */
848
    static const byte masks[1 * 4 * 4] =
849
    {
850
    /* 0% */
851
	0x00, 0x00, 0x00, 0x00,
852
    /* 25% */
853
	0x80, 0x40, 0x20, 0x10,
854
    /* 50% */
855
	0xa0, 0xa0, 0x50, 0x50,
856
    /* 75% */
857
	0xd0, 0xe0, 0x70, 0xb0
858
    };
859
    gs_ht *pht;
860
    int code;
861
    int i;
862
 
863
    /* Fabricate a Type 5 halftone. */
864
    code = gs_ht_build(&pht, 1, mem);
865
    dprintf1("ht build code = %d\n", code);
866
    code = gs_ht_set_mask_comp(pht, 0,
867
			       4, 4, 4, masks, NULL, NULL);
868
    dprintf1("set mask code = %d\n", code);
869
    code = gs_sethalftone(pgs, pht);
870
    dprintf1("sethalftone code = %d\n", code);
871
    for (i = 0; i <= 4; ++i) {
872
	gs_setgray(pgs, i / 4.0);
873
	fill_rect1(pgs, 100 + i * 100, 100, 50, 50);
874
    }
875
    return 0;
876
}
877
 
878
/* ---------------- Test program 8 ---------------- */
879
/* Test partially transparent patterns */
880
 
881
private int
882
test8(gs_state * pgs, gs_memory_t * mem)
883
{
884
    /*
885
     * Define a 16 x 16 pattern using a 4-entry palette
886
     * (white, red, green, black).
887
     */
888
    static const byte pdata[] =
889
    {
890
	0x7f, 0xff, 0x00, 0x03,
891
	0x7f, 0xff, 0x00, 0x0c,
892
	0x50, 0x00, 0x00, 0x30,
893
	0x50, 0x00, 0x00, 0xc0,
894
	0x50, 0x00, 0x03, 0x00,
895
	0x50, 0x00, 0x0c, 0x00,
896
	0x50, 0x00, 0x30, 0x00,
897
	0x50, 0x00, 0xc0, 0x00,
898
	0xf0, 0x00, 0xc0, 0x00,
899
	0xf0, 0x00, 0x30, 0x00,
900
	0xf0, 0x00, 0x0c, 0x00,
901
	0xf0, 0x00, 0x03, 0x00,
902
	0xf0, 0x00, 0x00, 0xc0,
903
	0xf0, 0x00, 0x00, 0x30,
904
	0xea, 0x55, 0xaa, 0x5c,
905
	0xea, 0x55, 0xaa, 0x57,
906
    };
907
    gs_depth_bitmap ptile;
908
    gs_const_string table;
909
    gs_color_space *pcs;
910
    gs_client_color ccolor;
911
    gs_color_space rgb_cs;
912
 
913
    gs_cspace_init_DeviceRGB(&rgb_cs);
914
 
915
    table.data =
916
	(const byte *)"\377\377\377\377\000\000\000\377\000\000\000\000";
917
    table.size = 12;
918
    gs_cspace_build_Indexed(&pcs, &rgb_cs, 4, &table, mem);
919
    ptile.data = pdata;
920
    ptile.raster = 4;
921
    ptile.size.x = ptile.size.y = 16;
922
    ptile.id = gs_no_bitmap_id;
923
    ptile.pix_depth = 2;
924
    ptile.num_comps = 1;
925
    gs_makepixmappattern(&ccolor, &ptile, false /*mask */ , NULL /*pmat */ ,
926
			 gs_no_id, pcs, 0 /*white_index */ , pgs, mem);
927
    {
928
	gs_rect r;
929
 
930
	r.p.x = 100;
931
	r.p.y = 100;
932
	r.q.x = 200;
933
	r.q.y = 200;
934
	gs_setrgbcolor(pgs, 1.0, 1.0, 0.0);
935
	gs_rectfill(pgs, &r, 1);
936
	gs_setpattern(pgs, &ccolor);
937
	gs_settexturetransparent(pgs, true);
938
	gs_rectfill(pgs, &r, 1);
939
	r.p.x += 150;
940
	r.q.x += 150;
941
	gs_setrgbcolor(pgs, 1.0, 1.0, 0.0);
942
	gs_rectfill(pgs, &r, 1);
943
	gs_setpattern(pgs, &ccolor);
944
	gs_settexturetransparent(pgs, false);
945
	gs_rectfill(pgs, &r, 1);
946
    }
947
    return 0;
948
}
949
 
950
 
951
#ifdef CAPTURE
952
 
953
/* ---------------- Test program 10 ---------------- */
954
/* Replay captured data for printer output. */
955
 
956
private const char outfile[] = "t.pbm";
957
private const float ypage_wid = 11.0;
958
private const float xpage_len = 17.0;
959
private const int rotate_value = 0;
960
private const float scale_x = 0.45;
961
private const float scale_y = 0.45;
962
private const float xmove_origin = 0.0;
963
private const float ymove_origin = 0.0;
964
 
965
private int
966
test10(gs_state * pgs, gs_memory_t * mem)
967
{
968
    gs_c_param_list list;
969
    gs_param_string nstr, OFstr;
970
    gs_param_float_array PSa;
971
    gs_param_float_array HWRa;
972
    gs_param_int_array HWSa;
973
    int HWSize[2];
974
    float HWResolution[2], PageSize[2];
975
    long MaxBitmap;
976
    int code;
977
    gx_device *dev = gs_currentdevice(pgs);
978
    float xlate_x, xlate_y;
979
    gs_rect cliprect;
980
 
981
    gs_c_param_list_write(&list, mem);
982
    code = gs_getdeviceparams(dev, (gs_param_list *) & list);
983
    if (code < 0) {
984
	lprintf1("getdeviceparams failed! code = %d\n", code);
985
	exit(1);
986
    }
987
    gs_c_param_list_read(&list);
988
    code = param_read_string((gs_param_list *) & list, "Name", &nstr);
989
    if (code < 0) {
990
	lprintf1("reading Name failed! code = %d\n", code);
991
	exit(1);
992
    }
993
    code = param_read_int_array((gs_param_list *) & list,
994
				"HWSize", &HWSa);
995
    if (code < 0) {
996
	lprintf1("reading HWSize failed! code = %d\n", code);
997
	exit(1);
998
    }
999
    eprintf3("HWSize[%d] = [ %d, %d ]\n", HWSa.size,
1000
	     HWSa.data[0], HWSa.data[1]);
1001
    code = param_read_float_array((gs_param_list *) & list,
1002
				  "HWResolution", &HWRa);
1003
    if (code < 0) {
1004
	lprintf1("reading Resolution failed! code = %d\n", code);
1005
	exit(1);
1006
    }
1007
    eprintf3("HWResolution[%d] = [ %f, %f ]\n", HWRa.size,
1008
	     HWRa.data[0], HWRa.data[1]);
1009
    code = param_read_float_array((gs_param_list *) & list,
1010
				  "PageSize", &PSa);
1011
    if (code < 0) {
1012
	lprintf1("reading PageSize failed! code = %d\n", code);
1013
	exit(1);
1014
    }
1015
    eprintf3("PageSize[%d] = [ %f, %f ]\n", PSa.size,
1016
	     PSa.data[0], PSa.data[1]);
1017
    code = param_read_long((gs_param_list *) & list,
1018
			   "MaxBitmap", &MaxBitmap);
1019
    if (code < 0) {
1020
	lprintf1("reading MaxBitmap failed! code = %d\n", code);
1021
	exit(1);
1022
    }
1023
    eprintf1("MaxBitmap = %ld\n", MaxBitmap);
1024
    /* Switch to param list functions to "write" */
1025
    gs_c_param_list_write(&list, mem);
1026
    /* Always set the PageSize. */
1027
    PageSize[0] = 72.0 * ypage_wid;
1028
    PageSize[1] = 72.0 * xpage_len;
1029
    PSa.data = PageSize;
1030
    code = param_write_float_array((gs_param_list *) & list,
1031
				   "PageSize", &PSa);
1032
    if (nstr.data[0] != 'v') {
1033
	/* Set the OutputFile string file name */
1034
	OFstr.persistent = false;
1035
	OFstr.data = outfile;
1036
	OFstr.size = strlen(outfile);
1037
	code = param_write_string((gs_param_list *) & list,
1038
				  "OutputFile", &OFstr);
1039
	if (code < 0) {
1040
	    lprintf1("setting OutputFile name failed, code=%d\n",
1041
		     code);
1042
	    exit(1);
1043
	}
1044
	if (nstr.data[0] == 'x') {
1045
	    HWResolution[0] = HWResolution[1] = 72.0;
1046
	} else {
1047
	    HWResolution[0] = HWResolution[1] = 360.0;
1048
	}
1049
	HWRa.data = HWResolution;
1050
	HWSize[0] = (int)(HWResolution[0] * ypage_wid);
1051
	HWSize[1] = (int)(HWResolution[1] * xpage_len);
1052
	eprintf3("	HWSize = [%d,%d], HWResolution = %f dpi\n",
1053
		 HWSize[0], HWSize[1], HWResolution[0]);
1054
	HWSa.data = HWSize;
1055
	code = param_write_float_array((gs_param_list *) & list,
1056
				       "HWResolution", &HWRa);
1057
	code = param_write_int_array((gs_param_list *) & list,
1058
				     "HWSize", &HWSa);
1059
	MaxBitmap = 1000000L;
1060
	code = param_write_long((gs_param_list *) & list,
1061
				"MaxBitmap", &MaxBitmap);
1062
    }
1063
    gs_c_param_list_read(&list);
1064
    code = gs_putdeviceparams(dev, (gs_param_list *) & list);
1065
    eprintf1("putdeviceparams: code=%d\n", code);
1066
    gs_c_param_list_release(&list);
1067
 
1068
    /* note: initgraphics no longer resets the color or color space */
1069
    gs_erasepage(pgs);
1070
    gs_initgraphics(pgs);
1071
    {
1072
        gs_color_space cs;
1073
 
1074
        gs_cspace_init_DeviceGray(&cs);
1075
        gs_setcolorspace(pgs, &cs);
1076
    }
1077
 
1078
    gs_clippath(pgs);
1079
    gs_pathbbox(pgs, &cliprect);
1080
    eprintf4("	cliprect = [[%g,%g],[%g,%g]]\n",
1081
	     cliprect.p.x, cliprect.p.y, cliprect.q.x, cliprect.q.y);
1082
    gs_newpath(pgs);
1083
 
1084
    switch (((rotate_value + 270) / 90) & 3) {
1085
	default:
1086
	case 0:		/* 0 = 360 degrees in PS == 90 degrees in printer */
1087
	    xlate_x = cliprect.p.x;
1088
	    xlate_y = cliprect.p.y;
1089
	    break;
1090
	case 1:		/* 90 degrees in PS = 180 degrees printer */
1091
	    xlate_x = cliprect.q.x;
1092
	    xlate_y = cliprect.p.y;
1093
	    break;
1094
	case 2:		/* 180 degrees in PS == 270 degrees in printer */
1095
	    xlate_x = cliprect.q.x;
1096
	    xlate_y = cliprect.q.y;
1097
	    break;
1098
	case 3:		/* 270 degrees in PS == 0 degrees in printer */
1099
	    xlate_x = cliprect.p.x;
1100
	    xlate_y = cliprect.q.y;
1101
	    break;
1102
    }
1103
    eprintf2("translate origin to [ %f, %f ]\n", xlate_x, xlate_y);
1104
    gs_translate(pgs, xlate_x, xlate_y);
1105
 
1106
    /* further move (before rotate) by user requested amount */
1107
    gs_translate(pgs, 72.0 * (float)xmove_origin, 72.0 * (float)ymove_origin);
1108
 
1109
    gs_rotate(pgs, (float)rotate_value + 270.0);
1110
    gs_scale(pgs, scale_x * 72.0 / 2032.0,
1111
	     scale_y * 72.0 / 2032.0);
1112
    gs_setlinecap(pgs, gs_cap_butt);
1113
    gs_setlinejoin(pgs, gs_join_bevel);
1114
    gs_setfilladjust(pgs, 0.0, 0.0);
1115
 
1116
    capture_exec(pgs);
1117
    return 0;
1118
}
1119
 
1120
#endif /* CAPTURE */