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

« back to all changes in this revision

Viewing changes to base/gdevxalt.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: gdevxalt.c 8250 2007-09-25 13:31:24Z giles $ */
 
15
/* Alternative X Windows drivers for help in driver debugging */
 
16
#include "gx.h"                 /* for gx_bitmap; includes std.h */
 
17
#include "math_.h"
 
18
#include "memory_.h"
 
19
#include "x_.h"
 
20
#include "gserrors.h"
 
21
#include "gsparam.h"
 
22
#include "gsstruct.h"
 
23
#include "gxdevice.h"
 
24
#include "gsdevice.h"           /* for gs_copydevice */
 
25
#include "gdevx.h"
 
26
 
 
27
extern const gx_device_X gs_x11_device;
 
28
extern const gx_device_X gs_x11alpha_device;
 
29
 
 
30
/*
 
31
 * Define a forwarding device with a cache for the first 16 colors,
 
32
 * which avoids all of the time-consuming color mapping calls for
 
33
 * the black-and-white, 2-bit gray, and 1-bit CMYK devices defined here.
 
34
 */
 
35
typedef struct {
 
36
    gx_device_forward_common;
 
37
    gx_color_index color_cache[16];
 
38
    /*
 
39
     * alt_map_color returns a value >= 0 if it maps directly to the final
 
40
     * gx_color_index, or < 0 if it only sets RGB values.
 
41
     */
 
42
    dev_proc_map_color_rgb((*alt_map_color));
 
43
} gx_device_X_wrapper;
 
44
#define X_WRAPPER_DATA(amc_proc)\
 
45
        /* gx_device_forward_common */\
 
46
    {0},                        /* std_procs */\
 
47
    0,                          /* target */\
 
48
        /* gx_device_X_wrapper */\
 
49
    {0},                        /* cache */\
 
50
    amc_proc
 
51
gs_private_st_suffix_add0_final(st_device_X_wrapper, gx_device_X_wrapper,
 
52
  "gx_device_X_wrapper", gdevx_wrapper_enum_ptrs, gdevx_wrapper_reloc_ptrs,
 
53
  gx_device_finalize, st_device_forward);
 
54
 
 
55
/* ---------------- Generic procedures ---------------- */
 
56
 
 
57
/* Forward declarations */
 
58
static int get_dev_target(gx_device **, gx_device *);
 
59
 
 
60
static int get_target_info(gx_device *);
 
61
static gx_color_index x_alt_map_color(gx_device *, gx_color_index);
 
62
 
 
63
/* Clear the color mapping cache. */
 
64
static void
 
65
x_clear_color_cache(gx_device /*gx_device_X_wrapper */  * dev)
 
66
{
 
67
    gx_device_X_wrapper *xdev = (gx_device_X_wrapper *) dev;
 
68
    int i;
 
69
 
 
70
    for (i = 0; i < countof(xdev->color_cache); ++i)
 
71
        xdev->color_cache[i] = gx_no_color_index;
 
72
    gx_device_decache_colors(dev);
 
73
}
 
74
 
 
75
/* "Wrappers" for driver procedures */
 
76
 
 
77
static int
 
78
x_wrap_open(gx_device * dev)
 
79
{
 
80
    gx_device *tdev;
 
81
    int rcode, code;
 
82
 
 
83
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
84
        return code;
 
85
    rcode = (*dev_proc(tdev, open_device)) (tdev);
 
86
    if (rcode < 0)
 
87
        return rcode;
 
88
    tdev->is_open = true;
 
89
    code = get_target_info(dev);
 
90
    return (code < 0 ? code : rcode);
 
91
}
 
92
 
 
93
static int
 
94
x_forward_sync_output(gx_device * dev)
 
95
{
 
96
    gx_device *tdev;
 
97
    int code;
 
98
 
 
99
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
100
        return code;
 
101
    return (*dev_proc(tdev, sync_output)) (tdev);
 
102
}
 
103
 
 
104
static int
 
105
x_forward_output_page(gx_device * dev, int num_copies, int flush)
 
106
{
 
107
    gx_device *tdev;
 
108
    int code;
 
109
 
 
110
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
111
        return code;
 
112
    return (*dev_proc(tdev, output_page)) (tdev, num_copies, flush);
 
113
}
 
114
 
 
115
static int
 
116
x_wrap_close(gx_device * dev)
 
117
{
 
118
    /*
 
119
     * The underlying x11 device will be closed and freed as soon as there
 
120
     * are no more pointers to it, which normally occurs in the next
 
121
     * statement.
 
122
     */
 
123
    gx_device_set_target((gx_device_forward *)dev, NULL);
 
124
    x_clear_color_cache(dev);
 
125
    return 0;
 
126
}
 
127
 
 
128
static int
 
129
x_wrap_map_color_rgb(gx_device * dev, gx_color_index color,
 
130
                     gx_color_value prgb[3])
 
