summaryrefslogtreecommitdiff
path: root/pcl/pcdraw.c
blob: f15d99545db1294fbbe839d5675b0a17521d8eb6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* Portions Copyright (C) 2001 artofcode LLC.
   Portions Copyright (C) 1996, 2001 Artifex Software Inc.
   Portions Copyright (C) 1988, 2000 Aladdin Enterprises.
   This software is based in part on the work of the Independent JPEG Group.
   All Rights Reserved.

   This software is distributed under license and may not be copied, modified
   or distributed except as expressly authorized under the terms of that
   license.  Refer to licensing information at http://www.artifex.com/ or
   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
   San Rafael, CA  94903, (415)492-9861, for further information. */
/*$Id$ */

/* pcdraw.c - PCL5 drawing utilities */

#include "gx.h"
#include "gsmatrix.h"
#include "gscoord.h"
#include "gsstate.h"
#include "gsrop.h"
#include "gxfixed.h"
#include "pcstate.h"
#include "pcht.h"
#include "pcpatrn.h"
#include "pcdraw.h"

/*
 * Set all necessary graphics state parameters for PCL drawing
 * (currently only CTM and clipping region).
 */
  int
pcl_set_graphics_state(
    pcl_state_t *   pcs
)
{
    int             code = pcl_set_ctm(pcs, true);
    return ( code < 0 ? code : gs_initclip(pcs->pgs) );
}

/*
 * Backwards compatibility function. Now, however, it provides accurate
 * results.
 */
  int
pcl_set_ctm(
    pcl_state_t *   pcs,
    bool            use_pd
)
{
    return gs_setmatrix( pcs->pgs,
                         ( use_pd ? &(pcs->xfm_state.pd2dev_mtx)
                           : &(pcs->xfm_state.lp2dev_mtx) )
                         );
}

/*
 * set pcl's drawing color.  Uses pcl state values to determine
 * rotation and translation of patterns.
 *
 * The final operand indicates if a PCL raster (image) is being rendered;
 * special considerations apply in this case. See the comments in pcbipatrn.c
 * pcpatrn.c for further information.
 *
 * PCL no longer uses the graphic library transparency mechanism.
 */
 int
pcl_set_drawing_color(
    pcl_state_t *           pcs,
    pcl_pattern_source_t    type,
    int                     id,
    bool                    for_image
)
{   int                     code;

    /* use PCL's pattern transparency */
    pcs->pattern_transparent = pcs->pcl_pattern_transparent;

    pcl_ht_set_halftone(pcs);

    if (type == pcl_pattern_raster_cspace)
        code = (pcl_pattern_get_proc_PCL(type))(pcs, 0, true);
    else
        code = (pcl_pattern_get_proc_PCL(type))(pcs, id, (int)for_image);
    if (code >= 0) {
        gs_setrasterop(pcs->pgs, (gs_rop3_t)pcs->logical_op);
        gs_setfilladjust(pcs->pgs, 0.0, 0.0);
    }
    return 0;
}

/*
 * The pcl state structure retains information concerning the current contents
 * of the grpahic state. To keep this information synchronized with the
 * graphic state itself, this information is kept in a stack that is pushed
 * or poped, repsectively, for each invocation of gsave and grestore.
 * This opertion is prefromed by the following pair of routines, which should
 * be used in place of gsave and grestore.
 */

private_st_gstate_ids_t();

  int
pcl_gsave(
    pcl_state_t *       pcs
)
{
    int                 code = 0;
    pcl_gstate_ids_t *  pids = gs_alloc_struct( pcs->memory,
                                                pcl_gstate_ids_t,
                                                &st_gstate_ids_t,
                                                "PCL gsave"
                                                );
    if (pids == 0)
        return e_Memory;

    pids->pht = 0;
    pids->pccolor = 0;

    if ((code = gs_gsave(pcs->pgs)) >= 0) {
        pids->prev = pcs->pids->prev;
        pcs->pids->prev = pids;
        pcl_ccolor_init_from(pids->pccolor, pcs->pids->pccolor);
        pcl_ht_init_from(pids->pht, pcs->pids->pht);
    } else
        gs_free_object(pcs->memory, pids, "PCL gsave");

    return code;
}

  int
pcl_grestore(
    pcl_state_t *       pcs
)
{
    pcl_gstate_ids_t *  pids = pcs->pids->prev;
    int                 code = 0;
    /* check for bottom of graphic state stack */
    if (pcs == 0 || pcs->pids == 0 || pids == 0)
        return e_Range;
    if ((code = gs_grestore(pcs->pgs)) >= 0) {
        pcs->pids->prev = pids->prev;
        pcl_ccolor_copy_from(pcs->pids->pccolor, pids->pccolor);
        pcl_ccolor_release(pids->pccolor);
        pcl_ht_copy_from(pcs->pids->pht, pids->pht);
        pcl_ht_release(pids->pht);
        gs_free_object(pcs->memory, pids, "PCL grestore");
    }

    return code;
}

  void
pcl_init_gstate_stk(
    pcl_state_t *       pcs
)
{
    pcl_gstate_ids_t *  pids = gs_alloc_struct( pcs->memory,
                                                pcl_gstate_ids_t,
                                                &st_gstate_ids_t,
                                                "PCL gsave"
                                                );
    if (pids != 0) {    /* otherwise will crash soon enough */
        pids->prev = 0;
        pids->pccolor = 0;
        pids->pht = 0;
    }
    pcs->pids = pids;
}

void
pcl_free_gstate_stk(pcl_state_t *pcs)
{
    gs_free_object(pcs->memory, pcs->pids, "PCL grestore");
}