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

« back to all changes in this revision

Viewing changes to src/gdevpdfb.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: gdevpdfb.c 8611 2008-03-27 08:37:58Z ken $ */
15
 
/* Low-level bitmap image handling for PDF-writing driver */
16
 
#include "string_.h"
17
 
#include "gx.h"
18
 
#include "gserrors.h"
19
 
#include "gdevpdfx.h"
20
 
#include "gdevpdfg.h"
21
 
#include "gdevpdfo.h"           /* for data stream */
22
 
#include "gxcspace.h"
23
 
#include "gxdcolor.h"
24
 
#include "gxpcolor.h"
25
 
#include "gxhldevc.h"
26
 
 
27
 
/* We need this color space type for constructing temporary color spaces. */
28
 
extern const gs_color_space_type gs_color_space_type_Indexed;
29
 
 
30
 
/* ---------------- Utilities ---------------- */
31
 
 
32
 
/* Fill in the image parameters for a bitmap image. */
33
 
static void
34
 
pdf_make_bitmap_image(gs_image_t * pim, int x, int y, int w, int h)
35
 
{
36
 
    pim->Width = w;
37
 
    pim->Height = h;
38
 
    pdf_make_bitmap_matrix(&pim->ImageMatrix, x, y, w, h, h);
39
 
}
40
 
 
41
 
/* ---------------- Driver procedures ---------------- */
42
 
 
43
 
/* Copy a mask bitmap.  for_pattern = -1 means put the image in-line, */
44
 
/* 1 means put the image in a resource. */
45
 
static int
46
 
pdf_copy_mask_data(gx_device_pdf * pdev, const byte * base, int sourcex,
47
 
                   int raster, gx_bitmap_id id, int x, int y, int w, int h,
48
 
                   gs_image_t *pim, pdf_image_writer *piw,
49
 
                   int for_pattern)
50
 
{
51
 
    ulong nbytes;
52
 
    int code;
53
 
    const byte *row_base;
54
 
    int row_step;
55
 
    bool in_line;
56
 
 
57
 
    gs_image_t_init_mask(pim, true);
58
 
    pdf_make_bitmap_image(pim, x, y, w, h);
59
 
    nbytes = ((ulong)w * h + 7) / 8;
60
 
 
61
 
    if (for_pattern) {
62
 
        /*
63
 
         * Patterns must be emitted in order of increasing user Y, i.e.,
64
 
         * the opposite of PDF's standard image order.
65
 
         */
66
 
        row_base = base + (h - 1) * raster;
67
 
        row_step = -raster;
68
 
        in_line = for_pattern < 0;
69
 
    } else {
70
 
        row_base = base;
71
 
        row_step = raster;
72
 
        in_line = nbytes < pdev->MaxInlineImageSize;
73
 
        pdf_put_image_matrix(pdev, &pim->ImageMatrix, 1.0);
74
 
        /*
75
 
         * Check whether we've already made an XObject resource for this
76
 
         * image.
77
 
         */
78
 
        if (id != gx_no_bitmap_id) {
79
 
            piw->pres = pdf_find_resource_by_gs_id(pdev, resourceXObject, id);
80
 
            if (piw->pres)
81
 
                return 0;
82
 
        }
83
 
    }
84
 
    /*
85
 
     * We have to be able to control whether to put Pattern images in line,
86
 
     * to avoid trying to create an XObject resource while we're in the
87
 
     * middle of writing a Pattern resource.
88
 
     */
89
 
    if (for_pattern < 0)
90
 
        stream_puts(pdev->strm, "q ");
91
 
    pdf_image_writer_init(piw);
92
 
    pdev->ParamCompatibilityLevel = pdev->CompatibilityLevel;
93
 
    if ((code = pdf_begin_write_image(pdev, piw, id, w, h, NULL, in_line)) < 0 ||
94
 
        (code = psdf_setup_lossless_filters((gx_device_psdf *) pdev,
95
 
                                            &piw->binary[0],
96
 
                                            (gs_pixel_image_t *)pim, in_line)) < 0 ||
97
 
        (code = pdf_begin_image_data(pdev, piw, (const gs_pixel_image_t *)pim,
98
 
                                     NULL, 0)) < 0
99
 
        )
100
 
        return code;
101
 
    pdf_copy_mask_bits(piw->binary[0].strm, row_base, sourcex, row_step, w, h, 0);
102
 
    pdf_end_image_binary(pdev, piw, piw->height);
103
 
    return pdf_end_write_image(pdev, piw);
104
 
}
105
 
 
106
 
