xref: /plan9-contrib/sys/src/cmd/gs/src/zdps.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
13ff48bf5SDavid du Colombier /* Copyright (C) 1997, 2000 Aladdin Enterprises.  All rights reserved.
27dd7cddfSDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
57dd7cddfSDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: zdps.c,v 1.8 2004/08/04 19:36:13 stefan Exp $ */
187dd7cddfSDavid du Colombier /* Display PostScript extensions */
197dd7cddfSDavid du Colombier #include "ghost.h"
207dd7cddfSDavid du Colombier #include "oper.h"
217dd7cddfSDavid du Colombier #include "gsstate.h"
227dd7cddfSDavid du Colombier #include "gsdps.h"
237dd7cddfSDavid du Colombier #include "gsimage.h"
247dd7cddfSDavid du Colombier #include "gsiparm2.h"
253ff48bf5SDavid du Colombier #include "gxalloc.h"		/* for names_array in allocator */
267dd7cddfSDavid du Colombier #include "gxfixed.h"		/* for gxpath.h */
277dd7cddfSDavid du Colombier #include "gxpath.h"
287dd7cddfSDavid du Colombier #include "btoken.h"		/* for user_names_p */
297dd7cddfSDavid du Colombier #include "iddict.h"
307dd7cddfSDavid du Colombier #include "idparam.h"
317dd7cddfSDavid du Colombier #include "igstate.h"
327dd7cddfSDavid du Colombier #include "iimage2.h"
337dd7cddfSDavid du Colombier #include "iname.h"
347dd7cddfSDavid du Colombier #include "store.h"
357dd7cddfSDavid du Colombier 
367dd7cddfSDavid du Colombier /* Import the procedure for constructing user paths. */
37*593dc095SDavid du Colombier extern int make_upath(i_ctx_t *, ref *, const gs_state *, gx_path *, bool);
387dd7cddfSDavid du Colombier 
397dd7cddfSDavid du Colombier /* ------ Graphics state ------ */
407dd7cddfSDavid du Colombier 
417dd7cddfSDavid du Colombier /* <screen_index> <x> <y> .setscreenphase - */
427dd7cddfSDavid du Colombier private int
zsetscreenphase(i_ctx_t * i_ctx_p)437dd7cddfSDavid du Colombier zsetscreenphase(i_ctx_t *i_ctx_p)
447dd7cddfSDavid du Colombier {
457dd7cddfSDavid du Colombier     os_ptr op = osp;
467dd7cddfSDavid du Colombier     int code;
477dd7cddfSDavid du Colombier     long x, y;
487dd7cddfSDavid du Colombier 
497dd7cddfSDavid du Colombier     check_type(op[-2], t_integer);
507dd7cddfSDavid du Colombier     check_type(op[-1], t_integer);
517dd7cddfSDavid du Colombier     check_type(*op, t_integer);
527dd7cddfSDavid du Colombier     x = op[-1].value.intval;
537dd7cddfSDavid du Colombier     y = op->value.intval;
547dd7cddfSDavid du Colombier     if (x != (int)x || y != (int)y ||
557dd7cddfSDavid du Colombier 	op[-2].value.intval < -1 ||
567dd7cddfSDavid du Colombier 	op[-2].value.intval >= gs_color_select_count
577dd7cddfSDavid du Colombier 	)
587dd7cddfSDavid du Colombier 	return_error(e_rangecheck);
597dd7cddfSDavid du Colombier     code = gs_setscreenphase(igs, (int)x, (int)y,
607dd7cddfSDavid du Colombier 			     (gs_color_select_t) op[-2].value.intval);
617dd7cddfSDavid du Colombier     if (code >= 0)
627dd7cddfSDavid du Colombier 	pop(3);
637dd7cddfSDavid du Colombier     return code;
647dd7cddfSDavid du Colombier }
657dd7cddfSDavid du Colombier 
667dd7cddfSDavid du Colombier /* <screen_index> .currentscreenphase <x> <y> */
677dd7cddfSDavid du Colombier private int
zcurrentscreenphase(i_ctx_t * i_ctx_p)687dd7cddfSDavid du Colombier zcurrentscreenphase(i_ctx_t *i_ctx_p)
697dd7cddfSDavid du Colombier {
707dd7cddfSDavid du Colombier     os_ptr op = osp;
717dd7cddfSDavid du Colombier     gs_int_point phase;
727dd7cddfSDavid du Colombier     int code;
737dd7cddfSDavid du Colombier 
747dd7cddfSDavid du Colombier     check_type(*op, t_integer);
757dd7cddfSDavid du Colombier     if (op->value.intval < -1 ||
767dd7cddfSDavid du Colombier 	op->value.intval >= gs_color_select_count
777dd7cddfSDavid du Colombier 	)
787dd7cddfSDavid du Colombier 	return_error(e_rangecheck);
797dd7cddfSDavid du Colombier     code = gs_currentscreenphase(igs, &phase,
807dd7cddfSDavid du Colombier 				 (gs_color_select_t)op->value.intval);
817dd7cddfSDavid du Colombier     if (code < 0)
827dd7cddfSDavid du Colombier 	return code;
837dd7cddfSDavid du Colombier     push(1);
847dd7cddfSDavid du Colombier     make_int(op - 1, phase.x);
857dd7cddfSDavid du Colombier     make_int(op, phase.y);
867dd7cddfSDavid du Colombier     return 0;
877dd7cddfSDavid du Colombier }
887dd7cddfSDavid du Colombier 
897dd7cddfSDavid du Colombier /* ------ Device-source images ------ */
907dd7cddfSDavid du Colombier 
917dd7cddfSDavid du Colombier /* <dict> .image2 - */
927dd7cddfSDavid du Colombier private int
zimage2(i_ctx_t * i_ctx_p)937dd7cddfSDavid du Colombier zimage2(i_ctx_t *i_ctx_p)
947dd7cddfSDavid du Colombier {
957dd7cddfSDavid du Colombier     os_ptr op = osp;
967dd7cddfSDavid du Colombier     int code;
977dd7cddfSDavid du Colombier 
987dd7cddfSDavid du Colombier     check_type(*op, t_dictionary);
997dd7cddfSDavid du Colombier     check_dict_read(*op);
1007dd7cddfSDavid du Colombier     {
1017dd7cddfSDavid du Colombier 	gs_image2_t image;
1027dd7cddfSDavid du Colombier 	ref *pDataSource;
1037dd7cddfSDavid du Colombier 
1047dd7cddfSDavid du Colombier 	gs_image2_t_init(&image);
105*593dc095SDavid du Colombier 	if ((code = dict_matrix_param(imemory, op, "ImageMatrix",
1067dd7cddfSDavid du Colombier 				      &image.ImageMatrix)) < 0 ||
1077dd7cddfSDavid du Colombier 	    (code = dict_find_string(op, "DataSource", &pDataSource)) < 0 ||
1087dd7cddfSDavid du Colombier 	    (code = dict_float_param(op, "XOrigin", 0.0,
1097dd7cddfSDavid du Colombier 				     &image.XOrigin)) != 0 ||
1107dd7cddfSDavid du Colombier 	    (code = dict_float_param(op, "YOrigin", 0.0,
1117dd7cddfSDavid du Colombier 				     &image.YOrigin)) != 0 ||
1127dd7cddfSDavid du Colombier 	    (code = dict_float_param(op, "Width", 0.0,
1137dd7cddfSDavid du Colombier 				     &image.Width)) != 0 ||
1147dd7cddfSDavid du Colombier 	    image.Width <= 0 ||
1157dd7cddfSDavid du Colombier 	    (code = dict_float_param(op, "Height", 0.0,
1167dd7cddfSDavid du Colombier 				     &image.Height)) != 0 ||
1177dd7cddfSDavid du Colombier 	    image.Height <= 0 ||
1187dd7cddfSDavid du Colombier 	    (code = dict_bool_param(op, "PixelCopy", false,
1197dd7cddfSDavid du Colombier 				    &image.PixelCopy)) < 0
1207dd7cddfSDavid du Colombier 	    )
1217dd7cddfSDavid du Colombier 	    return (code < 0 ? code : gs_note_error(e_rangecheck));
1227dd7cddfSDavid du Colombier 	check_stype(*pDataSource, st_igstate_obj);
1237dd7cddfSDavid du Colombier 	image.DataSource = igstate_ptr(pDataSource);
1247dd7cddfSDavid du Colombier 	{
1257dd7cddfSDavid du Colombier 	    ref *ignoref;
1267dd7cddfSDavid du Colombier 
1277dd7cddfSDavid du Colombier 	    if (dict_find_string(op, "UnpaintedPath", &ignoref) > 0) {
1287dd7cddfSDavid du Colombier 		check_dict_write(*op);
1297dd7cddfSDavid du Colombier 		image.UnpaintedPath = gx_path_alloc(imemory,
1307dd7cddfSDavid du Colombier 						    ".image2 UnpaintedPath");
1317dd7cddfSDavid du Colombier 		if (image.UnpaintedPath == 0)
1327dd7cddfSDavid du Colombier 		    return_error(e_VMerror);
1337dd7cddfSDavid du Colombier 	    } else
1347dd7cddfSDavid du Colombier 		image.UnpaintedPath = 0;
1357dd7cddfSDavid du Colombier 	}
1367dd7cddfSDavid du Colombier 	code = process_non_source_image(i_ctx_p,
1377dd7cddfSDavid du Colombier 					(const gs_image_common_t *)&image,
1387dd7cddfSDavid du Colombier 					".image2");
1397dd7cddfSDavid du Colombier 	if (image.UnpaintedPath) {
1407dd7cddfSDavid du Colombier 	    ref rupath;
1417dd7cddfSDavid du Colombier 
1427dd7cddfSDavid du Colombier 	    if (code < 0)
1437dd7cddfSDavid du Colombier 		return code;
1447dd7cddfSDavid du Colombier 	    if (gx_path_is_null(image.UnpaintedPath))
1457dd7cddfSDavid du Colombier 		make_null(&rupath);
1467dd7cddfSDavid du Colombier 	    else
1477dd7cddfSDavid du Colombier 		code = make_upath(i_ctx_p, &rupath, igs, image.UnpaintedPath,
1487dd7cddfSDavid du Colombier 				  false);
1497dd7cddfSDavid du Colombier 	    gx_path_free(image.UnpaintedPath, ".image2 UnpaintedPath");
1507dd7cddfSDavid du Colombier 	    if (code < 0)
1517dd7cddfSDavid du Colombier 		return code;
1527dd7cddfSDavid du Colombier 	    code = idict_put_string(op, "UnpaintedPath", &rupath);
1537dd7cddfSDavid du Colombier 	}
1547dd7cddfSDavid du Colombier     }
1557dd7cddfSDavid du Colombier     if (code >= 0)
1567dd7cddfSDavid du Colombier 	pop(1);
1577dd7cddfSDavid du Colombier     return code;
1587dd7cddfSDavid du Colombier }
1597dd7cddfSDavid du Colombier 
1607dd7cddfSDavid du Colombier /* ------ View clipping ------ */
1617dd7cddfSDavid du Colombier 
1627dd7cddfSDavid du Colombier /* - viewclip - */
1637dd7cddfSDavid du Colombier private int
zviewclip(i_ctx_t * i_ctx_p)1647dd7cddfSDavid du Colombier zviewclip(i_ctx_t *i_ctx_p)
1657dd7cddfSDavid du Colombier {
1667dd7cddfSDavid du Colombier     return gs_viewclip(igs);
1677dd7cddfSDavid du Colombier }
1687dd7cddfSDavid du Colombier 
1697dd7cddfSDavid du Colombier /* - eoviewclip - */
1707dd7cddfSDavid du Colombier private int
zeoviewclip(i_ctx_t * i_ctx_p)1717dd7cddfSDavid du Colombier zeoviewclip(i_ctx_t *i_ctx_p)
1727dd7cddfSDavid du Colombier {
1737dd7cddfSDavid du Colombier     return gs_eoviewclip(igs);
1747dd7cddfSDavid du Colombier }
1757dd7cddfSDavid du Colombier 
1767dd7cddfSDavid du Colombier /* - initviewclip - */
1777dd7cddfSDavid du Colombier private int
zinitviewclip(i_ctx_t * i_ctx_p)1787dd7cddfSDavid du Colombier zinitviewclip(i_ctx_t *i_ctx_p)
1797dd7cddfSDavid du Colombier {
1807dd7cddfSDavid du Colombier     return gs_initviewclip(igs);
1817dd7cddfSDavid du Colombier }
1827dd7cddfSDavid du Colombier 
1837dd7cddfSDavid du Colombier /* - viewclippath - */
1847dd7cddfSDavid du Colombier private int
zviewclippath(i_ctx_t * i_ctx_p)1857dd7cddfSDavid du Colombier zviewclippath(i_ctx_t *i_ctx_p)
1867dd7cddfSDavid du Colombier {
1877dd7cddfSDavid du Colombier     return gs_viewclippath(igs);
1887dd7cddfSDavid du Colombier }
1897dd7cddfSDavid du Colombier 
1907dd7cddfSDavid du Colombier /* ------ User names ------ */
1917dd7cddfSDavid du Colombier 
1927dd7cddfSDavid du Colombier /* <index> <name> defineusername - */
1937dd7cddfSDavid du Colombier private int
zdefineusername(i_ctx_t * i_ctx_p)1947dd7cddfSDavid du Colombier zdefineusername(i_ctx_t *i_ctx_p)
1957dd7cddfSDavid du Colombier {
1967dd7cddfSDavid du Colombier     os_ptr op = osp;
1977dd7cddfSDavid du Colombier     ref uname;
1987dd7cddfSDavid du Colombier 
1997dd7cddfSDavid du Colombier     check_int_ltu(op[-1], max_array_size);
2007dd7cddfSDavid du Colombier     check_type(*op, t_name);
2013ff48bf5SDavid du Colombier     if (user_names_p == 0) {
2023ff48bf5SDavid du Colombier 	int code = create_names_array(&user_names_p, imemory_local,
2033ff48bf5SDavid du Colombier 				      "defineusername");
2043ff48bf5SDavid du Colombier 
2053ff48bf5SDavid du Colombier 	if (code < 0)
2063ff48bf5SDavid du Colombier 	    return code;
2073ff48bf5SDavid du Colombier     }
208*593dc095SDavid du Colombier     if (array_get(imemory, user_names_p,
209*593dc095SDavid du Colombier 		  op[-1].value.intval, &uname) >= 0) {
2107dd7cddfSDavid du Colombier 	switch (r_type(&uname)) {
2117dd7cddfSDavid du Colombier 	    case t_null:
2127dd7cddfSDavid du Colombier 		break;
2137dd7cddfSDavid du Colombier 	    case t_name:
2147dd7cddfSDavid du Colombier 		if (name_eq(&uname, op))
2157dd7cddfSDavid du Colombier 		    goto ret;
2167dd7cddfSDavid du Colombier 		/* falls through */
2177dd7cddfSDavid du Colombier 	    default:
2187dd7cddfSDavid du Colombier 		return_error(e_invalidaccess);
2197dd7cddfSDavid du Colombier 	}
2207dd7cddfSDavid du Colombier     } else {			/* Expand the array. */
2217dd7cddfSDavid du Colombier 	ref new_array;
2227dd7cddfSDavid du Colombier 	uint old_size = r_size(user_names_p);
2237dd7cddfSDavid du Colombier 	uint new_size = (uint) op[-1].value.intval + 1;
2247dd7cddfSDavid du Colombier 
2257dd7cddfSDavid du Colombier 	if (new_size < 100)
2267dd7cddfSDavid du Colombier 	    new_size = 100;
2277dd7cddfSDavid du Colombier 	else if (new_size > max_array_size / 2)
2287dd7cddfSDavid du Colombier 	    new_size = max_array_size;
2297dd7cddfSDavid du Colombier 	else if (new_size >> 1 < old_size)
2307dd7cddfSDavid du Colombier 	    new_size = (old_size > max_array_size / 2 ? max_array_size :
2317dd7cddfSDavid du Colombier 			old_size << 1);
2327dd7cddfSDavid du Colombier 	else
2337dd7cddfSDavid du Colombier 	    new_size <<= 1;
2343ff48bf5SDavid du Colombier 	/*
2353ff48bf5SDavid du Colombier 	 * The user name array is allocated in stable local VM,
2363ff48bf5SDavid du Colombier 	 * because it must be immune to save/restore.
2373ff48bf5SDavid du Colombier 	 */
2387dd7cddfSDavid du Colombier 	{
2393ff48bf5SDavid du Colombier 	    gs_ref_memory_t *slmem =
2403ff48bf5SDavid du Colombier 		(gs_ref_memory_t *)gs_memory_stable(imemory_local);
2417dd7cddfSDavid du Colombier 	    int code;
2427dd7cddfSDavid du Colombier 
2433ff48bf5SDavid du Colombier 	    code = gs_alloc_ref_array(slmem, &new_array, a_all, new_size,
2447dd7cddfSDavid du Colombier 				      "defineusername(new)");
2453ff48bf5SDavid du Colombier 	    if (code < 0)
2467dd7cddfSDavid du Colombier 		return code;
2477dd7cddfSDavid du Colombier 	    refcpy_to_new(new_array.value.refs, user_names_p->value.refs,
2487dd7cddfSDavid du Colombier 			  old_size, idmemory);
2497dd7cddfSDavid du Colombier 	    refset_null(new_array.value.refs + old_size,
2507dd7cddfSDavid du Colombier 			new_size - old_size);
2513ff48bf5SDavid du Colombier 	    if (old_size)
2523ff48bf5SDavid du Colombier 		gs_free_ref_array(slmem, user_names_p, "defineusername(old)");
2537dd7cddfSDavid du Colombier 	}
2547dd7cddfSDavid du Colombier 	ref_assign(user_names_p, &new_array);
2557dd7cddfSDavid du Colombier     }
2567dd7cddfSDavid du Colombier     ref_assign(user_names_p->value.refs + op[-1].value.intval, op);
2573ff48bf5SDavid du Colombier   ret:
2583ff48bf5SDavid du Colombier     pop(2);
2597dd7cddfSDavid du Colombier     return 0;
2607dd7cddfSDavid du Colombier }
2617dd7cddfSDavid du Colombier 
2627dd7cddfSDavid du Colombier /* ------ Initialization procedure ------ */
2637dd7cddfSDavid du Colombier 
2647dd7cddfSDavid du Colombier const op_def zdps_op_defs[] =
2657dd7cddfSDavid du Colombier {
2667dd7cddfSDavid du Colombier 		/* Graphics state */
2677dd7cddfSDavid du Colombier     {"1.currentscreenphase", zcurrentscreenphase},
2687dd7cddfSDavid du Colombier     {"3.setscreenphase", zsetscreenphase},
2697dd7cddfSDavid du Colombier 		/* Device-source images */
2707dd7cddfSDavid du Colombier     {"1.image2", zimage2},
2717dd7cddfSDavid du Colombier 		/* View clipping */
2727dd7cddfSDavid du Colombier     {"0eoviewclip", zeoviewclip},
2737dd7cddfSDavid du Colombier     {"0initviewclip", zinitviewclip},
2747dd7cddfSDavid du Colombier     {"0viewclip", zviewclip},
2757dd7cddfSDavid du Colombier     {"0viewclippath", zviewclippath},
2767dd7cddfSDavid du Colombier 		/* User names */
2777dd7cddfSDavid du Colombier     {"2defineusername", zdefineusername},
2787dd7cddfSDavid du Colombier     op_def_end(0)
2797dd7cddfSDavid du Colombier };
280