/*
* Lips4.cpp
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
*/
#include "Lips4Cap.h"
#include <memory>
#include <Alert.h>
#include <Bitmap.h>
#include <File.h>
#include "DbgMsg.h"
#include "Halftone.h"
#include "JobData.h"
#include "Lips4.h"
#include "PackBits.h"
#include "PrinterData.h"
#include "ValidRect.h"
LIPS4Driver::LIPS4Driver(BMessage* message, PrinterData* printerData,
const PrinterCap* printerCap)
:
GraphicsDriver(message, printerData, printerCap),
fHalftone(NULL)
{
}
bool
LIPS4Driver::StartDocument()
{
try {
_BeginTextMode();
_JobStart();
_ColorModeDeclaration();
_SoftReset();
_SizeUnitMode();
_SelectSizeUnit();
_PaperFeedMode();
_SelectPageFormat();
_DisableAutoFF();
_SetNumberOfCopies();
_SidePrintingControl();
_SetBindingMargin();
fHalftone = new Halftone(GetJobData()->GetSurfaceType(),
GetJobData()->GetGamma(), GetJobData()->GetInkDensity(),
GetJobData()->GetDitherType());
return true;
}
catch (TransportException& err) {
return false;
}
}
bool
LIPS4Driver::StartPage(int)
{
try {
fCurrentX = 0;
fCurrentY = 0;
_MemorizedPosition();
return true;
}
catch (TransportException& err) {
return false;
}
}
bool
LIPS4Driver::EndPage(int)
{
try {
_FormFeed();
return true;
}
catch (TransportException& err) {
return false;
}
}
bool
LIPS4Driver::EndDocument(bool)
{
try {
if (fHalftone)
delete fHalftone;
_JobEnd();
return true;
}
catch (TransportException& err) {
return false;
}
}
bool
LIPS4Driver::NextBand(BBitmap* bitmap, BPoint* offset)
{
DBGMSG(("> nextBand\n"));
try {
if (bitmap == NULL) {
uchar dummy[1];
dummy[0] = '\0';
_RasterGraphics(1, 1, 1, 0, dummy);
DBGMSG(("< next_band\n"));
return true;
}
BRect bounds = bitmap->Bounds();
RECT rc;
rc.left = (int)bounds.left;
rc.top = (int)bounds.top;
rc.right = (int)bounds.right;
rc.bottom = (int)bounds.bottom;
int height = rc.bottom - rc.top + 1;
int x = (int)offset->x;
int y = (int)offset->y;
int page_height = GetPageHeight();
if (y + height > page_height)
height = page_height - y;
rc.bottom = height - 1;
DBGMSG(("height = %d\n", height));
DBGMSG(("x = %d\n", x));
DBGMSG(("y = %d\n", y));
if (get_valid_rect(bitmap, &rc)) {
DBGMSG(("validate rect = %d, %d, %d, %d\n",
rc.left, rc.top, rc.right, rc.bottom));
x = rc.left;
y += rc.top;
int width = rc.right - rc.left + 1;
int widthByte = (width + 7) / 8;
int height = rc.bottom - rc.top + 1;
int in_size = widthByte * height;
int out_size = (in_size * 6 + 4) / 5;
int delta = bitmap->BytesPerRow();
DBGMSG(("width = %d\n", width));
DBGMSG(("widthByte = %d\n", widthByte));
DBGMSG(("height = %d\n", height));
DBGMSG(("in_size = %d\n", in_size));
DBGMSG(("out_size = %d\n", out_size));
DBGMSG(("delta = %d\n", delta));
DBGMSG(("fHalftone_engine->Get_pixel_depth() = %d\n",
fHalftone->GetPixelDepth()));
uchar* ptr = static_cast<uchar*>(bitmap->Bits())
+ rc.top * delta
+ (rc.left * fHalftone->GetPixelDepth()) / 8;
int compression_method;
int compressed_size;
const uchar* buffer;
uchar* in_buffer = new uchar[in_size];
uchar* out_buffer = new uchar[out_size];
auto_ptr<uchar> _in_buffer (in_buffer);
auto_ptr<uchar> _out_buffer(out_buffer);
uchar* ptr2 = static_cast<uchar *>(in_buffer);
DBGMSG(("move\n"));
_Move(x, y);
for (int i = rc.top; i <= rc.bottom; i++) {
fHalftone->Dither(ptr2, ptr, x, y, width);
ptr += delta;
ptr2 += widthByte;
y++;
}
DBGMSG(("PackBits\n"));
compressed_size = pack_bits(out_buffer, in_buffer, in_size);
if (compressed_size < in_size) {
compression_method = 11;
buffer = out_buffer;
} else if (compressed_size > out_size) {
BAlert* alert = new BAlert("memory overrun!!!", "warning", "OK");
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
return false;
} else {
compression_method = 0;
buffer = in_buffer;
compressed_size = in_size;
}
DBGMSG(("compressed_size = %d\n", compressed_size));
DBGMSG(("widthByte = %d\n", widthByte));
DBGMSG(("height = %d\n", height));
DBGMSG(("compression_method = %d\n", compression_method));
_RasterGraphics(
compressed_size, // size,
widthByte, // widthByte
height, // height,
compression_method,
buffer);
} else
DBGMSG(("band bitmap is clean.\n"));
if (y >= page_height) {
offset->x = -1.0;
offset->y = -1.0;
} else
offset->y += height;
DBGMSG(("< nextBand\n"));
return true;
}
catch (TransportException& err) {
BAlert* alert = new BAlert("", err.What(), "OK");
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
return false;
}
}
void
LIPS4Driver::_BeginTextMode()
{
WriteSpoolString("\033%%@");
}
void
LIPS4Driver::_JobStart()
{
WriteSpoolString("\033P41;%d;1J\033\\", GetJobData()->GetXres());
}
void
LIPS4Driver::_ColorModeDeclaration()
{
// if (color)
// WriteSpoolString("\033[1\"p");
// else
WriteSpoolString("\033[0\"p");
}
void
LIPS4Driver::_SoftReset()
{
WriteSpoolString("\033<");
}
void
LIPS4Driver::_SizeUnitMode()
{
WriteSpoolString("\033[11h");
}
void
LIPS4Driver::_SelectSizeUnit()
{
WriteSpoolString("\033[?7;%d I", GetJobData()->GetXres());
}
void
LIPS4Driver::_PaperFeedMode()
{
// 0 auto
// --------------
// 1 MP tray
// 2 lower
// 3 lupper
// --------------
// 10 MP tray
// 11 casette 1
// 12 casette 2
// 13 casette 3
// 14 casette 4
// 15 casette 5
// 16 casette 6
// 17 casette 7
int i;
switch (GetJobData()->GetPaperSource()) {
case JobData::kManual:
i = 10;
break;
case JobData::kUpper:
i = 11;
break;
case JobData::kMiddle:
i = 12;
break;
case JobData::kLower:
i = 13;
break;
case JobData::kAuto:
default:
i = 0;
break;
}
WriteSpoolString("\033[%dq", i);
}
void
LIPS4Driver::_SelectPageFormat()
{
int i;
switch (GetJobData()->GetPaper()) {
case JobData::kA3:
i = 12;
break;
case JobData::kA4:
i = 14;
break;
case JobData::kA5:
i = 16;
break;
case JobData::kJapanesePostcard:
i = 18;
break;
case JobData::kB4:
i = 24;
break;
case JobData::kB5:
i = 26;
break;
case JobData::kLetter:
i = 30;
break;
case JobData::kLegal:
i = 32;
break;
case JobData::kExecutive:
i = 40;
break;
case JobData::kJEnvYou4:
i = 50;
break;
case JobData::kUser:
i = 90;
break;
default:
i = 0;
break;
}
if (JobData::kLandscape == GetJobData()->GetOrientation())
i++;
WriteSpoolString("\033[%d;;p", i);
}
void
LIPS4Driver::_DisableAutoFF()
{
WriteSpoolString("\033[?2h");
}
void
LIPS4Driver::_SetNumberOfCopies()
{
WriteSpoolString("\033[%ldv", GetJobData()->GetCopies());
}
void
LIPS4Driver::_SidePrintingControl()
{
if (GetJobData()->GetPrintStyle() == JobData::kSimplex)
WriteSpoolString("\033[0#x");
else
WriteSpoolString("\033[2;0#x");
}
void
LIPS4Driver::_SetBindingMargin()
{
if (GetJobData()->GetPrintStyle() == JobData::kDuplex) {
int i;
// switch (job_data()->binding_location()) {
// case kLongEdgeLeft:
i = 0;
// break;
// case kLongEdgeRight:
// i = 1;
// break;
// case kShortEdgeTop:
// i = 2;
// break;
// case kShortEdgeBottom:
// i = 3;
// break;
// }
WriteSpoolString("\033[%d;0#w", i);
}
}
void
LIPS4Driver::_MemorizedPosition()
{
WriteSpoolString("\033[0;1;0x");
}
void
LIPS4Driver::_MoveAbsoluteHorizontal(int x)
{
WriteSpoolString("\033[%ld`", x);
}
void
LIPS4Driver::_CarriageReturn()
{
WriteSpoolChar('\x0d');
}
void
LIPS4Driver::_MoveDown(int dy)
{
WriteSpoolString("\033[%lde", dy);
}
void
LIPS4Driver::_RasterGraphics(int compression_size, int widthbyte, int height,
int compression_method, const uchar* buffer)
{
// 0 RAW
// 10 RLE
// 11 packbits
WriteSpoolString(
"\033[%ld;%ld;%d;%ld;%ld.r",
compression_size,
widthbyte,
GetJobData()->GetXres(),
compression_method,
height);
WriteSpoolData(buffer, compression_size);
}
void
LIPS4Driver::_FormFeed()
{
WriteSpoolChar('\014');
}
void
LIPS4Driver::_JobEnd()
{
WriteSpoolString("\033P0J\033\\");
}
void
LIPS4Driver::_Move(int x, int y)
{
if (fCurrentX != x) {
if (x) {
_MoveAbsoluteHorizontal(x);
} else {
_CarriageReturn();
}
fCurrentX = x;
}
if (fCurrentY != y) {
int dy = y - fCurrentY;
_MoveDown(dy);
fCurrentY = y;
}
}
↑ V773 The function was exited without releasing the 'alert' pointer. A memory leak is possible.
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: fCurrentX, fCurrentY.
↑ V773 The function was exited without releasing the 'alert' pointer. A memory leak is possible.