static void 
107
 
set_image_color(gx_device_pdf *pdev, gx_color_index c)
108
 
{
109
 
    pdf_set_pure_color(pdev, c, &pdev->saved_fill_color,
110
 
                        &pdev->fill_used_process_color,
111
 
                        &psdf_set_fill_color_commands);
112
 
    if (!pdev->HaveStrokeColor)
113
 
        pdf_set_pure_color(pdev, c, &pdev->saved_stroke_color,
114
 
                            &pdev->stroke_used_process_color,
115
 
                            &psdf_set_stroke_color_commands);
116
 
}
117
 
 
118
 
/* Copy a monochrome bitmap or mask. */
119
 
static int
120
 
pdf_copy_mono(gx_device_pdf *pdev,
121
 
              const byte *base, int sourcex, int raster, gx_bitmap_id id,
122
 
              int x, int y, int w, int h, gx_color_index zero,
123
 
              gx_color_index one, const gx_clip_path *pcpath)
124
 
{
125
 
    int code;
126
 
    gs_color_space *pcs = NULL;
127
 
    cos_value_t cs_value;
128
 
    cos_value_t *pcsvalue;
129
 
    byte palette[arch_sizeof_color_index * 2];
130
 
    gs_image_t image;
131
 
    pdf_image_writer writer;
132
 
    pdf_stream_position_t ipos;
133
 
    pdf_resource_t *pres = 0;
134
 
    byte invert = 0;
135
 
    bool in_line = false;
136
 
 
137
 
    /* Update clipping. */
138
 
    if (pdf_must_put_clip_path(pdev, pcpath)) {
139
 
        code = pdf_open_page(pdev, PDF_IN_STREAM);
140
 
        if (code < 0)
141
 
            return code;
142
 
        code = pdf_put_clip_path(pdev, pcpath);
143
 
        if (code < 0)
144
 
            return code;
145
 
    }
146
 
    /* We have 3 cases: mask, inverse mask, and solid. */
147
 
    if (zero == gx_no_color_index) {
148
 
        if (one == gx_no_color_index)
149
 
            return 0;
150
 
        /* If a mask has an id, assume it's a character. */
151
 
        if (id != gx_no_bitmap_id && sourcex == 0) {
152
 
            pres = pdf_find_resource_by_gs_id(pdev, resourceCharProc, id);
153
 
            if (pres == 0) {    /* Define the character in an embedded font. */
154
 
                pdf_char_proc_t *pcp;
155
 
                double x_offset;
156
 
                int y_offset;
157
 
 
158
 
                gs_image_t_init_mask(&image, false);
159
 
                invert = 0xff;
160
 
                pdf_make_bitmap_image(&image, x, y, w, h);
161
 
                y_offset = pdf_char_image_y_offset(pdev, x, y, h);
162
 
                /*
163
 
                 * The Y axis of the text matrix is inverted,
164
 
                 * so we need to negate the Y offset appropriately.
165
 
                 */
166
 
                code = pdf_begin_char_proc(pdev, w, h, 0, y_offset, id,
167
 
                                           &pcp, &ipos);
168
 
                if (code < 0)
169
 
                    return code;
170
 
                y_offset = -y_offset;
171
 
                x_offset = psdf_round(pdev->char_width.x, 100, 10); /* See 
172
 
                        pdf_write_Widths about rounding. We need to provide 
173
 
                        a compatible data for Tj. */
174
 
                pprintg1(pdev->strm, "%g ", x_offset);
175
 
                pprintd3(pdev->strm, "0 0 %d %d %d d1\n", y_offset, w, h + y_offset);
176
 
                pprintd3(pdev->strm, "%d 0 0 %d 0 %d cm\n", w, h,
177
 
                         y_offset);
178
 
                pdf_image_writer_init(&writer);
179
 
                code = pdf_begin_write_image(pdev, &writer, gs_no_id, w, h, NULL, true);
180
 
                if (code < 0)
181
 
                    return code;
182
 
                pres = (pdf_resource_t *) pcp;
183
 
                goto wr;
184
 
            } else if (pdev->pte) {
185
 
                /* We're under pdf_text_process. It set a high level color. */
186
 
            } else
187
 
                set_image_color(pdev, one);
188
 
            pdf_make_bitmap_matrix(&image.ImageMatrix, x, y, w, h, h);
189
 
            goto rx;
190
 
        }
191
 
        set_image_color(pdev, one);
192
 
        gs_image_t_init_mask(&image, false);
193
 
        invert = 0xff;
194
 
    } else if (one == gx_no_color_index) {
195
 
        gs_image_t_init_mask(&image, false);
196
 
        set_image_color(pdev, zero);
197
 
    } else if (zero == pdev->black && one == pdev->white) {
198
 
        pcs = gs_cspace_new_DeviceGray(pdev->memory);
199
 
        gs_image_t_init(&image, pcs);
200
 
    } else if (zero == pdev->white && one == pdev->black) {
201
 
        pcs = gs_cspace_new_DeviceGray(pdev->memory);
202
 
        gs_image_t_init(&image, pcs);
203
 
        invert = 0xff;
204
 
    } else {
205
 
        /*
206
 
         * We think this code is never executed when interpreting PostScript
207
 
         * or PDF: the library never uses monobit non-mask images
208
 
         * internally, and high-level images don't go through this code.
209
 
         * However, we still want the code to work.
210
 
         */
211
 
        gs_color_space *pcs_base;
212
 
        gx_color_index c[2];
213
 
        int i, j;
214
 
        int ncomp = pdev->color_info.num_components;
215
 
        byte *p;
216
 
 
217
 
        code = pdf_cspace_init_Device(pdev->memory, &pcs_base, ncomp);
218
 
        if (code < 0)
219
 
            return code;
220
 
        c[0] = psdf_adjust_color_index((gx_device_vector *)pdev, zero);
221
 
        c[1] = psdf_adjust_color_index((gx_device_vector *)pdev, one);
222
 
        pcs = gs_cspace_alloc(pdev->memory, &gs_color_space_type_Indexed);
223
 
        if (pcs == NULL) {
224
 
            rc_decrement(pcs_base, "pdf_copy_mono");
225
 
            return_error(gs_error_VMerror);
226
 
        }
227
 
        pcs->base_space = pcs_base;
228
 
        pcs->params.indexed.hival = 1;
229
 
        pcs->params.indexed.n_comps = ncomp;
230
 
        p = palette;
231
 
        for (i = 0; i < 2; ++i)
232
 
            for (j = ncomp - 1; j >= 0; --j)
233
 
                *p++ = (byte)(c[i] >> (j * 8));
234
 
        pcs->params.indexed.lookup.table.data = palette;
235
 
        pcs->params.indexed.lookup.table.size = p - palette;
236
 
        pcs->params.indexed.use_proc = false;
237
 
        gs_image_t_init(&image, pcs);
238
 
        image.BitsPerComponent = 1;
239
 
    }
240
 
    pdf_make_bitmap_image(&image, x, y, w, h);
241
 
    {
242
 
        ulong nbytes = (ulong) ((w + 7) >> 3) * h;
243
 
 
244
 
        in_line = nbytes < pdev->MaxInlineImageSize;
245
 
        if (in_line)
246
 
            pdf_put_image_matrix(pdev, &image.ImageMatrix, 1.0);
247
 
        code = pdf_open_page(pdev, PDF_IN_STREAM);
248
 
        if (code < 0)
249
 
            return code;
250
 
        pdf_image_writer_init(&writer);
251
 
        code = pdf_begin_write_image(pdev, &writer, gs_no_id, w, h, NULL, in_line);
252
 
        if (code < 0)
253
 
            return code;
254
 
    }
255
 
  wr:
256
 
    if (image.ImageMask)
257
 
        pcsvalue = NULL;
258
 
    else {
259
 
        /*
260
 
         * We don't have to worry about color space scaling: the color
261
 
         * space is always a Device space.
262
 
         */
263
 
        code = pdf_color_space(pdev, &cs_value, NULL, pcs,
264
 
                               &writer.pin->color_spaces, in_line);
265
 
        if (code < 0)
266
 
            return code;
267
 
        pcsvalue = &cs_value;
268
 
    }
269
 
    /*
270
 
     * There are 3 different cases at this point:
271
 
     *      - Writing an in-line image (pres == 0, writer.pres == 0);
272
 
     *      - Writing an XObject image (pres == 0, writer.pres != 0);
273
 
     *      - Writing the image for a CharProc (pres != 0).
274
 
     * We handle them with in-line code followed by a switch,
275
 
     * rather than making the shared code into a procedure,
276
 
     * simply because there would be an awful lot of parameters
277
 
     * that would need to be passed.
278
 
     */
279
 
    if (pres) {
280
 
        /*
281
 
         * Always use CCITTFax 2-D for character bitmaps.  It takes less
282
 
         * space to invert the data with Decode than to set BlackIs1.
283
 
         */
284
 
        float d0 = image.Decode[0];
285
 
 
286
 
        image.Decode[0] = image.Decode[1];
287
 
        image.Decode[1] = d0;
288
 
        psdf_CFE_binary(&writer.binary[0], image.Width, image.Height, true);
289
 
        invert ^= 0xff;
290
 
    } else {
291
 
        /* Use the Distiller compression parameters. */
292
 
        pdev->ParamCompatibilityLevel = pdev->CompatibilityLevel;
293
 
        psdf_setup_image_filters((gx_device_psdf *) pdev, &writer.binary[0],
294
 
                                 (gs_pixel_image_t *)&image, NULL, NULL, true, in_line);
295
 
    }
296
 
    pdf_begin_image_data(pdev, &writer, (const gs_pixel_image_t *)&image,
297
 
                         pcsvalue, 0);
298
 
    code = pdf_copy_mask_bits(writer.binary[0].strm, base, sourcex, raster,
299
 
                              w, h, invert);
300
 
    if (code < 0)
301
 
        return code;
302
 
    pdf_end_image_binary(pdev, &writer, writer.height);
303
 
    if (!pres) {
304
 
        switch ((code = pdf_end_write_image(pdev, &writer))) {
305
 
            default:            /* error */
306
 
                return code;
307
 
            case 1:
308
 
                return 0;
309
 
            case 0:
310
 
                return pdf_do_image(pdev, writer.pres, &image.ImageMatrix,
311
 
                                    true);
312
 
        }
313
 
    }
314
 
    writer.end_string = "";     /* no Q */
315
 
    switch ((code = pdf_end_write_image(pdev, &writer))) {
316
 
    default:            /* error */
317
 
        return code;
318
 
    case 0:                     /* not possible */
319
 
        return_error(gs_error_Fatal);
320
 
    case 1:
321
 
        break;
322
 
    }
323
 
    code = pdf_end_char_proc(pdev, &ipos);
324
 
    if (code < 0)
325
 
        return code;
326
 
  rx:{
327
 
        gs_matrix imat;
328
 
 
329
 
        imat = image.ImageMatrix;
330
 
        imat.xx /= w;
331
 
        imat.xy /= h;
332
 
        imat.yx /= w;
333
 
        imat.yy /= h;
334
 
        return pdf_do_char_image(pdev, (const pdf_char_proc_t *)pres, &imat);
335
 
    }
336
 
}
337
 
