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