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