131
{
 
132
    gx_device *tdev;
 
133
    int code;
 
134
 
 
135
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
136
        return code;
 
137
    return (*dev_proc(tdev, map_color_rgb)) (tdev,
 
138
                                             x_alt_map_color(dev, color),
 
139
                                             prgb);
 
140
}
 
141
 
 
142
static int
 
143
x_wrap_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
 
144
                      gx_color_index color)
 
145
{
 
146
    gx_device *tdev;
 
147
    int code;
 
148
 
 
149
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
150
        return code;
 
151
    return (*dev_proc(tdev, fill_rectangle)) (tdev, x, y, w, h,
 
152
                                              x_alt_map_color(dev, color));
 
153
}
 
154
 
 
155
static int
 
156
x_wrap_copy_mono(gx_device * dev,
 
157
                 const byte * base, int sourcex, int raster, gx_bitmap_id id,
 
158
                 int x, int y, int w, int h,
 
159
                 gx_color_index zero, gx_color_index one)
 
160
{
 
161
    gx_device *tdev;
 
162
    int code;
 
163
 
 
164
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
165
        return code;
 
166
    return (*dev_proc(tdev, copy_mono)) (tdev, base, sourcex, raster, id,
 
167
                                         x, y, w, h,
 
168
                                         x_alt_map_color(dev, zero),
 
169
                                         x_alt_map_color(dev, one));
 
170
 
 
171
}
 
172
 
 
173
static int
 
174
x_wrap_copy_color(gx_device * dev, const byte * base, int sourcex,
 
175
                  int raster, gx_bitmap_id id, int x, int y, int w, int h)
 
176
{
 
177
    gx_device *tdev;
 
178
 
 
179
#define mapped_bytes 480        /* must be a multiple of 3 & 4 */
 
180
    int depth_bytes, source_bits;
 
181
    int block_w, block_h;
 
182
    int xblock, yblock;
 
183
    byte mapped[mapped_bytes];
 
184
    int code;
 
185
 
 
186
    fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
 
187
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
188
        return code;
 
189
    /* Device pixels must be an integral number of bytes. */
 
190
    if (tdev->color_info.depth & 7)
 
191
        return gx_default_copy_color(dev, base, sourcex, raster, id,
 
192
                                     x, y, w, h);
 
193
    depth_bytes = tdev->color_info.depth >> 3;
 
194
    source_bits = dev->color_info.depth;
 
195
    {
 
196
        int mapped_pixels = mapped_bytes / depth_bytes;
 
197
 
 
198
        if (w > mapped_pixels >> 1)
 
199
            block_w = min(w, mapped_pixels), block_h = 1;
 
200
        else
 
201
            block_w = w, block_h = mapped_pixels / w;
 
202
    }
 
203
    for (yblock = y; yblock < y + h; yblock += block_h)
 
204
        for (xblock = x; xblock < x + w; xblock += block_w) {
 
205
            byte *p = mapped;
 
206
            int xend = min(xblock + block_w, x + w);
 
207
            int yend = min(yblock + block_h, y + h);
 
208
            int xcur, ycur;
 
209
            int code;
 
210
 
 
211
            for (ycur = yblock; ycur < yend; ++ycur)
 
212
                for (xcur = xblock; xcur < xend; ++xcur) {
 
213
                    int sbit = (xcur - x + sourcex) * source_bits;
 
214
                    uint sbyte =
 
215
                        base[(ycur - y) * raster + (sbit >> 3)];
 
216
                    uint spixel =
 
217
                        ((sbyte << (sbit & 7)) & 0xff) >> (8 - source_bits);
 
218
                    gx_color_index cindex =
 
219
                        ((gx_device_X_wrapper *) dev)->color_cache[spixel];
 
220
 
 
221
                    if (cindex == gx_no_color_index)
 
222
                        cindex = x_alt_map_color(dev, spixel);
 
223
                    switch (depth_bytes) {
 
224
                        case 4:
 
225
                            *p++ = (byte) (cindex >> 24);
 
226
                        case 3:
 
227
                            *p++ = (byte) (cindex >> 16);
 
228
                        case 2:
 
229
                            *p++ = (byte) (cindex >> 8);
 
230
                        default /*case 1 */ :
 
231
                            *p++ = (byte) cindex;
 
232
                    }
 
233
                }
 
234
            code = (*dev_proc(tdev, copy_color))
 
235
                (tdev, mapped, 0, (xend - xblock) * depth_bytes, gx_no_bitmap_id,
 
236
                 xblock, yblock, xend - xblock, yend - yblock);
 
237
            if (code < 0)
 
238
                return code;
 
239
        }
 
240
    return 0;
 
241
}
 
242
 
 
243
 
 
244
static int
 
245
x_forward_copy_color(gx_device * dev, const byte * base, int sourcex,
 
246
                     int raster, gx_bitmap_id id, int x, int y, int w, int h)
 
