xref: /haiku/src/add-ons/print/drivers/pcl6/PCL6.cpp (revision 4410ee1269f6a039e1c1060feb105ce40c8152dc)
13bfe34e2SMichael Pfeiffer /*
23bfe34e2SMichael Pfeiffer  * PCL6.cpp
33bfe34e2SMichael Pfeiffer  * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
43bfe34e2SMichael Pfeiffer  * Copyright 2003 Michael Pfeiffer.
53bfe34e2SMichael Pfeiffer  */
63bfe34e2SMichael Pfeiffer 
7568716beSWim van der Meer 
8568716beSWim van der Meer #include "PCL6.h"
9568716beSWim van der Meer 
10568716beSWim van der Meer #include <memory.h>
11568716beSWim van der Meer 
123bfe34e2SMichael Pfeiffer #include <Alert.h>
133bfe34e2SMichael Pfeiffer #include <Bitmap.h>
143bfe34e2SMichael Pfeiffer #include <File.h>
152e86189fSMichael Pfeiffer 
163bfe34e2SMichael Pfeiffer #include "DbgMsg.h"
17dcab4343SMichael Pfeiffer #include "DeltaRowCompression.h"
182e86189fSMichael Pfeiffer #include "Halftone.h"
192e86189fSMichael Pfeiffer #include "JobData.h"
202e86189fSMichael Pfeiffer #include "PackBits.h"
212e86189fSMichael Pfeiffer #include "PCL6Cap.h"
225fc71589SMichael Pfeiffer #include "PCL6Config.h"
232e86189fSMichael Pfeiffer #include "PCL6Rasterizer.h"
24568716beSWim van der Meer #include "PrinterData.h"
252e86189fSMichael Pfeiffer #include "UIDriver.h"
262e86189fSMichael Pfeiffer #include "ValidRect.h"
273bfe34e2SMichael Pfeiffer 
28568716beSWim van der Meer 
29dcab4343SMichael Pfeiffer // DeltaRowStreamCompressor writes the delta row directly to the
30dcab4343SMichael Pfeiffer // in the contructor specified stream.
31dcab4343SMichael Pfeiffer class DeltaRowStreamCompressor : public AbstractDeltaRowCompressor
32dcab4343SMichael Pfeiffer {
33dcab4343SMichael Pfeiffer public:
34568716beSWim van der Meer 				DeltaRowStreamCompressor(int rowSize, uchar initialSeed,
35568716beSWim van der Meer 					PCL6Writer* writer)
36568716beSWim van der Meer 				:
37568716beSWim van der Meer 				AbstractDeltaRowCompressor(rowSize, initialSeed),
38568716beSWim van der Meer 				fWriter(writer)
39568716beSWim van der Meer 				{}
40dcab4343SMichael Pfeiffer 
41dcab4343SMichael Pfeiffer protected:
42568716beSWim van der Meer 	void		AppendByteToDeltaRow(uchar byte)
43568716beSWim van der Meer 				{
44b1a3ccb8SMichael Pfeiffer 					fWriter->Append(byte);
45dcab4343SMichael Pfeiffer 				}
46dcab4343SMichael Pfeiffer 
47dcab4343SMichael Pfeiffer private:
48b1a3ccb8SMichael Pfeiffer 	PCL6Writer*	fWriter;
49dcab4343SMichael Pfeiffer };
50dcab4343SMichael Pfeiffer 
512e86189fSMichael Pfeiffer 
52fefd3ba5SMichael Pfeiffer PCL6Driver::PCL6Driver(BMessage* message, PrinterData* printerData,
53fefd3ba5SMichael Pfeiffer 	const PrinterCap* printerCap)
54568716beSWim van der Meer 	:
55fefd3ba5SMichael Pfeiffer 	GraphicsDriver(message, printerData, printerCap),
56fefd3ba5SMichael Pfeiffer 	fWriter(NULL),
57fefd3ba5SMichael Pfeiffer 	fMediaSide(PCL6Writer::kFrontMediaSide),
58fefd3ba5SMichael Pfeiffer 	fHalftone(NULL)
593bfe34e2SMichael Pfeiffer {
603bfe34e2SMichael Pfeiffer }
613bfe34e2SMichael Pfeiffer 
62568716beSWim van der Meer 
63568716beSWim van der Meer void
64fefd3ba5SMichael Pfeiffer PCL6Driver::Write(const uint8* data, uint32 size)
653bfe34e2SMichael Pfeiffer {
66fefd3ba5SMichael Pfeiffer 	WriteSpoolData(data, size);
673bfe34e2SMichael Pfeiffer }
683bfe34e2SMichael Pfeiffer 
69568716beSWim van der Meer 
70568716beSWim van der Meer bool
71fefd3ba5SMichael Pfeiffer PCL6Driver::StartDocument()
723bfe34e2SMichael Pfeiffer {
733bfe34e2SMichael Pfeiffer 	try {
74fefd3ba5SMichael Pfeiffer 		_JobStart();
75*4410ee12SMichael Pfeiffer 		fHalftone = new Halftone(GetJobData()->GetSurfaceType(),
76*4410ee12SMichael Pfeiffer 			GetJobData()->GetGamma(), GetJobData()->GetInkDensity(),
77*4410ee12SMichael Pfeiffer 			GetJobData()->GetDitherType());
783bfe34e2SMichael Pfeiffer 		return true;
793bfe34e2SMichael Pfeiffer 	}
803bfe34e2SMichael Pfeiffer 	catch (TransportException& err) {
813bfe34e2SMichael Pfeiffer 		return false;
823bfe34e2SMichael Pfeiffer 	}
833bfe34e2SMichael Pfeiffer }
843bfe34e2SMichael Pfeiffer 
85568716beSWim van der Meer 
86568716beSWim van der Meer bool
87fefd3ba5SMichael Pfeiffer PCL6Driver::EndDocument(bool)
883bfe34e2SMichael Pfeiffer {
893bfe34e2SMichael Pfeiffer 	try {
90568716beSWim van der Meer 		if (fHalftone)
91d2c03b1bSMichael Pfeiffer 			delete fHalftone;
92fefd3ba5SMichael Pfeiffer 		_JobEnd();
933bfe34e2SMichael Pfeiffer 		return true;
943bfe34e2SMichael Pfeiffer 	}
953bfe34e2SMichael Pfeiffer 	catch (TransportException& err) {
963bfe34e2SMichael Pfeiffer 		return false;
973bfe34e2SMichael Pfeiffer 	}
983bfe34e2SMichael Pfeiffer }
993bfe34e2SMichael Pfeiffer 
100568716beSWim van der Meer 
101568716beSWim van der Meer bool
102fefd3ba5SMichael Pfeiffer PCL6Driver::NextBand(BBitmap* bitmap, BPoint* offset)
1033bfe34e2SMichael Pfeiffer {
1043bfe34e2SMichael Pfeiffer 	DBGMSG(("> nextBand\n"));
1053bfe34e2SMichael Pfeiffer 
1063bfe34e2SMichael Pfeiffer 	try {
1073bfe34e2SMichael Pfeiffer 		int y = (int)offset->y;
1083bfe34e2SMichael Pfeiffer 
1092e86189fSMichael Pfeiffer 		PCL6Rasterizer* rasterizer;
110fefd3ba5SMichael Pfeiffer 		if (_UseColorMode()) {
1112e86189fSMichael Pfeiffer 			#if COLOR_DEPTH == 8
1122e86189fSMichael Pfeiffer 				rasterizer = new ColorRGBRasterizer(fHalftone);
1132e86189fSMichael Pfeiffer 			#elif COLOR_DEPTH == 1
1142e86189fSMichael Pfeiffer 				rasterizer = new ColorRasterizer(fHalftone);
1152e86189fSMichael Pfeiffer 			#else
1162e86189fSMichael Pfeiffer 				#error COLOR_DEPTH must be either 1 or 8!
1172e86189fSMichael Pfeiffer 			#endif
118568716beSWim van der Meer 		} else
1192e86189fSMichael Pfeiffer 			rasterizer = new MonochromeRasterizer(fHalftone);
120568716beSWim van der Meer 
1212e86189fSMichael Pfeiffer 		auto_ptr<Rasterizer> _rasterizer(rasterizer);
122568716beSWim van der Meer 		bool valid = rasterizer->SetBitmap((int)offset->x, (int)offset->y,
123fefd3ba5SMichael Pfeiffer 			bitmap, GetPageHeight());
12491c89ca3SMichael Pfeiffer 
1252e86189fSMichael Pfeiffer 		if (valid) {
1262e86189fSMichael Pfeiffer 			rasterizer->InitializeBuffer();
12791c89ca3SMichael Pfeiffer 
1282e86189fSMichael Pfeiffer 			// Use compressor to calculate delta row size
1292e86189fSMichael Pfeiffer 			DeltaRowCompressor* deltaRowCompressor = NULL;
130fefd3ba5SMichael Pfeiffer 			if (_SupportsDeltaRowCompression()) {
131568716beSWim van der Meer 				deltaRowCompressor =
132568716beSWim van der Meer 					new DeltaRowCompressor(rasterizer->GetOutRowSize(), 0);
1332e86189fSMichael Pfeiffer 				if (deltaRowCompressor->InitCheck() != B_OK) {
1342e86189fSMichael Pfeiffer 					delete deltaRowCompressor;
135dcab4343SMichael Pfeiffer 					return false;
136dcab4343SMichael Pfeiffer 				}
1372e86189fSMichael Pfeiffer 			}
1382e86189fSMichael Pfeiffer 			auto_ptr<DeltaRowCompressor>_deltaRowCompressor(deltaRowCompressor);
139dcab4343SMichael Pfeiffer 			int deltaRowSize = 0;
1403bfe34e2SMichael Pfeiffer 
1412e86189fSMichael Pfeiffer 			// remember position
1422e86189fSMichael Pfeiffer 			int xPage = rasterizer->GetX();
1432e86189fSMichael Pfeiffer 			int yPage = rasterizer->GetY();
1443bfe34e2SMichael Pfeiffer 
1452e86189fSMichael Pfeiffer 			while (rasterizer->HasNextLine()) {
146568716beSWim van der Meer 				const uchar* rowBuffer =
147568716beSWim van der Meer 					static_cast<const uchar*>(rasterizer->RasterizeNextLine());
1482e86189fSMichael Pfeiffer 
1492e86189fSMichael Pfeiffer 				if (deltaRowCompressor != NULL) {
150568716beSWim van der Meer 					int size =
151568716beSWim van der Meer 						deltaRowCompressor->CalculateSize(rowBuffer, true);
152568716beSWim van der Meer 					deltaRowSize += size + 2;
153568716beSWim van der Meer 						// two bytes for the row byte count
154dcab4343SMichael Pfeiffer 				}
1553bfe34e2SMichael Pfeiffer 			}
1563bfe34e2SMichael Pfeiffer 
1572e86189fSMichael Pfeiffer 			y = rasterizer->GetY();
1583bfe34e2SMichael Pfeiffer 
1592e86189fSMichael Pfeiffer 			uchar* outBuffer = rasterizer->GetOutBuffer();
1602e86189fSMichael Pfeiffer 			int outBufferSize = rasterizer->GetOutBufferSize();
1612e86189fSMichael Pfeiffer 			int outRowSize = rasterizer->GetOutRowSize();
1622e86189fSMichael Pfeiffer 			int width = rasterizer->GetWidth();
1632e86189fSMichael Pfeiffer 			int height = rasterizer->GetHeight();
164fefd3ba5SMichael Pfeiffer 			_WriteBitmap(outBuffer, outBufferSize, outRowSize, xPage, yPage,
165568716beSWim van der Meer 				width, height, deltaRowSize);
1663bfe34e2SMichael Pfeiffer 		}
1673bfe34e2SMichael Pfeiffer 
168fefd3ba5SMichael Pfeiffer 		if (y >= GetPageHeight()) {
1693bfe34e2SMichael Pfeiffer 			offset->x = -1.0;
1703bfe34e2SMichael Pfeiffer 			offset->y = -1.0;
1713bfe34e2SMichael Pfeiffer 		} else {
1722e86189fSMichael Pfeiffer 			offset->y += bitmap->Bounds().IntegerHeight()+1;
1733bfe34e2SMichael Pfeiffer 		}
1743bfe34e2SMichael Pfeiffer 
1753bfe34e2SMichael Pfeiffer 		return true;
1763bfe34e2SMichael Pfeiffer 	}
1773bfe34e2SMichael Pfeiffer 	catch (TransportException& err) {
178*4410ee12SMichael Pfeiffer 		BAlert* alert = new BAlert("", err.What(), "OK");
1793bfe34e2SMichael Pfeiffer 		alert->Go();
1803bfe34e2SMichael Pfeiffer 		return false;
1813bfe34e2SMichael Pfeiffer 	}
1823bfe34e2SMichael Pfeiffer }
1833bfe34e2SMichael Pfeiffer 
184568716beSWim van der Meer 
185568716beSWim van der Meer void
186fefd3ba5SMichael Pfeiffer PCL6Driver::_WriteBitmap(const uchar* buffer, int outSize, int rowSize, int x,
187568716beSWim van der Meer 	int y, int width, int height, int deltaRowSize)
188dcab4343SMichael Pfeiffer {
189dcab4343SMichael Pfeiffer 	// choose the best compression method
190b1a3ccb8SMichael Pfeiffer 	PCL6Writer::Compression compressionMethod = PCL6Writer::kNoCompression;
191dcab4343SMichael Pfeiffer 	int dataSize = outSize;
192dcab4343SMichael Pfeiffer 
193dcab4343SMichael Pfeiffer #if ENABLE_DELTA_ROW_COMPRESSION
194fefd3ba5SMichael Pfeiffer 	if (_SupportsDeltaRowCompression() && deltaRowSize < dataSize) {
195b1a3ccb8SMichael Pfeiffer 		compressionMethod = PCL6Writer::kDeltaRowCompression;
196dcab4343SMichael Pfeiffer 		dataSize = deltaRowSize;
197dcab4343SMichael Pfeiffer 	}
198dcab4343SMichael Pfeiffer #endif
199dcab4343SMichael Pfeiffer 
200dcab4343SMichael Pfeiffer #if ENABLE_RLE_COMPRESSION
201fefd3ba5SMichael Pfeiffer 	if (_SupportsRLECompression()) {
2025fc71589SMichael Pfeiffer 		int rleSize = pack_bits_size(buffer, outSize);
2035fc71589SMichael Pfeiffer 		if (rleSize < dataSize) {
204b1a3ccb8SMichael Pfeiffer 			compressionMethod = PCL6Writer::kRLECompression;
2055fc71589SMichael Pfeiffer 			dataSize = rleSize;
206dcab4343SMichael Pfeiffer 		}
207fcccd8b7SMichael Pfeiffer 	}
208dcab4343SMichael Pfeiffer #endif
209dcab4343SMichael Pfeiffer 
210dcab4343SMichael Pfeiffer 	// write bitmap
211fefd3ba5SMichael Pfeiffer 	_Move(x, y);
212dcab4343SMichael Pfeiffer 
213fefd3ba5SMichael Pfeiffer 	_StartRasterGraphics(x, y, width, height, compressionMethod);
214dcab4343SMichael Pfeiffer 
215fefd3ba5SMichael Pfeiffer 	_RasterGraphics(buffer, outSize, dataSize, rowSize, height,
216568716beSWim van der Meer 		compressionMethod);
217dcab4343SMichael Pfeiffer 
218fefd3ba5SMichael Pfeiffer 	_EndRasterGraphics();
219dcab4343SMichael Pfeiffer 
2205fc71589SMichael Pfeiffer #if DISPLAY_COMPRESSION_STATISTICS
221dcab4343SMichael Pfeiffer 	fprintf(stderr, "Out Size       %d %2.2f\n", (int)outSize, 100.0);
222dcab4343SMichael Pfeiffer #if ENABLE_RLE_COMPRESSION
223568716beSWim van der Meer 	fprintf(stderr, "RLE Size       %d %2.2f\n", (int)rleSize,
224568716beSWim van der Meer 		100.0 * rleSize / outSize);
225dcab4343SMichael Pfeiffer #endif
226dcab4343SMichael Pfeiffer #if ENABLE_DELTA_ROW_COMPRESSION
227568716beSWim van der Meer 	fprintf(stderr, "Delta Row Size %d %2.2f\n", (int)deltaRowSize,
228568716beSWim van der Meer 		100.0 * deltaRowSize / outSize);
229dcab4343SMichael Pfeiffer #endif
230568716beSWim van der Meer 	fprintf(stderr, "Data Size      %d %2.2f\n", (int)dataSize,
231568716beSWim van der Meer 		100.0 * dataSize / outSize);
232dcab4343SMichael Pfeiffer #endif
233dcab4343SMichael Pfeiffer }
234dcab4343SMichael Pfeiffer 
235dcab4343SMichael Pfeiffer 
236568716beSWim van der Meer void
237fefd3ba5SMichael Pfeiffer PCL6Driver::_JobStart()
2383bfe34e2SMichael Pfeiffer {
2393bfe34e2SMichael Pfeiffer 	// PCL6 begin
240b1a3ccb8SMichael Pfeiffer 	fWriter = new PCL6Writer(this);
241568716beSWim van der Meer 	PCL6Writer::ProtocolClass pc =
242fefd3ba5SMichael Pfeiffer 		(PCL6Writer::ProtocolClass)GetProtocolClass();
243*4410ee12SMichael Pfeiffer 	fWriter->PJLHeader(pc, GetJobData()->GetXres(),
244fefd3ba5SMichael Pfeiffer 		"Copyright (c) 2003 - 2010 Haiku");
245*4410ee12SMichael Pfeiffer 	fWriter->BeginSession(GetJobData()->GetXres(), GetJobData()->GetYres(),
246568716beSWim van der Meer 		PCL6Writer::kInch, PCL6Writer::kBackChAndErrPage);
247b1a3ccb8SMichael Pfeiffer 	fWriter->OpenDataSource();
248b1a3ccb8SMichael Pfeiffer 	fMediaSide = PCL6Writer::kFrontMediaSide;
2493bfe34e2SMichael Pfeiffer }
2503bfe34e2SMichael Pfeiffer 
251568716beSWim van der Meer 
252568716beSWim van der Meer bool
253fefd3ba5SMichael Pfeiffer PCL6Driver::StartPage(int)
2548fb205f2SMichael Pfeiffer {
255b1a3ccb8SMichael Pfeiffer 	PCL6Writer::Orientation orientation = PCL6Writer::kPortrait;
256*4410ee12SMichael Pfeiffer 	if (GetJobData()->GetOrientation() == JobData::kLandscape) {
257b1a3ccb8SMichael Pfeiffer 		orientation = PCL6Writer::kLandscape;
25882f24520SMichael Pfeiffer 	}
259dcab4343SMichael Pfeiffer 
260568716beSWim van der Meer 	PCL6Writer::MediaSize mediaSize =
261*4410ee12SMichael Pfeiffer 		_MediaSize(GetJobData()->GetPaper());
262568716beSWim van der Meer 	PCL6Writer::MediaSource mediaSource =
263*4410ee12SMichael Pfeiffer 		_MediaSource(GetJobData()->GetPaperSource());
264*4410ee12SMichael Pfeiffer 	if (GetJobData()->GetPrintStyle() == JobData::kSimplex) {
265b1a3ccb8SMichael Pfeiffer 		fWriter->BeginPage(orientation, mediaSize, mediaSource);
266*4410ee12SMichael Pfeiffer 	} else if (GetJobData()->GetPrintStyle() == JobData::kDuplex) {
267eb856078SMichael Pfeiffer 		// TODO move duplex binding option to UI
268b1a3ccb8SMichael Pfeiffer 		fWriter->BeginPage(orientation, mediaSize, mediaSource,
269eb856078SMichael Pfeiffer 			PCL6Writer::kDuplexVerticalBinding, fMediaSide);
270dcab4343SMichael Pfeiffer 
271568716beSWim van der Meer 		if (fMediaSide == PCL6Writer::kFrontMediaSide)
272b1a3ccb8SMichael Pfeiffer 			fMediaSide = PCL6Writer::kBackMediaSide;
273568716beSWim van der Meer 		else
274b1a3ccb8SMichael Pfeiffer 			fMediaSide = PCL6Writer::kFrontMediaSide;
275568716beSWim van der Meer 	} else
276dcab4343SMichael Pfeiffer 		return false;
277dcab4343SMichael Pfeiffer 
2788fb205f2SMichael Pfeiffer 	// PageOrigin from Windows NT printer driver
279*4410ee12SMichael Pfeiffer 	int x = 142 * GetJobData()->GetXres() / 600;
280*4410ee12SMichael Pfeiffer 	int y = 100 * GetJobData()->GetYres() / 600;
281b1a3ccb8SMichael Pfeiffer 	fWriter->SetPageOrigin(x, y);
282fefd3ba5SMichael Pfeiffer 	fWriter->SetColorSpace(_UseColorMode() ? PCL6Writer::kRGB
283568716beSWim van der Meer 		: PCL6Writer::kGray);
284b1a3ccb8SMichael Pfeiffer 	fWriter->SetPaintTxMode(PCL6Writer::kOpaque);
285b1a3ccb8SMichael Pfeiffer 	fWriter->SetSourceTxMode(PCL6Writer::kOpaque);
286b1a3ccb8SMichael Pfeiffer 	fWriter->SetROP(204);
2878fb205f2SMichael Pfeiffer 	return true;
2888fb205f2SMichael Pfeiffer }
2898fb205f2SMichael Pfeiffer 
290568716beSWim van der Meer 
291568716beSWim van der Meer void
292fefd3ba5SMichael Pfeiffer PCL6Driver::_StartRasterGraphics(int x, int y, int width, int height,
293568716beSWim van der Meer 	PCL6Writer::Compression compressionMethod)
2943bfe34e2SMichael Pfeiffer {
2952e86189fSMichael Pfeiffer 	PCL6Writer::ColorDepth colorDepth;
296fefd3ba5SMichael Pfeiffer 	if (_UseColorMode()) {
2972e86189fSMichael Pfeiffer 		#if COLOR_DEPTH == 8
2982e86189fSMichael Pfeiffer 			colorDepth = PCL6Writer::k8Bit;
2992e86189fSMichael Pfeiffer 		#elif COLOR_DEPTH == 1
3002e86189fSMichael Pfeiffer 			colorDepth = PCL6Writer::k1Bit;
3012e86189fSMichael Pfeiffer 		#else
3022e86189fSMichael Pfeiffer 			#error COLOR_DEPTH must be either 1 or 8!
3032e86189fSMichael Pfeiffer 		#endif
304568716beSWim van der Meer 	} else
3052e86189fSMichael Pfeiffer 		colorDepth = PCL6Writer::k1Bit;
306568716beSWim van der Meer 
307568716beSWim van der Meer 	fWriter->BeginImage(PCL6Writer::kDirectPixel, colorDepth, width, height,
308568716beSWim van der Meer 		width, height);
309b1a3ccb8SMichael Pfeiffer 	fWriter->ReadImage(compressionMethod, 0, height);
3103bfe34e2SMichael Pfeiffer }
3113bfe34e2SMichael Pfeiffer 
312568716beSWim van der Meer 
313568716beSWim van der Meer void
314fefd3ba5SMichael Pfeiffer PCL6Driver::_EndRasterGraphics()
3153bfe34e2SMichael Pfeiffer {
316b1a3ccb8SMichael Pfeiffer 	fWriter->EndImage();
3173bfe34e2SMichael Pfeiffer }
3183bfe34e2SMichael Pfeiffer 
319568716beSWim van der Meer 
320568716beSWim van der Meer void
321fefd3ba5SMichael Pfeiffer PCL6Driver::_RasterGraphics(const uchar* buffer, int bufferSize, int dataSize,
322568716beSWim van der Meer 	int rowSize, int height, int compressionMethod)
3233bfe34e2SMichael Pfeiffer {
324dcab4343SMichael Pfeiffer 	// write bitmap byte size
325b1a3ccb8SMichael Pfeiffer 	fWriter->EmbeddedDataPrefix32(dataSize);
326dcab4343SMichael Pfeiffer 
327dcab4343SMichael Pfeiffer 	// write data
328b1a3ccb8SMichael Pfeiffer 	if (compressionMethod == PCL6Writer::kRLECompression) {
329dcab4343SMichael Pfeiffer 		// use RLE compression
3305fc71589SMichael Pfeiffer 		uchar* outBuffer = new uchar[dataSize];
3315fc71589SMichael Pfeiffer 		pack_bits(outBuffer, buffer, bufferSize);
3325fc71589SMichael Pfeiffer 		fWriter->Append(outBuffer, dataSize);
333c9e62886SStefano Ceccherini 		delete[] outBuffer;
334b1a3ccb8SMichael Pfeiffer 		return;
335b1a3ccb8SMichael Pfeiffer 	} else if (compressionMethod == PCL6Writer::kDeltaRowCompression) {
336dcab4343SMichael Pfeiffer 		// use delta row compression
337b1a3ccb8SMichael Pfeiffer 		DeltaRowStreamCompressor compressor(rowSize, 0, fWriter);
338dcab4343SMichael Pfeiffer 		if (compressor.InitCheck() != B_OK) {
339dcab4343SMichael Pfeiffer 			return;
3403bfe34e2SMichael Pfeiffer 		}
341dcab4343SMichael Pfeiffer 
342b1a3ccb8SMichael Pfeiffer 		const uint8* row = buffer;
343dcab4343SMichael Pfeiffer 		for (int i = 0; i < height; i ++) {
344dcab4343SMichael Pfeiffer 			// write row byte count
345b1a3ccb8SMichael Pfeiffer 			int32 size = compressor.CalculateSize(row);
346b1a3ccb8SMichael Pfeiffer 			fWriter->Append((uint16)size);
347dcab4343SMichael Pfeiffer 
348dcab4343SMichael Pfeiffer 			if (size > 0) {
349dcab4343SMichael Pfeiffer 				// write delta row
350dcab4343SMichael Pfeiffer 				compressor.Compress(row);
351dcab4343SMichael Pfeiffer 			}
352dcab4343SMichael Pfeiffer 
353dcab4343SMichael Pfeiffer 			row += rowSize;
354dcab4343SMichael Pfeiffer 		}
355dcab4343SMichael Pfeiffer 	} else {
356dcab4343SMichael Pfeiffer 		// write raw data
357b1a3ccb8SMichael Pfeiffer 		fWriter->Append(buffer, bufferSize);
358dcab4343SMichael Pfeiffer 	}
3593bfe34e2SMichael Pfeiffer }
3603bfe34e2SMichael Pfeiffer 
361568716beSWim van der Meer 
362568716beSWim van der Meer bool
363fefd3ba5SMichael Pfeiffer PCL6Driver::EndPage(int)
3648fb205f2SMichael Pfeiffer {
3658fb205f2SMichael Pfeiffer 	try {
366*4410ee12SMichael Pfeiffer 		fWriter->EndPage(GetJobData()->GetCopies());
3678fb205f2SMichael Pfeiffer 		return true;
3688fb205f2SMichael Pfeiffer 	}
3698fb205f2SMichael Pfeiffer 	catch (TransportException& err) {
3708fb205f2SMichael Pfeiffer 		return false;
3718fb205f2SMichael Pfeiffer 	}
3728fb205f2SMichael Pfeiffer }
3738fb205f2SMichael Pfeiffer 
374568716beSWim van der Meer 
375568716beSWim van der Meer void
376fefd3ba5SMichael Pfeiffer PCL6Driver::_JobEnd()
3773bfe34e2SMichael Pfeiffer {
378b1a3ccb8SMichael Pfeiffer 	fWriter->CloseDataSource();
379b1a3ccb8SMichael Pfeiffer 	fWriter->EndSession();
3802e86189fSMichael Pfeiffer 	fWriter->PJLFooter();
381b1a3ccb8SMichael Pfeiffer 	fWriter->Flush();
382b1a3ccb8SMichael Pfeiffer 	delete fWriter;
383b1a3ccb8SMichael Pfeiffer 	fWriter = NULL;
3843bfe34e2SMichael Pfeiffer }
3853bfe34e2SMichael Pfeiffer 
386568716beSWim van der Meer 
387568716beSWim van der Meer void
388fefd3ba5SMichael Pfeiffer PCL6Driver::_Move(int x, int y)
3893bfe34e2SMichael Pfeiffer {
390b1a3ccb8SMichael Pfeiffer 	fWriter->SetCursor(x, y);
3913bfe34e2SMichael Pfeiffer }
3923bfe34e2SMichael Pfeiffer 
393568716beSWim van der Meer 
3942e86189fSMichael Pfeiffer bool
395fefd3ba5SMichael Pfeiffer PCL6Driver::_SupportsRLECompression()
396fcccd8b7SMichael Pfeiffer {
397*4410ee12SMichael Pfeiffer 	return GetJobData()->GetColor() != JobData::kColorCompressionDisabled;
398fcccd8b7SMichael Pfeiffer }
399fcccd8b7SMichael Pfeiffer 
400568716beSWim van der Meer 
401fcccd8b7SMichael Pfeiffer bool
402fefd3ba5SMichael Pfeiffer PCL6Driver::_SupportsDeltaRowCompression()
4032e86189fSMichael Pfeiffer {
404fefd3ba5SMichael Pfeiffer 	return GetProtocolClass() >= PCL6Writer::kProtocolClass2_1
405*4410ee12SMichael Pfeiffer 		&& GetJobData()->GetColor() != JobData::kColorCompressionDisabled;
406fcccd8b7SMichael Pfeiffer }
407fcccd8b7SMichael Pfeiffer 
408568716beSWim van der Meer 
409fcccd8b7SMichael Pfeiffer bool
410fefd3ba5SMichael Pfeiffer PCL6Driver::_UseColorMode()
411fcccd8b7SMichael Pfeiffer {
412*4410ee12SMichael Pfeiffer 	return GetJobData()->GetColor() != JobData::kMonochrome;
4132e86189fSMichael Pfeiffer }
4142e86189fSMichael Pfeiffer 
415568716beSWim van der Meer 
416568716beSWim van der Meer PCL6Writer::MediaSize
417fefd3ba5SMichael Pfeiffer PCL6Driver::_MediaSize(JobData::Paper paper)
4183bfe34e2SMichael Pfeiffer {
4193bfe34e2SMichael Pfeiffer 	switch (paper) {
420568716beSWim van der Meer 		case JobData::kLetter:
421568716beSWim van der Meer 			return PCL6Writer::kLetterPaper;
422568716beSWim van der Meer 		case JobData::kLegal:
423568716beSWim van der Meer 			return PCL6Writer::kLegalPaper;
424568716beSWim van der Meer 		case JobData::kA4:
425568716beSWim van der Meer 			return PCL6Writer::kA4Paper;
426568716beSWim van der Meer 		case JobData::kExecutive:
427568716beSWim van der Meer 			return PCL6Writer::kExecPaper;
428568716beSWim van der Meer 		case JobData::kLedger:
429568716beSWim van der Meer 			return PCL6Writer::kLedgerPaper;
430568716beSWim van der Meer 		case JobData::kA3:
431568716beSWim van der Meer 			return PCL6Writer::kA3Paper;
432568716beSWim van der Meer 		case JobData::kB5:
433568716beSWim van der Meer 			return PCL6Writer::kB5Paper;
4342e86189fSMichael Pfeiffer 		case JobData::kJapanesePostcard:
4352e86189fSMichael Pfeiffer 			return PCL6Writer::kJPostcard;
436568716beSWim van der Meer 		case JobData::kA5:
437568716beSWim van der Meer 			return PCL6Writer::kA5Paper;
438568716beSWim van der Meer 		case JobData::kB4:
439568716beSWim van der Meer 			return PCL6Writer::kJB4Paper;
4403bfe34e2SMichael Pfeiffer /*
441b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kCOM10Envelope;
442b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kMonarchEnvelope;
443b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kC5Envelope;
444b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kDLEnvelope;
445b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kJB4Paper;
446b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kJB5Paper;
447b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kB5Envelope;
448b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kJPostcard;
449b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kJDoublePostcard;
450b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kA5Paper;
451b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kA6Paper;
452b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kJB6Paper;
453b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kJIS8KPaper;
454b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kJIS16KPaper;
455b1a3ccb8SMichael Pfeiffer 		case : return PCL6Writer::kJISExecPaper;
4563bfe34e2SMichael Pfeiffer */
457d2c03b1bSMichael Pfeiffer 		default:
458b1a3ccb8SMichael Pfeiffer 			return PCL6Writer::kLegalPaper;
4593bfe34e2SMichael Pfeiffer 	}
4603bfe34e2SMichael Pfeiffer }
4613bfe34e2SMichael Pfeiffer 
462568716beSWim van der Meer 
463568716beSWim van der Meer PCL6Writer::MediaSource
464fefd3ba5SMichael Pfeiffer PCL6Driver::_MediaSource(JobData::PaperSource source)
465dcab4343SMichael Pfeiffer {
466dcab4343SMichael Pfeiffer 	switch (source) {
467568716beSWim van der Meer 		case JobData::kAuto:
468568716beSWim van der Meer 			return PCL6Writer::kAutoSelect;
469568716beSWim van der Meer 		case JobData::kCassette1:
470568716beSWim van der Meer 			return PCL6Writer::kDefaultSource;
471568716beSWim van der Meer 		case JobData::kCassette2:
472568716beSWim van der Meer 			return PCL6Writer::kEnvelopeTray;
473568716beSWim van der Meer 		case JobData::kLower:
474568716beSWim van der Meer 			return PCL6Writer::kLowerCassette;
475568716beSWim van der Meer 		case JobData::kUpper:
476568716beSWim van der Meer 			return PCL6Writer::kUpperCassette;
477568716beSWim van der Meer 		case JobData::kMiddle:
478568716beSWim van der Meer 			return PCL6Writer::kThirdCassette;
479568716beSWim van der Meer 		case JobData::kManual:
480568716beSWim van der Meer 			return PCL6Writer::kManualFeed;
481568716beSWim van der Meer 		case JobData::kCassette3:
482568716beSWim van der Meer 			return PCL6Writer::kMultiPurposeTray;
483dcab4343SMichael Pfeiffer 		default:
484b1a3ccb8SMichael Pfeiffer 			return PCL6Writer::kAutoSelect;
485dcab4343SMichael Pfeiffer 	}
486dcab4343SMichael Pfeiffer }
487