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

« back to all changes in this revision

Viewing changes to src/gsptype2.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: gsptype2.c 8655 2008-04-21 14:53:38Z leonardo $ */
15
 
/* PatternType 2 implementation */
16
 
#include "gx.h"
17
 
#include "gserrors.h"
18
 
#include "gscspace.h"
19
 
#include "gsshade.h"
20
 
#include "gsmatrix.h"           /* for gspcolor.h */
21
 
#include "gsstate.h"            /* for set/currentfilladjust */
22
 
#include "gxcolor2.h"
23
 
#include "gxdcolor.h"
24
 
#include "gsptype2.h"
25
 
#include "gxpcolor.h"
26
 
#include "gxstate.h"            /* for gs_state_memory */
27
 
#include "gzpath.h"
28
 
#include "gzcpath.h"
29
 
#include "gzstate.h"
30
 
 
31
 
/* GC descriptors */
32
 
private_st_pattern2_template();
33
 
private_st_pattern2_instance();
34
 
 
35
 
/* GC procedures */
36
 
static ENUM_PTRS_BEGIN(pattern2_instance_enum_ptrs) {
37
 
    if (index < st_pattern2_template_max_ptrs) {
38
 
        gs_ptr_type_t ptype =
39
 
            ENUM_SUPER_ELT(gs_pattern2_instance_t, st_pattern2_template,
40
 
                           template, 0);
41
 
 
42
 
        if (ptype)
43
 
            return ptype;
44
 
        return ENUM_OBJ(NULL);  /* don't stop early */
45
 
    }
46
 
    ENUM_PREFIX(st_pattern_instance, st_pattern2_template_max_ptrs);
47
 
}
48
 
ENUM_PTRS_END
49
 
static RELOC_PTRS_BEGIN(pattern2_instance_reloc_ptrs) {
50
 
    RELOC_PREFIX(st_pattern_instance);
51
 
    RELOC_SUPER(gs_pattern2_instance_t, st_pattern2_template, template);
52
 
} RELOC_PTRS_END
53
 
 
54
 
/* Define a PatternType 2 pattern. */
55
 
static pattern_proc_uses_base_space(gs_pattern2_uses_base_space);
56
 
static pattern_proc_make_pattern(gs_pattern2_make_pattern);
57
 
static pattern_proc_get_pattern(gs_pattern2_get_pattern);
58
 
static pattern_proc_remap_color(gs_pattern2_remap_color);
59
 
static pattern_proc_set_color(gs_pattern2_set_color);
60
 
static const gs_pattern_type_t gs_pattern2_type = {
61
 
    2, {
62
 
        gs_pattern2_uses_base_space, gs_pattern2_make_pattern,
63
 
        gs_pattern2_get_pattern, gs_pattern2_remap_color,
64
 
        gs_pattern2_set_color,
65
 
    }
66
 
};
67
 
 
68
 
/* Initialize a PatternType 2 pattern. */
69
 
void
70
 
gs_pattern2_init(gs_pattern2_template_t * ppat)
71
 
{
72
 
    gs_pattern_common_init((gs_pattern_template_t *)ppat, &gs_pattern2_type);
73
 
}
74
 
 
75
 
/* Test whether a PatternType 2 pattern uses a base space. */
76
 
static bool
77
 
gs_pattern2_uses_base_space(const gs_pattern_template_t *ptemp)
78
 
{
79
 
    return false;
80
 
}
81
 
 
82
 
/* Make an instance of a PatternType 2 pattern. */
83
 
static int
84
 
gs_pattern2_make_pattern(gs_client_color * pcc,
85
 
                         const gs_pattern_template_t * pcp,
86
 
                         const gs_matrix * pmat, gs_state * pgs,
87
 
                         gs_memory_t * mem)
88
 