247
{
 
248
    gx_device *tdev;
 
249
    int code;
 
250
 
 
251
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
252
        return code;
 
253
    return (*dev_proc(tdev, copy_color)) (tdev, base, sourcex, raster, id,
 
254
                                          x, y, w, h);
 
255
}
 
256
 
 
257
static int
 
258
x_forward_get_bits(gx_device * dev, int y, byte * str, byte ** actual_data)
 
259
{
 
260
    gx_device *tdev;
 
261
    int code;
 
262
 
 
263
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
264
        return code;
 
265
    return (*dev_proc(tdev, get_bits)) (tdev, y, str, actual_data);
 
266
}
 
267
 
 
268
static int
 
269
x_wrap_get_bits(gx_device * dev, int y, byte * str, byte ** actual_data)
 
270
{
 
271
    int depth = dev->color_info.depth;
 
272
    gx_device *tdev;
 
273
    int width;
 
274
    int sdepth;
 
275
    byte smask;
 
276
    uint dsize;
 
277
    gs_memory_t *mem = dev->memory;
 
278
    byte *row;
 
279
    byte *base;
 
280
    int code;
 
281
    gx_color_index pixel_in = gx_no_color_index;
 
282
    /*
 
283
     * The following initialization is unnecessary: since no pixel has a
 
284
     * value of gx_no_color_index, the test pixel != pixel_in will always
 
285
     * succeed the first time through the loop below, so pixel_out will
 
286
     * always be set before it is used.  We initialize pixel_out solely to
 
287
     * suppress bogus warning messages from certain compilers.
 
288
     */
 
289
    gx_color_index pixel_out = 0;
 
290
    int xi;
 
291
    int sbit;
 
292
 
 
293
    DECLARE_LINE_ACCUM(str, depth, 0);
 
294
 
 
295
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
296
        return code;
 
297
    width = tdev->width;
 
298
    sdepth = tdev->color_info.depth;
 
299
    smask = (sdepth <= 8 ? (1 << sdepth) - 1 : 0xff);
 
300
    dsize = (width * sdepth + 7) / 8;
 
301
    row = gs_alloc_bytes(mem, dsize, "x_wrap_get_bits");
 
302
    if (row == 0)
 
303
        return_error(gs_error_VMerror);
 
304
    code = (*dev_proc(tdev, get_bits)) (tdev, y, row, &base);
 
305
    if (code < 0)
 
306
        goto gx;
 
307
    for (sbit = 0, xi = 0; xi < width; sbit += sdepth, ++xi) {
 
308
        const byte *sptr = base + (sbit >> 3);
 
309
        gx_color_index pixel;
 
310
        gx_color_value rgb[3];
 
311
        int i;
 
312
 
 
313
        if (sdepth <= 8)
 
314
            pixel = (*sptr >> (8 - sdepth - (sbit & 7))) & smask;
 
315
        else {
 
316
            pixel = 0;
 
317
            for (i = 0; i < sdepth; i += 8, ++sptr)
 
318
                pixel = (pixel << 8) + *sptr;
 
319
        }
 
320
        if (pixel != pixel_in) {
 
321
            (*dev_proc(tdev, map_color_rgb))(tdev, pixel, rgb);
 
322
            pixel_in = pixel;
 
323
            if (dev->color_info.num_components <= 3)
 
324
                pixel_out = (*dev_proc(dev, map_rgb_color))(dev, rgb);
 
325
            else {
 
326
                /* Convert RGB to CMYK. */
 
327
                gx_color_value c = gx_max_color_value - rgb[0];
 
328
                gx_color_value m = gx_max_color_value - rgb[1];
 
329
                gx_color_value y = gx_max_color_value - rgb[2];
 
330
                gx_color_value k = (c < m ? min(c, y) : min(m, y));
 
331
 
 
332
                gx_color_value cmyk[4];
 
333
                cmyk[0] = c - k; cmyk[1] = m - k; cmyk[2] = y - k; cmyk[3] = k;
 
334
                pixel_out = (*dev_proc(dev, map_cmyk_color))(dev, cmyk);
 
335
            }
 
336
        }
 
337
        LINE_ACCUM(pixel_out, depth);
 
338
    }
 
339
    LINE_ACCUM_STORE(depth);
 
340
  gx:gs_free_object(mem, row, "x_wrap_get_bits");
 
341
    *actual_data = str;
 
342
    return code;
 
343
}
 
344
 
 
345
static int
 
346
x_wrap_get_params(gx_device * dev, gs_param_list * plist)
 
347
{
 
348
    gx_device *tdev;
 
349
    /* We assume that a get_params call has no side effects.... */
 
350
    gx_device_X save_dev;
 
351
    int ecode;
 
352
    int code;
 
353
 
 
354
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
355
        return code;
 
356
    save_dev = *(gx_device_X *) tdev;
 
357
    if (tdev->is_open)
 
358
        tdev->color_info = dev->color_info;
 
359
    tdev->dname = dev->dname;
 
360
    ecode = (*dev_proc(tdev, get_params)) (tdev, plist);
 
361
    *(gx_device_X *) tdev = save_dev;
 
362
    return ecode;
 
363
}
 
