1/*
2** PCL6Writer.cpp
3** Copyright 2005, Michael Pfeiffer, laplace@users.sourceforge.net.
4** All rights reserved.
5** Distributed under the terms of the MIT License.
6*/
7
8
9#include "PCL6Writer.h"
10
11#include <ByteOrder.h>
12#include <String.h>
13
14#define BYTE_AT(lvalue, index) (((uint8*)(&lvalue))[index])
15
16
17PCL6Writer::PCL6Writer(PCL6WriterStream* stream, uint32 bufferSize)
18	:
19	fStream(stream),
20	fBuffer(new uint8[bufferSize]),
21	fSize(bufferSize),
22	fIndex(0)
23{
24}
25
26
27PCL6Writer::~PCL6Writer()
28{
29	delete[] fBuffer;
30	fBuffer = NULL;
31}
32
33
34// throws TransportException
35void
36PCL6Writer::Append(uint8 value)
37{
38	if (fIndex == fSize)
39		Flush();
40	fBuffer[fIndex] = value;
41	fIndex ++;
42}
43
44
45void
46PCL6Writer::Flush()
47{
48	if (fIndex > 0) {
49		fStream->Write(fBuffer, fIndex);
50		fIndex = 0;
51	}
52}
53
54
55void
56PCL6Writer::Append(int16 value)
57{
58	int16 v = B_HOST_TO_LENDIAN_INT16(value);
59	Append(BYTE_AT(v, 0));
60	Append(BYTE_AT(v, 1));
61}
62
63
64void
65PCL6Writer::Append(uint16 value)
66{
67	int16 v = B_HOST_TO_LENDIAN_INT16(value);
68	Append(BYTE_AT(v, 0));
69	Append(BYTE_AT(v, 1));
70}
71
72
73void
74PCL6Writer::Append(int32 value)
75{
76	int32 v = B_HOST_TO_LENDIAN_INT32(value);
77	Append(BYTE_AT(v, 0));
78	Append(BYTE_AT(v, 1));
79	Append(BYTE_AT(v, 2));
80	Append(BYTE_AT(v, 3));
81}
82
83
84void
85PCL6Writer::Append(uint32 value)
86{
87	int32 v = B_HOST_TO_LENDIAN_INT32(value);
88	Append(BYTE_AT(v, 0));
89	Append(BYTE_AT(v, 1));
90	Append(BYTE_AT(v, 2));
91	Append(BYTE_AT(v, 3));
92}
93
94
95void
96PCL6Writer::Append(float value)
97{
98	float v = B_HOST_TO_LENDIAN_FLOAT(value);
99	Append(BYTE_AT(v, 0));
100	Append(BYTE_AT(v, 1));
101	Append(BYTE_AT(v, 2));
102	Append(BYTE_AT(v, 3));
103}
104
105
106void
107PCL6Writer::Append(const uint8* data, uint32 size)
108{
109	for (uint32 i = 0; i < size; i++) {
110		Append(data[i]);
111	}
112}
113
114
115void
116PCL6Writer::AppendString(const char* string)
117{
118	uint8 ch = *string;
119	while (ch != 0) {
120		Append(ch);
121		string ++;
122		ch = *string;
123	}
124}
125
126
127void
128PCL6Writer::AppendOperator(Operator op)
129{
130	Append((uint8)op);
131}
132
133
134void
135PCL6Writer::AppendAttribute(Attribute attr)
136{
137	AppendDataTag(k8BitAttrId);
138	Append((uint8)attr);
139}
140
141
142void
143PCL6Writer::AppendDataTag(DataTag tag)
144{
145	Append((uint8)tag);
146}
147
148
149void
150PCL6Writer::AppendData(uint8 value)
151{
152	AppendDataTag(kUByteData);
153	Append(value);
154}
155
156
157void
158PCL6Writer::AppendData(int16 value)
159{
160	AppendDataTag(kSInt16Data);
161	Append(value);
162}
163
164
165void
166PCL6Writer::AppendData(uint16 value)
167{
168	AppendDataTag(kUInt16Data);
169	Append(value);
170}
171
172
173void
174PCL6Writer::AppendData(int32 value)
175{
176	AppendDataTag(kSInt32Data);
177	Append(value);
178}
179
180
181void
182PCL6Writer::AppendData(uint32 value)
183{
184	AppendDataTag(kUInt32Data);
185	Append(value);
186}
187
188
189void
190PCL6Writer::AppendData(float value)
191{
192	AppendDataTag(kReal32Data);
193	Append(value);
194}
195
196
197void
198PCL6Writer::EmbeddedDataPrefix(uint32 size)
199{
200	if (size < 256) {
201		AppendDataTag(kEmbeddedDataByte);
202		Append((uint8)size);
203	} else {
204		AppendDataTag(kEmbeddedData);
205		Append(size);
206	}
207}
208
209
210void
211PCL6Writer::EmbeddedDataPrefix32(uint32 size)
212{
213	AppendDataTag(kEmbeddedData);
214	Append(size);
215}
216
217
218void
219PCL6Writer::AppendDataXY(uint8 x, uint8 y)
220{
221	AppendDataTag(kUByteXY);
222	Append(x); Append(y);
223}
224
225
226void
227PCL6Writer::AppendDataXY(int16 x, int16 y)
228{
229	AppendDataTag(kSInt16XY);
230	Append(x); Append(y);
231}
232
233
234void
235PCL6Writer::AppendDataXY(uint16 x, uint16 y)
236{
237	AppendDataTag(kUInt16XY);
238	Append(x); Append(y);
239}
240
241
242void
243PCL6Writer::AppendDataXY(int32 x, int32 y)
244{
245	AppendDataTag(kSInt32XY);
246	Append(x); Append(y);
247}
248
249
250void
251PCL6Writer::AppendDataXY(uint32 x, uint32 y)
252{
253	AppendDataTag(kUInt32XY);
254	Append(x); Append(y);
255}
256
257
258void
259PCL6Writer::AppendDataXY(float x, float y)
260{
261	AppendDataTag(kReal32XY);
262	Append(x); Append(y);
263}
264
265
266void
267PCL6Writer::PJLHeader(ProtocolClass protocolClass, int dpi, const char* comment)
268{
269	BString string;
270	AppendString("\033%-12345X@PJL JOB\n@PJL SET RESOLUTION=");
271	string << dpi;
272	AppendString(string.String());
273	AppendString("\n@PJL ENTER LANGUAGE=PCLXL\n) HP-PCL XL;");
274
275	const char* pc = "";
276	switch (protocolClass) {
277		case kProtocolClass1_1:
278			pc = "1;1;";
279			break;
280		case kProtocolClass2_0:
281			pc = "2;0;";
282			break;
283		case kProtocolClass2_1:
284			pc = "2;1;";
285			break;
286		case kProtocolClass3_0:
287			pc = "3;0;";
288			break;
289	}
290	AppendString(pc);
291
292	if (comment != NULL) {
293		AppendString("Comment ");
294		AppendString(comment);
295	}
296
297	AppendString("\n");
298}
299
300
301void
302PCL6Writer::PJLFooter()
303{
304	AppendString("\033%-12345X@PJL EOJ\n\033%-12345X");
305}
306
307
308void
309PCL6Writer::BeginSession(uint16 xres, uint16 yres, UnitOfMeasure unitOfMeasure,
310	ErrorReporting errorReporting)
311{
312	AppendDataXY(xres, yres);
313	AppendAttribute(kUnitsPerMeasure);
314
315	AppendData((uint8)unitOfMeasure);
316	AppendAttribute(kMeasure);
317
318	AppendData((uint8)errorReporting);
319	AppendAttribute(kErrorReport);
320
321	AppendOperator(kBeginSession);
322}
323
324
325void
326PCL6Writer::EndSession()
327{
328	AppendOperator(kEndSession);
329}
330
331
332void
333PCL6Writer::OpenDataSource()
334{
335	AppendData((uint8)kDefaultDataSource);
336	AppendAttribute(kSourceType);
337
338	AppendData((uint8)kBinaryLowByteFirst);
339	AppendAttribute(kDataOrg);
340
341	AppendOperator(kOpenDataSource);
342}
343
344
345void
346PCL6Writer::CloseDataSource()
347{
348	AppendOperator(kCloseDataSource);
349}
350
351
352void
353PCL6Writer::BeginPage(Orientation orientation, MediaSize mediaSize,
354	MediaSource mediaSource)
355{
356	AppendData((uint8)orientation);
357	AppendAttribute(kOrientation);
358
359	AppendData((uint8)mediaSize);
360	AppendAttribute(kMediaSize);
361
362	AppendData((uint8)mediaSource);
363	AppendAttribute(kMediaSource);
364
365	AppendOperator(kBeginPage);
366}
367
368
369void
370PCL6Writer::BeginPage(Orientation orientation, MediaSize mediaSize,
371	MediaSource mediaSource, DuplexPageMode duplexPageMode, MediaSide mediaSide)
372{
373	AppendData((uint8)orientation);
374	AppendAttribute(kOrientation);
375
376	AppendData((uint8)mediaSize);
377	AppendAttribute(kMediaSize);
378
379	AppendData((uint8)mediaSource);
380	AppendAttribute(kMediaSource);
381
382	AppendData((uint8)duplexPageMode);
383	AppendAttribute(kDuplexPageMode);
384
385	AppendData((uint8)mediaSide);
386	AppendAttribute(kDuplexPageSide);
387
388	AppendOperator(kBeginPage);
389}
390
391
392void
393PCL6Writer::EndPage(uint16 copies)
394{
395//	if (copies != 1) {
396		AppendData(copies);
397		AppendAttribute(kPageCopies);
398//	}
399
400	AppendOperator(kEndPage);
401}
402
403
404void
405PCL6Writer::SetPageOrigin(int16 x, int16 y)
406{
407	AppendDataXY(x, y);
408	AppendAttribute(kPageOrigin);
409
410	AppendOperator(kSetPageOrigin);
411}
412
413
414void
415PCL6Writer::SetColorSpace(ColorSpace colorSpace)
416{
417	AppendData((uint8)colorSpace);
418	AppendAttribute(kColorSpace);
419
420	AppendOperator(kSetColorSpace);
421}
422
423
424void
425PCL6Writer::SetPaintTxMode(Transparency transparency)
426{
427	AppendData((uint8)transparency);
428	AppendAttribute(kTxMode);
429
430	AppendOperator(kSetPaintTxMode);
431}
432
433
434void
435PCL6Writer::SetSourceTxMode(Transparency transparency)
436{
437	AppendData((uint8)transparency);
438	AppendAttribute(kTxMode);
439
440	AppendOperator(kSetSourceTxMode);
441}
442
443
444void
445PCL6Writer::SetROP(uint8 rop)
446{
447	AppendData((uint8)rop);
448	AppendAttribute(kROP3);
449
450	AppendOperator(kSetROP);
451}
452
453
454void
455PCL6Writer::SetCursor(int16 x, int16 y)
456{
457	AppendDataXY(x, y);
458	AppendAttribute(kPoint);
459
460	AppendOperator(kSetCursor);
461}
462
463
464void
465PCL6Writer::BeginImage(ColorMapping colorMapping, ColorDepth colorDepth,
466	uint16 sourceWidth, uint16 sourceHeight, uint16 destWidth,
467	uint16 destHeight)
468{
469	AppendData((uint8)colorMapping);
470	AppendAttribute(kColorMapping);
471
472	AppendData((uint8)colorDepth);
473	AppendAttribute(kColorDepth);
474
475	AppendData(sourceWidth);
476	AppendAttribute(kSourceWidth);
477
478	AppendData(sourceHeight);
479	AppendAttribute(kSourceHeight);
480
481	AppendDataXY(destWidth, destHeight);
482	AppendAttribute(kDestinationSize);
483
484	AppendOperator(kBeginImage);
485}
486
487
488void
489PCL6Writer::ReadImage(Compression compression, uint16 startLine,
490	uint16 blockHeight, uint8 padBytes)
491{
492	AppendData(startLine);
493	AppendAttribute(kStartLine);
494
495	AppendData(blockHeight);
496	AppendAttribute(kBlockHeight);
497
498	AppendData((uint8)compression);
499	AppendAttribute(kCompressMode);
500
501	if (padBytes < 1 || padBytes > 4) {
502		// XXX throw exception
503		return;
504	}
505	if (padBytes != 4) {
506		AppendData((uint8)padBytes);
507		AppendAttribute(kPadBytesMultiple);
508	}
509
510	AppendOperator(kReadImage);
511}
512
513
514void
515PCL6Writer::EndImage()
516{
517	AppendOperator(kEndImage);
518}
519