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

« back to all changes in this revision

Viewing changes to src/gxoprect.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: gxoprect.c 8250 2007-09-25 13:31:24Z giles $ */
15
 
/* generic (very slow) overprint fill rectangle implementation */
16
 
 
17
 
#include "memory_.h"
18
 
#include "gx.h"
19
 
#include "gserrors.h"
20
 
#include "gsutil.h"             /* for gs_next_ids */
21
 
#include "gxdevice.h"
22
 
#include "gsdevice.h"
23
 
#include "gxgetbit.h"
24
 
#include "gxoprect.h"
25
 
#include "gsbitops.h"
26
 
 
27
 
 
28
 
/*
29
 
 * Unpack a scanline for a depth < 8. In this case we know the depth is
30
 
 * divisor of 8 and thus a power of 2, which implies that 8 / depth is
31
 
 * also a power of 2.
32
 
 */
33
 
static void
34
 
unpack_scanline_lt8(
35
 
    gx_color_index *    destp,
36
 
    const byte *        srcp,
37
 
    int                 src_offset,
38
 
    int                 width,
39
 
    int                 depth )
40
 
{
41
 
    byte                buff = 0;
42
 
    int                 i = 0, shift = 8 - depth, p_per_byte = 8 / depth;
43
 
 
44
 
    /* exit early if nothing to do */
45
 
    if (width == 0)
46
 
        return;
47
 
 
48
 
    /* skip over src_offset */
49
 
    if (src_offset >= p_per_byte) {
50
 
        srcp += src_offset / p_per_byte;
51
 
        src_offset &= (p_per_byte - 1);
52
 
    }
53
 
    if (src_offset > 0) {
54
 
        buff = *srcp++ << (src_offset * depth);
55
 
        i = src_offset;
56
 
        width += src_offset;
57
 
    }
58
 
 
59
 
    /* process the interesting part of the scanline */
60
 
    for (; i < width; i++, buff <<= depth) {
61
 
        if ((i & (p_per_byte - 1)) == 0)
62
 
            buff = *srcp++;
63
 
        *destp++ = buff >> shift;
64
 
    }
65
 
}
66
 
 
67
 
/*
68
 
 * Pack a scanline for a depth of < 8. Note that data prior to dest_offset
69
 
 * and any data beyond the width must be left undisturbed.
70
 
 */
71
 
static void
72
 
pack_scanline_lt8(
73
 
    const gx_color_index *  srcp,
74
 
    byte *                  destp,
75
 
    int                     dest_offset,
76
 
    int                     width,
77
 
    int                     depth )
78
 
{
79
 
    byte                    buff = 0;
80
 
    int                     i = 0, p_per_byte = 8 / depth;
81
 
 
82
 
    /* exit early if nothing to do */
83
 
    if (width == 0)
84
 
        return;
85
 
 
86
 
    /* skip over dest_offset */
87
 
    if (dest_offset >= p_per_byte) {
88
 
        destp += dest_offset / p_per_byte;
89
 
        dest_offset &= (p_per_byte - 1);
90
 
    }
91
 
    if (dest_offset > 0) {
92
 
        buff = *destp++ >> (8 - dest_offset * depth);
93
 
        i = dest_offset;
94
 
        width += dest_offset;
95
 
    }
96
 
 
97
 
    /* process the interesting part of the scanline */
98
 
    for (; i < width; i++) {
99
 
        buff = (buff << depth) | *srcp++;
100
 
        if ((i & (p_per_byte - 1)) == p_per_byte - 1)
101
 
            *destp++ = buff;
102
 
    }
103
 
    if ((i &= (p_per_byte - 1)) != 0) {
104
 
        int     shift = depth * (p_per_byte - i);
105
 
        int     mask = (1 << shift) - 1;
106
 
 
107
 
        *destp = (*destp & mask) | (buff << shift);
108
 
    }
109
 
}
110
 
 
111
 
/*
112
 
 * Unpack a scanline for a depth >= 8. In this case, the depth must be
113
 
 * a multiple of 8.
114
 
 */
115
 
static void
116
 
unpack_scanline_ge8(
117
 
    gx_color_index *    destp,
118
 
    const byte *        srcp,
119
 
    int                 src_offset,
120
 
    int                 width,
121
 
    int                 depth )
122
 