int
338
 
gdev_pdf_copy_mono(gx_device * dev,
339
 
                   const byte * base, int sourcex, int raster, gx_bitmap_id id,
340
 
                   int x, int y, int w, int h, gx_color_index zero,
341
 
                   gx_color_index one)
342
 
{
343
 
    gx_device_pdf *pdev = (gx_device_pdf *) dev;
344
 
 
345
 
    if (w <= 0 || h <= 0)
346
 
        return 0;
347
 
    return pdf_copy_mono(pdev, base, sourcex, raster, id, x, y, w, h,
348
 
                         zero, one, NULL);
349
 
}
350
 
 
351
 
/* Copy a color bitmap.  for_pattern = -1 means put the image in-line, */
352
 
/* 1 means put the image in a resource, 2 means image is a rasterized shading. */
353
 
int
354
 
pdf_copy_color_data(gx_device_pdf * pdev, const byte * base, int sourcex,
355
 
                    int raster, gx_bitmap_id id, int x, int y, int w, int h,
356
 
                    gs_image_t *pim, pdf_image_writer *piw,
357
 
                    int for_pattern)
358
 
{
359
 
    int depth = pdev->color_info.depth;
360
 
    int bytes_per_pixel = depth >> 3;
361
 
    gs_color_space *pcs;
362
 
    cos_value_t cs_value;
363
 
    ulong nbytes;
364
 
    int code = pdf_cspace_init_Device(pdev->memory, &pcs, bytes_per_pixel);
365
 
    const byte *row_base;
366
 
    int row_step;
367
 
    bool in_line;
368
 
 
369
 
    if (code < 0)
370
 
        return code;            /* can't happen */
371
 
    gs_image_t_init(pim, pcs);
372
 
    pdf_make_bitmap_image(pim, x, y, w, h);
373
 
    pim->BitsPerComponent = 8;
374
 
    nbytes = (ulong)w * bytes_per_pixel * h;
375
 
 
376
 
    if (for_pattern == 1) {
377
 
        /*
378
 
         * Patterns must be emitted in order of increasing user Y, i.e.,
379
 
         * the opposite of PDF's standard image order.
380
 
         */
381
 
        row_base = base + (h - 1) * raster;
382
 
        row_step = -raster;
383
 
        in_line = for_pattern < 0;
384
 
    } else {
385
 
        row_base = base;
386
 
        row_step = raster;
387
 
        in_line = nbytes < pdev->MaxInlineImageSize;
388
 
        pdf_put_image_matrix(pdev, &pim->ImageMatrix, 1.0);
389
 
        /*
390
 
         * Check whether we've already made an XObject resource for this
391
 
         * image.
392
 
         */
393
 
        if (id != gx_no_bitmap_id) {
394
 
            piw->pres = pdf_find_resource_by_gs_id(pdev, resourceXObject, id);
395
 
            if (piw->pres)
396
 
                return 0;
397
 
        }
398
 
    }
399
 
    /*
400
 
     * We have to be able to control whether to put Pattern images in line,
401
 
     * to avoid trying to create an XObject resource while we're in the
402
 
     * middle of writing a Pattern resource.
403
 
     */
404
 
    if (for_pattern < 0)
405
 
        stream_puts(pdev->strm, "q ");
406
 
    /*
407
 
     * We don't have to worry about color space scaling: the color
408
 
     * space is always a Device space.
409
 
     */
410
 
    pdf_image_writer_init(piw);
411
 
    pdev->ParamCompatibilityLevel = pdev->CompatibilityLevel;
412
 
    if ((code = pdf_begin_write_image(pdev, piw, id, w, h, NULL, in_line)) < 0 ||
413
 
        (code = pdf_color_space(pdev, &cs_value, NULL, pcs,
414
 
                                &piw->pin->color_spaces, in_line)) < 0 ||
415
 
        (for_pattern < 2 || nbytes < 512000 ?
416
 
            (code = psdf_setup_lossless_filters((gx_device_psdf *) pdev,
417
 
                        &piw->binary[0], (gs_pixel_image_t *)pim, false)) :
418
 
            (code = psdf_setup_image_filters((gx_device_psdf *) pdev,
419
 
                        &piw->binary[0], (gs_pixel_image_t *)pim, NULL, NULL, false, false))
420
 
        ) < 0 ||
421
 
        (code = pdf_begin_image_data(pdev, piw, (const gs_pixel_image_t *)pim,
422
 
                                     &cs_value, 0)) < 0
423
 
        )
424
 
        return code;
425
 
    pdf_copy_color_bits(piw->binary[0].strm, row_base, sourcex, row_step, w, h,
426
 
                        bytes_per_pixel);
427
 
    pdf_end_image_binary(pdev, piw, piw->height);
428
 
    return pdf_end_write_image(pdev, piw);
429
 
}
430
 
 
431
 
