Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1998, 1999 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gdevclj.c,v 1.4 2002/02/21 22:24:51 giles Exp $ */
18
/*
19
 * H-P Color LaserJet 5/5M device; based on the PaintJet.
20
 */
21
#include "math_.h"
22
#include "gx.h"
23
#include "gsparam.h"
24
#include "gdevprn.h"
25
#include "gdevpcl.h"
26
 
27
typedef struct gx_device_clj_s gx_device_clj;
28
struct gx_device_clj_s {
29
	gx_device_common;
30
	gx_prn_device_common;
31
	bool rotated;
32
};
33
 
34
#define pclj ((gx_device_clj *)pdev)
35
 
36
/*
37
 * The HP Color LaserJet 5/5M provides a rather unexpected speed/performance
38
 * tradeoff.
39
 *
40
 * When generating rasters, only the fixed (simple) color spaces provide
41
 * reasonable performance (in this case, reasonable != good). However, in
42
 * these modes, certain of the fully-saturated primary colors (cyan, blue,
43
 * green, and red) are rendered differently as rasters as opposed to colored
44
 * geometric objects. Hence, the color of the output will be other than what
45
 * is expected.
46
 *
47
 * Alternatively, the direct color, 1-bit per pixel scheme can be used. This
48
 * will produce the expected colors, but performance will deteriorate
49
 * significantly (observed printing time will be about 3 times longer than
50
 * when using the simple color mode).
51
 *
52
 * Note that when using the latter mode to view output from the PCL
53
 * interpreter, geometric objects and raster rendered with other than
54
 * geometric color spaces will have the same appearance as if sent directly
55
 * to the CLJ, but rasters generated from simple color spaces will have a
56
 * different appearance. To make the latter rasters match in appearance, the
57
 * faster printing mode must be used (in which the case the other objects
58
 * will not have the same appearance).
59
 */
60
#define USE_FAST_MODE
61
 
62
/* X_DPI and Y_DPI must be the same */
63
#define X_DPI 300
64
#define Y_DPI 300
65
 
66
/*
67
 * Array of paper sizes, and the corresponding offsets.
68
 */
69
typedef struct clj_paper_size_s {
70
    uint        tag;                /* paper type tag */
71
    int         orient;             /* logical page orientation to use */
72
    float       width, height;      /* in pts; +- 5 pts */
73
    gs_point    offsets;            /* offsets in the given orientation */
74
} clj_paper_size;
75
 
76
/*
77
 * The Color LaserJet prints page sizes up to 11.8" wide (A4 size) in
78
 * long-edge-feed (landscape) orientation. Only executive, letter, and
79
 * A4 size are supported for color, so we don't bother to list the others.
80
 */
81
private const clj_paper_size    clj_paper_sizes[] = {
82
    /* U.S. letter size comes first so it will be the default. */
83
    {   2,  1, 11.00 * 72.0, 8.50 * 72.0, { .200 * 72.0, 0.0 } },
84
    {   1,  1, 10.50 * 72.0, 7.25 * 72.0, { .200 * 72.0, 0.0 } },
85
    {  26,  1, 11.69 * 72.0, 8.27 * 72.0, { .197 * 72.0, 0.0 } }
86
};
87
 
88
/*
89
 * The supported set of resolutions.
90
 *
91
 * The Color LaserJet 5/5M is actually a pseudo-contone device, with hardware
92
 * capable of providing about 16 levels of intensity. The current code does
93
 * not take advantage of this feature, because it is not readily controllable
94
 * via PCL. Rather, the device is modeled as a bi-level device in each of
95
 * three color planes. The maximum supported resolution for such an arrangement
96
 * is 300 dpi.
97
 *
98
 * The CLJ does support raster scaling, but to invoke that scaling, even for
99
 * integral factors, involves a large performance penalty. Hence, only those
100
 * resolutions that can be supported without invoking raster scaling are
101
 * included here. These resolutions are always the same in the fast and slow
102
 * scan directions, so only a single value is listed here.
103
 *
104
 * All valuse are in dots per inch.
105
 */
