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