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