364
 
 
365
static int
 
366
x_wrap_put_params(gx_device * dev, gs_param_list * plist)
 
367
{
 
368
    gx_device *tdev;
 
369
    gx_device_color_info cinfo;
 
370
    const char *dname;
 
371
    int rcode, code;
 
372
 
 
373
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
374
        return code;
 
375
    /*
 
376
     * put_params will choke if we simply feed it the output of
 
377
     * get_params; we have to substitute color_info the same way.
 
378
     */
 
379
    cinfo = tdev->color_info;
 
380
    dname = tdev->dname;
 
381
    tdev->color_info = dev->color_info;
 
382
    tdev->dname = dev->dname;
 
383
    rcode = (*dev_proc(tdev, put_params)) (tdev, plist);
 
384
    tdev->color_info = cinfo;
 
385
    tdev->dname = dname;
 
386
    if (rcode < 0)
 
387
        return rcode;
 
388
    code = get_target_info(dev);
 
389
    return (code < 0 ? code : rcode);
 
390
}
 
391
 
 
392
/* Internal procedures */
 
393
 
 
394
/* Get the target, creating it if necessary. */
 
395
static int
 
396
get_dev_target(gx_device ** ptdev, gx_device * dev)
 
397
{
 
398
    gx_device *tdev = ((gx_device_forward *) dev)->target;
 
399
 
 
400
    if (tdev == 0) {
 
401
        /* Create an X device instance. */
 
402
        int code = gs_copydevice(&tdev, (const gx_device *)&gs_x11_device,
 
403
                                 dev->memory);
 
404
 
 
405
        if (code < 0)
 
406
            return 0;
 
407
        check_device_separable(tdev);
 
408
        gx_device_fill_in_procs(tdev);
 
409
        gx_device_set_target((gx_device_forward *)dev, tdev);
 
410
        x_clear_color_cache(dev);
 
411
    }
 
412
    *ptdev = tdev;
 
413
    return 0;
 
414
}
 
415
 
 
416
/* Copy parameters back from the target. */
 
417
static int
 
418
get_target_info(gx_device * dev)
 
419
{
 
420
    gx_device *tdev;
 
421
    int code;
 
422
 
 
423
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
424
        return code;
 
425
 
 
426
#define copy(m) dev->m = tdev->m;
 
427
#define copy2(m) copy(m[0]); copy(m[1])
 
428
#define copy4(m) copy2(m); copy(m[2]); copy(m[3])
 
429
 
 
430
    copy(width);
 
431
    copy(height);
 
432
    copy2(MediaSize);
 
433
    copy4(ImagingBBox);
 
434
    copy(ImagingBBox_set);
 
435
    copy2(HWResolution);
 
436
    copy2(MarginsHWResolution);
 
437
    copy2(Margins);
 
438
    copy4(HWMargins);
 
439
    if (dev->color_info.num_components == 3) {
 
440
        /* Leave the anti-aliasing information alone. */
 
441
        gx_device_anti_alias_info aa;
 
442
 
 
443
        aa = dev->color_info.anti_alias;
 
444
        copy(color_info);
 
445
        dev->color_info.anti_alias = aa;
 
446
    }
 
447
 
 
448
#undef copy4
 
449
#undef copy2
 
450
#undef copy
 
451
 
 
452
    x_clear_color_cache(dev);
 
453
    return 0;
 
454
}
 
455
 
 
456
/* Map a fake CMYK or black/white color to a real X color if necessary. */
 
457
static gx_color_index
 
458
x_alt_map_color(gx_device * dev, gx_color_index color)
 
459
{
 
460
    gx_device_X_wrapper *xdev = (gx_device_X_wrapper *) dev;
 
461
    gx_device *tdev;
 
462
    gx_color_value rgb[3];
 
463
    gx_color_index cindex;
 
464
    int result;
 
465
    int code;
 
466
 
 
467
    if (color == gx_no_color_index)
 
468
        return color;
 
469
    if (color < 16) {
 
470
        cindex = ((gx_device_X_wrapper *) dev)->color_cache[color];
 
471
        if (cindex != gx_no_color_index)
 
472
            return cindex;
 
473
    }
 
474
    if ((code = get_dev_target(&tdev, dev)) < 0)
 
475
        return code;
 
476
    result = xdev->alt_map_color(dev, color, rgb);
 
477
    if (result >= 0)
 
478
        cindex = result;
 
479
    else
 
480
        cindex = dev_proc(tdev, map_rgb_color)(tdev, rgb);
 
481
    if (color < 16)
 
482
        ((gx_device_X_wrapper *) dev)->color_cache[color] = cindex;
 
483
    return cindex;
 
484
}
 
485
 
 
486
/* ---------------- CMYK procedures ---------------- */
 