{
89
 
    const gs_pattern2_template_t *ptemp =
90
 
        (const gs_pattern2_template_t *)pcp;
91
 
    int code = gs_make_pattern_common(pcc, pcp, pmat, pgs, mem,
92
 
                                      &st_pattern2_instance);
93
 
    gs_pattern2_instance_t *pinst;
94
 
 
95
 
    if (code < 0)
96
 
        return code;
97
 
    pinst = (gs_pattern2_instance_t *)pcc->pattern;
98
 
    pinst->template = *ptemp;
99
 
    pinst->shfill = false;
100
 
    return 0;
101
 
}
102
 
 
103
 
/* Get the template of a PatternType 2 pattern instance. */
104
 
static const gs_pattern_template_t *
105
 
gs_pattern2_get_pattern(const gs_pattern_instance_t *pinst)
106
 
{
107
 
    return (const gs_pattern_template_t *)
108
 
        &((const gs_pattern2_instance_t *)pinst)->template;
109
 
}
110
 
 
111
 
/* Set the 'shfill' flag to a PatternType 2 pattern instance. */
112
 
int
113
 
gs_pattern2_set_shfill(gs_client_color * pcc)
114
 
{
115
 
    gs_pattern2_instance_t *pinst;
116
 
 
117
 
    if (pcc->pattern->type != &gs_pattern2_type)
118
 
        return_error(gs_error_unregistered); /* Must not happen. */
119
 
    pinst = (gs_pattern2_instance_t *)pcc->pattern;
120
 
    pinst->shfill = true;
121
 
    return 0;
122
 
}
123
 
 
124
 
 
125
 
/* ---------------- Rendering ---------------- */
126
 
 
127
 
/* GC descriptor */
128
 
gs_private_st_ptrs_add0(st_dc_pattern2, gx_device_color, "dc_pattern2",
129
 
                        dc_pattern2_enum_ptrs, dc_pattern2_reloc_ptrs,
130
 
                        st_client_color, ccolor);
131
 
 
132
 
static dev_color_proc_get_dev_halftone(gx_dc_pattern2_get_dev_halftone);
133
 
static dev_color_proc_load(gx_dc_pattern2_load);
134
 
static dev_color_proc_fill_rectangle(gx_dc_pattern2_fill_rectangle);
135
 
static dev_color_proc_equal(gx_dc_pattern2_equal);
136
 
static dev_color_proc_save_dc(gx_dc_pattern2_save_dc);
137
 
/*
138
 
 * Define the PatternType 2 Pattern device color type.  This is public only
139
 
 * for testing when writing PDF or PostScript.
140
 
 */
141
 
const gx_device_color_type_t gx_dc_pattern2 = {
142
 
    &st_dc_pattern2,
143
 
    gx_dc_pattern2_save_dc, gx_dc_pattern2_get_dev_halftone,
144
 
    gx_dc_ht_get_phase,
145
 
    gx_dc_pattern2_load, gx_dc_pattern2_fill_rectangle,
146
 
    gx_dc_default_fill_masked, gx_dc_pattern2_equal,
147
 
    gx_dc_cannot_write, gx_dc_cannot_read, 
148
 
    gx_dc_pattern_get_nonzero_comps
149
 
};
150
 
 
151
 
/* Check device color for Pattern Type 2. */
152
 
bool
153
 
gx_dc_is_pattern2_color(const gx_device_color *pdevc)
154
 
{
155
 
    return pdevc->type == &gx_dc_pattern2;
156
 
}
157
 
 
158
 
/*
159
 
 * The device halftone used by a PatternType 2 patter is that current in
160
 
 * the graphic state at the time of the makepattern call.
161
 
 */
162
 
static const gx_device_halftone *
163
 
gx_dc_pattern2_get_dev_halftone(const gx_device_color * pdevc)
164
 
{
165
 
    return ((gs_pattern2_instance_t *)pdevc->ccolor.pattern)->saved->dev_ht;
166
 
}
167
 
 
168
 
/* Load a PatternType 2 color into the cache.  (No effect.) */
169
 
static int
170
 
gx_dc_pattern2_load(gx_device_color *pdevc, const gs_imager_state *ignore_pis,
171
 
                    gx_device *ignore_dev, gs_color_select_t ignore_select)
172
 