{
123
 
    gx_color_index      buff = 0;
124
 
    int                 i, j, bytes_per_p = depth >> 3;
125
 
 
126
 
    /* skip over src_offset */
127
 
    srcp += src_offset * bytes_per_p;
128
 
 
129
 
    /* process the interesting part of the scanline */
130
 
    width *= bytes_per_p;
131
 
    for (i = 0, j = 0; i < width; i++) {
132
 
        buff = (buff << 8) | *srcp++;
133
 
        if (++j == bytes_per_p) {
134
 
            *destp++ = buff;
135
 
            buff = 0;
136
 
            j = 0;
137
 
        }
138
 
    }
139
 
}
140
 
 
141
 
/*
142
 
 * Pack a scanline for depth >= 8.
143
 
 */
144
 
static void
145
 
pack_scanline_ge8(
146
 
    const gx_color_index *  srcp,
147
 
    byte *                  destp,
148
 
    int                     dest_offset,
149
 
    int                     width,
150
 
    int                     depth )
151
 
{
152
 
    gx_color_index          buff = 0;
153
 
    int                     i, j, bytes_per_p = depth >> 3;
154
 
    int                     shift = depth - 8;
155
 
 
156
 
    /* skip over dest_offset */
157
 
    destp += dest_offset;
158
 
 
159
 
    /* process the interesting part of the scanline */
160
 
    width *= bytes_per_p;
161
 
    for (i = 0, j = bytes_per_p - 1; i < width; i++, buff <<= 8) {
162
 
        if (++j == bytes_per_p) {
163
 
            buff = *srcp++;
164
 
            j = 0;
165
 
        }
166
 
        *destp++ = buff >> shift;
167
 
    }
168
 
}
169
 
 
170
 
 
171
 
/*
172
 
 * Perform the fill rectangle operation for a non-separable color encoding
173
 
 * that requires overprint support. This situation requires that colors be
174
 
 * decoded, modified, and re-encoded. These steps must be performed per
175
 
 * output pixel, so there is no hope of achieving good performance.
176
 
 * Consequently, only minimal performance optimizations are applied below.
177
 
 *
178
 
 * The overprint device structure is known only in gsovr.c, and thus is not
179
 
 * available here. The required information from the overprint device is,
180
 
 * therefore, provided via explicit operands.  The device operand points to
181
 
 * the target of the overprint compositor device, not the compositor device
182
 
 * itself. The drawn_comps bit array and the memory descriptor pointer are
183
 
 * also provided explicitly as operands.
184
 
 *
185
 
 * Returns 0 on success, < 0 in the event of an error.
186
 
 */
187
 
int
188
 
gx_overprint_generic_fill_rectangle(
189
 
    gx_device *             tdev,
190
 
    gx_color_index          drawn_comps,
191
 
    int                     x,
192
 
    int                     y,
193
 
    int                     w,
194
 
    int                     h,
195
 
    gx_color_index          color,
196
 
    gs_memory_t *           mem )
197
 
{
198
 
    gx_color_value          src_cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];
199
 
    gx_color_index *        pcolor_buff = 0;
200
 
    byte *                  gb_buff = 0;
201
 
    gs_get_bits_params_t    gb_params;
202
 
    gs_int_rect             gb_rect;
203
 
    int                     depth = tdev->color_info.depth;
204
 
    int                     bit_x, start_x, end_x, raster, code;
205
 
    void                    (*unpack_proc)( gx_color_index *,
206
 
                                            const byte *,
207
 
                                            int, int, int );
208
 
    void                    (*pack_proc)( const gx_color_index *,
209
 
                                          byte *,
210
 
                                          int, int, int );
211
 
 
212
 
    fit_fill(tdev, x, y, w, h);
213
 
    bit_x = x * depth;
214
 
    start_x = bit_x & ~(8 * align_bitmap_mod - 1);
215
 
    end_x = bit_x + w * depth;
216
 
 
217
 
    /* select the appropriate pack/unpack routines */
218
 
    if (depth >= 8) {
219
 
        unpack_proc = unpack_scanline_ge8;
220
 
        pack_proc = pack_scanline_ge8;
221
 
    } else {
222
 
        unpack_proc = unpack_scanline_lt8;
223
 
        pack_proc = pack_scanline_lt8;
224
 
    }
225
 
 
226
 
    /* decode the source color */
227
 
    if ((code = dev_proc(tdev, decode_color)(tdev, color, src_cvals)) < 0)
228
 
        return code;
229
 
 
230
 
    /* allocate space for a scanline of color indices */
231
 
    pcolor_buff = (gx_color_index *)