int
432
 
gdev_pdf_copy_color(gx_device * dev, const byte * base, int sourcex,
433
 
                    int raster, gx_bitmap_id id, int x, int y, int w, int h)
434
 
{
435
 
    gx_device_pdf *pdev = (gx_device_pdf *) dev;
436
 
    gs_image_t image;
437
 
    pdf_image_writer writer;
438
 
    int code;
439
 
    
440
 
    if (w <= 0 || h <= 0)
441
 
        return 0;
442
 
    code = pdf_open_page(pdev, PDF_IN_STREAM);
443
 
    if (code < 0)
444
 
        return code;
445
 
    /* Make sure we aren't being clipped. */
446
 
    code = pdf_put_clip_path(pdev, NULL);
447
 
    if (code < 0)
448
 
        return code;
449
 
    code = pdf_copy_color_data(pdev, base, sourcex, raster, id, x, y, w, h,
450
 
                               &image, &writer, 0);
451
 
    switch (code) {
452
 
        default:
453
 
            return code;        /* error */
454
 
        case 1:
455
 
            return 0;
456
 
        case 0:
457
 
            return pdf_do_image(pdev, writer.pres, NULL, true);
458
 
    }
459
 
}
460
 
 
461
 
/* Fill a mask. */
462
 
int
463
 
