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