232
 
                      gs_alloc_bytes( mem,
233
 
                                      w *  arch_sizeof_color_index,
234
 
                                      "overprint generic fill rectangle" );
235
 
    if (pcolor_buff == 0)
236
 
        return gs_note_error(gs_error_VMerror);
237
 
 
238
 
    /* allocate a buffer for the returned data */
239
 
    raster = bitmap_raster(end_x - start_x);
240
 
    gb_buff = gs_alloc_bytes(mem, raster, "overprint generic fill rectangle");
241
 
    if (gb_buff == 0) {
242
 
        gs_free_object( mem,
243
 
                        pcolor_buff,
244
 
                        "overprint generic fill rectangle" );
245
 
        return gs_note_error(gs_error_VMerror);
246
 
    }
247
 
 
248
 
    /*
249
 
     * Initialize the get_bits parameters. The selection of options is
250
 
     * based on the following logic:
251
 
     *
252
 
     *  - Overprint is only defined with respect to components of the
253
 
     *    process color model, so the retrieved information must be kept
254
 
     *    in that color model. The gx_bitmap_format_t bitfield regards
255
 
     *    this as the native color space.
256
 
     *
257
 
     *  - Overprinting and alpha compositing don't mix, so there is no
258
 
     *    reason to retrieve the alpha information.
259
 
     *
260
 
     *  - Data should be returned in the depth of the process color
261
 
     *    model. Though this depth could be specified explicitly, there
262
 
     *    is little reason to do so. 
263
 
     *
264
 
     *  - Though overprint is much more easily implemented with planar
265
 
     *    data, there is no planar version of the copy_color method to
266
 
     *    send the modified data back to device. Hence, we must retrieve
267
 
     *    data in chunky form.
268
 
     *
269
 
     *  - It is not possible to modify the raster data "in place", as
270
 
     *    doing so would bypass any other forwarding devices currently
271
 
     *    in the device "stack" (e.g.: a bounding box device). Hence,
272
 
     *    we must work with a copy of the data, which is passed to the
273
 
     *    copy_color method at the end of fill_rectangle operation.
274
 
     *
275
 
     *  - Though we only require data for those planes that will not be
276
 
     *    modified, there is no benefit to returning less than the full
277
 
     *    data for each pixel if the color encoding is not separable.
278
 
     *    Since this routine will be used only for encodings that are
279
 
     *    not separable, we might as well ask for full information.
280
 
     *
281
 
     *  - Though no particular alignment and offset are required, it is
282
 
     *    useful to make the copy operation as fast as possible. Ideally
283
 
     *    we would calculate an offset so that the data achieves optimal
284
 
     *    alignment. Alas, some of the devices work much more slowly if
285
 
     *    anything but GB_OFFSET_0 is specified, so that is what we use.
286
 
     */
287
 
    gb_params.options =  GB_COLORS_NATIVE
288
 
                       | GB_ALPHA_NONE
289
 
                       | GB_DEPTH_ALL
290
 
                       | GB_PACKING_CHUNKY
291
 
                       | GB_RETURN_COPY
292
 
                       | GB_ALIGN_STANDARD
293
 
                       | GB_OFFSET_0
294
 
                       | GB_RASTER_STANDARD;
295
 
    gb_params.x_offset = 0;     /* for consistency */
296
 
    gb_params.data[0] = gb_buff;
297
 
    gb_params.raster = raster;
298
 
 
299
 
    gb_rect.p.x = x;
300
 
    gb_rect.q.x = x + w;
301
 
 
302
 
    /* process each scanline separately */
303
 
    while (h-- > 0 && code >= 0) {
304
 
        gx_color_index *    cp = pcolor_buff;
305
 
        int                 i;
306
 
 
307
 
        gb_rect.p.y = y++;
308
 
        gb_rect.q.y = y;
309
 
        code = dev_proc(tdev, get_bits_rectangle)( tdev,
310
 
                                                   &gb_rect,
311
 
                                                   &gb_params,
312
 
                                                   0 );
313
 
        if (code < 0)
314
 
            break;
315
 
        unpack_proc(pcolor_buff, gb_buff, 0, w, depth);
316
 
        for (i = 0; i < w; i++, cp++) {
317
 
            gx_color_index  comps;
318
 
            int             j;
319
 
            gx_color_value  dest_cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];
320
 
        
321
 
            if ((code = dev_proc(tdev, decode_color)(tdev, *cp, dest_cvals)) < 0)
322
 
                break;
323
 
            for (j = 0, comps = drawn_comps; comps != 0; ++j, comps >>= 1) {
324
 
                if ((comps & 0x1) != 0)
325
 
                    dest_cvals[j] = src_cvals[j];
326
 
            }
327
 
            *cp = dev_proc(tdev, encode_color)(tdev, dest_cvals);
328
 
        }
