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 25LIPS3Driver::LIPS3Driver(BMessage* message, PrinterData* printerData, 26 const PrinterCap* printerCap) 27 : 28 GraphicsDriver(message, printerData, printerCap), 29 fHalftone(NULL) 30{ 31} 32 33 34bool 35LIPS3Driver::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 58bool 59LIPS3Driver::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 73bool 74LIPS3Driver::EndPage(int) 75{ 76 try { 77 _FormFeed(); 78 return true; 79 } 80 catch (TransportException& err) { 81 return false; 82 } 83} 84 85 86bool 87LIPS3Driver::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 102bool 103LIPS3Driver::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 232void 233LIPS3Driver::_BeginTextMode() 234{ 235 WriteSpoolString("\033%%@"); 236} 237 238 239void 240LIPS3Driver::_JobStart() 241{ 242 WriteSpoolString("\033P31;300;1J\033\\"); 243} 244 245 246void 247LIPS3Driver::_SoftReset() 248{ 249 WriteSpoolString("\033<"); 250} 251 252 253void 254LIPS3Driver::_SizeUnitMode() 255{ 256 WriteSpoolString("\033[11h"); 257} 258 259 260void 261LIPS3Driver::_SelectSizeUnit() 262{ 263 WriteSpoolString("\033[7 I"); 264} 265 266 267void 268LIPS3Driver::_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 336void 337LIPS3Driver::_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 376void 377LIPS3Driver::_DisableAutoFF() 378{ 379 WriteSpoolString("\033[?2h"); 380} 381 382 383void 384LIPS3Driver::_SetNumberOfCopies() 385{ 386 WriteSpoolString("\033[%ldv", GetJobData()->GetCopies()); 387} 388 389 390void 391LIPS3Driver::_MemorizedPosition() 392{ 393 WriteSpoolString("\033[0;1;0x"); 394} 395 396 397void 398LIPS3Driver::_MoveAbsoluteHorizontal(int x) 399{ 400 WriteSpoolString("\033[%d`", x); 401} 402 403 404void 405LIPS3Driver::_CarriageReturn() 406{ 407 WriteSpoolChar('\x0d'); 408} 409 410 411void 412LIPS3Driver::_MoveDown(int dy) 413{ 414 WriteSpoolString("\033[%de", dy); 415} 416 417 418void 419LIPS3Driver::_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 431void 432LIPS3Driver::_FormFeed() 433{ 434 WriteSpoolChar('\014'); 435} 436 437 438void 439LIPS3Driver::_JobEnd() 440{ 441 WriteSpoolString("\033P0J\033\\"); 442} 443 444 445void 446LIPS3Driver::_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