106
private const float supported_resolutions[] = { 75.0, 100.0, 150.0, 300.0 };
107
 
108
 
109
/* indicate the maximum supported resolution and scan-line length (pts) */
110
#define CLJ_MAX_RES        300.0
111
#define CLJ_MAX_SCANLINE   (12.0 * 72.0)
112
 
113
 
114
/*
115
 * Determine a requested resolution pair is supported.
116
 */
117
  private bool
118
is_supported_resolution(
119
    const float HWResolution[2]
120
)
121
{
122
    int     i;
123
 
124
    for (i = 0; i < countof(supported_resolutions); i++) {
125
        if (HWResolution[0] == supported_resolutions[i])
126
            return HWResolution[0] == HWResolution[1];
127
    }
128
    return false;
129
}
130
 
131
/* ---------------- Standard driver ---------------- */
132
 
133
/*
134
 * Find the paper size information corresponding to a given pair of dimensions.
135
 * If rotatep != 0, *rotatep is set to true if the page must be rotated 90
136
 * degrees to fit.
137
 *
138
 * A return value of 0 indicates the paper size is not supported.
139
 *
140
 * Note that for the standard driver, rotation is not allowed.
141
 */
142
  private const clj_paper_size *
143
get_paper_size(
144
    const float             MediaSize[2],
145
    bool *                  rotatep
146
)
147
{
148
    static const float      tolerance = 5.0;
149
    float                   width = MediaSize[0];
150
    float                   height = MediaSize[1];
151
    const clj_paper_size *  psize = 0;
152
    int                     i;
153
 
154
    for (i = 0, psize = clj_paper_sizes; i < countof(clj_paper_sizes); i++, psize++) {
155
        if ( (fabs(width - psize->width) <= tolerance)  &&
156
             (fabs(height - psize->height) <= tolerance)  ) {
157
            if (rotatep != 0)
158
                *rotatep = false;
159
            return psize;
160
        } else if ( (fabs(width - psize->height) <= tolerance) &&
161
                    (fabs(height - psize->width) <= tolerance)   ) {
162
            if (rotatep != 0)
163
                *rotatep = true;
164
            return psize;
165
        }
166
    }
167
 
168
    return 0;
169
}
170
 
171
/*
172
 * Get the (PostScript style) default matrix for the current page size.
173
 *
174
 * For all of the supported sizes, the page will be printed with long-edge
175
 * feed (the CLJ does support some additional sizes, but only for monochrome).
176
 * As will all HP laser printers, the printable region marin is 12 pts. from
177
 * the edge of the physical page.
178
 */
179
private void
180
clj_get_initial_matrix( gx_device *pdev, gs_matrix *pmat)
181
{
182
    floatp      	fs_res = pdev->HWResolution[0] / 72.0;
183
    floatp      	ss_res = pdev->HWResolution[1] / 72.0;
184
    const clj_paper_size *psize;
185
 
186
    psize = get_paper_size(pdev->MediaSize, NULL);
187
    /* if the paper size is not recognized, not much can be done */
188
    /* This shouldn't be possible since clj_put_params rejects   */
189
    /* unknown media sizes.					 */
190
    if (psize == 0) {
191
	pmat->xx = fs_res;
192
	pmat->xy = 0.0;
193
	pmat->yx = 0.0;
194
	pmat->yy = -ss_res;
195
	pmat->tx = 0.0;
196
	pmat->ty = pdev->MediaSize[1] * ss_res;
197
	return;
198
    }
199
 
200
    if (pclj->rotated) {
201
        pmat->xx = 0.0;
202
        pmat->xy = ss_res;
203
        pmat->yx = fs_res;
204
        pmat->yy = 0.0;
205
        pmat->tx = -psize->offsets.x * fs_res;
206
        pmat->ty = -psize->offsets.y * ss_res;
207
    } else {
208
        pmat->xx = fs_res;
209
        pmat->xy = 0.0;
210
        pmat->yx = 0.0;
211
        pmat->yy = -ss_res;
212
        pmat->tx = -psize->offsets.x * fs_res;
213
        pmat->ty = pdev->height + psize->offsets.y * ss_res;
214
    }
215
}
216
 
