1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied, modified
8    or distributed except as expressly authorized under the terms of that
9    license.  Refer to licensing information at http://www.artifex.com/
10    or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 
14 /* $Id: gsdps.c 8250 2007-09-25 13:31:24Z giles $ */
15 /* Display PostScript extensions */
16 #include "gx.h"
17 #include "gserrors.h"
18 #include "gsdps.h"
19 #include "gspath.h"		/* for newpath */
20 #include "gxdevice.h"		/* for gxcpath.h */
21 #include "gzpath.h"		/* for gzcpath.h */
22 #include "gzstate.h"
23 #include "gzcpath.h"
24 
25 /* ---------------- View clipping ---------------- */
26 
27 /* Forward references */
28 static int common_viewclip(gs_state *, int);
29 
30 int
gs_initviewclip(gs_state * pgs)31 gs_initviewclip(gs_state * pgs)
32 {
33     gx_clip_path *pcpath = pgs->view_clip;
34 
35     if (pcpath != 0 && pcpath->rule != 0) {
36 	gx_cpath_reset(pcpath);
37 	pcpath->rule = 0;
38     }
39     return 0;
40 }
41 
42 int
gs_viewclip(gs_state * pgs)43 gs_viewclip(gs_state * pgs)
44 {
45     return common_viewclip(pgs, gx_rule_winding_number);
46 }
47 
48 int
gs_eoviewclip(gs_state * pgs)49 gs_eoviewclip(gs_state * pgs)
50 {
51     return common_viewclip(pgs, gx_rule_even_odd);
52 }
53 
54 /* This code is (almost) copied from common_clip in gspath.c. */
55 /* Someday we'll find a way to merge them. */
56 static int
common_viewclip(gs_state * pgs,int rule)57 common_viewclip(gs_state * pgs, int rule)
58 {
59     gs_fixed_rect bbox;
60     gx_clip_path rpath;
61     int code;
62     gx_clip_path *pcpath = pgs->view_clip;
63 
64     if (pcpath == 0) {
65 	pcpath = gx_cpath_alloc(pgs->memory, "gs_[eo]viewclip");
66 	if (pcpath == 0)
67 	    return_error(gs_error_VMerror);
68 	pgs->view_clip = pcpath;
69     }
70     if ((code = gx_path_bbox(pgs->path, &bbox)) < 0)
71 	return code;
72     gx_cpath_init_local(&rpath, pgs->memory);
73     code = gx_cpath_from_rectangle(&rpath, &bbox);
74     if (code >= 0)
75 	code = gx_cpath_clip(pgs, &rpath, pgs->path, rule);
76     if (code < 0) {
77 	gx_cpath_free(&rpath, "gs_[eo]viewclip");
78 	return code;
79     }
80     rpath.rule = rule;
81     gx_cpath_assign_free(pcpath, &rpath);
82     gs_newpath(pgs);
83     return 0;
84 }
85 
86 int
gs_viewclippath(gs_state * pgs)87 gs_viewclippath(gs_state * pgs)
88 {
89     gx_path cpath;
90     gx_clip_path *pcpath = pgs->view_clip;
91     int code;
92 
93     gx_path_init_local(&cpath, pgs->memory);
94     if (pcpath == 0 || pcpath->rule == 0) {
95 	/* No view clip path is active: fabricate one. */
96 	gs_fixed_rect box;
97 
98 	code = gx_default_clip_box(pgs, &box);
99 	if (code < 0)
100 	    return code;
101 	code = gx_path_add_rectangle(&cpath, box.p.x, box.p.y,
102 				     box.q.x, box.q.y);
103     } else {
104 	code = gx_cpath_to_path(pcpath, &cpath);
105     }
106     if (code < 0)
107 	return code;
108     return gx_path_assign_free(pgs->path, &cpath);
109 }
110