487
 
 
488
/* Device procedures */
 
489
static dev_proc_open_device(x_cmyk_open);
 
490
static dev_proc_put_params(x_cmyk_put_params);
 
491
static dev_proc_map_cmyk_color(x_cmyk_map_cmyk_color);
 
492
/* Extended device procedures */
 
493
static dev_proc_map_color_rgb(x_cmyk_alt_map_color);
 
494
 
 
495
/* The device descriptor */
 
496
static const gx_device_procs x_cmyk_procs = {
 
497
    x_cmyk_open,
 
498
    gx_forward_get_initial_matrix,
 
499
    x_forward_sync_output,
 
500
    x_forward_output_page,
 
501
    x_wrap_close,
 
502
    NULL,                       /* map_rgb_color */
 
503
    x_wrap_map_color_rgb,
 
504
    x_wrap_fill_rectangle,
 
505
    gx_default_tile_rectangle,
 
506
    x_wrap_copy_mono,
 
507
    x_wrap_copy_color,
 
508
    gx_default_draw_line,
 
509
    x_wrap_get_bits,
 
510
    x_wrap_get_params,
 
511
    x_cmyk_put_params,
 
512
    x_cmyk_map_cmyk_color,
 
513
    gx_forward_get_xfont_procs,
 
514
    gx_forward_get_xfont_device,
 
515
    NULL,                       /* map_rgb_alpha_color */
 
516
    gx_forward_get_page_device,
 
517
    gx_forward_get_alpha_bits,
 
518
    NULL                        /* copy_alpha */
 
519
};
 
520
 
 
521
/* The instances are public. */
 
522
const gx_device_X_wrapper gs_x11cmyk_device = {
 
523
    std_device_dci_type_body(gx_device_X_wrapper, &x_cmyk_procs, "x11cmyk",
 
524
        &st_device_X_wrapper,
 
525
        FAKE_RES * 85 / 10, FAKE_RES * 11,      /* x and y extent (nominal) */
 
526
        FAKE_RES, FAKE_RES,     /* x and y density (nominal) */
 
527
        4, 4, 1, 1, 2, 2),
 
528
    X_WRAPPER_DATA(x_cmyk_alt_map_color)
 
529
};
 
530
const gx_device_X_wrapper gs_x11cmyk2_device = {
 
531
    std_device_dci_type_body(gx_device_X_wrapper, &x_cmyk_procs, "x11cmyk2",
 
532
        &st_device_X_wrapper,
 
533
        FAKE_RES * 85 / 10, FAKE_RES * 11,      /* x and y extent (nominal) */
 
534
        FAKE_RES, FAKE_RES,     /* x and y density (nominal) */
 
535
        4, 8, 3, 3, 4, 4),
 
536
    X_WRAPPER_DATA(x_cmyk_alt_map_color)
 
537
};
 
538
const gx_device_X_wrapper gs_x11cmyk4_device = {
 
539
    std_device_dci_type_body(gx_device_X_wrapper, &x_cmyk_procs, "x11cmyk4",
 
540
        &st_device_X_wrapper,
 
541
        FAKE_RES * 85 / 10, FAKE_RES * 11,      /* x and y extent (nominal) */
 
542
        FAKE_RES, FAKE_RES,     /* x and y density (nominal) */
 
543
        4, 16, 15, 15, 16, 16),
 
544
    X_WRAPPER_DATA(x_cmyk_alt_map_color)
 
545
};
 
546
const gx_device_X_wrapper gs_x11cmyk8_device = {
 
547
    std_device_dci_type_body(gx_device_X_wrapper, &x_cmyk_procs, "x11cmyk8",
 
548
        &st_device_X_wrapper,
 
549
        FAKE_RES * 85 / 10, FAKE_RES * 11,      /* x and y extent (nominal) */
 
550
        FAKE_RES, FAKE_RES,     /* x and y density (nominal) */
 
551
        4, 32, 255, 255, 256, 256),
 
552
    X_WRAPPER_DATA(x_cmyk_alt_map_color)
 
553
};
 
554
 
 
555
/* Map a fake color to RGB. */
 
556
static int
 
557
x_cmyk_alt_map_color(gx_device * dev, gx_color_index color,
 
558
                     gx_color_value rgb[3])
 
559
{
 
560
    int shift = dev->color_info.depth >> 2;
 
561
    int mask = (1 << shift) - 1;
 
562
    /* The following division is guaranteed exact. */
 
563
    gx_color_value scale = gx_max_color_value / mask;
 
564
    int cw = ~color & mask;
 
565
    int cb = cw - ((color >> shift) & mask);
 
566
    int cg = cw - ((color >> (shift * 2)) & mask);
 
567
    int cr = cw - ((color >> (shift * 3)) & mask);
 
568
 
 
569
    rgb[0] = max(cr, 0) * scale;
 
570
    rgb[1] = max(cg, 0) * scale;
 
571
    rgb[2] = max(cb, 0) * scale;
 
572
    return -1;
 
573
}
 
