xref: /haiku/src/add-ons/print/drivers/canon_lips/lips4/Lips4.cpp (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
1 /*
2  * Lips4.cpp
3  * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
4  */
5 
6 #include <Alert.h>
7 #include <Bitmap.h>
8 #include <File.h>
9 #include <memory>
10 #include "Lips4.h"
11 #include "PackBits.h"
12 #include "JobData.h"
13 #include "PrinterData.h"
14 #include "Lips4Cap.h"
15 #include "Halftone.h"
16 #include "ValidRect.h"
17 #include "DbgMsg.h"
18 
19 #if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE))
20 using namespace std;
21 #else
22 #define std
23 #endif
24 
25 LIPS4Driver::LIPS4Driver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap)
26 	: GraphicsDriver(msg, printer_data, printer_cap)
27 {
28 	fHalftone = NULL;
29 }
30 
31 bool LIPS4Driver::startDoc()
32 {
33 	try {
34 		beginTextMode();
35 		jobStart();
36 		colorModeDeclaration();
37 		softReset();
38 		sizeUnitMode();
39 		selectSizeUnit();
40 		paperFeedMode();
41 		selectPageFormat();
42 		disableAutoFF();
43 		setNumberOfCopies();
44 		sidePrintingControl();
45 		setBindingMargin();
46 		fHalftone = new Halftone(getJobData()->getSurfaceType(), getJobData()->getGamma(), getJobData()->getInkDensity(), getJobData()->getDitherType());
47 		return true;
48 	}
49 	catch (TransportException &err) {
50 		return false;
51 	}
52 }
53 
54 bool LIPS4Driver::startPage(int)
55 {
56 	try {
57 		fCurrentX = 0;
58 		fCurrentY = 0;
59 		memorizedPosition();
60 		return true;
61 	}
62 	catch (TransportException &err) {
63 		return false;
64 	}
65 }
66 
67 bool LIPS4Driver::endPage(int)
68 {
69 	try {
70 		formFeed();
71 		return true;
72 	}
73 	catch (TransportException &err) {
74 		return false;
75 	}
76 }
77 
78 bool LIPS4Driver::endDoc(bool)
79 {
80 	try {
81 		if (fHalftone) {
82 			delete fHalftone;
83 		}
84 		jobEnd();
85 		return true;
86 	}
87 	catch (TransportException &err) {
88 		return false;
89 	}
90 }
91 
92 bool LIPS4Driver::nextBand(BBitmap *bitmap, BPoint *offset)
93 {
94 	DBGMSG(("> nextBand\n"));
95 
96 	try {
97 
98 		if (bitmap == NULL) {
99 			uchar dummy[1];
100 			dummy[0] =  '\0';
101 			rasterGraphics(1, 1, 1, 0, dummy);
102 			DBGMSG(("< next_band\n"));
103 			return true;
104 		}
105 
106 		BRect bounds = bitmap->Bounds();
107 
108 		RECT rc;
109 		rc.left   = (int)bounds.left;
110 		rc.top    = (int)bounds.top;
111 		rc.right  = (int)bounds.right;
112 		rc.bottom = (int)bounds.bottom;
113 
114 		int height = rc.bottom - rc.top + 1;
115 
116 		int x = (int)offset->x;
117 		int y = (int)offset->y;
118 
119 		int page_height = getPageHeight();
120 
121 		if (y + height > page_height) {
122 			height = page_height - y;
123 		}
124 
125 		rc.bottom = height - 1;
126 
127 		DBGMSG(("height = %d\n", height));
128 		DBGMSG(("x = %d\n", x));
129 		DBGMSG(("y = %d\n", y));
130 
131 		if (get_valid_rect(bitmap, &rc)) {
132 
133 			DBGMSG(("validate rect = %d, %d, %d, %d\n",
134 				rc.left, rc.top, rc.right, rc.bottom));
135 
136 			x = rc.left;
137 			y += rc.top;
138 
139 			int width     = rc.right - rc.left + 1;
140 			int widthByte = (width + 7) / 8;
141 			int height    = rc.bottom - rc.top + 1;
142 			int in_size   = widthByte * height;
143 			int out_size  = (in_size * 6 + 4) / 5;
144 			int delta     = bitmap->BytesPerRow();
145 
146 			DBGMSG(("width = %d\n", width));
147 			DBGMSG(("widthByte = %d\n", widthByte));
148 			DBGMSG(("height = %d\n", height));
149 			DBGMSG(("in_size = %d\n", in_size));
150 			DBGMSG(("out_size = %d\n", out_size));
151 			DBGMSG(("delta = %d\n", delta));
152 			DBGMSG(("fHalftone_engine->get_pixel_depth() = %d\n", fHalftone->getPixelDepth()));
153 
154 			uchar *ptr = (uchar *)bitmap->Bits()
155 						+ rc.top * delta
156 						+ (rc.left * fHalftone->getPixelDepth()) / 8;
157 
158 			int compression_method;
159 			int compressed_size;
160 			const uchar *buffer;
161 
162 			uchar *in_buffer  = new uchar[in_size];
163 			uchar *out_buffer = new uchar[out_size];
164 
165 			auto_ptr<uchar> _in_buffer (in_buffer);
166 			auto_ptr<uchar> _out_buffer(out_buffer);
167 
168 			uchar *ptr2 = (uchar *)in_buffer;
169 
170 			DBGMSG(("move\n"));
171 
172 			move(x, y);
173 
174 			for (int i = rc.top; i <= rc.bottom; i++) {
175 				fHalftone->dither(ptr2, ptr, x, y, width);
176 				ptr  += delta;
177 				ptr2 += widthByte;
178 				y++;
179 			}
180 
181 			DBGMSG(("PackBits\n"));
182 
183 			compressed_size = pack_bits(out_buffer, in_buffer, in_size);
184 
185 			if (compressed_size < in_size) {
186 				compression_method = 11;
187 				buffer = out_buffer;
188 			} else if (compressed_size > out_size) {
189 				BAlert *alert = new BAlert("memory overrun!!!", "warning", "OK");
190 				alert->Go();
191 				return false;
192 			} else {
193 				compression_method = 0;
194 				buffer = in_buffer;
195 				compressed_size = in_size;
196 			}
197 
198 			DBGMSG(("compressed_size = %d\n", compressed_size));
199 			DBGMSG(("widthByte = %d\n", widthByte));
200 			DBGMSG(("height = %d\n", height));
201 			DBGMSG(("compression_method = %d\n", compression_method));
202 
203 			rasterGraphics(
204 				compressed_size,	// size,
205 				widthByte,			// widthByte
206 				height,				// height,
207 				compression_method,
208 				buffer);
209 
210 		} else {
211 			DBGMSG(("band bitmap is clean.\n"));
212 		}
213 
214 		if (y >= page_height) {
215 			offset->x = -1.0;
216 			offset->y = -1.0;
217 		} else {
218 			offset->y += height;
219 		}
220 
221 		DBGMSG(("< nextBand\n"));
222 		return true;
223 	}
224 	catch (TransportException &err) {
225 		BAlert *alert = new BAlert("", err.what(), "OK");
226 		alert->Go();
227 		return false;
228 	}
229 }
230 
231 void LIPS4Driver::beginTextMode()
232 {
233 	writeSpoolString("\033%%@");
234 }
235 
236 void LIPS4Driver::jobStart()
237 {
238 	writeSpoolString("\033P41;%d;1J\033\\", getJobData()->getXres());
239 }
240 
241 void LIPS4Driver::colorModeDeclaration()
242 {
243 //	if (color)
244 //		writeSpoolString("\033[1\"p");
245 //	else
246 		writeSpoolString("\033[0\"p");
247 }
248 
249 void LIPS4Driver::softReset()
250 {
251 	writeSpoolString("\033<");
252 }
253 
254 void LIPS4Driver::sizeUnitMode()
255 {
256 	writeSpoolString("\033[11h");
257 }
258 
259 void LIPS4Driver::selectSizeUnit()
260 {
261 	writeSpoolString("\033[?7;%d I", getJobData()->getXres());
262 }
263 
264 void LIPS4Driver::paperFeedMode()
265 {
266 	// 0 auto
267 	// --------------
268 	// 1 MP tray
269 	// 2 lower
270 	// 3 lupper
271 	// --------------
272 	// 10 MP tray
273 	// 11 casette 1
274 	// 12 casette 2
275 	// 13 casette 3
276 	// 14 casette 4
277 	// 15 casette 5
278 	// 16 casette 6
279 	// 17 casette 7
280 
281 	int i;
282 
283 	switch (getJobData()->getPaperSource()) {
284 	case JobData::kManual:
285 		i = 10;
286 		break;
287 	case JobData::kUpper:
288 		i = 11;
289 		break;
290 	case JobData::kMiddle:
291 		i = 12;
292 		break;
293 	case JobData::kLower:
294 		i = 13;
295 		break;
296 	case JobData::kAuto:
297 	default:
298 		i = 0;
299 		break;
300 	}
301 
302 	writeSpoolString("\033[%dq", i);
303 }
304 
305 void LIPS4Driver::selectPageFormat()
306 {
307 	int i;
308 
309 	switch (getJobData()->getPaper()) {
310 	case JobData::kA3:
311 		i = 12;
312 		break;
313 
314 	case JobData::kA4:
315 		i = 14;
316 		break;
317 
318 	case JobData::kA5:
319 		i = 16;
320 		break;
321 
322 	case JobData::kJapanesePostcard:
323 		i = 18;
324 		break;
325 
326 	case JobData::kB4:
327 		i = 24;
328 		break;
329 
330 	case JobData::kB5:
331 		i = 26;
332 		break;
333 
334 	case JobData::kLetter:
335 		i = 30;
336 		break;
337 
338 	case JobData::kLegal:
339 		i = 32;
340 		break;
341 
342 	case JobData::kExecutive:
343 		i = 40;
344 		break;
345 
346 	case JobData::kJEnvYou4:
347 		i = 50;
348 		break;
349 
350 	case JobData::kUser:
351 		i = 90;
352 		break;
353 
354 	default:
355 		i = 0;
356 		break;
357 	}
358 
359 	if (JobData::kLandscape == getJobData()->getOrientation())
360 		i++;
361 
362 	writeSpoolString("\033[%d;;p", i);
363 }
364 
365 void LIPS4Driver::disableAutoFF()
366 {
367 	writeSpoolString("\033[?2h");
368 }
369 
370 void LIPS4Driver::setNumberOfCopies()
371 {
372 	writeSpoolString("\033[%ldv", getJobData()->getCopies());
373 }
374 
375 void LIPS4Driver::sidePrintingControl()
376 {
377 	if (getJobData()->getPrintStyle() == JobData::kSimplex)
378 		writeSpoolString("\033[0#x");
379 	else
380 		writeSpoolString("\033[2;0#x");
381 }
382 
383 void LIPS4Driver::setBindingMargin()
384 {
385 	if (getJobData()->getPrintStyle() == JobData::kDuplex) {
386 		int i;
387 //		switch (job_data()->binding_location()) {
388 //		case kLongEdgeLeft:
389 			i = 0;
390 //			break;
391 //		case kLongEdgeRight:
392 //			i = 1;
393 //			break;
394 //		case kShortEdgeTop:
395 //			i = 2;
396 //			break;
397 //		case kShortEdgeBottom:
398 //			i = 3;
399 //			break;
400 //		}
401 		writeSpoolString("\033[%d;0#w", i);
402 	}
403 }
404 
405 void LIPS4Driver::memorizedPosition()
406 {
407 	writeSpoolString("\033[0;1;0x");
408 }
409 
410 void LIPS4Driver::moveAbsoluteHorizontal(int x)
411 {
412 	writeSpoolString("\033[%ld`", x);
413 }
414 
415 void LIPS4Driver::carriageReturn()
416 {
417 	writeSpoolChar('\x0d');
418 }
419 
420 void LIPS4Driver::moveDown(int dy)
421 {
422 	writeSpoolString("\033[%lde", dy);
423 }
424 
425 void LIPS4Driver::rasterGraphics(
426 	int compression_size,
427 	int widthbyte,
428 	int height,
429 	int compression_method,
430 	const uchar *buffer)
431 {
432 // 0  RAW
433 // 10 RLE
434 // 11 packbits
435 
436 	writeSpoolString(
437 		"\033[%ld;%ld;%d;%ld;%ld.r",
438 		compression_size,
439 		widthbyte,
440 		getJobData()->getXres(),
441 		compression_method,
442 		height);
443 
444 	writeSpoolData(buffer, compression_size);
445 }
446 
447 void LIPS4Driver::formFeed()
448 {
449 	writeSpoolChar('\014');
450 }
451 
452 void LIPS4Driver::jobEnd()
453 {
454 	writeSpoolString("\033P0J\033\\");
455 }
456 
457 void LIPS4Driver::move(int x, int y)
458 {
459 	if (fCurrentX != x) {
460 		if (x) {
461 			moveAbsoluteHorizontal(x);
462 		} else {
463 			carriageReturn();
464 		}
465 		fCurrentX = x;
466 	}
467 	if (fCurrentY != y) {
468 		int dy = y - fCurrentY;
469 		moveDown(dy);
470 		fCurrentY = y;
471 	}
472 }
473