329
 
        pack_proc(pcolor_buff, gb_buff, 0, w, depth);
330
 
        code = dev_proc(tdev, copy_color)( tdev,
331
 
                                           gb_buff,
332
 
                                           0,
333
 
                                           raster,
334
 
                                           gs_no_bitmap_id,
335
 
                                           x, y - 1, w, 1 );
336
 
    }
337
 
 
338
 
    gs_free_object( mem,
339
 
                    gb_buff,
340
 
                    "overprint generic fill rectangle" );
341
 
    gs_free_object( mem,
342
 
                    pcolor_buff,
343
 
                    "overprint generic fill rectangle" );
344
 
 
345
 
    return code;
346
 
}
347
 
 
348
 
 
349
 
 
350
 
/*
351
 
 * Replication of 2 and 4 bit patterns to fill a mem_mono_chunk.
352
 
 */
353
 
static mono_fill_chunk fill_pat_2[4] = {
354
 
    mono_fill_make_pattern(0x00), mono_fill_make_pattern(0x55),
355
 
    mono_fill_make_pattern(0xaa), mono_fill_make_pattern(0xff)
356
 
};
357
 
 
358
 
static mono_fill_chunk fill_pat_4[16] = {
359
 
    mono_fill_make_pattern(0x00), mono_fill_make_pattern(0x11),
360
 
    mono_fill_make_pattern(0x22), mono_fill_make_pattern(0x33),
361
 
    mono_fill_make_pattern(0x44), mono_fill_make_pattern(0x55),
362
 
    mono_fill_make_pattern(0x66), mono_fill_make_pattern(0x77),
363
 
    mono_fill_make_pattern(0x88), mono_fill_make_pattern(0x99),
364
 
    mono_fill_make_pattern(0xaa), mono_fill_make_pattern(0xbb),
365
 
    mono_fill_make_pattern(0xcc), mono_fill_make_pattern(0xdd),
366
 
    mono_fill_make_pattern(0xee), mono_fill_make_pattern(0xff)
367
 
};
368
 
 
369
 
/*
370
 
 * Replicate a color or mask as required to fill a mem_mono_fill_chunk.
371
 
 * This is possible if (8 * sizeof(mono_fill_chunk)) % depth == 0.
372
 
 * Since sizeof(mono_fill_chunk) is a power of 2, this will be the case
373
 
 * if depth is a power of 2 and depth <= 8 * sizeof(mono_fill_chunk).
374
 
 */
375
 
static mono_fill_chunk
376
 
replicate_color(int depth, mono_fill_chunk color)
377
 
{
378
 
    switch (depth) {
379
 
 
380
 
      case 1:
381
 
        color = (mono_fill_chunk)(-(int)color); break;
382
 
 
383
 
      case 2:
384
 
        color = fill_pat_2[color]; break;
385
 
 
386
 
      case 4:
387
 
        color = fill_pat_4[color]; break;
388
 
 
389
 
      case 8:
390
 
        color= mono_fill_make_pattern(color); break;
391
 
 
392
 
#if mono_fill_chunk_bytes > 2
393
 
      case 16:
394
 
        color = (color << 16) | color;
395
 
        /* fall through */
396
 
#endif
397
 
#if mono_fill_chunk_bytes > 4
398
 
      case 32:
399
 
        color = (color << 32) | color;
400
 
        break;
401
 
#endif
402
 
    }
403
 
 
404
 
    return color;
405
 
}
406
 
 
407
 
 
408
 
