Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 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: gdevpxut.c,v 1.8 2005/07/11 22:08:30 stefan Exp $ */
18
/* Utilities for PCL XL generation */
19
#include "math_.h"
20
#include "string_.h"
21
#include "gx.h"
22
#include "stream.h"
23
#include "gxdevcli.h"
24
#include "gdevpxat.h"
25
#include "gdevpxen.h"
26
#include "gdevpxop.h"
27
#include "gdevpxut.h"
28
#include <assert.h>
29
 
30
/* ---------------- High-level constructs ---------------- */
31
 
32
/* Write the file header, including the resolution. */
33
int
34
px_write_file_header(stream *s, const gx_device *dev)
35
{
36
    static const char *const enter_pjl_header =
37
        "\033%-12345X@PJL SET RENDERMODE=";
38
    static const char *const rendermode_gray = "GRAYSCALE";
39
    static const char *const rendermode_color = "COLOR";
40
    static const char *const file_header =
41
	"\n@PJL ENTER LANGUAGE = PCLXL\n\
42
) HP-PCL XL;1;1;Comment Copyright artofcode LLC 2005\000\n";
43
    static const byte stream_header[] = {
44
	DA(pxaUnitsPerMeasure),
45
	DUB(0), DA(pxaMeasure),
46
	DUB(eBackChAndErrPage), DA(pxaErrorReport),
47
	pxtBeginSession,
48
	DUB(0), DA(pxaSourceType),
49
	DUB(eBinaryLowByteFirst), DA(pxaDataOrg),
50
	pxtOpenDataSource
51
    };
52
 
53
    px_put_bytes(s, (const byte *)enter_pjl_header,
54
		 strlen(enter_pjl_header));
55
 
56
    if (dev->color_info.num_components == 1)
57
	px_put_bytes(s, (const byte *)rendermode_gray,
58
		     strlen(rendermode_gray));
59
    else
60
	px_put_bytes(s, (const byte *)rendermode_color,
61
		     strlen(rendermode_color));
62
 
63
    /* We have to add 2 to the strlen because the next-to-last */
64
    /* character is a null. */
65
    px_put_bytes(s, (const byte *)file_header,
66
		 strlen(file_header) + 2);
67
    px_put_usp(s, (uint) (dev->HWResolution[0] + 0.5),
68
	       (uint) (dev->HWResolution[1] + 0.5));
69
    PX_PUT_LIT(s, stream_header);
70
    return 0;
71
}
72
 
73
/* Write the page header, including orientation. */
74
int
75
px_write_page_header(stream *s, const gx_device *dev)
76
{
77
    static const byte page_header_1[] = {
78
	DUB(ePortraitOrientation), DA(pxaOrientation)
79
    };
80
 
81
    PX_PUT_LIT(s, page_header_1);
82
    return 0;
83
}
84
 
85
/* Write the media selection command if needed, updating the media size. */
86
int
87
px_write_select_media(stream *s, const gx_device *dev, 
88
		      pxeMediaSize_t *pms, byte *media_source)
89
{
90
#define MSD(ms, res, w, h)\
91
  { ms, (float)((w) * 1.0 / (res)), (float)((h) * 1.0 / res) },
92
    static const struct {
93
	pxeMediaSize_t ms;
94
	float width, height;
95
    } media_sizes[] = {
96
	px_enumerate_media(MSD)
97
	{ pxeMediaSize_next }
98
    };
99
#undef MSD
100
    float w = dev->width / dev->HWResolution[0],
101
	h = dev->height / dev->HWResolution[1];
102
    int i;
103
    pxeMediaSize_t size;
104
    byte tray = eAutoSelect;
105
 
106
    /* The default is eLetterPaper, media size 0. */
107
    for (i = countof(media_sizes) - 2; i > 0; --i)
108
	if (fabs(media_sizes[i].width - w) < 5.0 / 72 &&
109
	    fabs(media_sizes[i].height - h) < 5.0 / 72
110
	    )
111
	    break;
112
    size = media_sizes[i].ms;
113
    /*
114
     * According to the PCL XL documentation, MediaSize must always
115
     * be specified, but MediaSource is optional.
116
     */
117
    px_put_uba(s, (byte)size, pxaMediaSize);
118
 
119
    if (media_source != NULL)
120
	tray = *media_source;
121
    px_put_uba(s, tray, pxaMediaSource);
122
    if (pms)
123
	*pms = size;
124
 
125
    return 0;
126
}
127
 
128
/*
129
 * Write the file trailer.  Note that this takes a FILE *, not a stream *,
130
 * since it may be called after the stream is closed.
131
 */
