xref: /haiku/src/add-ons/print/drivers/canon_lips/lips4/Lips4.cpp (revision 1c09002cbee8e797a0f8bbfc5678dfadd39ee1a7)
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->Go();
204 				return false;
205 			} else {
206 				compression_method = 0;
207 				buffer = in_buffer;
208 				compressed_size = in_size;
209 			}
210 
211 			DBGMSG(("compressed_size = %d\n", compressed_size));
212 			DBGMSG(("widthByte = %d\n", widthByte));
213 			DBGMSG(("height = %d\n", height));
214 			DBGMSG(("compression_method = %d\n", compression_method));
215 
216 			_RasterGraphics(
217 				compressed_size,	// size,
218 				widthByte,			// widthByte
219 				height,				// height,
220 				compression_method,
221 				buffer);
222 
223 		} else
224 			DBGMSG(("band bitmap is clean.\n"));
225 
226 		if (y >= page_height) {
227 			offset->x = -1.0;
228 			offset->y = -1.0;
229 		} else
230 			offset->y += height;
231 
232 		DBGMSG(("< nextBand\n"));
233 		return true;
234 	}
235 	catch (TransportException& err) {
236 		BAlert* alert = new BAlert("", err.What(), "OK");
237 		alert->Go();
238 		return false;
239 	}
240 }
241 
242 
243 void
244 LIPS4Driver::_BeginTextMode()
245 {
246 	WriteSpoolString("\033%%@");
247 }
248 
249 
250 void
251 LIPS4Driver::_JobStart()
252 {
253 	WriteSpoolString("\033P41;%d;1J\033\\", GetJobData()->GetXres());
254 }
255 
256 
257 void
258 LIPS4Driver::_ColorModeDeclaration()
259 {
260 //	if (color)
261 //		WriteSpoolString("\033[1\"p");
262 //	else
263 		WriteSpoolString("\033[0\"p");
264 }
265 
266 
267 void
268 LIPS4Driver::_SoftReset()
269 {
270 	WriteSpoolString("\033<");
271 }
272 
273 
274 void
275 LIPS4Driver::_SizeUnitMode()
276 {
277 	WriteSpoolString("\033[11h");
278 }
279 
280 
281 void
282 LIPS4Driver::_SelectSizeUnit()
283 {
284 	WriteSpoolString("\033[?7;%d I", GetJobData()->GetXres());
285 }
286 
287 
288 void
289 LIPS4Driver::_PaperFeedMode()
290 {
291 	// 0 auto
292 	// --------------
293 	// 1 MP tray
294 	// 2 lower
295 	// 3 lupper
296 	// --------------
297 	// 10 MP tray
298 	// 11 casette 1
299 	// 12 casette 2
300 	// 13 casette 3
301 	// 14 casette 4
302 	// 15 casette 5
303 	// 16 casette 6
304 	// 17 casette 7
305 
306 	int i;
307 
308 	switch (GetJobData()->GetPaperSource()) {
309 		case JobData::kManual:
310 			i = 10;
311 			break;
312 		case JobData::kUpper:
313 			i = 11;
314 			break;
315 		case JobData::kMiddle:
316 			i = 12;
317 			break;
318 		case JobData::kLower:
319 			i = 13;
320 			break;
321 		case JobData::kAuto:
322 		default:
323 			i = 0;
324 			break;
325 	}
326 
327 	WriteSpoolString("\033[%dq", i);
328 }
329 
330 
331 void
332 LIPS4Driver::_SelectPageFormat()
333 {
334 	int i;
335 
336 	switch (GetJobData()->GetPaper()) {
337 		case JobData::kA3:
338 			i = 12;
339 			break;
340 
341 		case JobData::kA4:
342 			i = 14;
343 			break;
344 
345 		case JobData::kA5:
346 			i = 16;
347 			break;
348 
349 		case JobData::kJapanesePostcard:
350 			i = 18;
351 			break;
352 
353 		case JobData::kB4:
354 			i = 24;
355 			break;
356 
357 		case JobData::kB5:
358 			i = 26;
359 			break;
360 
361 		case JobData::kLetter:
362 			i = 30;
363 			break;
364 
365 		case JobData::kLegal:
366 			i = 32;
367 			break;
368 
369 		case JobData::kExecutive:
370 			i = 40;
371 			break;
372 
373 		case JobData::kJEnvYou4:
374 			i = 50;
375 			break;
376 
377 		case JobData::kUser:
378 			i = 90;
379 			break;
380 
381 		default:
382 			i = 0;
383 			break;
384 	}
385 
386 	if (JobData::kLandscape == GetJobData()->GetOrientation())
387 		i++;
388 
389 	WriteSpoolString("\033[%d;;p", i);
390 }
391 
392 
393 void
394 LIPS4Driver::_DisableAutoFF()
395 {
396 	WriteSpoolString("\033[?2h");
397 }
398 
399 
400 void
401 LIPS4Driver::_SetNumberOfCopies()
402 {
403 	WriteSpoolString("\033[%ldv", GetJobData()->GetCopies());
404 }
405 
406 
407 void
408 LIPS4Driver::_SidePrintingControl()
409 {
410 	if (GetJobData()->GetPrintStyle() == JobData::kSimplex)
411 		WriteSpoolString("\033[0#x");
412 	else
413 		WriteSpoolString("\033[2;0#x");
414 }
415 
416 
417 void
418 LIPS4Driver::_SetBindingMargin()
419 {
420 	if (GetJobData()->GetPrintStyle() == JobData::kDuplex) {
421 		int i;
422 //		switch (job_data()->binding_location()) {
423 //		case kLongEdgeLeft:
424 			i = 0;
425 //			break;
426 //		case kLongEdgeRight:
427 //			i = 1;
428 //			break;
429 //		case kShortEdgeTop:
430 //			i = 2;
431 //			break;
432 //		case kShortEdgeBottom:
433 //			i = 3;
434 //			break;
435 //		}
436 		WriteSpoolString("\033[%d;0#w", i);
437 	}
438 }
439 
440 
441 void
442 LIPS4Driver::_MemorizedPosition()
443 {
444 	WriteSpoolString("\033[0;1;0x");
445 }
446 
447 
448 void
449 LIPS4Driver::_MoveAbsoluteHorizontal(int x)
450 {
451 	WriteSpoolString("\033[%ld`", x);
452 }
453 
454 
455 void
456 LIPS4Driver::_CarriageReturn()
457 {
458 	WriteSpoolChar('\x0d');
459 }
460 
461 
462 void
463 LIPS4Driver::_MoveDown(int dy)
464 {
465 	WriteSpoolString("\033[%lde", dy);
466 }
467 
468 
469 void
470 LIPS4Driver::_RasterGraphics(int compression_size, int widthbyte, int height,
471 	int compression_method, const uchar* buffer)
472 {
473 // 0  RAW
474 // 10 RLE
475 // 11 packbits
476 
477 	WriteSpoolString(
478 		"\033[%ld;%ld;%d;%ld;%ld.r",
479 		compression_size,
480 		widthbyte,
481 		GetJobData()->GetXres(),
482 		compression_method,
483 		height);
484 
485 	WriteSpoolData(buffer, compression_size);
486 }
487 
488 
489 void
490 LIPS4Driver::_FormFeed()
491 {
492 	WriteSpoolChar('\014');
493 }
494 
495 
496 void
497 LIPS4Driver::_JobEnd()
498 {
499 	WriteSpoolString("\033P0J\033\\");
500 }
501 
502 
503 void
504 LIPS4Driver::_Move(int x, int y)
505 {
506 	if (fCurrentX != x) {
507 		if (x) {
508 			_MoveAbsoluteHorizontal(x);
509 		} else {
510 			_CarriageReturn();
511 		}
512 		fCurrentX = x;
513 	}
514 	if (fCurrentY != y) {
515 		int dy = y - fCurrentY;
516 		_MoveDown(dy);
517 		fCurrentY = y;
518 	}
519 }
520