574
 
 
575
/* Set color mapping procedures */
 
576
static void
 
577
x_cmyk_set_procs(gx_device *dev)
 
578
{
 
579
    if (dev->color_info.depth == 4) {
 
580
        set_dev_proc(dev, map_cmyk_color, cmyk_1bit_map_cmyk_color);
 
581
    } else {
 
582
        set_dev_proc(dev, map_cmyk_color, x_cmyk_map_cmyk_color);
 
583
    }
 
584
}
 
585
 
 
586
/* Device procedures */
 
587
 
 
588
static int
 
589
x_cmyk_open(gx_device *dev)
 
590
{
 
591
    int code = x_wrap_open(dev);
 
592
 
 
593
    if (code >= 0)
 
594
        x_cmyk_set_procs(dev);
 
595
    return code;
 
596
}
 
597
 
 
598
static int
 
599
x_cmyk_put_params(gx_device * dev, gs_param_list * plist)
 
600
{
 
601
    int code = x_wrap_put_params(dev, plist);
 
602
 
 
603
    if (code >= 0)
 
604
        x_cmyk_set_procs(dev);
 
605
    return code;
 
606
}
 
607
 
 
608
static gx_color_index
 
609
x_cmyk_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
 
610
{
 
611
    int shift = dev->color_info.depth >> 2;
 
612
    gx_color_index pixel = cv[0] >> (gx_color_value_bits - shift);
 
613
    gx_color_value c, m, y, k;
 
614
    c = cv[0]; m = cv[1]; y = cv[2]; k = cv[3];
 
615
    pixel = (pixel << shift) | (m >> (gx_color_value_bits - shift));
 
616
    pixel = (pixel << shift) | (y >> (gx_color_value_bits - shift));
 
617
    return (pixel << shift) | (k >> (gx_color_value_bits - shift));
 
618
}
 
619
 
 
620
/* ---------------- Black-and-white procedures ---------------- */
 
621
 
 
622
/* Extended device procedures */
 
623
static dev_proc_map_color_rgb(x_mono_alt_map_color);
 
624
 
 
625
/* The device descriptor */
 
626
static const gx_device_procs x_mono_procs = {
 
627
    x_wrap_open,
 
628
    gx_forward_get_initial_matrix,
 
629
    x_forward_sync_output,
 
630
    x_forward_output_page,
 
631
    x_wrap_close,
 
632
    gx_default_b_w_map_rgb_color,
 
633
    x_wrap_map_color_rgb,
 
634
    x_wrap_fill_rectangle,
 
635
    gx_default_tile_rectangle,
 
636
    x_wrap_copy_mono,
 
637
    gx_default_copy_color,      /* this is fast for the 1-bit case */
 
638
    gx_default_draw_line,
 
639
    x_wrap_get_bits,
 
640
    x_wrap_get_params,
 
641
    x_wrap_put_params,
 
642
    gx_default_map_cmyk_color,
 
643
    gx_forward_get_xfont_procs,
 
644
    gx_forward_get_xfont_device,
 
645
    NULL,                       /* map_rgb_alpha_color */
 
646
    gx_forward_get_page_device,
 
647
    gx_forward_get_alpha_bits,
 
648
    NULL                        /* copy_alpha */
 
649
};
 
650
 
 
651
/* The instance is public. */
 
652
const gx_device_X_wrapper gs_x11mono_device = {
 
653
    std_device_dci_type_body(gx_device_X_wrapper, &x_mono_procs, "x11mono",
 
654
        &st_device_X_wrapper,
 
655
        FAKE_RES * 85 / 10, FAKE_RES * 11,      /* x and y extent (nominal) */
 
656
        FAKE_RES, FAKE_RES,     /* x and y density (nominal) */
 
657
        1, 1, 1, 0, 2, 0),
 
658
    X_WRAPPER_DATA(x_mono_alt_map_color)
 
659
};
 
660
 
 
661
/* Map a fake color to RGB. */
 
662
static int
 
663
x_mono_alt_map_color(gx_device * dev, gx_color_index color,
 
664
                     gx_color_value rgb[3])
 
665
{
 
666
    rgb[0] = rgb[1] = rgb[2] = (color ? 0 : gx_max_color_value);
 
667
    return -1;
 
668
}
 
669
 
 
670
/* ---------------- 2- and 4-bit gray-scale procedures ---------------- */
 
671
 
 
672
/* Extended device procedures */
 
673
static dev_proc_map_color_rgb(x_gray_alt_map_color);
 
674
 
 
675
/* The device descriptor */
 