217
/*
218
 * Get parameters, including InputAttributes for all supported page sizes.
219
 * We associate each page size with a different "media source", since that
220
 * is currently the only way to register multiple page sizes.
221
 */
222
private int
223
clj_get_params(gx_device *pdev, gs_param_list *plist)
224
{
225
    gs_param_dict mdict;
226
    int code = gdev_prn_get_params(pdev, plist);
227
    int ecode = code;
228
    int i;
229
 
230
    code = gdev_begin_input_media(plist, &mdict, countof(clj_paper_sizes));
231
    if (code < 0)
232
	ecode = code;
233
    else {
234
	for (i = 0; i < countof(clj_paper_sizes); ++i) {
235
	    code = gdev_write_input_page_size(i, &mdict,
236
					      clj_paper_sizes[i].width,
237
					      clj_paper_sizes[i].height);
238
	    if (code < 0)
239
		ecode = code;
240
	}
241
	code = gdev_end_input_media(plist, &mdict);
242
	if (code < 0)
243
	    ecode = code;
244
    }
245
    return ecode;
246
}
247
 
248
/*
249
 * Get the media size being set by put_params, if any.  Return 0 if no media
250
 * size is being set, 1 (and set mediasize[]) if the size is being set, <0
251
 * on error.
252
 */
253
private int
254
clj_media_size(float mediasize[2], gs_param_list *plist)
255
{
256
    gs_param_float_array fres;
257
    gs_param_float_array fsize;
258
    gs_param_int_array hwsize;
259
    int have_pagesize = 0;
260
 
261
    if ( (param_read_float_array(plist, "HWResolution", &fres) == 0) &&
262
          !is_supported_resolution(fres.data) ) 
263
        return_error(gs_error_rangecheck);
264
 
265
    if ( (param_read_float_array(plist, "PageSize", &fsize) == 0) ||
266
         (param_read_float_array(plist, ".MediaSize", &fsize) == 0) ) {
267
	mediasize[0] = fsize.data[0];
268
	mediasize[1] = fsize.data[1];
269
	have_pagesize = 1;
270
    }
271
 
272
    if (param_read_int_array(plist, "HWSize", &hwsize) == 0) {
273
        mediasize[0] = ((float)hwsize.data[0]) / fres.data[0];
274
        mediasize[1] = ((float)hwsize.data[1]) / fres.data[1];
275
	have_pagesize = 1;
276
    }
277
 
278
    return have_pagesize;
279
}
280
 
281
/*
282
 * Special put_params routine, to make certain the desired MediaSize and
283
 * HWResolution are supported.
284
 */
285
  private int
286
clj_put_params(
287
    gx_device *             pdev,
288
    gs_param_list *         plist
289
)
290
{
291
    float		    mediasize[2];
292
    bool                    rotate = false;
293
    int                     have_pagesize = clj_media_size(mediasize, plist);
294
 
295
    if (have_pagesize < 0)
296
	return have_pagesize;
297
    if (have_pagesize) {
298
	if (get_paper_size(mediasize, &rotate) == 0 || rotate)
299
	    return_error(gs_error_rangecheck);
300
    }
301
    return gdev_prn_put_params(pdev, plist);
302
}
303
 
