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