1 /* 2 * Lips3.cpp 3 * Copyright 1999-2000 Y.Takagi. All Rights Reserved. 4 */ 5 6 #include <Alert.h> 7 #include <Bitmap.h> 8 #include <File.h> 9 #include <memory> 10 #include "Lips3.h" 11 #include "UIDriver.h" 12 #include "Compress3.h" 13 #include "JobData.h" 14 #include "PrinterData.h" 15 #include "Lips3Cap.h" 16 #include "Halftone.h" 17 #include "ValidRect.h" 18 #include "DbgMsg.h" 19 20 #if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) 21 using namespace std; 22 #else 23 #define std 24 #endif 25 26 LIPS3Driver::LIPS3Driver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap) 27 : GraphicsDriver(msg, printer_data, printer_cap) 28 { 29 fHalftone = NULL; 30 } 31 32 bool LIPS3Driver::startDoc() 33 { 34 try { 35 beginTextMode(); 36 jobStart(); 37 softReset(); 38 sizeUnitMode(); 39 selectSizeUnit(); 40 selectPageFormat(); 41 paperFeedMode(); 42 disableAutoFF(); 43 setNumberOfCopies(); 44 fHalftone = new Halftone(getJobData()->getSurfaceType(), getJobData()->getGamma(), getJobData()->getInkDensity(), getJobData()->getDitherType()); 45 return true; 46 } 47 catch (TransportException &err) { 48 return false; 49 } 50 } 51 52 bool LIPS3Driver::startPage(int) 53 { 54 try { 55 fCurrentX = 0; 56 fCurrentY = 0; 57 memorizedPosition(); 58 return true; 59 } 60 catch (TransportException &err) { 61 return false; 62 } 63 } 64 65 bool LIPS3Driver::endPage(int) 66 { 67 try { 68 formFeed(); 69 return true; 70 } 71 catch (TransportException &err) { 72 return false; 73 } 74 } 75 76 bool LIPS3Driver::endDoc(bool) 77 { 78 try { 79 if (fHalftone) { 80 delete fHalftone; 81 } 82 jobEnd(); 83 return true; 84 } 85 catch (TransportException &err) { 86 return false; 87 } 88 } 89 90 bool LIPS3Driver::nextBand(BBitmap *bitmap, BPoint *offset) 91 { 92 DBGMSG(("> nextBand\n")); 93 94 try { 95 BRect bounds = bitmap->Bounds(); 96 97 RECT rc; 98 rc.left = (int)bounds.left; 99 rc.top = (int)bounds.top; 100 rc.right = (int)bounds.right; 101 rc.bottom = (int)bounds.bottom; 102 103 int height = rc.bottom - rc.top + 1; 104 105 int x = (int)offset->x; 106 int y = (int)offset->y; 107 108 int page_height = getPageHeight(); 109 110 if (y + height > page_height) { 111 height = page_height - y; 112 } 113 114 rc.bottom = height - 1; 115 116 DBGMSG(("height = %d\n", height)); 117 DBGMSG(("x = %d\n", x)); 118 DBGMSG(("y = %d\n", y)); 119 120 if (get_valid_rect(bitmap, &rc)) { 121 122 DBGMSG(("validate rect = %d, %d, %d, %d\n", 123 rc.left, rc.top, rc.right, rc.bottom)); 124 125 x = rc.left; 126 y += rc.top; 127 128 int width = rc.right - rc.left + 1; 129 int widthByte = (width + 7) / 8; /* byte boundary */ 130 int height = rc.bottom - rc.top + 1; 131 int in_size = widthByte * height; 132 int out_size = (in_size * 6 + 4) / 5; 133 int delta = bitmap->BytesPerRow(); 134 135 DBGMSG(("width = %d\n", width)); 136 DBGMSG(("widthByte = %d\n", widthByte)); 137 DBGMSG(("height = %d\n", height)); 138 DBGMSG(("in_size = %d\n", in_size)); 139 DBGMSG(("out_size = %d\n", out_size)); 140 DBGMSG(("delta = %d\n", delta)); 141 DBGMSG(("renderobj->get_pixel_depth() = %d\n", fHalftone->getPixelDepth())); 142 143 uchar *ptr = (uchar *)bitmap->Bits() 144 + rc.top * delta 145 + (rc.left * fHalftone->getPixelDepth()) / 8; 146 147 int compression_method; 148 int compressed_size; 149 const uchar *buffer; 150 151 uchar *in_buffer = new uchar[in_size]; 152 uchar *out_buffer = new uchar[out_size]; 153 154 auto_ptr<uchar> _in_buffer (in_buffer); 155 auto_ptr<uchar> _out_buffer(out_buffer); 156 157 uchar *ptr2 = (uchar *)in_buffer; 158 159 DBGMSG(("move\n")); 160 161 move(x, y); 162 163 for (int i = rc.top; i <= rc.bottom; i++) { 164 fHalftone->dither(ptr2, ptr, x, y, width); 165 ptr += delta; 166 ptr2 += widthByte; 167 y++; 168 } 169 170 compressed_size = compress3(out_buffer, in_buffer, in_size); 171 172 if (compressed_size < in_size) { 173 compression_method = 9; /* compress3 */ 174 buffer = out_buffer; 175 } else if (compressed_size > out_size) { 176 BAlert *alert = new BAlert("memory overrun!!!", "warning", "OK"); 177 alert->Go(); 178 return false; 179 } else { 180 compression_method = 0; 181 buffer = in_buffer; 182 compressed_size = in_size; 183 } 184 185 DBGMSG(("compressed_size = %d\n", compressed_size)); 186 DBGMSG(("widthByte = %d\n", widthByte)); 187 DBGMSG(("height = %d\n", height)); 188 DBGMSG(("compression_method = %d\n", compression_method)); 189 190 rasterGraphics( 191 compressed_size, // size, 192 widthByte, // widthByte 193 height, // height, 194 compression_method, 195 buffer); 196 197 } else { 198 DBGMSG(("band bitmap is clean.\n")); 199 } 200 201 if (y >= page_height) { 202 offset->x = -1.0; 203 offset->y = -1.0; 204 } else { 205 offset->y += height; 206 } 207 208 DBGMSG(("< nextBand\n")); 209 return true; 210 } 211 catch (TransportException &err) { 212 BAlert *alert = new BAlert("", err.what(), "OK"); 213 alert->Go(); 214 return false; 215 } 216 } 217 218 void LIPS3Driver::beginTextMode() 219 { 220 writeSpoolString("\033%%@"); 221 } 222 223 void LIPS3Driver::jobStart() 224 { 225 writeSpoolString("\033P31;300;1J\033\\"); 226 } 227 228 void LIPS3Driver::softReset() 229 { 230 writeSpoolString("\033<"); 231 } 232 233 void LIPS3Driver::sizeUnitMode() 234 { 235 writeSpoolString("\033[11h"); 236 } 237 238 void LIPS3Driver::selectSizeUnit() 239 { 240 writeSpoolString("\033[7 I"); 241 } 242 243 void LIPS3Driver::selectPageFormat() 244 { 245 int i; 246 int width = 0; 247 int height = 0; 248 249 switch (getJobData()->getPaper()) { 250 case JobData::kA3: 251 i = 12; 252 break; 253 254 case JobData::kA4: 255 i = 14; 256 break; 257 258 case JobData::kA5: 259 i = 16; 260 break; 261 262 case JobData::kJapanesePostcard: 263 i = 18; 264 break; 265 266 case JobData::kB4: 267 i = 24; 268 break; 269 270 case JobData::kB5: 271 i = 26; 272 break; 273 274 case JobData::kLetter: 275 i = 30; 276 break; 277 278 case JobData::kLegal: 279 i = 32; 280 break; 281 282 // case JobData::kExecutive: 283 // i = 40; 284 // break; 285 // 286 // case JobData::kJEnvYou4: 287 // i = 50; 288 // break; 289 // 290 // case JobData::kUser: 291 // i = 90; 292 // break; 293 // 294 default: 295 i = 80; 296 width = getJobData()->getPaperRect().IntegerWidth(); 297 height = getJobData()->getPaperRect().IntegerHeight(); 298 break; 299 } 300 301 if (JobData::kLandscape == getJobData()->getOrientation()) 302 i++; 303 304 if (i < 80) { 305 writeSpoolString("\033[%d;;p", i); 306 } else { 307 writeSpoolString("\033[%d;%d;%dp", i, height, width); 308 } 309 } 310 311 void LIPS3Driver::paperFeedMode() 312 { 313 // 0 auto 314 // -------------- 315 // 1 MP tray 316 // 2 lower 317 // 3 lupper 318 // -------------- 319 // 10 MP tray 320 // 11 casette 1 321 // 12 casette 2 322 // 13 casette 3 323 // 14 casette 4 324 // 15 casette 5 325 // 16 casette 6 326 // 17 casette 7 327 328 int i; 329 330 switch (getJobData()->getPaperSource()) { 331 case JobData::kManual: 332 i = 1; 333 break; 334 case JobData::kLower: 335 i = 2; 336 break; 337 case JobData::kUpper: 338 i = 3; 339 break; 340 case JobData::kAuto: 341 default: 342 i = 0; 343 break; 344 } 345 346 writeSpoolString("\033[%dq", i); 347 } 348 349 void LIPS3Driver::disableAutoFF() 350 { 351 writeSpoolString("\033[?2h"); 352 } 353 354 void LIPS3Driver::setNumberOfCopies() 355 { 356 writeSpoolString("\033[%ldv", getJobData()->getCopies()); 357 } 358 359 void LIPS3Driver::memorizedPosition() 360 { 361 writeSpoolString("\033[0;1;0x"); 362 } 363 364 void LIPS3Driver::moveAbsoluteHorizontal(int x) 365 { 366 writeSpoolString("\033[%d`", x); 367 } 368 369 void LIPS3Driver::carriageReturn() 370 { 371 writeSpoolChar('\x0d'); 372 } 373 374 void LIPS3Driver::moveDown(int dy) 375 { 376 writeSpoolString("\033[%de", dy); 377 } 378 379 void LIPS3Driver::rasterGraphics( 380 int compression_size, 381 int widthbyte, 382 int height, 383 int compression_method, 384 const uchar *buffer) 385 { 386 // 0 RAW 387 // 9 compress-3 388 writeSpoolString( 389 "\033[%d;%d;%d;%d;%d.r", 390 compression_size, 391 widthbyte, 392 getJobData()->getXres(), 393 compression_method, 394 height); 395 396 writeSpoolData(buffer, compression_size); 397 } 398 399 void LIPS3Driver::formFeed() 400 { 401 writeSpoolChar('\014'); 402 } 403 404 void LIPS3Driver::jobEnd() 405 { 406 writeSpoolString("\033P0J\033\\"); 407 } 408 409 void LIPS3Driver::move(int x, int y) 410 { 411 if (fCurrentX != x) { 412 if (x) { 413 moveAbsoluteHorizontal(x); 414 } else { 415 carriageReturn(); 416 } 417 fCurrentX = x; 418 } 419 if (fCurrentY != y) { 420 int dy = y - fCurrentY; 421 moveDown(dy); 422 fCurrentY = y; 423 } 424 } 425