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