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