~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/gsdps1.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
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: gsdps1.c 8613 2008-03-28 16:30:25Z leonardo $ */
15
 
/* Display PostScript graphics additions for Ghostscript library */
16
 
#include "math_.h"
17
 
#include "gx.h"
18
 
#include "gserrors.h"
19
 
#include "gsmatrix.h"           /* for gscoord.h */
20
 
#include "gscoord.h"
21
 
#include "gspaint.h"
22
 
#include "gxdevice.h"
23
 
#include "gxfixed.h"
24
 
#include "gxmatrix.h"
25
 
#include "gxhldevc.h"
26
 
#include "gspath.h"
27
 
#include "gspath2.h"            /* defines interface */
28
 
#include "gzpath.h"
29
 
#include "gzcpath.h"
30
 
#include "gzstate.h"
31
 
#include "gsutil.h"
32
 
 
33
 
/*
34
 
 * Define how much rounding slop setbbox should leave,
35
 
 * in device coordinates.  Because of rounding in transforming
36
 
 * path coordinates to fixed point, the minimum realistic value is:
37
 
 *
38
 
 *      #define box_rounding_slop_fixed (fixed_epsilon)
39
 
 *
40
 
 * But even this isn't enough to compensate for cumulative rounding error
41
 
 * in rmoveto or rcurveto.  Instead, we somewhat arbitrarily use:
42
 
 */
43
 
#define box_rounding_slop_fixed (fixed_epsilon * 3)
44
 
 
45
 
/* ------ Graphics state ------ */
46
 
 
47
 
/* Set the bounding box for the current path. */
48
 
int
49
 
gs_setbbox(gs_state * pgs, floatp llx, floatp lly, floatp urx, floatp ury)
50
 
{
51
 
    gs_rect ubox, dbox;
52
 
    gs_fixed_rect obox, bbox;
53
 
    gx_path *ppath = pgs->path;
54
 
    int code;
55
 
 
56
 
    if (llx > urx || lly > ury)
57
 
        return_error(gs_error_rangecheck);
58
 
    /* Transform box to device coordinates. */
59
 
    ubox.p.x = llx;
60
 
    ubox.p.y = lly;
61
 
    ubox.q.x = urx;
62
 
    ubox.q.y = ury;
63
 
    if ((code = gs_bbox_transform(&ubox, &ctm_only(pgs), &dbox)) < 0)
64
 
        return code;
65
 
    /* Round the corners in opposite directions. */
66
 
    /* Because we can't predict the magnitude of the dbox values, */
67
 
    /* we add/subtract the slop after fixing. */
68
 
    if (dbox.p.x < fixed2float(min_fixed + box_rounding_slop_fixed) ||
69
 
        dbox.p.y < fixed2float(min_fixed + box_rounding_slop_fixed) ||
70
 
        dbox.q.x >= fixed2float(max_fixed - box_rounding_slop_fixed + fixed_epsilon) ||
71
 
        dbox.q.y >= fixed2float(max_fixed - box_rounding_slop_fixed + fixed_epsilon)
72
 
        )
73
 
        return_error(gs_error_limitcheck);
74
 
    bbox.p.x =
75
 
        (fixed) floor(dbox.p.x * fixed_scale) - box_rounding_slop_fixed;
76
 
    bbox.p.y =
77
 
        (fixed) floor(dbox.p.y * fixed_scale) - box_rounding_slop_fixed;
78
 
    bbox.q.x =
79
 
        (fixed) ceil(dbox.q.x * fixed_scale) + box_rounding_slop_fixed;
80
 
    bbox.q.y =
81
 
        (fixed) ceil(dbox.q.y * fixed_scale) + box_rounding_slop_fixed;
82
 
    if (gx_path_bbox_set(ppath, &obox) >= 0) {  /* Take the union of the bboxes. */
83
 
        ppath->bbox.p.x = min(obox.p.x, bbox.p.x);
84
 
        ppath->bbox.p.y = min(obox.p.y, bbox.p.y);
85
 
        ppath->bbox.q.x = max(obox.q.x, bbox.q.x);
86
 
        ppath->bbox.q.y = max(obox.q.y, bbox.q.y);
87
 
    } else {                    /* empty path *//* Just set the bbox. */
88
 
        ppath->bbox = bbox;
89
 
    }
90
 
    ppath->bbox_set = 1;
91
 
    return 0;
92
 
}
93
 
 
94
 
/* ------ Rectangles ------ */
95
 
 
96
 
/* Append a list of rectangles to a path. */
97
 
static int
98
 
gs_rectappend_compat(gs_state * pgs, const gs_rect * pr, uint count, bool clip)
99
 