/*
409
 
 * Perform the fill rectangle operation for a separable color encoding
410
 
 * that requires overprint support.
411
 
 *
412
 
 * This is handled via two separate cases. If
413
 
 *
414
 
 *    (8 * sizeof(mono_fill_chunk)) % tdev->color_info.depth = 0,
415
 
 *
416
 
 * then is possible to work via the masked analog of the bits_fill_rectangle
417
 
 * procedure, bits_fill_rectangle_masked. This requires that both the
418
 
 * color and component mask be replicated sufficiently to fill the
419
 
 * mono_fill_chunk. The somewhat elaborate set-up aside, the resulting
420
 
 * algorithm is about as efficient as can be achieved when using
421
 
 * get_bits_rectangle. More efficient algorithms require overprint to be
422
 
 * implemented in the target device itself.
423
 
 *
424
 
 * If the condition is not satisfied, a simple byte-wise algorithm is
425
 
 * used. This requires minimal setup but is not efficient, as it works in
426
 
 * units that are too small. More efficient methods are possible in this
427
 
 * case, but the required setup for a general depth is excessive (even
428
 
 * with the restriction that depth % 8 = 0). Hence, efficiency for these
429
 
 * cases is better addressed by direct implementation of overprint for
430
 
 * memory devices.
431
 
 *
432
 
 * For both cases, the color and retain_mask values passed to this
433
 
 * procedure are expected to be already swapped as required for a byte-
434
 
 * oriented bitmap. This consideration affects only little-endian
435
 
 * machines. For those machines, if depth > 9 the color passed to these
436
 
 * two procedures will not be the same as that passed to
437
 
 * gx_overprint_generic_fill_rectangle.
438
 
 *
439
 
 * Returns 0 on success, < 0 in the event of an error.
440
 
 */
441
 
int
442
 
gx_overprint_sep_fill_rectangle_1(
443
 
    gx_device *             tdev,
444
 
    gx_color_index          retain_mask,    /* already swapped */
445
 
    int                     x,
446
 
    int                     y,
447
 
    int                     w,
448
 
    int                     h,
449
 
    gx_color_index          color,          /* already swapped */
450
 
    gs_memory_t *           mem )
451
 
{
452
 
    byte *                  gb_buff = 0;
453
 
    gs_get_bits_params_t    gb_params;
454
 
    gs_int_rect             gb_rect;
455
 
    int                     code = 0, bit_w, depth = tdev->color_info.depth;
456
 
    int                     raster;
457
 
    mono_fill_chunk         rep_color, rep_mask;
458
 
 
459
 
    fit_fill(tdev, x, y, w, h);
460
 
    bit_w = w * depth;
461
 
 
462
 
    /* set up replicated color and retain mask */
463
 
    if (depth < 8 * sizeof(mono_fill_chunk)) {
464
 
        rep_color = replicate_color(depth, (mono_fill_chunk)color);
465
 
        rep_mask = replicate_color(depth, (mono_fill_chunk)retain_mask);
466
 
    } else {
467
 
        rep_color = (mono_fill_chunk)color;
468
 
        rep_mask = (mono_fill_chunk)retain_mask;
469
 
    }
470
 
 
471
 
    /* allocate a buffer for the returned data */
472
 
    raster = bitmap_raster(w * depth);
473
 
    gb_buff = gs_alloc_bytes(mem, raster, "overprint sep fill rectangle 1");
474
 
    if (gb_buff == 0)
475
 
        return gs_note_error(gs_error_VMerror);
476
 
 
477
 
    /*
478
 
     * Initialize the get_bits parameters. The selection of options is
479
 
     * the same as that for gx_overprint_generic_fill_rectangle (above).
480
 
     */
481
 
    gb_params.options =  GB_COLORS_NATIVE
482
 
                       | GB_ALPHA_NONE
483
 
                       | GB_DEPTH_ALL
484
 
                       | GB_PACKING_CHUNKY
485
 
                       | GB_RETURN_COPY
486
 
                       | GB_ALIGN_STANDARD
487
 
                       | GB_OFFSET_0
488
 
                       | GB_RASTER_STANDARD;
489
 
    gb_params.x_offset = 0;     /* for consistency */
490
 
    gb_params.data[0] = gb_buff;
491
 
    gb_params.raster = raster;
492
 
 
493
 
    gb_rect.p.x = x;
494
 
    gb_rect.q.x = x + w;
495
 
 
496
 
    /* process each scanline separately */
497
 
    while (h-- > 0 && code >= 0) {
498
 
        gb_rect.p.y = y++;
499
 
        gb_rect.q.y = y;
500
 
        code = dev_proc(tdev, get_bits_rectangle)( tdev,
501
 
                                                   &gb_rect,
502
 
                                                   &gb_params,
503
 
                                                   0 );
504
 
        if (code < 0)
505
 
            break;
506
 
        bits_fill_rectangle_masked( gb_buff,
507
 
                                    0,
508
 
                                    raster,
509
 
                                    rep_color,
510
 
                                    rep_mask,
511
 
                                    bit_w,
512
 
                                    1 );
513
 
        code = dev_proc(tdev, copy_color)( tdev,
514
 
                                           gb_buff,
515
 
                                           0,
516
 
                                           raster,
517
 
                                           gs_no_bitmap_id,
518
 
                                           x, y - 1, w, 1 );
519
 
    }
520
 
 
521
 
    gs_free_object( mem,
522
 
                    gb_buff,
523
 
                    "overprint generic fill rectangle" );
524
 
 
525
 
    return code;
526
 
}
527
 
 
528
 
 
529
 