{
173
 
    return 0;
174
 
}
175
 
 
176
 
/* Remap a PatternType 2 color. */
177
 
static int
178
 
gs_pattern2_remap_color(const gs_client_color * pc, const gs_color_space * pcs,
179
 
                        gx_device_color * pdc, const gs_imager_state * pis,
180
 
                        gx_device * dev, gs_color_select_t select)
181
 
{
182
 
    /* We don't do any actual color mapping now. */
183
 
    pdc->type = &gx_dc_pattern2;
184
 
    pdc->ccolor = *pc;
185
 
    pdc->ccolor_valid = true;
186
 
    return 0;
187
 
}
188
 
 
189
 
/*
190
 
 * Perform actions required at set_color time. Since PatternType 2
191
 
 * patterns specify a color space, we must update the overprint
192
 
 * information as required by that color space. We temporarily disable
193
 
 * overprint_mode, as it is never applicable when using shading patterns.
194
 
 */
195
 
static int
196
 
gs_pattern2_set_color(const gs_client_color * pcc, gs_state * pgs)
197
 
{
198
 
    gs_pattern2_instance_t * pinst = (gs_pattern2_instance_t *)pcc->pattern;
199
 
    gs_color_space * pcs = pinst->template.Shading->params.ColorSpace;
200
 
    int code, save_overprint_mode = pgs->overprint_mode;
201
 
 
202
 
    pgs->overprint_mode = 0;
203
 
    code = pcs->type->set_overprint(pcs, pgs);
204
 
    pgs->overprint_mode = save_overprint_mode;
205
 
    return code;
206
 
}
207
 
 
208
 
/* Fill a rectangle with a PatternType 2 color. */
209
 
/* WARNING: This function doesn't account the shading BBox
210
 
   to allow the clipent to optimize the clipping 
211
 
   with changing the order of clip patrhs and rects.
212
 
   The client must clip with the shading BBOx before calling this function. */
213
 
static int
214
 
gx_dc_pattern2_fill_rectangle(const gx_device_color * pdevc, int x, int y,
215
 
                              int w, int h, gx_device * dev,
216
 
                              gs_logical_operation_t lop,
217
 
                              const gx_rop_source_t * source)
218
 