{
100
 
    extern bool CPSI_mode;
101
 
 
102
 
    for (; count != 0; count--, pr++) {
103
 
        floatp px = pr->p.x, py = pr->p.y, qx = pr->q.x, qy = pr->q.y;
104
 
        int code;
105
 
 
106
 
        if (CPSI_mode) {
107
 
            /* We believe that the result must be independent
108
 
               on the device initial matrix. 
109
 
               Particularly for the correct dashing 
110
 
               the starting point and the contour direction 
111
 
               must be same with any device initial matrix.
112
 
               Only way to provide it is to choose the starting point 
113
 
               and the direction in the user space. */
114
 
            if (clip) {
115
 
                /* CPSI starts a clippath with the upper right corner. */
116
 
                /* Debugged with CET 11-11.PS page 6 item much13.*/
117
 
                if ((code = gs_moveto(pgs, qx, qy)) < 0 ||
118
 
                    (code = gs_lineto(pgs, qx, py)) < 0 ||
119
 
                    (code = gs_lineto(pgs, px, py)) < 0 ||
120
 
                    (code = gs_lineto(pgs, px, qy)) < 0 ||
121
 
                    (code = gs_closepath(pgs)) < 0
122
 
                    )
123
 
                    return code;
124
 
            } else {
125
 
                /* Debugged with CET 12-12.PS page 10 item more20.*/
126
 
                if (px > qx) {
127
 
                    px = qx; qx = pr->p.x;
128
 
                }
129
 
                if (py > qy) {
130
 
                    py = qy; qy = pr->p.y;
131
 
                }
132
 
                if ((code = gs_moveto(pgs, px, py)) < 0 ||
133
 
                    (code = gs_lineto(pgs, qx, py)) < 0 ||
134
 
                    (code = gs_lineto(pgs, qx, qy)) < 0 ||
135
 
                    (code = gs_lineto(pgs, px, qy)) < 0 ||
136
 
                    (code = gs_closepath(pgs)) < 0
137
 
                    )
138
 
                    return code;
139
 
            }
140
 
        } else {
141
 
            /* Ensure counter-clockwise drawing. */
142
 
            if ((qx >= px) != (qy >= py))
143
 
                qx = px, px = pr->q.x;  /* swap x values */
144
 
            if ((code = gs_moveto(pgs, px, py)) < 0 ||
145
 
                (code = gs_lineto(pgs, qx, py)) < 0 ||
146
 
                (code = gs_lineto(pgs, qx, qy)) < 0 ||
147
 
                (code = gs_lineto(pgs, px, qy)) < 0 ||
148
 
                (code = gs_closepath(pgs)) < 0
149
 
                )
150
 
                return code;
151
 
        }
152
 
    }
153
 
    return 0;
154
 
}
155
 
int
156
 
gs_rectappend(gs_state * pgs, const gs_rect * pr, uint count)
157
 
{
158
 
    return gs_rectappend_compat(pgs, pr, count, false);
159
 
}
160
 
 
161
 
/* Clip to a list of rectangles. */
162
 
int
163
 
gs_rectclip(gs_state * pgs, const gs_rect * pr, uint count)
164
 
{
165
 
    int code;
166
 
    gx_path save;
167
 
 
168
 
    gx_path_init_local(&save, pgs->memory);
169
 
    gx_path_assign_preserve(&save, pgs->path);
170
 
    gs_newpath(pgs);
171
 
    if ((code = gs_rectappend_compat(pgs, pr, count, true)) < 0 ||
172
 
        (code = gs_clip(pgs)) < 0
173
 
        ) {
174
 
        gx_path_assign_free(pgs->path, &save);
175
 
        return code;
176
 
    }
177
 
    gx_path_free(&save, "gs_rectclip");
178
 
    gs_newpath(pgs);
179
 
    return 0;
180
 
}
181
 
 
182
 
/* Fill a list of rectangles. */
183
 
/* We take the trouble to do this efficiently in the simple cases. */
184
 
int
185
 
gs_rectfill(gs_state * pgs, const gs_rect * pr, uint count)
186
 