int
530
 
gx_overprint_sep_fill_rectangle_2(
531
 
    gx_device *             tdev,
532
 
    gx_color_index          retain_mask,    /* already swapped */
533
 
    int                     x,
534
 
    int                     y,
535
 
    int                     w,
536
 
    int                     h,
537
 
    gx_color_index          color,          /* already swapped */
538
 
    gs_memory_t *           mem )
539
 
{
540
 
    byte *                  gb_buff = 0;
541
 
    gs_get_bits_params_t    gb_params;
542
 
    gs_int_rect             gb_rect;
543
 
    int                     code = 0, byte_w, raster;
544
 
    int                     byte_depth = tdev->color_info.depth >> 3;
545
 
    byte *                  pcolor;
546
 
    byte *                  pmask;
547
 
 
548
 
    fit_fill(tdev, x, y, w, h);
549
 
    byte_w = w * byte_depth;
550
 
 
551
 
    /* set up color and retain mask pointers */
552
 
    pcolor = (byte *)&color;
553
 
    pmask = (byte *)&retain_mask;
554
 
#if arch_is_big_endian
555
 
    pcolor += arch_sizeof_color_index - byte_depth;
556
 
    pmask += arch_sizeof_color_index - byte_depth;
557
 
#endif
558
 
 
559
 
    /* allocate a buffer for the returned data */
560
 
    raster = bitmap_raster(w * (byte_depth << 3));
561
 
    gb_buff = gs_alloc_bytes(mem, raster, "overprint sep fill rectangle 2");
562
 
    if (gb_buff == 0)
563
 
        return gs_note_error(gs_error_VMerror);
564
 
 
565
 
    /*
566
 
     * Initialize the get_bits parameters. The selection of options is
567
 
     * the same as that for gx_overprint_generic_fill_rectangle (above).
568
 
     */
569
 
    gb_params.options =  GB_COLORS_NATIVE
570
 
                       | GB_ALPHA_NONE
571
 
                       | GB_DEPTH_ALL
572
 
                       | GB_PACKING_CHUNKY
573
 
                       | GB_RETURN_COPY
574
 
                       | GB_ALIGN_STANDARD
575
 
                       | GB_OFFSET_0
576
 
                       | GB_RASTER_STANDARD;
577
 
    gb_params.x_offset = 0;     /* for consistency */
578
 
    gb_params.data[0] = gb_buff;
579
 
    gb_params.raster = raster;
580
 
 
581
 
    gb_rect.p.x = x;
582
 
    gb_rect.q.x = x + w;
583
 
 
584
 
    /* process each scanline separately */
585
 
    while (h-- > 0 && code >= 0) {
586
 
        int     i, j;
587
 
        byte *  cp = gb_buff;
588
 
 
589
 
        gb_rect.p.y = y++;
590
 
        gb_rect.q.y = y;
591
 
        code = dev_proc(tdev, get_bits_rectangle)( tdev,
592
 
                                                   &gb_rect,
593
 
                                                   &gb_params,
594
 
                                                   0 );
595
 
        if (code < 0)
596
 
            break;
597
 
        for (i = 0, j = 0; i < byte_w; i++, cp++) {
598
 
            *cp = (*cp & pmask[j]) | pcolor[j];
599
 
            if (++j == byte_depth)
600
 
                j = 0;
601
 
        }
602
 
        code = dev_proc(tdev, copy_color)( tdev,
603
 
                                           gb_buff,
604
 
                                           0,
605
 
                                           raster,
606
 
                                           gs_no_bitmap_id,
607
 
                                           x, y - 1, w, 1 );
608
 
    }
609
 
 
610
 
    gs_free_object( mem,
611
 
                    gb_buff,
612
 
                    "overprint generic fill rectangle" );
613
 
 
614
 
    return code;
615
 
}
616