304
/*
305
 * Pack and then compress a scanline of data. Return the size of the compressed
306
 * data produced.
307
 *
308
 * Input is arranged with one byte per pixel, but only the three low-order bits
309
 * are used. These bits are in order ymc, with yellow being the highest order
310
 * bit.
311
 *
312
 * Output is arranged in three planes, with one bit per pixel per plane. The
313
 * Color LaserJet 5/5M does support more congenial pixel encodings, but use
314
 * of anything other than the fixed palettes seems to result in very poor
315
 * performance.
316
 *
317
 * Only compresion mode 2 is used. Compression mode 1 (pure run length) has
318
 * an advantage over compression mode 2 only in cases in which very long runs
319
 * occur (> 128 bytes). Since both methods provide good compression in that
320
 * case, it is not worth worrying about, and compression mode 2 provides much
321
 * better worst-case behavior. Compression mode 3 requires considerably more
322
 * effort to generate, so it is useful only when it is known a prior that
323
 * scanlines repeat frequently.
324
 */
325
  private void
326
pack_and_compress_scanline(
327
    const byte *        pin,
328
    int                 in_size,
329
    byte  *             pout[3],
330
    int                 out_size[3]
331
)
332
{
333
#define BUFF_SIZE                                                           \
334
    ( ((int)(CLJ_MAX_RES * CLJ_MAX_SCANLINE / 72.0) + sizeof(ulong) - 1)    \
335
         / sizeof(ulong) )
336
 
337
    ulong               buff[3 * BUFF_SIZE];
338
    byte *              p_c = (byte *)buff;
339
    byte *              p_m = (byte *)(buff + BUFF_SIZE);
340
    byte *              p_y = (byte *)(buff + 2 * BUFF_SIZE);
341
    ulong *             ptrs[3];
342
    byte                c_val = 0, m_val = 0, y_val = 0;
343
    ulong               mask = 0x80;
344
    int                 i;
345
 
346
    /* pack the input for 4-bits per index */
347
    for (i = 0; i < in_size; i++) {
348
        uint    ival = *pin++;
349
 
350
        if (ival != 0) {
351
            if ((ival & 0x4) != 0)
352
                y_val |= mask;
353
            if ((ival & 0x2) != 0)
354
                m_val |= mask;
355
            if ((ival & 0x1) != 0)
356
                c_val |= mask;
357
        }
358
 
359
        if ((mask >>= 1) == 0) {
360
            /* NB - write out in byte units */
361
            *p_c++ = c_val;
362
            c_val = 0L;
363
            *p_m++ = m_val;
364
            m_val = 0L;
365
            *p_y++ = y_val;
366
            y_val = 0L;
367
            mask = 0x80;
368
        }
369
    }
370
    if (mask != 0x80) {
371
        /* NB - write out in byte units */
372
        *p_c++ = c_val;
373
        *p_m++ = m_val;
374
        *p_y++ = y_val;
375
    }
376
 
377
    /* clear to up a longword boundary */
378
    while ((((ulong)p_c) & (sizeof(ulong) - 1)) != 0) {
379
        *p_c++ = 0;
380
        *p_m++ = 0;
381
        *p_y++ = 0;
382
    }
383
 
384
    ptrs[0] = (ulong *)p_c;
385
    ptrs[1] = (ulong *)p_m;
386
    ptrs[2] = (ulong *)p_y;
387
 
388
    for (i = 0; i < 3; i++) {
389
        ulong * p_start = buff + i * BUFF_SIZE;
390
        ulong * p_end = ptrs[i];
391
 
392
        /* eleminate trailing 0's */
393
        while ((p_end > p_start) && (p_end[-1] == 0))
394
            p_end--;
395
 
396
        if (p_start == p_end)
397
            out_size[i] = 0;
398
        else
399
            out_size[i] = gdev_pcl_mode2compress(p_start, p_end, pout[i]);
400
    }
401
 
402
#undef BUFF_SIZE
403
}
404
 
405
/*
406
 * Send the page to the printer.  Compress each scan line.
407
 */
408
  private int