gdev_pdf_fill_mask(gx_device * dev,
464
 
                 const byte * data, int data_x, int raster, gx_bitmap_id id,
465
 
                   int x, int y, int width, int height,
466
 
                   const gx_drawing_color * pdcolor, int depth,
467
 
                   gs_logical_operation_t lop, const gx_clip_path * pcpath)
468
 
{
469
 
    gx_device_pdf *pdev = (gx_device_pdf *) dev;
470
 
 
471
 
    if (width <= 0 || height <= 0)
472
 
        return 0;
473
 
    if (depth > 1 || (!gx_dc_is_pure(pdcolor) != 0 && pdcolor->type != &gx_dc_pattern))
474
 
        return gx_default_fill_mask(dev, data, data_x, raster, id,
475
 
                                    x, y, width, height, pdcolor, depth, lop,
476
 
                                    pcpath);
477
 
    return pdf_copy_mono(pdev, data, data_x, raster, id, x, y, width, height,
478
 
                         gx_no_color_index, gx_dc_pure_color(pdcolor),
479
 
                         pcpath);
480
 
}
481
 
 
482
 
/* Tile with a bitmap.  This is important for pattern fills. */
483
 
int
484
 
gdev_pdf_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
485
 
                              int x, int y, int w, int h,
486
 
                              gx_color_index color0, gx_color_index color1,
