diff options
Diffstat (limited to 'gs/src/gslib.c')
-rw-r--r-- | gs/src/gslib.c | 549 |
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 */ |