409
clj_print_page(
410
    gx_device_printer *     pdev,
411
    FILE *                  prn_stream
412
)
413
{
414
    gs_memory_t *mem = pdev->memory;
415
    bool                    rotate;
416
    const clj_paper_size *  psize = get_paper_size(pdev->MediaSize, &rotate);
417
    int                     lsize = pdev->width;
418
    int                     clsize = (lsize + (lsize + 255) / 128) / 8;
419
    byte *                  data = 0;
420
    byte *                  cdata[3];
421
    int                     blank_lines = 0;
422
    int                     i;
423
    floatp                  fs_res = pdev->HWResolution[0] / 72.0;
424
    floatp                  ss_res = pdev->HWResolution[1] / 72.0;
425
    int			    imageable_width, imageable_height;
426
 
427
    /* no paper size at this point is a serious error */
428
    if (psize == 0)
429
        return_error(gs_error_unregistered);
430
 
431
    /* allocate memory for the raw and compressed data */
432
    if ((data = gs_alloc_bytes(mem, lsize, "clj_print_page(data)")) == 0)
433
        return_error(gs_error_VMerror);
434
    if ((cdata[0] = gs_alloc_bytes(mem, 3 * clsize, "clj_print_page(cdata)")) == 0) {
435
        gs_free_object(mem, data, "clj_print_page(data)");
436
        return_error(gs_error_VMerror);
437
    }
438
    cdata[1] = cdata[0] + clsize;
439
    cdata[2] = cdata[1] + clsize;
440
 
441
 
442
    /* Imageable area is without the margins. Note that the actual rotation
443
     * of page size into pdev->width & height has been done. We just use
444
     * rotate to access the correct offsets. */
445
    if (pclj->rotated) {
446
    	imageable_width = pdev->width - (2 * psize->offsets.x) * fs_res;
447
    	imageable_height = pdev->height - (2 * psize->offsets.y) * ss_res;
448
    }
449
    else {
450
    	imageable_width = pdev->width - (2 * psize->offsets.y) * ss_res;
451
    	imageable_height = pdev->height - (2 * psize->offsets.x) * fs_res;
452
    }
453
 
454
    /* start the page.  The pcl origin (0, 150 dots by default, y
455
       increasing down the long edge side of the page) needs to be
456
       offset such that it coincides with the offsets of the imageable
457
       area.  This calculation should be independant of rotation but
458
       only the rotated case has been tested with a real device. */
459
    fprintf( prn_stream,
460
             "\033E\033&u300D\033&l%da1x%dO\033*p0x0y+50x-100Y\033*t%dR"
461
#ifdef USE_FAST_MODE
462
	     "\033*r-3U"
463
#else
464
             "\033*v6W\001\002\003\001\001\001"
465
#endif
466
             "\033*r0f%ds%dt1A\033*b2M",
467
             psize->tag,
468
             pclj->rotated,
469
             (int)(pdev->HWResolution[0]),
470
             imageable_width,
471
             imageable_height
472
             );
473
 
474
    /* process each scanline */
475
    for (i = 0; i < imageable_height; i++) {
476
        int     clen[3];
477
 
478
        gdev_prn_copy_scan_lines(pdev, i, data, lsize);
479
 
480
	/* The 'lsize' bytes of data have the blank margin area at the end due	*/
481
	/* to the 'initial_matrix' offsets that are applied.			*/
482
        pack_and_compress_scanline(data, imageable_width, cdata, clen);
483
        if ((clen[0] == 0) && (clen[1] == 0) && (clen[2] == 0))
484
            ++blank_lines;
485
        else {
486
            if (blank_lines != 0) {
487
                fprintf(prn_stream, "\033*b%dY", blank_lines);
488
                blank_lines = 0;
489
            }
490
            fprintf(prn_stream, "\033*b%dV", clen[0]);
491
            fwrite(cdata[0], sizeof(byte), clen[0], prn_stream);
492
            fprintf(prn_stream, "\033*b%dV", clen[1]);
493
            fwrite(cdata[1], sizeof(byte), clen[1], prn_stream);
494
            fprintf(prn_stream, "\033*b%dW", clen[2]);
495
            fwrite(cdata[2], sizeof(byte), clen[2], prn_stream);
496
        }
497
    }
498
 
499
    /* PCL will take care of blank lines at the end */
500
    fputs("\033*rC\f", prn_stream);
501
 
502
    /* free the buffers used */
503
    gs_free_object(mem, cdata[0], "clj_print_page(cdata)");
504
    gs_free_object(mem, data, "clj_print_page(data)");
505
 
506
    return 0;
507
}
508
 
