Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1998 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gsclipsr.c,v 1.4 2002/02/21 22:24:52 giles Exp $ */
18
/* clipsave/cliprestore */
19
#include "gx.h"
20
#include "gserrors.h"
21
#include "gsclipsr.h"
22
#include "gsstruct.h"
23
#include "gxclipsr.h"
24
#include "gxfixed.h"		/* for gxpath.h */
25
#include "gxpath.h"
26
#include "gzstate.h"
27
 
28
/* Structure descriptors */
29
private_st_clip_stack();
30
 
31
/*
32
 * When we free a clip stack entry, free the associated clip path,
33
 * and iterate down the list.  We do this iteratively so that we don't
34
 * take a level of recursion for each node on the list.
35
 */
36
private void
37
rc_free_clip_stack(gs_memory_t * mem, void *vstack, client_name_t cname)
38
{
39
    gx_clip_stack_t *stack = (gx_clip_stack_t *)vstack;
40
    gx_clip_stack_t *next;
41
 
42
    do {
43
	gx_clip_path *pcpath = stack->clip_path;
44
 
45
	next = stack->next;
46
	gs_free_object(stack->rc.memory, stack, cname);
47
	gx_cpath_free(pcpath, "rc_free_clip_stack");
48
    } while ((stack = next) != 0 && !--(stack->rc.ref_count));
49
}
50
 
51
/* clipsave */
52
int
53
gs_clipsave(gs_state *pgs)
54
{
55
    gs_memory_t *mem = pgs->memory;
56
    gx_clip_path *copy =
57
	gx_cpath_alloc_shared(pgs->clip_path, mem, "gs_clipsave(clip_path)");
58
    gx_clip_stack_t *stack =
59
	gs_alloc_struct(mem, gx_clip_stack_t, &st_clip_stack,
60
			"gs_clipsave(stack)");
61
 
62
    if (copy == 0 || stack == 0) {
63
	gs_free_object(mem, stack, "gs_clipsave(stack)");
64
	gs_free_object(mem, copy, "gs_clipsave(clip_path)");
65
	return_error(gs_error_VMerror);
66
    }
67
    rc_init_free(stack, mem, 1, rc_free_clip_stack);
68
    stack->clip_path = copy;
69
    stack->next = pgs->clip_stack;
70
    pgs->clip_stack = stack;
71
    return 0;
72
}
73
 
74
/* cliprestore */
75
int
76
gs_cliprestore(gs_state *pgs)
77
{
78
    gx_clip_stack_t *stack = pgs->clip_stack;
79
 
80
    if (stack) {
81
	gx_clip_stack_t *next = stack->next;
82
	gx_clip_path *pcpath = stack->clip_path;
83
	int code;
84
 
85
	if (stack->rc.ref_count == 1) {
86
	    /* Use assign_free rather than assign_preserve. */
87
	    gs_free_object(stack->rc.memory, stack, "cliprestore");
88
	    code = gx_cpath_assign_free(pgs->clip_path, pcpath);
89
	} else {
90
	    code = gx_cpath_assign_preserve(pgs->clip_path, pcpath);
91
	    if (code < 0)
92
		return code;
93
	    --(stack->rc.ref_count);
94
	}
95
	pgs->clip_stack = next;
96
	return code;
97
    } else {
98
	return gx_cpath_assign_preserve(pgs->clip_path, pgs->saved->clip_path);
99
    }
100
}