487
 
                              int px, int py)
488
 
{
489
 
    gx_device_pdf *const pdev = (gx_device_pdf *) dev;
490
 
    int tw = tiles->rep_width, th = tiles->rep_height;
491
 
    double xscale = pdev->HWResolution[0] / 72.0,
492
 
        yscale = pdev->HWResolution[1] / 72.0;
493
 
    bool mask;
494
 
    int depth;
495
 
    int (*copy_data)(gx_device_pdf *, const byte *, int, int,
496
 
                     gx_bitmap_id, int, int, int, int,
497
 
                     gs_image_t *, pdf_image_writer *, int);
498
 
    pdf_resource_t *pres;
499
 
    cos_value_t cs_value;
500
 
    int code;
501
 
 
502
 
    if (tiles->id == gx_no_bitmap_id || tiles->shift != 0 ||
503
 
        (w < tw && h < th) ||
504
 
        color0 != gx_no_color_index
505
 
        )
506
 
        goto use_default;
507
 
    if (color1 != gx_no_color_index) {
508
 
        /* This is a mask pattern. */
509
 
        mask = true;
510
 
        depth = 1;
511
 
        copy_data = pdf_copy_mask_data;
512
 
        code = pdf_cs_Pattern_uncolored(pdev, &cs_value);
513
 
    } else {
514
 
        /* This is a colored pattern. */
515
 
        mask = false;
516
 
        depth = pdev->color_info.depth;
517
 
        copy_data = pdf_copy_color_data;
518
 
        code = pdf_cs_Pattern_colored(pdev, &cs_value);
519
 
    }
520
 
    if (code < 0)
521
 
        goto use_default;
522
 
    pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, tiles->id);
