summaryrefslogtreecommitdiff
path: root/gs/src/gslib.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/gslib.c')
-rw-r--r--gs/src/gslib.c549
1 files changed, 549 insertions, 0 deletions
diff --git a/gs/src/gslib.c b/gs/src/gslib.c
new file mode 100644
index 000000000..6dd54bfc7
--- /dev/null
+++ b/gs/src/gslib.c
@@ -0,0 +1,549 @@
+/* Copyright (C) 1995, 1996 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin 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 Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin 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 Aladdin 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.
+*/
+
+/* gslib.c */
+/* Test program for Ghostscript library */
+/* Capture stdin/out/err before gs.h redefines them. */
+#include <stdio.h>
+static FILE *real_stdin, *real_stdout, *real_stderr;
+static void
+get_real(void)
+{ real_stdin = stdin, real_stdout = stdout, real_stderr = stderr;
+}
+#include "math_.h"
+#include "gx.h"
+#include "gp.h"
+#include "gscdefs.h"
+#include "gserrors.h"
+#include "gslib.h"
+#include "gsmatrix.h"
+#include "gsstate.h"
+#include "gscspace.h"
+#include "gscolor2.h"
+#include "gscoord.h"
+#include "gsparam.h"
+#include "gspaint.h"
+#include "gspath.h"
+#include "gsstruct.h"
+#include "gsutil.h"
+#include "gxalloc.h"
+#include "gxdevice.h"
+
+/* Define whether we are processing captured data. */
+/*#define CAPTURE*/
+
+/* Test programs */
+private void test1(P2(gs_state *, gs_memory_t *)); /* kaleidoscope */
+private void test2(P2(gs_state *, gs_memory_t *)); /* pattern fill */
+private void test3(P2(gs_state *, gs_memory_t *)); /* RasterOp */
+private void test4(P2(gs_state *, gs_memory_t *)); /* set resolution */
+#ifdef CAPTURE
+#include "k/capture.c"
+private void test5(P2(gs_state *, gs_memory_t *)); /* captured data */
+#endif
+private void (*tests[])(P2(gs_state *, gs_memory_t *)) =
+ { test1, test2, test3, test4
+#ifdef CAPTURE
+ , test5
+#endif
+ };
+
+/* Include the extern for the device list. */
+extern_gs_lib_device_list();
+
+/* Other imported procedures */
+ /* from gsalloc.c */
+extern gs_ref_memory_t *ialloc_alloc_state(P2(gs_memory_t *, uint));
+
+/* Forward references */
+private float odsf(P2(floatp, floatp));
+
+int
+main(int argc, const char *argv[])
+{ char achar;
+ gs_ref_memory_t *imem;
+#define mem ((gs_memory_t *)imem)
+ gs_state *pgs;
+ const gx_device **list;
+ gx_device *dev;
+
+ gp_init();
+ get_real();
+ gs_stdin = real_stdin;
+ gs_stdout = real_stdout;
+ gs_stderr = real_stderr;
+ gs_lib_init(stdout);
+ if ( argc < 2 || (achar = argv[1][0]) < '1' ||
+ achar > '0' + countof(tests)
+
+ )
+ { lprintf1("Usage: gslib 1..%c\n", '0' + countof(tests));
+ exit(1);
+ }
+ gs_debug['@'] = 1;
+ gs_debug['?'] = 1;
+ /*gs_debug['L'] = 1;*/ /****** PATCH ******/
+ imem = ialloc_alloc_state(&gs_memory_default, 20000);
+ imem->space = 0; /****** WRONG ******/
+ gs_lib_device_list(&list, NULL);
+ gs_copydevice(&dev, list[0], mem);
+ /* Print out the device name just to test the gsparam.c API. */
+ { gs_c_param_list list;
+ gs_param_string nstr;
+ int code;
+ gs_c_param_list_write(&list, mem);
+ code = gs_getdeviceparams(dev, (gs_param_list *)&list);
+ if ( code < 0 )
+ { lprintf1("getdeviceparams failed! code = %d\n", code);
+ exit(1);
+ }
+ gs_c_param_list_read(&list);
+ code = param_read_string((gs_param_list *)&list, "Name", &nstr);
+ if ( code < 0 )
+ { lprintf1("reading Name failed! code = %d\n", code);
+ exit(1);
+ }
+ dputs("Device name = ");
+ debug_print_string(nstr.data, nstr.size);
+ dputs("\n");
+ gs_c_param_list_release(&list);
+ }
+ pgs = gs_state_alloc(mem);
+ gs_setdevice_no_erase(pgs, dev); /* can't erase yet */
+ { gs_point dpi;
+ gs_screen_halftone ht;
+ gs_dtransform(pgs, 72.0, 72.0, &dpi);
+ ht.frequency = min(fabs(dpi.x), fabs(dpi.y)) / 16.001;
+ ht.angle = 0;
+ ht.spot_function = odsf;
+ gs_setscreen(pgs, &ht);
+ }
+ /* gsave and grestore (among other places) assume that */
+ /* there are at least 2 gstates on the graphics stack. */
+ /* Ensure that now. */
+ gs_gsave(pgs);
+ gs_erasepage(pgs);
+ (*tests[achar - '1'])(pgs, mem);
+ gs_output_page(pgs, 1, 1);
+ dputs("Done. Press <enter> to exit.");
+ getchar();
+ gs_lib_finit(0, 0);
+ return 0;
+#undef mem
+}
+/* Ordered dither spot function */
+private float
+odsf(floatp x, floatp y)
+{ static const byte dither[256] = {
+0x0E,0x8E,0x2E,0xAE,0x06,0x86,0x26,0xA6,0x0C,0x8C,0x2C,0xAC,0x04,0x84,0x24,0xA4,
+0xCE,0x4E,0xEE,0x6E,0xC6,0x46,0xE6,0x66,0xCC,0x4C,0xEC,0x6C,0xC4,0x44,0xE4,0x64,
+0x3E,0xBE,0x1E,0x9E,0x36,0xB6,0x16,0x96,0x3C,0xBC,0x1C,0x9C,0x34,0xB4,0x14,0x94,
+0xFE,0x7E,0xDE,0x5E,0xF6,0x76,0xD6,0x56,0xFC,0x7C,0xDC,0x5C,0xF4,0x74,0xD4,0x54,
+0x01,0x81,0x21,0xA1,0x09,0x89,0x29,0xA9,0x03,0x83,0x23,0xA3,0x0B,0x8B,0x2B,0xAB,
+0xC1,0x41,0xE1,0x61,0xC9,0x49,0xE9,0x69,0xC3,0x43,0xE3,0x63,0xCB,0x4B,0xEB,0x6B,
+0x31,0xB1,0x11,0x91,0x39,0xB9,0x19,0x99,0x33,0xB3,0x13,0x93,0x3B,0xBB,0x1B,0x9B,
+0xF1,0x71,0xD1,0x51,0xF9,0x79,0xD9,0x59,0xF3,0x73,0xD3,0x53,0xFB,0x7B,0xDB,0x5B,
+0x0D,0x8D,0x2D,0xAD,0x05,0x85,0x25,0xA5,0x0F,0x8F,0x2F,0xAF,0x07,0x87,0x27,0xA7,
+0xCD,0x4D,0xED,0x6D,0xC5,0x45,0xE5,0x65,0xCF,0x4F,0xEF,0x6F,0xC7,0x47,0xE7,0x67,
+0x3D,0xBD,0x1D,0x9D,0x35,0xB5,0x15,0x95,0x3F,0xBF,0x1F,0x9F,0x37,0xB7,0x17,0x97,
+0xFD,0x7D,0xDD,0x5D,0xF5,0x75,0xD5,0x55,0xFF,0x7F,0xDF,0x5F,0xF7,0x77,0xD7,0x57,
+0x02,0x82,0x22,0xA2,0x0A,0x8A,0x2A,0xAA,0x00,0x80,0x20,0xA0,0x08,0x88,0x28,0xA8,
+0xC2,0x42,0xE2,0x62,0xCA,0x4A,0xEA,0x6A,0xC0,0x40,0xE0,0x60,0xC8,0x48,0xE8,0x68,
+0x32,0xB2,0x12,0x92,0x3A,0xBA,0x1A,0x9A,0x30,0xB0,0x10,0x90,0x38,0xB8,0x18,0x98,
+0xF2,0x72,0xD2,0x52,0xFA,0x7A,0xDA,0x5A,0xF0,0x70,0xD0,0x50,0xF8,0x78,0xD8,0x58
+ };
+ int i = (int)((x + 1) * 7.9999);
+ int j = (int)((y + 1) * 7.9999);
+ return dither[16 * i + j] / 256.0;
+}
+
+/* Stubs for GC */
+const gs_ptr_procs_t ptr_struct_procs = { NULL, NULL, NULL };
+const gs_ptr_procs_t ptr_string_procs = { NULL, NULL, NULL };
+const gs_ptr_procs_t ptr_const_string_procs = { NULL, NULL, NULL };
+void * /* obj_header_t * */
+gs_reloc_struct_ptr(const void * /* obj_header_t * */ obj, gc_state_t *gcst)
+{ return (void *)obj;
+}
+void
+gs_reloc_string(gs_string *sptr, gc_state_t *gcst)
+{
+}
+void
+gs_reloc_const_string(gs_const_string *sptr, gc_state_t *gcst)
+{
+}
+
+/* Other stubs */
+void
+gs_exit(int exit_status)
+{ gs_lib_finit(exit_status, 0);
+ exit(exit_status);
+}
+
+
+/* ---------------- Test program 1 ---------------- */
+/* Draw a colored kaleidoscope. */
+
+/* Random number generator */
+private long rand_state = 1;
+private long
+rand(void)
+{
+#define A 16807
+#define M 0x7fffffff
+#define Q 127773 /* M / A */
+#define R 2836 /* M % A */
+ rand_state = A * (rand_state % Q) - R * (rand_state / Q);
+ /* Note that rand_state cannot be 0 here. */
+ if ( rand_state <= 0 ) rand_state += M;
+#undef A
+#undef M
+#undef Q
+#undef R
+ return rand_state;
+}
+private void
+test1(gs_state *pgs, gs_memory_t *mem)
+{ int n;
+ gs_scale(pgs, 72.0, 72.0);
+ gs_translate(pgs, 4.25, 5.5);
+ gs_scale(pgs, 4.0, 4.0);
+ gs_newpath(pgs);
+ for ( n = 200; --n >= 0; )
+ { int j;
+#define rf() (rand() / (1.0 * 0x10000 * 0x8000))
+ double r = rf(), g = rf(), b = rf();
+ double x0=rf(), y0=rf(), x1=rf(), y1=rf(), x2=rf(), y2=rf();
+ gs_setrgbcolor(pgs, r, g, b);
+ for ( j = 0; j < 6; j++ )
+ { gs_gsave(pgs);
+ gs_rotate(pgs, 60.0 * j);
+ gs_moveto(pgs, x0, y0);
+ gs_lineto(pgs, x1, y1);
+ gs_lineto(pgs, x2, y2);
+ gs_fill(pgs);
+ gs_grestore(pgs);
+ }
+ }
+#undef mem
+}
+
+/* ---------------- Test program 2 ---------------- */
+/* Fill an area with a pattern. */
+
+private void
+test2(gs_state *pgs, gs_memory_t *mem)
+{ gs_client_color cc;
+ gx_tile_bitmap tile;
+ /*const*/ byte tpdata[] = {
+ /* Define a pattern that looks like this:
+ ..xxxx
+ .....x
+ .....x
+ ..xxxx
+ .x....
+ x.....
+ */
+ 0x3c,0,0,0, 0x04,0,0,0, 0x04,0,0,0, 0x3c,0,0,0,
+ 0x40,0,0,0, 0x80,0,0,0
+ };
+
+ gs_newpath(pgs);
+ gs_moveto(pgs, 100.0, 300.0);
+ gs_lineto(pgs, 500.0, 500.0);
+ gs_lineto(pgs, 200.0, 100.0);
+ gs_lineto(pgs, 300.0, 500.0);
+ gs_lineto(pgs, 500.0, 200.0);
+ gs_closepath(pgs);
+ gs_setrgbcolor(pgs, 0.0, 0.0, 0.0);
+ gs_gsave(pgs);
+ gs_fill(pgs);
+ gs_grestore(pgs);
+ tile.data = tpdata;
+ tile.raster = 4;
+ tile.size.x = tile.rep_width = 6;
+ tile.size.y = tile.rep_height = 6;
+ tile.id = gx_no_bitmap_id;
+ gs_makebitmappattern(&cc, &tile, true, pgs, NULL);
+ /* Note: color space is DeviceRGB */
+ cc.paint.values[0] = 0.0;
+ cc.paint.values[1] = 1.0;
+ cc.paint.values[2] = 1.0;
+ gs_setpattern(pgs, &cc);
+ gs_eofill(pgs);
+ gs_makebitmappattern(&cc, &tile, false, pgs, NULL);
+ gs_setcolor(pgs, &cc);
+ gs_moveto(pgs, 50.0, 50.0);
+ gs_lineto(pgs, 300.0, 50.0);
+ gs_lineto(pgs, 50.0, 300.0);
+ gs_closepath(pgs);
+ gs_setrgbcolor(pgs, 1.0, 0.0, 0.0);
+ gs_gsave(pgs);
+ gs_fill(pgs);
+ gs_grestore(pgs);
+ gs_setpattern(pgs, &cc);
+ gs_eofill(pgs);
+}
+
+/* ---------------- Test program 3 ---------------- */
+/* Exercise RasterOp a little. */
+/* Currently, this only works with monobit devices. */
+
+private void
+test3(gs_state *pgs, gs_memory_t *mem)
+{ gx_device *dev = gs_currentdevice(pgs);
+ gx_color_index black =
+ (*dev_proc(dev, map_rgb_color))(dev, 0, 0, 0);
+ gx_color_index white =
+ (*dev_proc(dev, map_rgb_color))(dev, gx_max_color_value,
+ gx_max_color_value,
+ gx_max_color_value);
+ gx_color_index black2[2];
+ gx_color_index black_white[2];
+ gx_color_index white_black[2];
+ long pattern[max(align_bitmap_mod / sizeof(long), 1) * 4];
+#define pbytes ((byte *)pattern)
+ gx_tile_bitmap tile;
+
+ black2[0] = black2[1] = black;
+ black_white[0] = white_black[1] = black;
+ black_white[1] = white_black[0] = white;
+ pbytes[0] = 0xf0;
+ pbytes[align_bitmap_mod] = 0x90;
+ pbytes[align_bitmap_mod*2] = 0x90;
+ pbytes[align_bitmap_mod*3] = 0xf0;
+ tile.data = pbytes;
+ tile.raster = align_bitmap_mod;
+ tile.size.x = tile.size.y = 4;
+ tile.id = gs_next_ids(1);
+ tile.rep_width = tile.rep_height = 4;
+ (*dev_proc(dev, copy_rop))
+ (dev, NULL, 0, 0, gx_no_bitmap_id, black2,
+ &tile, white_black, 100, 100, 150, 150, 0, 0, rop3_T);
+ (*dev_proc(dev, copy_rop))
+ (dev, NULL, 0, 0, gx_no_bitmap_id, black2,
+ NULL, NULL, 120, 120, 110, 110, 0, 0, ~rop3_S & rop3_1);
+ (*dev_proc(dev, copy_rop))
+ (dev, NULL, 0, 0, gx_no_bitmap_id, black2,
+ &tile, white_black, 110, 110, 130, 130, 0, 0, rop3_T ^ rop3_D);
+#undef pbytes
+}
+
+/* ---------------- Test program 4 ---------------- */
+/* Set the resolution dynamically. */
+
+private void
+test4(gs_state *pgs, gs_memory_t *mem)
+{ gs_c_param_list list;
+ float resv[2];
+ gs_param_float_array ares;
+ int code;
+ gx_device *dev = gs_currentdevice(pgs);
+
+ gs_c_param_list_write(&list, mem);
+ resv[0] = resv[1] = 100;
+ ares.data = resv;
+ ares.size = 2;
+ ares.persistent = true;
+ code = param_write_float_array((gs_param_list *)&list,
+ "HWResolution", &ares);
+ if ( code < 0 )
+ { lprintf1("Writing HWResolution failed: %d\n", code);
+ exit(1);
+ }
+ gs_c_param_list_read(&list);
+ code = gs_putdeviceparams(dev, (gs_param_list *)&list);
+ gs_c_param_list_release(&list);
+ if ( code < 0 )
+ { lprintf1("Setting HWResolution failed: %d\n", code);
+ exit(1);
+ }
+ gs_initmatrix(pgs);
+ gs_initclip(pgs);
+ if ( code == 1 )
+ { code = (*dev_proc(dev, open_device))(dev);
+ if ( code < 0 )
+ { lprintf1("Reopening device failed: %d\n", code);
+ exit(1);
+ }
+ }
+ gs_moveto(pgs, 0.0, 72.0);
+ gs_rlineto(pgs, 72.0, 0.0);
+ gs_rlineto(pgs, 0.0, 72.0);
+ gs_closepath(pgs);
+ gs_stroke(pgs);
+}
+
+#ifdef CAPTURE
+
+/* ---------------- Test program 5 ---------------- */
+/* Replay captured data for printer output. */
+
+private const char outfile[] = "t.pbm";
+private const float ypage_wid = 11.0;
+private const float xpage_len = 17.0;
+private const int rotate_value = 0;
+private const float scale_x = 0.45;
+private const float scale_y = 0.45;
+private const float xmove_origin = 0.0;
+private const float ymove_origin = 0.0;
+
+private void
+test5(gs_state *pgs, gs_memory_t *mem)
+{ gs_c_param_list list;
+ gs_param_string nstr, OFstr;
+ gs_param_float_array PSa;
+ gs_param_float_array HWRa;
+ gs_param_int_array HWSa;
+ int HWSize[2];
+ float HWResolution[2], PageSize[2];
+ long MaxBitmap;
+ int code;
+ gx_device *dev = gs_currentdevice(pgs);
+ float xlate_x, xlate_y;
+ gs_rect cliprect;
+
+ gs_c_param_list_write(&list, mem);
+ code = gs_getdeviceparams(dev, (gs_param_list *)&list);
+ if ( code < 0 )
+ { lprintf1("getdeviceparams failed! code = %d\n", code);
+ exit(1);
+ }
+ gs_c_param_list_read(&list);
+ code = param_read_string((gs_param_list *)&list, "Name", &nstr);
+ if ( code < 0 )
+ { lprintf1("reading Name failed! code = %d\n", code);
+ exit(1);
+ }
+ code = param_read_int_array((gs_param_list *)&list,
+ "HWSize", &HWSa);
+ if ( code < 0 )
+ { lprintf1("reading HWSize failed! code = %d\n", code);
+ exit(1);
+ }
+ eprintf3("HWSize[%d] = [ %d, %d ]\n", HWSa.size,
+ HWSa.data[0], HWSa.data[1]);
+ code = param_read_float_array((gs_param_list *)&list,
+ "HWResolution", &HWRa);
+ if ( code < 0 )
+ { lprintf1("reading Resolution failed! code = %d\n", code);
+ exit(1);
+ }
+ eprintf3("HWResolution[%d] = [ %f, %f ]\n", HWRa.size,
+ HWRa.data[0], HWRa.data[1]);
+ code = param_read_float_array((gs_param_list *)&list,
+ "PageSize", &PSa);
+ if ( code < 0 )
+ { lprintf1("reading PageSize failed! code = %d\n", code);
+ exit(1);
+ }
+ eprintf3("PageSize[%d] = [ %f, %f ]\n", PSa.size,
+ PSa.data[0], PSa.data[1]);
+ code = param_read_long((gs_param_list *)&list,
+ "MaxBitmap", &MaxBitmap);
+ if ( code < 0 )
+ { lprintf1("reading MaxBitmap failed! code = %d\n", code);
+ exit(1);
+ }
+ eprintf1("MaxBitmap = %ld\n", MaxBitmap );
+ /* Switch to param list functions to "write" */
+ gs_c_param_list_write(&list, mem);
+ /* Always set the PageSize. */
+ PageSize[0] = 72.0 * ypage_wid;
+ PageSize[1] = 72.0 * xpage_len;
+ PSa.data = PageSize;
+ code = param_write_float_array((gs_param_list *)&list,
+ "PageSize", &PSa);
+ if( nstr.data[0] != 'v' ) {
+ /* Set the OutputFile string file name */
+ OFstr.persistent = false;
+ OFstr.data = outfile;
+ OFstr.size = strlen(outfile);
+ code = param_write_string((gs_param_list *)&list,
+ "OutputFile", &OFstr);
+ if ( code < 0 )
+ { lprintf1("setting OutputFile name failed, code=%d\n",
+ code);
+ exit(1);
+ }
+ if( nstr.data[0] == 'x' ) {
+ HWResolution[0] = HWResolution[1] = 72.0;
+ }
+ else {
+ HWResolution[0] = HWResolution[1] = 360.0;
+ }
+ HWRa.data = HWResolution;
+ HWSize[0] = (int) (HWResolution[0] * ypage_wid);
+ HWSize[1] = (int) (HWResolution[1] * xpage_len);
+ eprintf3(" HWSize = [%d,%d], HWResolution = %f dpi\n",
+ HWSize[0], HWSize[1], HWResolution[0] );
+ HWSa.data = HWSize;
+ code = param_write_float_array((gs_param_list *)&list,
+ "HWResolution", &HWRa);
+ code = param_write_int_array((gs_param_list *)&list,
+ "HWSize", &HWSa);
+ MaxBitmap = 1000000L;
+ code = param_write_long((gs_param_list *)&list,
+ "MaxBitmap", &MaxBitmap);
+ }
+ gs_c_param_list_read(&list);
+ code = gs_putdeviceparams(dev, (gs_param_list *)&list);
+ eprintf1("putdeviceparams: code=%d\n", code);
+ gs_c_param_list_release(&list);
+
+ gs_erasepage(pgs);
+ gs_initgraphics(pgs);
+ gs_clippath( pgs );
+ gs_pathbbox( pgs, &cliprect );
+ eprintf4(" cliprect = [[%g,%g],[%g,%g]]\n",
+ cliprect.p.x, cliprect.p.y, cliprect.q.x, cliprect.q.y);
+ gs_newpath( pgs );
+
+ switch( ((rotate_value+270)/90) & 3 ) {
+ default:
+ case 0: /* 0 = 360 degrees in PS == 90 degrees in printer */
+ xlate_x = cliprect.p.x; xlate_y = cliprect.p.y;
+ break;
+ case 1: /* 90 degrees in PS = 180 degrees printer */
+ xlate_x = cliprect.q.x; xlate_y = cliprect.p.y;
+ break;
+ case 2: /* 180 degrees in PS == 270 degrees in printer */
+ xlate_x = cliprect.q.x; xlate_y = cliprect.q.y;
+ break;
+ case 3: /* 270 degrees in PS == 0 degrees in printer */
+ xlate_x = cliprect.p.x; xlate_y = cliprect.q.y;
+ break;
+ }
+ eprintf2("translate origin to [ %f, %f ]\n", xlate_x, xlate_y);
+ gs_translate( pgs, xlate_x, xlate_y );
+
+ /* further move (before rotate) by user requested amount */
+ gs_translate( pgs, 72.0*(float)xmove_origin, 72.0*(float)ymove_origin );
+
+ gs_rotate( pgs, (float)rotate_value + 270.0 );
+ gs_scale( pgs, scale_x*72.0/2032.0,
+ scale_y*72.0/2032.0);
+ gs_setlinecap( pgs, gs_cap_butt );
+ gs_setlinejoin( pgs, gs_join_bevel );
+ gs_setfilladjust(pgs, 0.0, 0.0);
+
+ capture_exec(pgs);
+}
+
+#endif /* CAPTURE */