509
/* CLJ device methods */
510
#define CLJ_PROCS(get_params, put_params)\
511
    gdev_prn_open,                  /* open_device */\
512
    clj_get_initial_matrix,         /* get_initial matrix */\
513
    NULL,	                    /* sync_output */\
514
    gdev_prn_output_page,           /* output_page */\
515
    gdev_prn_close,                 /* close_device */\
516
    gdev_pcl_3bit_map_rgb_color,    /* map_rgb_color */\
517
    gdev_pcl_3bit_map_color_rgb,    /* map_color_rgb */\
518
    NULL,	                    /* fill_rectangle */\
519
    NULL,	                    /* tile_rectangle */\
520
    NULL,	                    /* copy_mono */\
521
    NULL,	                    /* copy_color */\
522
    NULL,	                    /* obsolete draw_line */\
523
    NULL,	                    /* get_bits */\
524
    get_params, 	            /* get_params */\
525
    put_params,                     /* put_params */\
526
    NULL,	                    /* map_cmyk_color */\
527
    NULL,	                    /* get_xfont_procs */\
528
    NULL,	                    /* get_xfont_device */\
529
    NULL,	                    /* map_rgb_alpha_color */\
530
    gx_page_device_get_page_device  /* get_page_device */
531
 
532
private gx_device_procs cljet5_procs = {
533
    CLJ_PROCS(clj_get_params, clj_put_params)
534
};
535
 
536
/* CLJ device structure */
537
#define CLJ_DEVICE_BODY(procs, dname, rotated)\
538
  prn_device_body(\
539
    gx_device_clj,\
540
    procs,                  /* procedures */\
541
    dname,                  /* device name */\
542
    110,                    /* width - will be overridden subsequently */\
543
    85,                     /* height - will be overridden subsequently */\
544
    X_DPI, Y_DPI,           /* resolutions - current must be the same */\
545
    0.167, 0.167,           /* margins (left, bottom, right, top */\
546
    0.167, 0.167,\
547
    3,                      /* num_components - 3 colors, 1 bit per pixel */\
548
    8,			    /* depth - pack into bytes */\
549
    1, 1, 		    /* max_gray=max_component=1 */\
550
    2, 2,		    /* dithered_grays=dithered_components=2 */ \
551
    clj_print_page          /* routine to output page */\
552
),\
553
    rotated		    /* rotated - may be overridden subsequently */
554
 
555
gx_device_clj gs_cljet5_device = {
556
    CLJ_DEVICE_BODY(cljet5_procs, "cljet5", 0 /*false*/)
557
};
558
 
559
/* ---------------- Driver with page rotation ---------------- */
560
 
561
/*
562
 * For use with certain PCL interpreters, which don't implement
563
 * setpagedevice, we provide a version of this driver that attempts to
564
 * handle page rotation at the driver level.  This version breaks an
565
 * invariant that all drivers must obey, namely, that drivers are not
566
 * allowed to change the parameters passed by put_params (they can only
567
 * accept or reject them).  Consequently, this driver must not be used in
568
 * any context other than these specific PCL interpreters.  We support this
569
 * hack only because these PCL interpreters can't be changed to handle page
570
 * rotation properly.
571
 */
572
 
573
/*
574
 * Special get_params routine, to fake MediaSize, width, and height if
575
 * we were in a 'rotated' state.
576
 */