523
 
    if (!pres) {
524
 
        /* Create the Pattern resource. */
525
 
        int code;
526
 
        long image_id, length_id, start, end;
527
 
        stream *s;
528
 
        gs_image_t image;
529
 
        pdf_image_writer writer;
530
 
        long image_bytes = ((long)tw * depth + 7) / 8 * th;
531
 
        bool in_line = image_bytes < pdev->MaxInlineImageSize;
532
 
        ulong tile_id =
533
 
            (tw == tiles->size.x && th == tiles->size.y ? tiles->id :
534
 
             gx_no_bitmap_id);
535
 
 
536
 
        if (in_line)
537
 
            image_id = 0;
538
 
        else if (image_bytes > 65500) {
539
 
            /*
540
 
             * Acrobat Reader can't handle image Patterns with more than
541
 
             * 64K of data.  :-(
542
 
             */
543
 
            goto use_default;
544
 
        } else {
545
 
            /* Write the image as an XObject resource now. */
546
 
            code = copy_data(pdev, tiles->data, 0, tiles->raster,
547
 
                             tile_id, 0, 0, tw, th, &image, &writer, 1);
548
 
            if (code < 0)
549
 
                goto use_default;
550
 
            image_id = pdf_resource_id(writer.pres);
551
 
        }
552
 
        code = pdf_begin_resource(pdev, resourcePattern, tiles->id, &pres);
553
 
        if (code < 0)
554
 
            goto use_default;
555
 
        s = pdev->strm;
556
 
        pprintd1(s, "/PatternType 1/PaintType %d/TilingType 1/Resources<<\n",
557
 
                 (mask ? 2 : 1));
558
 
        if (image_id)
559
 
            pprintld2(s, "/XObject<</R%ld %ld 0 R>>", image_id, image_id);
560
 
        pprints1(s, "/ProcSet[/PDF/Image%s]>>\n", (mask ? "B" : "C"));
561
 
        /*
562
 
         * Because of bugs in Acrobat Reader's Print function, we can't use
563
 
         * the natural BBox and Step here: they have to be 1.
564
 
         */
565
 
        pprintg2(s, "/Matrix[%g 0 0 %g 0 0]", tw / xscale, th / yscale);
566
 
        stream_puts(s, "/BBox[0 0 1 1]/XStep 1/YStep 1/Length ");
567
 
        if (image_id) {
568
 
            char buf[MAX_REF_CHARS + 6 + 1]; /* +6 for /R# Do\n */
569
 
 
570
 
            sprintf(buf, "/R%ld Do\n", image_id);
571
 
            pprintd1(s, "%d>>stream\n", strlen(buf));
572
 
            if (pdev->PDFA)
573
 
                pprints1(s, "%s\nendstream\n", buf);
574
 
            else
575
 
                pprints1(s, "%sendstream\n", buf);
576
 
            pdf_end_resource(pdev);
577
 
        } else {
578
 
            length_id = pdf_obj_ref(pdev);
579
 
            pprintld1(s, "%ld 0 R>>stream\n", length_id);
580
 
            start = pdf_stell(pdev);
581
 
            code = copy_data(pdev, tiles->data, 0, tiles->raster,
582
 
                             tile_id, 0, 0, tw, th, &image, &writer, -1);
583
 
            switch (code) {
584
 
            default:
585
 
                return code;    /* error */
586
 
            case 1:
587
 
                break;
588
 
            case 0:                     /* not possible */
589
 
                return_error(gs_error_Fatal);
590
 
            }
591
 
            end = pdf_stell(pdev);
592
 
            stream_puts(s, "\nendstream\n");
593
 
            pdf_end_resource(pdev);
594
 
            pdf_open_separate(pdev, length_id);
595
 
            pprintld1(pdev->strm, "%ld\n", end - start);
596
 
            pdf_end_separate(pdev);
597
 
        }
598
 
        pres->object->written = true; /* don't write at end of page */
599
 
    }
600
 
    /* Fill the rectangle with the Pattern. */
601
 
    {
602
 
        int code = pdf_open_page(pdev, PDF_IN_STREAM);
603
 
        stream *s;
604
 
 
605
 
        if (code < 0)
606
 
            goto use_default;
607
 
        /* Make sure we aren't being clipped. */
608
 
        code = pdf_put_clip_path(pdev, NULL);
609
 
        if (code < 0)
610
 
            return code;
611
 
        s = pdev->strm;
612
 
        /*
613
 
         * Because of bugs in Acrobat Reader's Print function, we can't
614
 
         * leave the CTM alone here: we have to reset it to the default.
615
 
         */
616
 
        pprintg2(s, "q %g 0 0 %g 0 0 cm\n", xscale, yscale);
617
 
        cos_value_write(&cs_value, pdev);
618
 
        stream_puts(s, " cs");
619
 
        if (mask)
620
 
            pprintg3(s, " %g %g %g", (int)(color1 >> 16) / 255.0,
621
 
                     (int)((color1 >> 8) & 0xff) / 255.0,
622
 
                     (int)(color1 & 0xff) / 255.0);
623
 
        pprintld1(s, "/R%ld scn", pdf_resource_id(pres));
624
 
        pprintg4(s, " %g %g %g %g re f Q\n",
625
 
                 x / xscale, y / yscale, w / xscale, h / xscale);
626
 
    }
627
 
    return 0;
628
 
use_default:
629
 
    return gx_default_strip_tile_rectangle(dev, tiles, x, y, w, h,
630
 
                                           color0, color1, px, py);
631
 
}