676
static const gx_device_procs x_gray_procs = {
 
677
    x_wrap_open,
 
678
    gx_forward_get_initial_matrix,
 
679
    x_forward_sync_output,
 
680
    x_forward_output_page,
 
681
    x_wrap_close,
 
682
    gx_default_gray_map_rgb_color,
 
683
    x_wrap_map_color_rgb,
 
684
    x_wrap_fill_rectangle,
 
685
    gx_default_tile_rectangle,
 
686
    x_wrap_copy_mono,
 
687
    x_wrap_copy_color,
 
688
    gx_default_draw_line,
 
689
    x_wrap_get_bits,
 
690
    x_wrap_get_params,
 
691
    x_wrap_put_params,
 
692
    gx_default_map_cmyk_color,
 
693
    gx_forward_get_xfont_procs,
 
694
    gx_forward_get_xfont_device,
 
695
    NULL,                       /* map_rgb_alpha_color */
 
696
    gx_forward_get_page_device,
 
697
    gx_forward_get_alpha_bits,
 
698
    NULL                        /* copy_alpha */
 
699
};
 
700
 
 
701
/* The instances are public. */
 
702
const gx_device_X_wrapper gs_x11gray2_device = {
 
703
    std_device_dci_type_body(gx_device_X_wrapper, &x_gray_procs, "x11gray2",
 
704
        &st_device_X_wrapper,
 
705
        FAKE_RES * 85 / 10, FAKE_RES * 11,      /* x and y extent (nominal) */
 
706
        FAKE_RES, FAKE_RES,     /* x and y density (nominal) */
 
707
        1, 2, 3, 0, 4, 0),
 
708
    X_WRAPPER_DATA(x_gray_alt_map_color)
 
709
};
 
710
 
 
711
const gx_device_X_wrapper gs_x11gray4_device = {
 
712
    std_device_dci_type_body(gx_device_X_wrapper, &x_gray_procs, "x11gray4",
 
713
        &st_device_X_wrapper,
 
714
        FAKE_RES * 85 / 10, FAKE_RES * 11,      /* x and y extent (nominal) */
 
715
        FAKE_RES, FAKE_RES,     /* x and y density (nominal) */
 
716
        1, 4, 15, 0, 16, 0),
 
717
    X_WRAPPER_DATA(x_gray_alt_map_color)
 
718
};
 
719
 
 
720
/* Map a fake color to RGB. */
 
721
static int
 
722
x_gray_alt_map_color(gx_device * dev, gx_color_index color,
 
723
                     gx_color_value rgb[3])
 
724
{
 
725
    rgb[0] = rgb[1] = rgb[2] =
 
726
        color * gx_max_color_value / dev->color_info.max_gray;
 
727
    return -1;
 
728
}
 
729
 
 
730
/* Device procedures */
 
731
 
 
732
/* We encode a complemented alpha value in the top 8 bits of the */
 
733
/* device color. */
 
734
static gx_color_index
 
735
x_alpha_map_rgb_alpha_color(gx_device * dev,
 
736
 gx_color_value r, gx_color_value g, gx_color_value b, gx_color_value alpha)
 
737
{
 
738
    gx_color_index color;
 
739
    gx_color_value cv[3];
 
740
    byte abyte = alpha >> (gx_color_value_bits - 8);
 
741
    cv[0] = r; cv[1] = g; cv[2] = b;
 
742
    color = gx_forward_map_rgb_color(dev, cv);
 
743
    return (abyte == 0 ? (gx_color_index)0xff << 24 :
 
744
            ((gx_color_index) (abyte ^ 0xff) << 24) + color);
 
745
}
 
746
 
 
747
/* ---------------- Permuted RGB16/32 procedures ---------------- */
 
748
 
 
749
/* Device procedures */
 
750
static dev_proc_map_rgb_color(x_rg16x_map_rgb_color);
 
751
static dev_proc_map_rgb_color(x_rg32x_map_rgb_color);
 
752
/* Extended device procedures */
 
753
static dev_proc_map_color_rgb(x_rg16x_alt_map_color);
 
754
static dev_proc_map_color_rgb(x_rg32x_alt_map_color);
 
755
 
 
756
/* The device descriptor */
 
757
#define RGBX_PROCS(map_rgb_proc)\
 
758
    x_wrap_open,\
 
759
    gx_forward_get_initial_matrix,\
 
760
    x_forward_sync_output,\
 
761
    x_forward_output_page,\
 
762
    x_wrap_close,\
 
763
    map_rgb_proc,               /* differs */\
 
764
    x_wrap_map_color_rgb,\
 
765
    x_wrap_fill_rectangle,\
 
766
    gx_default_tile_rectangle,\
 
767
    x_wrap_copy_mono,\
 
768
    x_forward_copy_color,\
 
769
    gx_default_draw_line,\
 
770
    x_forward_get_bits,\
 
771
    x_wrap_get_params,\
 
772
    x_wrap_put_params,\
 
773
    gx_forward_map_cmyk_color,\
 
774
    gx_forward_get_xfont_procs,\
 
775
    gx_forward_get_xfont_device,\
 
776
    x_alpha_map_rgb_alpha_color,\
 