132
int
133
px_write_file_trailer(FILE *file)
134
{
135
    static const byte file_trailer[] = {
136
	pxtCloseDataSource,
137
	pxtEndSession,
138
	033, '%', '-', '1', '2', '3', '4', '5', 'X'
139
    };
140
 
141
    fwrite(file_trailer, 1, sizeof(file_trailer), file);
142
    return 0;
143
}
144
 
145
/* ---------------- Low-level data output ---------------- */
146
 
147
/* Write a sequence of bytes. */
148
void
149
px_put_bytes(stream * s, const byte * data, uint count)
150
{
151
    uint used;
152
 
153
    sputs(s, data, count, &used);
154
}
155
 
156
/* Utilities for writing data values. */
157
/* H-P printers only support little-endian data, so that's what we emit. */
158
void
159
px_put_a(stream * s, px_attribute_t a)
160
{
161
    sputc(s, pxt_attr_ubyte);
162
    sputc(s, (byte)a);
163
}
164
void
165
px_put_ac(stream *s, px_attribute_t a, px_tag_t op)
166
{
167
    px_put_a(s, a);
168
    sputc(s, (byte)op);
169
}
170
 
171
void
172
px_put_ub(stream * s, byte b)
173
{
174
    sputc(s, pxt_ubyte);
175
    sputc(s, b);
176
}
177
void
178
px_put_uba(stream *s, byte b, px_attribute_t a)
179
{
180
    px_put_ub(s, b);
181
    px_put_a(s, a);
182
}
183
 
184
void
185
px_put_s(stream * s, uint i)
186
{
187
    sputc(s, (byte) i);
188
    sputc(s, (byte) (i >> 8));
189
}
190
void
191
px_put_us(stream * s, uint i)
192
{
193
    sputc(s, pxt_uint16);
194
    px_put_s(s, i);
195
}
196
void
197
px_put_usa(stream *s, uint i, px_attribute_t a)
198
{
199
    px_put_us(s, i);
200
    px_put_a(s, a);
201
}
202
void
203
px_put_u(stream * s, uint i)
204
{
205
    if (i <= 255)
206
	px_put_ub(s, (byte)i);
207
    else
208
	px_put_us(s, i);
209
}
210
 
211
void
212
px_put_usp(stream * s, uint ix, uint iy)
213
{
214
    spputc(s, pxt_uint16_xy);
215
    px_put_s(s, ix);
216
    px_put_s(s, iy);
217
}
218
void
219
px_put_usq_fixed(stream * s, fixed x0, fixed y0, fixed x1, fixed y1)
220
{
221
    spputc(s, pxt_uint16_box);
222
    px_put_s(s, fixed2int(x0));
223
    px_put_s(s, fixed2int(y0));
224
    px_put_s(s, fixed2int(x1));
225
    px_put_s(s, fixed2int(y1));
226
}
227
 
228
void
229
px_put_ss(stream * s, int i)
230
{
231
    sputc(s, pxt_sint16);
232
    px_put_s(s, (uint) i);
233
}
234
void
235
px_put_ssp(stream * s, int ix, int iy)
236
{
237
    sputc(s, pxt_sint16_xy);
238
    px_put_s(s, (uint) ix);
239
    px_put_s(s, (uint) iy);
240
}
241
 
242
void
243
px_put_l(stream * s, ulong l)
244
{
245
    px_put_s(s, (uint) l);
246
    px_put_s(s, (uint) (l >> 16));
247
}
248
 
249
void
250
px_put_r(stream * s, floatp r)
251
{				/* Convert to single-precision IEEE float. */
252
    int exp;
253
    long mantissa = (long)(frexp(r, &exp) * 0x1000000);
254
 
255
    if (exp < -126)
256
	mantissa = 0, exp = 0;	/* unnormalized */
257
    if (mantissa < 0)
258
	exp += 128, mantissa = -mantissa;
259
    /* All quantities are little-endian. */
260
    spputc(s, (byte) mantissa);
261
    spputc(s, (byte) (mantissa >> 8));
262
    spputc(s, (byte) (((exp + 127) << 7) + ((mantissa >> 16) & 0x7f)));
263
    spputc(s, (byte) ((exp + 127) >> 1));
264
}
265
void
266
px_put_rl(stream * s, floatp r)
267
{
268
    spputc(s, pxt_real32);
269
    px_put_r(s, r);
270
}
271
 
272
void
273
px_put_data_length(stream * s, uint num_bytes)
274
{
275
    if (num_bytes > 255) {
276
	spputc(s, pxt_dataLength);
277
	px_put_l(s, (ulong) num_bytes);
278
    } else {
279
	spputc(s, pxt_dataLengthByte);
280
	spputc(s, (byte) num_bytes);
281
    }
282
}