{
219
 
    if (dev_proc(dev, pattern_manage)(dev, gs_no_id, NULL, pattern_manage__is_cpath_accum)) {
220
 
        /* Performing a conversion of imagemask into a clipping path.
221
 
           Fall back to the device procedure. */
222
 
        return dev_proc(dev, fill_rectangle)(dev, x, y, w, h, (gx_color_index)0/*any*/);
223
 
    } else {
224
 
        gs_fixed_rect rect;
225
 
        gs_pattern2_instance_t *pinst =
226
 
            (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
227
 
 
228
 
        rect.p.x = int2fixed(x);
229
 
        rect.p.y = int2fixed(y);
230
 
        rect.q.x = int2fixed(x + w);
231
 
        rect.q.y = int2fixed(y + h);
232
 
        return gs_shading_do_fill_rectangle(pinst->template.Shading, &rect, dev,
233
 
                                    (gs_imager_state *)pinst->saved, !pinst->shfill);
234
 
    }
235
 
}
236
 
 
237
 
/* Compare two PatternType 2 colors for equality. */
238
 
static bool
239
 
gx_dc_pattern2_equal(const gx_device_color * pdevc1,
240
 
                     const gx_device_color * pdevc2)
241
 
{
242
 
    return pdevc2->type == pdevc1->type &&
243
 
        pdevc1->ccolor.pattern == pdevc2->ccolor.pattern;
244
 
}
245
 
 
246
 
/*
247
 
 * Currently patterns cannot be passed through the command list,
248
 
 * however vector devices need to save a color for comparing
249
 
 * it with another color, which appears later.
250
 
 * We provide a minimal support, which is necessary
251
 
 * for the current implementation of pdfwrite.
252
 
 * It is not sufficient for restoring the pattern from the saved color.
253
 
 */
254
 
static void
255
 
gx_dc_pattern2_save_dc(
256
 
    const gx_device_color * pdevc, 
257
 
    gx_device_color_saved * psdc )
258
 
{
259
 
    gs_pattern2_instance_t * pinst = (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
260
 
 
261
 
    psdc->type = pdevc->type;
262
 
    psdc->colors.pattern2.id = pinst->pattern_id;
263
 
    psdc->colors.pattern2.shfill = pinst->shfill;
264
 
}
265
 
 
266
 
/* Transform a shading bounding box into device space. */
267
 
/* This is just a bridge to an old code. */
268
 
int
269
 
gx_dc_pattern2_shade_bbox_transform2fixed(const gs_rect * rect, const gs_imager_state * pis,
270
 
                           gs_fixed_rect * rfixed)
271
 
{
272
 
    gs_rect dev_rect;
273
 
    int code = gs_bbox_transform(rect, &ctm_only(pis), &dev_rect);
274
 
 
275
 
    if (code >= 0) {
276
 
        rfixed->p.x = float2fixed(dev_rect.p.x);
277
 
        rfixed->p.y = float2fixed(dev_rect.p.y);
278
 
        rfixed->q.x = float2fixed(dev_rect.q.x);
279
 
        rfixed->q.y = float2fixed(dev_rect.q.y);
280
 
    }
281
 
    return code;
282
 
}
283
 
 
284
 
/* Get a shading bbox. Returns 1 on success. */
285
 
int
286
 
gx_dc_pattern2_get_bbox(const gx_device_color * pdevc, gs_fixed_rect *bbox)
287
 
{
288
 
    gs_pattern2_instance_t *pinst =
289
 
        (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
290
 
    int code;
291
 
 
292
 
    if (!pinst->template.Shading->params.have_BBox)
293
 
        return 0;
294
 
    code = gx_dc_pattern2_shade_bbox_transform2fixed(
295
 
                &pinst->template.Shading->params.BBox, (gs_imager_state *)pinst->saved, bbox);
296
 
    if (code < 0)
297
 
        return code;
298
 
    return 1;
299
 
}
300
 
 
301
 
int
302
 
gx_dc_pattern2_color_has_bbox(const gx_device_color * pdevc)
303
 
{
304
 
    gs_pattern2_instance_t *pinst = (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
305
 
    const gs_shading_t *psh = pinst->template.Shading;
306
 
 
307
 
    return psh->params.have_BBox;
308
 
}
309
 
 
310
 
/* Create a path from a PatternType 2 shading BBox to a path. */
311
 
static int
312
 
gx_dc_shading_path_add_box(gx_path *ppath, const gx_device_color * pdevc)
313
 
{
314
 
    gs_pattern2_instance_t *pinst = (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
315
 
    const gs_shading_t *psh = pinst->template.Shading;
316
 
 
317
 
    if (!psh->params.have_BBox)
318
 
        return_error(gs_error_unregistered); /* Do not call in this case. */
319
 
    else {
320
 
        gs_state *pis = pinst->saved;
321
 
 
322
 
        return gs_shading_path_add_box(ppath, &psh->params.BBox, &pis->ctm);
323
 
    }
324
 
}
325
 
 
326
 
/* Intersect a clipping path a shading BBox. */
327
 
int
328
 
gx_dc_pattern2_clip_with_bbox_simple(const gx_device_color * pdevc, gx_device * pdev, 
329
 
                              gx_clip_path *cpath_local)
330
 
{
331
 
    int code = 0;
332
 
 
333
 
    if (gx_dc_is_pattern2_color(pdevc) && gx_dc_pattern2_color_has_bbox(pdevc) &&
334
 
            (*dev_proc(pdev, pattern_manage))(pdev, gs_no_id, NULL, pattern_manage__shading_area) == 0) {
335
 
        gs_pattern2_instance_t *pinst = (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
336
 
        gx_path box_path;
337
 
        gs_memory_t *mem = cpath_local->path.memory;
338
 
 
339
 
        gx_path_init_local(&box_path, mem);
340
 
        code = gx_dc_shading_path_add_box(&box_path, pdevc);
341
 
        if (code == gs_error_limitcheck) {
342
 
            /* Ignore huge BBox - bug 689027. */
343
 
            code = 0;
344
 
        } else if (code >= 0) {
345
 
            code = gx_cpath_intersect(cpath_local, &box_path, gx_rule_winding_number, (gs_imager_state *)pinst->saved);
346
 
        }
347
 
        gx_path_free(&box_path, "gx_default_fill_path(path_bbox)");
348
 
    }
349
 
    return code;
350
 
}
351
 
 
352
 
/* Check whether color is a shading with BBox. */
353
 
int
354
 
gx_dc_pattern2_is_rectangular_cell(const gx_device_color * pdevc, gx_device * pdev, gs_fixed_rect *rect)
355
 
{
356
 
    if (gx_dc_is_pattern2_color(pdevc) && gx_dc_pattern2_color_has_bbox(pdevc) &&
357
 
            (*dev_proc(pdev, pattern_manage))(pdev, gs_no_id, NULL, pattern_manage__shading_area) == 0) {
358
 
        gs_pattern2_instance_t *pinst = (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
359
 
        const gs_shading_t *psh = pinst->template.Shading;
360
 
        gs_fixed_point p, q; 
361
 
 
362
 
        if (is_xxyy(&ctm_only(pinst->saved)))
363
 
            if (psh->params.have_BBox) {
364
 
                int code = gs_point_transform2fixed(&pinst->saved->ctm, 
365
 
                            psh->params.BBox.p.x, psh->params.BBox.p.y, &p);
366
 
                if (code < 0)
367
 
                    return code;
368
 
                code = gs_point_transform2fixed(&pinst->saved->ctm, 
369
 
                            psh->params.BBox.q.x, psh->params.BBox.q.y, &q);
370
 
                if (code < 0)
371
 
                    return code;
372
 
                if (p.x > q.x) {
373
 
                    p.x ^= q.x; q.x ^= p.x; p.x ^= q.x;
374
 
                }
375
 
                if (p.y > q.y) {
376
 
                    p.y ^= q.y; q.y ^= p.y; p.y ^= q.y;
377
 
                }
378
 
                rect->p = p;
379
 
                rect->q = q;
380
 
                return 1;
381
 
            }
382
 
    }
383
 
    return 0;
384
 
}
385
 
 
386
 
 
387
 
/* Get a shading color space. */
388
 
const gs_color_space *
389
 
gx_dc_pattern2_get_color_space(const gx_device_color * pdevc)
390
 
{
391
 
    gs_pattern2_instance_t *pinst =
392
 
        (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
393
 
    const gs_shading_t *psh = pinst->template.Shading;
394
 
 
395
 
    return psh->params.ColorSpace;
396
 
}
397
 
 
398
 
 
399
 
/* Check device color for a possibly self-overlapping shading. */
400
 
bool
401
 
gx_dc_pattern2_can_overlap(const gx_device_color *pdevc)
402
 
{
403
 
    gs_pattern2_instance_t * pinst;
404
 
 
405
 
    if (pdevc->type != &gx_dc_pattern2)
406
 
        return false;
407
 
    pinst = (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
408
 
    switch (pinst->template.Shading->head.type) {
409
 
        case 3: case 6: case 7:
410
 
            return true;
411
 
        default:
412
 
            return false;
413
 
    }
414
 
}
415
 
 
416
 
/* Check whether a pattern color has a background. */
417
 
bool gx_dc_pattern2_has_background(const gx_device_color *pdevc)
418
 
{
419
 
    gs_pattern2_instance_t * pinst;
420
 
    const gs_shading_t *Shading;
421
 
 
422
 
    if (pdevc->type != &gx_dc_pattern2)
423
 
        return false;
424
 
    pinst = (gs_pattern2_instance_t *)pdevc->ccolor.pattern;
425
 
    Shading = pinst->template.Shading;
426
 
    return !pinst->shfill && Shading->params.Background != NULL;
427
 
}