577
private int
578
clj_pr_get_params( gx_device *pdev, gs_param_list *plist )
579
{
580
    int code;
581
 
582
    /* First un-rotate the MediaSize, etc. if we were in a rotated mode		*/
583
    if (pclj->rotated) {
584
        float ftmp;
585
	int   itmp;
586
 
587
	ftmp = pdev->MediaSize[0];
588
	pdev->MediaSize[0] = pdev->MediaSize[1];
589
	pdev->MediaSize[1] = ftmp;
590
	itmp = pdev->width;
591
	pdev->width = pdev->height;
592
	pdev->height = itmp;
593
    }
594
 
595
    /* process the parameter list */
596
    code = gdev_prn_get_params(pdev, plist);
597
 
598
    /* Now re-rotate the page size if needed */
599
    if (pclj->rotated) {
600
        float ftmp;
601
	int   itmp;
602
 
603
	ftmp = pdev->MediaSize[0];
604
	pdev->MediaSize[0] = pdev->MediaSize[1];
605
	pdev->MediaSize[1] = ftmp;
606
	itmp = pdev->width;
607
	pdev->width = pdev->height;
608
	pdev->height = itmp;
609
    }
610
 
611
    return code;
612
}
613
 
614
/*
615
 * Special put_params routine, to intercept changes in the MediaSize, and to
616
 * make certain the desired MediaSize and HWResolution are supported.
617
 *
618
 * This function will rotate MediaSize if it is needed by the device in
619
 * order to print this size page.
620
 */
621
  private int
622
clj_pr_put_params(
623
    gx_device *             pdev,
624
    gs_param_list *         plist
625
)
626
{
627
    float		    mediasize[2];
628
    int                     code = 0;
629
    bool                    rotate = false;
630
    int                     have_pagesize = clj_media_size(mediasize, plist);
631
 
632
    if (have_pagesize < 0)
633
	return have_pagesize;
634
    if (have_pagesize) {
635
	if (get_paper_size(mediasize, &rotate) == 0)
636
	    return_error(gs_error_rangecheck);
637
	if (rotate) {
638
	    /* We need to rotate the requested page size, so synthesize a new	*/
639
	    /* parameter list in front of the requestor's list to force the	*/
640
	    /* rotated page size.						*/
641
	    gs_param_float_array	pf_array;
642
	    gs_c_param_list		alist;
643
	    float			ftmp = mediasize[0];
644
 
645
	    mediasize[0] = mediasize[1];
646
	    mediasize[1] = ftmp;
647
	    pf_array.data = mediasize;
648
	    pf_array.size = 2;
649
	    pf_array.persistent = false;
650
 
651
	    gs_c_param_list_write(&alist, pdev->memory);
652
	    code = param_write_float_array((gs_param_list *)&alist, ".MediaSize", &pf_array);
653
	    gs_c_param_list_read(&alist);
654
 
655
	    /* stick this synthesized parameter on the front of the existing list */
656
	    gs_c_param_list_set_target(&alist, plist);
657
	    if ((code = gdev_prn_put_params(pdev, (gs_param_list *)&alist)) >= 0)
658
		pclj->rotated = true;
659
	    gs_c_param_list_release(&alist);
660
	} else {
661
	    if ((code = gdev_prn_put_params(pdev, plist)) >= 0)
662
		pclj->rotated = false;
663
	}
664
    } else 
665
	code = gdev_prn_put_params(pdev, plist);
666
 
667
    return code;
668
}
669
 
670
/* CLJ device methods -- se above for CLJ_PROCS */
671
private gx_device_procs cljet5pr_procs = {
672
    CLJ_PROCS(clj_pr_get_params, clj_pr_put_params)
673
};
674
 
675
/* CLJ device structure -- see above for CLJ_DEVICE_BODY */
676
gx_device_clj gs_cljet5pr_device = {
677
    CLJ_DEVICE_BODY(cljet5pr_procs, "cljet5pr", 1 /*true*/)
678
};