{
187
 
    const gs_rect *rlist = pr;
188
 
    gx_clip_path *pcpath;
189
 
    uint rcount = count;
190
 
    int code;
191
 
    gx_device * pdev = pgs->device;
192
 
    gx_device_color *pdc = pgs->dev_color;
193
 
    const gs_imager_state *pis = (const gs_imager_state *)pgs;
194
 
    bool hl_color_available = gx_hld_is_hl_color_available(pis, pdc);
195
 
    gs_fixed_rect empty = {{0, 0}, {0, 0}};
196
 
    bool hl_color = (hl_color_available && 
197
 
                dev_proc(pdev, fill_rectangle_hl_color)(pdev, 
198
 
                            &empty, pis, pdc, NULL) == 0);
199
 
 
200
 
    /* Processing a fill object operation */
201
 
    gs_set_object_tag(pgs, GS_PATH_TAG);
202
 
 
203
 
    gx_set_dev_color(pgs);
204
 
    if ((is_fzero2(pgs->ctm.xy, pgs->ctm.yx) ||
205
 
         is_fzero2(pgs->ctm.xx, pgs->ctm.yy)) &&
206
 
        gx_effective_clip_path(pgs, &pcpath) >= 0 &&
207
 
        clip_list_is_rectangle(gx_cpath_list(pcpath)) &&
208
 
        (hl_color ||
209
 
         pdc->type == gx_dc_type_pure ||
210
 
         pdc->type == gx_dc_type_ht_binary ||
211
 
         pdc->type == gx_dc_type_ht_colored
212
 
         /* DeviceN todo: add wts case */) &&
213
 
        gs_state_color_load(pgs) >= 0 &&
214
 
        (*dev_proc(pdev, get_alpha_bits)) (pdev, go_graphics)
215
 
        <= 1 &&
216
 
        (!pgs->overprint || !pgs->effective_overprint_mode)
217
 
        ) {
218
 
        uint i;
219
 
        gs_fixed_rect clip_rect;
220
 
 
221
 
        gx_cpath_inner_box(pcpath, &clip_rect);
222
 
        for (i = 0; i < count; ++i) {
223
 
            gs_fixed_point p, q;
224
 
            gs_fixed_rect draw_rect;
225
 
            
226
 
            if (gs_point_transform2fixed(&pgs->ctm, pr[i].p.x, pr[i].p.y, &p) < 0 ||
227
 
                gs_point_transform2fixed(&pgs->ctm, pr[i].q.x, pr[i].q.y, &q) < 0
228
 
                ) {             /* Switch to the slow algorithm. */
229
 
                goto slow;
230
 
            }
231
 
            draw_rect.p.x = min(p.x, q.x);
232
 
            draw_rect.p.y = min(p.y, q.y);
233
 
            draw_rect.q.x = max(p.x, q.x);
234
 
            draw_rect.q.y = max(p.y, q.y);
235
 
            if (hl_color) {
236
 
                rect_intersect(draw_rect, clip_rect);
237
 
                if (draw_rect.p.x < draw_rect.q.x &&
238
 
                    draw_rect.p.y < draw_rect.q.y) {
239
 
                    code = dev_proc(pdev, fill_rectangle_hl_color)(pdev,
240
 
                             &draw_rect, pis, pdc, pcpath);
241
 
                    if (code < 0)
242
 
                        return code;
243
 
                }
244
 
            } else {
245
 
                int x, y, w, h;
246
 
 
247
 
                draw_rect.p.x -= max(pgs->fill_adjust.x - fixed_epsilon, 0);
248
 
                draw_rect.p.y -= max(pgs->fill_adjust.y - fixed_epsilon, 0);
249
 
                draw_rect.q.x += pgs->fill_adjust.x;
250
 
                draw_rect.q.y += pgs->fill_adjust.y;
251
 
                rect_intersect(draw_rect, clip_rect);
252
 
                x = fixed2int_pixround(draw_rect.p.x);
253
 
                y = fixed2int_pixround(draw_rect.p.y);
254
 
                w = fixed2int_pixround(draw_rect.q.x) - x;
255
 
                h = fixed2int_pixround(draw_rect.q.y) - y;
256
 
                if (w > 0 && h > 0)
257
 
                    if (gx_fill_rectangle(x, y, w, h, pdc, pgs) < 0)
258
 
                        goto slow;
259
 
            }
260
 
        }
261
 
        return 0;
262
 
      slow:rlist = pr + i;
263
 
        rcount = count - i;
264
 
    } {
265
 
        bool do_save = !gx_path_is_null(pgs->path);
266
 
 
267
 
        if (do_save) {
268
 
            if ((code = gs_gsave(pgs)) < 0)
269
 
                return code;
270
 
            gs_newpath(pgs);
271
 
        }
272
 
        if ((code = gs_rectappend(pgs, rlist, rcount)) < 0 ||
273
 
            (code = gs_fill(pgs)) < 0
274
 
            )
275
 
            DO_NOTHING;
276
 
        if (do_save)
277
 
            gs_grestore(pgs);
278
 
        else if (code < 0)
279
 
            gs_newpath(pgs);
280
 
    }
281
 
    return code;
282
 
}
283
 
 
284
 
/* Stroke a list of rectangles. */
285
 
/* (We could do this a lot more efficiently.) */
286
 
int
287
 
gs_rectstroke(gs_state * pgs, const gs_rect * pr, uint count,
288
 
              const gs_matrix * pmat)
289
 
{
290
 
    bool do_save = pmat != NULL || !gx_path_is_null(pgs->path);
291
 
    int code;
292
 
 
293
 
    if (do_save) {
294
 
        if ((code = gs_gsave(pgs)) < 0)
295
 
            return code;
296
 
        gs_newpath(pgs);
297
 
    }
298
 
    if ((code = gs_rectappend(pgs, pr, count)) < 0 ||
299
 
        (pmat != NULL && (code = gs_concat(pgs, pmat)) < 0) ||
300
 
        (code = gs_stroke(pgs)) < 0
301
 
        )
302
 
        DO_NOTHING;
303
 
    if (do_save)
304
 
        gs_grestore(pgs);
305
 
    else if (code < 0)
306
 
        gs_newpath(pgs);
307
 
    return code;
308
 
}