home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / sharewar / dos / program / gs300sr1 / gs300sr1.exe / ZGSTATE.C < prev    next >
C/C++ Source or Header  |  1994-07-27  |  7KB  |  283 lines

  1. /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* zgstate.c */
  20. /* Graphics state operators */
  21. #include "ghost.h"
  22. #include "errors.h"
  23. #include "oper.h"
  24. #include "ialloc.h"
  25. #include "istruct.h"
  26. #include "igstate.h"
  27. #include "gsmatrix.h"
  28. #include "store.h"
  29.  
  30. /* Imported operators */
  31. extern int zpop(P1(os_ptr));
  32.  
  33. /* Forward references */
  34. private int near num_param(P2(os_ptr, int (*)(P2(gs_state *, floatp))));
  35. private int near line_param(P2(os_ptr, int *));
  36.  
  37. /* Structure descriptor */
  38. private_st_int_gstate();
  39.  
  40. /* ------ Operations on the entire graphics state ------ */
  41.  
  42. /* The current graphics state */
  43. gs_state *igs;
  44. private gs_gc_root_t igs_root;
  45.  
  46. /* "Client" procedures */
  47. private void *gs_istate_alloc(P1(gs_memory_t *mem));
  48. private int gs_istate_copy(P2(void *to, const void *from));
  49. private void gs_istate_free(P2(void *old, gs_memory_t *mem));
  50. private const gs_state_client_procs istate_procs = {
  51.     gs_istate_alloc,
  52.     gs_istate_copy,
  53.     gs_istate_free
  54. };
  55.  
  56. /* Initialize the graphics stack. */
  57. void
  58. igs_init(void)
  59. {    int_gstate *iigs;
  60.     ref proc0;
  61.     igs = gs_state_alloc(imemory);
  62.     iigs = gs_alloc_struct(imemory, int_gstate, &st_int_gstate, "igs_init");
  63.     int_gstate_map_refs(iigs, make_null);
  64.     make_array(&iigs->dash_pattern, a_all, 0, NULL);
  65.     ialloc_ref_array(&proc0, a_readonly + a_executable, 2,
  66.              "igs_init");
  67.     make_oper(proc0.value.refs, 0, zpop);
  68.     make_real(proc0.value.refs + 1, 0.0);
  69.     iigs->black_generation = proc0;
  70.     iigs->undercolor_removal = proc0;
  71.     gs_state_set_client(igs, iigs, &istate_procs);
  72.     gs_register_struct_root(imemory, &igs_root, (void **)&igs, "igs");
  73.     /*
  74.      * gsave and grestore only work properly
  75.      * if there are always at least 2 entries on the stack.
  76.      * We count on the PostScript initialization code to do a gsave.
  77.      */
  78. }
  79.  
  80. /* - gsave - */
  81. int
  82. zgsave(register os_ptr op)
  83. {    return gs_gsave(igs);
  84. }
  85.  
  86. /* - grestore - */
  87. int
  88. zgrestore(register os_ptr op)
  89. {    return gs_grestore(igs);
  90. }
  91.  
  92. /* - grestoreall - */
  93. int
  94. zgrestoreall(register os_ptr op)
  95. {    return gs_grestoreall(igs);
  96. }
  97.  
  98. /* - initgraphics - */
  99. int
  100. zinitgraphics(register os_ptr op)
  101. {    return gs_initgraphics(igs);
  102. }
  103.  
  104. /* ------ Operations on graphics state elements ------ */
  105.  
  106. /* <num> setlinewidth - */
  107. int
  108. zsetlinewidth(register os_ptr op)
  109. {    return num_param(op, gs_setlinewidth);
  110. }
  111.  
  112. /* - currentlinewidth <num> */
  113. int
  114. zcurrentlinewidth(register os_ptr op)
  115. {    push(1);
  116.     make_real(op, gs_currentlinewidth(igs));
  117.     return 0;
  118. }
  119.  
  120. /* <cap_int> setlinecap - */
  121. int
  122. zsetlinecap(register os_ptr op)
  123. {    int param;
  124.     int code = line_param(op, ¶m);
  125.     if ( !code ) code = gs_setlinecap(igs, (gs_line_cap)param);
  126.     return code;
  127. }
  128.  
  129. /* - currentlinecap <cap_int> */
  130. int
  131. zcurrentlinecap(register os_ptr op)
  132. {    push(1);
  133.     make_int(op, (int)gs_currentlinecap(igs));
  134.     return 0;
  135. }
  136.  
  137. /* <join_int> setlinejoin - */
  138. int
  139. zsetlinejoin(register os_ptr op)
  140. {    int param;
  141.     int code = line_param(op, ¶m);
  142.     if ( !code ) code = gs_setlinejoin(igs, (gs_line_join)param);
  143.     return code;
  144. }
  145.  
  146. /* - currentlinejoin <join_int> */
  147. int
  148. zcurrentlinejoin(register os_ptr op)
  149. {    push(1);
  150.     make_int(op, (int)gs_currentlinejoin(igs));
  151.     return 0;
  152. }
  153.  
  154. /* <num> setmiterlimit - */
  155. int
  156. zsetmiterlimit(register os_ptr op)
  157. {    return num_param(op, gs_setmiterlimit);
  158. }
  159.  
  160. /* - currentmiterlimit <num> */
  161. int
  162. zcurrentmiterlimit(register os_ptr op)
  163. {    push(1);
  164.     make_real(op, gs_currentmiterlimit(igs));
  165.     return 0;
  166. }
  167.  
  168. /* <array> <offset> setdash - */
  169. int
  170. zsetdash(register os_ptr op)
  171. {    float offset;
  172.     int code = real_param(op, &offset);
  173.     uint n;
  174.     gs_memory_t *mem = imemory;
  175.     float *pattern;
  176.     if ( code )
  177.         return code;
  178.     check_array(op[-1]);
  179.     check_read(op[-1]);
  180.     /* Unpack the dash pattern and check it */
  181.     n = r_size(op - 1);
  182.     pattern =
  183.       (float *)gs_alloc_byte_array(mem, n, sizeof(float), "setdash");
  184.     if ( pattern == 0 )
  185.       return_error(e_VMerror);
  186.     code = num_params(op[-1].value.const_refs + (n - 1), n, pattern);
  187.     if ( code >= 0 )
  188.       code = gs_setdash(igs, pattern, n, offset);
  189.     gs_free_object(mem, pattern, "setdash"); /* gs_setdash copies this */
  190.     if ( code >= 0 )
  191.     {    ref_assign(&istate->dash_pattern, op - 1);
  192.         pop(2);
  193.     }
  194.     return code;
  195. }
  196.  
  197. /* - currentdash <array> <offset> */
  198. int
  199. zcurrentdash(register os_ptr op)
  200. {    push(2);
  201.     ref_assign(op - 1, &istate->dash_pattern);
  202.     make_real(op, gs_currentdash_offset(igs));
  203.     return 0;
  204. }
  205.  
  206. /* <num> setflat - */
  207. int
  208. zsetflat(register os_ptr op)
  209. {    return num_param(op, gs_setflat);
  210. }
  211.  
  212. /* - currentflat <num> */
  213. int
  214. zcurrentflat(register os_ptr op)
  215. {    push(1);
  216.     make_real(op, gs_currentflat(igs));
  217.     return 0;
  218. }
  219.  
  220. /* ------ Initialization procedure ------ */
  221.  
  222. op_def zgstate_op_defs[] = {
  223.     {"0currentdash", zcurrentdash},
  224.     {"0currentflat", zcurrentflat},
  225.     {"0currentlinecap", zcurrentlinecap},
  226.     {"0currentlinejoin", zcurrentlinejoin},
  227.     {"0currentlinewidth", zcurrentlinewidth},
  228.     {"0currentmiterlimit", zcurrentmiterlimit},
  229.     {"0grestore", zgrestore},
  230.     {"0grestoreall", zgrestoreall},
  231.     {"0gsave", zgsave},
  232.     {"0initgraphics", zinitgraphics},
  233.     {"2setdash", zsetdash},
  234.     {"1setflat", zsetflat},
  235.     {"1setlinecap", zsetlinecap},
  236.     {"1setlinejoin", zsetlinejoin},
  237.     {"1setlinewidth", zsetlinewidth},
  238.     {"1setmiterlimit", zsetmiterlimit},
  239.     op_def_end(0)
  240. };
  241.  
  242. /* ------ Internal routines ------ */
  243.  
  244. /* Allocate the interpreter's part of a graphics state. */
  245. private void *
  246. gs_istate_alloc(gs_memory_t *mem)
  247. {    return (char *)gs_alloc_struct(mem, int_gstate, &st_int_gstate, "int_gsave");
  248. }
  249.  
  250. /* Copy the interpreter's part of a graphics state. */
  251. private int
  252. gs_istate_copy(void *to, const void *from)
  253. {    *(int_gstate *)to = *(int_gstate *)from;
  254.     return 0;
  255. }
  256.  
  257. /* Free the interpreter's part of a graphics state. */
  258. private void
  259. gs_istate_free(void *old, gs_memory_t *mem)
  260. {    gs_free_object(mem, old, "int_grestore");
  261. }
  262.  
  263. /* Get a numeric parameter */
  264. private int near
  265. num_param(os_ptr op, int (*pproc)(P2(gs_state *, floatp)))
  266. {    float param;
  267.     int code = real_param(op, ¶m);
  268.     if ( !code ) code = (*pproc)(igs, param);
  269.     if ( !code ) pop(1);
  270.     return code;
  271. }
  272.  
  273. /* Get an integer parameter 0-2. */
  274. private int near
  275. line_param(register os_ptr op, int *pparam)
  276. {    check_type(*op, t_integer);
  277.     if ( op->value.intval < 0 || op->value.intval > 2 )
  278.         return_error(e_rangecheck);
  279.     *pparam = (int)op->value.intval;
  280.     pop(1);
  281.     return 0;
  282. }
  283.