777
    gx_forward_get_page_device,\
 
778
    gx_default_get_alpha_bits,\
 
779
    gx_default_copy_alpha
 
780
 
 
781
static const gx_device_procs x_rg16x_procs = {
 
782
    RGBX_PROCS(x_rg16x_map_rgb_color)
 
783
};
 
784
const gx_device_X_wrapper gs_x11rg16x_device = {
 
785
    std_device_dci_type_body(gx_device_X_wrapper, &x_rg16x_procs, "x11rg16x",
 
786
        &st_device_X_wrapper,
 
787
        FAKE_RES * 85 / 10, FAKE_RES * 11,      /* x and y extent (nominal) */
 
788
        FAKE_RES, FAKE_RES,     /* x and y density (nominal) */
 
789
        3, 16, 31, 31, 32, 32),
 
790
    X_WRAPPER_DATA(x_rg16x_alt_map_color)
 
791
};
 
792
 
 
793
static const gx_device_procs x_rg32x_procs = {
 
794
    RGBX_PROCS(x_rg32x_map_rgb_color)
 
795
};
 
796
const gx_device_X_wrapper gs_x11rg32x_device = {
 
797
    std_device_dci_type_body(gx_device_X_wrapper, &x_rg32x_procs, "x11rg32x",
 
798
        &st_device_X_wrapper,
 
799
        FAKE_RES * 85 / 10, FAKE_RES * 11,      /* x and y extent (nominal) */
 
800
        FAKE_RES, FAKE_RES,     /* x and y density (nominal) */
 
801
        3, 32, 1023, 1023, 1024, 1024),
 
802
    X_WRAPPER_DATA(x_rg32x_alt_map_color)
 
803
};
 
804
 
 
805
/* Map RGB to a fake color. */
 
806
static gx_color_index
 
807
x_rg16x_map_rgb_color(gx_device * dev, const gx_color_value cv[])
 
808
{
 
809
    /* Permute the colors to G5/B5/R6. */
 
810
    gx_color_value r, g, b;
 
811
    r = cv[0]; g = cv[1]; b = cv[2];
 
812
    return (r >> (gx_color_value_bits - 6)) +
 
813
        ((g >> (gx_color_value_bits - 5)) << 11) +
 
814
        ((b >> (gx_color_value_bits - 5)) << 6);
 
815
}
 
816
static gx_color_index
 
817
x_rg32x_map_rgb_color(gx_device * dev, const gx_color_value cv[])
 
818
{
 
819
    /* Permute the colors to G11/B10/R11. */
 
820
    gx_color_value r, g, b;
 
821
    r = cv[0]; g = cv[1]; b = cv[2];
 
822
    return (r >> (gx_color_value_bits - 11)) +
 
823
        ((gx_color_index)(g >> (gx_color_value_bits - 11)) << 21) +
 
824
        ((gx_color_index)(b >> (gx_color_value_bits - 10)) << 11);
 
825
}
 
826
 
 
827
/* Map a fake color to RGB. */
 
828
static int
 
829
x_rg16x_alt_map_color(gx_device * dev, gx_color_index color,
 
830
                      gx_color_value rgb[3])
 
831
{
 
832
    rgb[0] = (color & 0x3f) * gx_max_color_value / 0x3f;
 
833
    rgb[1] = ((color >> 11) & 0x1f) * gx_max_color_value / 0x1f;
 
834
    rgb[2] = ((color >> 6) & 0x1f) * gx_max_color_value / 0x1f;
 
835
    return -1;
 
836
}
 
837
static int
 
838
x_rg32x_alt_map_color(gx_device * dev, gx_color_index color,
 
839
                      gx_color_value rgb[3])
 
840
{
 
841
    rgb[0] = (color & 0x7ff) * gx_max_color_value / 0x7ff;
 
842
    rgb[1] = ((color >> 21) & 0x7ff) * gx_max_color_value / 0x7ff;
 
843
    rgb[2] = ((color >> 11) & 0x3ff) * gx_max_color_value / 0x3ff;
 
844
    return -1;
 
845
}
 
846
 
 
847
#ifdef GS_DEVS_SHARED
 
848
extern void gs_lib_register_device(const gx_device *dev);
 
849
void
 
850
gs_shared_init(void)
 
851
{
 
852
  gs_lib_register_device(&gs_x11_device);
 
853
  gs_lib_register_device(&gs_x11alpha_device);
 
854
  gs_lib_register_device(&gs_x11cmyk_device);
 
855
  gs_lib_register_device(&gs_x11cmyk2_device);
 
856
  gs_lib_register_device(&gs_x11cmyk4_device);
 
857
  gs_lib_register_device(&gs_x11cmyk8_device);
 
858
  gs_lib_register_device(&gs_x11gray2_device);
 
859
  gs_lib_register_device(&gs_x11gray4_device);
 
860
  gs_lib_register_device(&gs_x11mono_device);
 
861
}
 
862
#endif