Set protocol class in PCL6 header correctly (untested; hopefully this does not break anything).
Rewrote description of protocol classes. Set 300 DPI as default resolution. Uncommented protocol class 3.0 as driver does not support any new features of it. Removed second enumeration ProtocolClass from PCL6Cap.h; it is already declared in PCL6Writer.h. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16318 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,411 +1,412 @@
|
||||
/*
|
||||
* PCL6.cpp
|
||||
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
||||
* Copyright 2003 Michael Pfeiffer.
|
||||
*/
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Bitmap.h>
|
||||
#include <File.h>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#include "DbgMsg.h"
|
||||
#include "DeltaRowCompression.h"
|
||||
#include "Halftone.h"
|
||||
#include "JobData.h"
|
||||
#include "PackBits.h"
|
||||
#include "PCL6.h"
|
||||
#include "PCL6Cap.h"
|
||||
#include "PCL6Config.h"
|
||||
#include "PrinterData.h"
|
||||
#include "PCL6Rasterizer.h"
|
||||
#include "UIDriver.h"
|
||||
#include "ValidRect.h"
|
||||
|
||||
#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE))
|
||||
using namespace std;
|
||||
#else
|
||||
#define std
|
||||
#endif
|
||||
|
||||
// DeltaRowStreamCompressor writes the delta row directly to the
|
||||
// in the contructor specified stream.
|
||||
class DeltaRowStreamCompressor : public AbstractDeltaRowCompressor
|
||||
{
|
||||
public:
|
||||
DeltaRowStreamCompressor(int rowSize, uchar initialSeed, PCL6Writer *writer)
|
||||
: AbstractDeltaRowCompressor(rowSize, initialSeed)
|
||||
, fWriter(writer)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
protected:
|
||||
void AppendByteToDeltaRow(uchar byte) {
|
||||
fWriter->Append(byte);
|
||||
}
|
||||
|
||||
private:
|
||||
PCL6Writer *fWriter;
|
||||
};
|
||||
|
||||
|
||||
PCL6Driver::PCL6Driver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap)
|
||||
: GraphicsDriver(msg, printer_data, printer_cap)
|
||||
{
|
||||
fHalftone = NULL;
|
||||
fWriter = NULL;
|
||||
}
|
||||
|
||||
void PCL6Driver::write(const uint8 *data, uint32 size)
|
||||
{
|
||||
writeSpoolData(data, size);
|
||||
}
|
||||
|
||||
bool PCL6Driver::startDoc()
|
||||
{
|
||||
try {
|
||||
jobStart();
|
||||
fHalftone = new Halftone(getJobData()->getSurfaceType(), getJobData()->getGamma(), getJobData()->getInkDensity(), getJobData()->getDitherType());
|
||||
return true;
|
||||
}
|
||||
catch (TransportException &err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PCL6Driver::endDoc(bool)
|
||||
{
|
||||
try {
|
||||
if (fHalftone) {
|
||||
delete fHalftone;
|
||||
}
|
||||
jobEnd();
|
||||
return true;
|
||||
}
|
||||
catch (TransportException &err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PCL6Driver::nextBand(BBitmap *bitmap, BPoint *offset)
|
||||
{
|
||||
DBGMSG(("> nextBand\n"));
|
||||
|
||||
try {
|
||||
int y = (int)offset->y;
|
||||
|
||||
PCL6Rasterizer *rasterizer;
|
||||
if (getJobData()->getColor() == JobData::kColor) {
|
||||
#if COLOR_DEPTH == 8
|
||||
rasterizer = new ColorRGBRasterizer(fHalftone);
|
||||
#elif COLOR_DEPTH == 1
|
||||
rasterizer = new ColorRasterizer(fHalftone);
|
||||
#else
|
||||
#error COLOR_DEPTH must be either 1 or 8!
|
||||
#endif
|
||||
} else {
|
||||
rasterizer = new MonochromeRasterizer(fHalftone);
|
||||
}
|
||||
auto_ptr<Rasterizer> _rasterizer(rasterizer);
|
||||
bool valid = rasterizer->SetBitmap((int)offset->x, (int)offset->y, bitmap, getPageHeight());
|
||||
|
||||
if (valid) {
|
||||
rasterizer->InitializeBuffer();
|
||||
|
||||
// Use compressor to calculate delta row size
|
||||
DeltaRowCompressor *deltaRowCompressor = NULL;
|
||||
if (supportsDeltaRowCompression()) {
|
||||
deltaRowCompressor = new DeltaRowCompressor(rasterizer->GetOutRowSize(), 0);
|
||||
if (deltaRowCompressor->InitCheck() != B_OK) {
|
||||
delete deltaRowCompressor;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
auto_ptr<DeltaRowCompressor> _deltaRowCompressor(deltaRowCompressor);
|
||||
int deltaRowSize = 0;
|
||||
|
||||
// remember position
|
||||
int xPage = rasterizer->GetX();
|
||||
int yPage = rasterizer->GetY();
|
||||
|
||||
while (rasterizer->HasNextLine()) {
|
||||
const uchar *rowBuffer = (uchar*)rasterizer->RasterizeNextLine();
|
||||
|
||||
if (deltaRowCompressor != NULL) {
|
||||
int size = deltaRowCompressor->CalculateSize(rowBuffer, true);
|
||||
deltaRowSize += size + 2; // two bytes for the row byte count
|
||||
}
|
||||
}
|
||||
|
||||
y = rasterizer->GetY();
|
||||
|
||||
uchar *outBuffer = rasterizer->GetOutBuffer();
|
||||
int outBufferSize = rasterizer->GetOutBufferSize();
|
||||
int outRowSize = rasterizer->GetOutRowSize();
|
||||
int width = rasterizer->GetWidth();
|
||||
int height = rasterizer->GetHeight();
|
||||
writeBitmap(outBuffer, outBufferSize, outRowSize, xPage, yPage, width, height, deltaRowSize);
|
||||
}
|
||||
|
||||
if (y >= getPageHeight()) {
|
||||
offset->x = -1.0;
|
||||
offset->y = -1.0;
|
||||
} else {
|
||||
offset->y += bitmap->Bounds().IntegerHeight()+1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (TransportException &err) {
|
||||
BAlert *alert = new BAlert("", err.what(), "OK");
|
||||
alert->Go();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void PCL6Driver::writeBitmap(const uchar* buffer, int outSize, int rowSize, int x, int y, int width, int height, int deltaRowSize)
|
||||
{
|
||||
// choose the best compression method
|
||||
PCL6Writer::Compression compressionMethod = PCL6Writer::kNoCompression;
|
||||
int dataSize = outSize;
|
||||
|
||||
#if ENABLE_DELTA_ROW_COMPRESSION
|
||||
if (supportsDeltaRowCompression() && deltaRowSize < dataSize) {
|
||||
compressionMethod = PCL6Writer::kDeltaRowCompression;
|
||||
dataSize = deltaRowSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_RLE_COMPRESSION
|
||||
int rleSize = pack_bits_size(buffer, outSize);
|
||||
if (rleSize < dataSize) {
|
||||
compressionMethod = PCL6Writer::kRLECompression;
|
||||
dataSize = rleSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
// write bitmap
|
||||
move(x, y);
|
||||
|
||||
startRasterGraphics(x, y, width, height, compressionMethod);
|
||||
|
||||
rasterGraphics(buffer, outSize, dataSize, rowSize, height, compressionMethod);
|
||||
|
||||
endRasterGraphics();
|
||||
|
||||
#if DISPLAY_COMPRESSION_STATISTICS
|
||||
fprintf(stderr, "Out Size %d %2.2f\n", (int)outSize, 100.0);
|
||||
#if ENABLE_RLE_COMPRESSION
|
||||
fprintf(stderr, "RLE Size %d %2.2f\n", (int)rleSize, 100.0 * rleSize / outSize);
|
||||
#endif
|
||||
#if ENABLE_DELTA_ROW_COMPRESSION
|
||||
fprintf(stderr, "Delta Row Size %d %2.2f\n", (int)deltaRowSize, 100.0 * deltaRowSize / outSize);
|
||||
#endif
|
||||
fprintf(stderr, "Data Size %d %2.2f\n", (int)dataSize, 100.0 * dataSize / outSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PCL6Driver::jobStart()
|
||||
{
|
||||
// PCL6 begin
|
||||
fWriter = new PCL6Writer(this);
|
||||
fWriter->PJLHeader(PCL6Writer::kProtocolClass1_1, getJobData()->getXres(), "Copyright (c) 2003, 2004 Haiku");
|
||||
fWriter->BeginSession(getJobData()->getXres(), getJobData()->getYres(), PCL6Writer::kInch, PCL6Writer::kBackChAndErrPage);
|
||||
fWriter->OpenDataSource();
|
||||
fMediaSide = PCL6Writer::kFrontMediaSide;
|
||||
}
|
||||
|
||||
bool PCL6Driver::startPage(int)
|
||||
{
|
||||
PCL6Writer::Orientation orientation = PCL6Writer::kPortrait;
|
||||
if (getJobData()->getOrientation() == JobData::kLandscape) {
|
||||
orientation = PCL6Writer::kLandscape;
|
||||
}
|
||||
|
||||
PCL6Writer::MediaSize mediaSize = PCL6Driver::mediaSize(getJobData()->getPaper());
|
||||
PCL6Writer::MediaSource mediaSource = PCL6Driver::mediaSource(getJobData()->getPaperSource());
|
||||
if (getJobData()->getPrintStyle() == JobData::kSimplex) {
|
||||
fWriter->BeginPage(orientation, mediaSize, mediaSource);
|
||||
} else if (getJobData()->getPrintStyle() == JobData::kDuplex) {
|
||||
fWriter->BeginPage(orientation, mediaSize, mediaSource,
|
||||
PCL6Writer::kDuplexHorizontalBinding, fMediaSide);
|
||||
|
||||
if (fMediaSide == PCL6Writer::kFrontMediaSide) {
|
||||
fMediaSide = PCL6Writer::kBackMediaSide;
|
||||
} else {
|
||||
fMediaSide = PCL6Writer::kFrontMediaSide;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// PageOrigin from Windows NT printer driver
|
||||
int x = 142 * getJobData()->getXres() / 600;
|
||||
int y = 100 * getJobData()->getYres() / 600;
|
||||
bool color = getJobData()->getColor() == JobData::kColor;
|
||||
fWriter->SetPageOrigin(x, y);
|
||||
fWriter->SetColorSpace(color ? PCL6Writer::kRGB : PCL6Writer::kGray);
|
||||
fWriter->SetPaintTxMode(PCL6Writer::kOpaque);
|
||||
fWriter->SetSourceTxMode(PCL6Writer::kOpaque);
|
||||
fWriter->SetROP(204);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PCL6Driver::startRasterGraphics(int x, int y, int width, int height, PCL6Writer::Compression compressionMethod)
|
||||
{
|
||||
bool color = getJobData()->getColor() == JobData::kColor;
|
||||
PCL6Writer::ColorDepth colorDepth;
|
||||
if (color) {
|
||||
#if COLOR_DEPTH == 8
|
||||
colorDepth = PCL6Writer::k8Bit;
|
||||
#elif COLOR_DEPTH == 1
|
||||
colorDepth = PCL6Writer::k1Bit;
|
||||
#else
|
||||
#error COLOR_DEPTH must be either 1 or 8!
|
||||
#endif
|
||||
} else {
|
||||
colorDepth = PCL6Writer::k1Bit;
|
||||
}
|
||||
fWriter->BeginImage(PCL6Writer::kDirectPixel, colorDepth, width, height, width, height);
|
||||
fWriter->ReadImage(compressionMethod, 0, height);
|
||||
}
|
||||
|
||||
void PCL6Driver::endRasterGraphics()
|
||||
{
|
||||
fWriter->EndImage();
|
||||
}
|
||||
|
||||
void PCL6Driver::rasterGraphics(
|
||||
const uchar *buffer,
|
||||
int bufferSize,
|
||||
int dataSize,
|
||||
int rowSize,
|
||||
int height,
|
||||
int compressionMethod
|
||||
)
|
||||
{
|
||||
// write bitmap byte size
|
||||
fWriter->EmbeddedDataPrefix32(dataSize);
|
||||
|
||||
// write data
|
||||
if (compressionMethod == PCL6Writer::kRLECompression) {
|
||||
// use RLE compression
|
||||
uchar *outBuffer = new uchar[dataSize];
|
||||
pack_bits(outBuffer, buffer, bufferSize);
|
||||
fWriter->Append(outBuffer, dataSize);
|
||||
delete outBuffer;
|
||||
return;
|
||||
} else if (compressionMethod == PCL6Writer::kDeltaRowCompression) {
|
||||
// use delta row compression
|
||||
DeltaRowStreamCompressor compressor(rowSize, 0, fWriter);
|
||||
if (compressor.InitCheck() != B_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8* row = buffer;
|
||||
for (int i = 0; i < height; i ++) {
|
||||
// write row byte count
|
||||
int32 size = compressor.CalculateSize(row);
|
||||
fWriter->Append((uint16)size);
|
||||
|
||||
if (size > 0) {
|
||||
// write delta row
|
||||
compressor.Compress(row);
|
||||
}
|
||||
|
||||
row += rowSize;
|
||||
}
|
||||
} else {
|
||||
// write raw data
|
||||
fWriter->Append(buffer, bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
bool PCL6Driver::endPage(int)
|
||||
{
|
||||
try {
|
||||
fWriter->EndPage(getJobData()->getCopies());
|
||||
return true;
|
||||
}
|
||||
catch (TransportException &err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void PCL6Driver::jobEnd()
|
||||
{
|
||||
fWriter->CloseDataSource();
|
||||
fWriter->EndSession();
|
||||
fWriter->PJLFooter();
|
||||
fWriter->Flush();
|
||||
delete fWriter;
|
||||
fWriter = NULL;
|
||||
}
|
||||
|
||||
void PCL6Driver::move(int x, int y)
|
||||
{
|
||||
fWriter->SetCursor(x, y);
|
||||
}
|
||||
|
||||
bool
|
||||
PCL6Driver::supportsDeltaRowCompression()
|
||||
{
|
||||
return getProtocolClass() >= kProtocolClass2_1;
|
||||
}
|
||||
|
||||
PCL6Writer::MediaSize PCL6Driver::mediaSize(JobData::Paper paper)
|
||||
{
|
||||
switch (paper) {
|
||||
case JobData::kLetter: return PCL6Writer::kLetterPaper;
|
||||
case JobData::kLegal: return PCL6Writer::kLegalPaper;
|
||||
case JobData::kA4: return PCL6Writer::kA4Paper;
|
||||
case JobData::kExecutive: return PCL6Writer::kExecPaper;
|
||||
case JobData::kLedger: return PCL6Writer::kLedgerPaper;
|
||||
case JobData::kA3: return PCL6Writer::kA3Paper;
|
||||
case JobData::kB5: return PCL6Writer::kB5Paper;
|
||||
case JobData::kJapanesePostcard:
|
||||
return PCL6Writer::kJPostcard;
|
||||
case JobData::kA5: return PCL6Writer::kA5Paper;
|
||||
case JobData::kB4: return PCL6Writer::kJB4Paper;
|
||||
/*
|
||||
case : return PCL6Writer::kCOM10Envelope;
|
||||
case : return PCL6Writer::kMonarchEnvelope;
|
||||
case : return PCL6Writer::kC5Envelope;
|
||||
case : return PCL6Writer::kDLEnvelope;
|
||||
case : return PCL6Writer::kJB4Paper;
|
||||
case : return PCL6Writer::kJB5Paper;
|
||||
case : return PCL6Writer::kB5Envelope;
|
||||
case : return PCL6Writer::kJPostcard;
|
||||
case : return PCL6Writer::kJDoublePostcard;
|
||||
case : return PCL6Writer::kA5Paper;
|
||||
case : return PCL6Writer::kA6Paper;
|
||||
case : return PCL6Writer::kJB6Paper;
|
||||
case : return PCL6Writer::kJIS8KPaper;
|
||||
case : return PCL6Writer::kJIS16KPaper;
|
||||
case : return PCL6Writer::kJISExecPaper;
|
||||
*/
|
||||
default:
|
||||
return PCL6Writer::kLegalPaper;
|
||||
}
|
||||
}
|
||||
|
||||
PCL6Writer::MediaSource PCL6Driver::mediaSource(JobData::PaperSource source)
|
||||
{
|
||||
switch (source) {
|
||||
case JobData::kAuto: return PCL6Writer::kAutoSelect;
|
||||
case JobData::kCassette1: return PCL6Writer::kDefaultSource;
|
||||
case JobData::kCassette2: return PCL6Writer::kEnvelopeTray;
|
||||
case JobData::kLower: return PCL6Writer::kLowerCassette;
|
||||
case JobData::kUpper: return PCL6Writer::kUpperCassette;
|
||||
case JobData::kMiddle: return PCL6Writer::kThirdCassette;
|
||||
case JobData::kManual: return PCL6Writer::kManualFeed;
|
||||
case JobData::kCassette3: return PCL6Writer::kMultiPurposeTray;
|
||||
|
||||
default:
|
||||
return PCL6Writer::kAutoSelect;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* PCL6.cpp
|
||||
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
||||
* Copyright 2003 Michael Pfeiffer.
|
||||
*/
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Bitmap.h>
|
||||
#include <File.h>
|
||||
#include <memory>
|
||||
|
||||
|
||||
#include "DbgMsg.h"
|
||||
#include "DeltaRowCompression.h"
|
||||
#include "Halftone.h"
|
||||
#include "JobData.h"
|
||||
#include "PackBits.h"
|
||||
#include "PCL6.h"
|
||||
#include "PCL6Cap.h"
|
||||
#include "PCL6Config.h"
|
||||
#include "PrinterData.h"
|
||||
#include "PCL6Rasterizer.h"
|
||||
#include "UIDriver.h"
|
||||
#include "ValidRect.h"
|
||||
|
||||
#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE))
|
||||
using namespace std;
|
||||
#else
|
||||
#define std
|
||||
#endif
|
||||
|
||||
// DeltaRowStreamCompressor writes the delta row directly to the
|
||||
// in the contructor specified stream.
|
||||
class DeltaRowStreamCompressor : public AbstractDeltaRowCompressor
|
||||
{
|
||||
public:
|
||||
DeltaRowStreamCompressor(int rowSize, uchar initialSeed, PCL6Writer *writer)
|
||||
: AbstractDeltaRowCompressor(rowSize, initialSeed)
|
||||
, fWriter(writer)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
protected:
|
||||
void AppendByteToDeltaRow(uchar byte) {
|
||||
fWriter->Append(byte);
|
||||
}
|
||||
|
||||
private:
|
||||
PCL6Writer *fWriter;
|
||||
};
|
||||
|
||||
|
||||
PCL6Driver::PCL6Driver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap)
|
||||
: GraphicsDriver(msg, printer_data, printer_cap)
|
||||
{
|
||||
fHalftone = NULL;
|
||||
fWriter = NULL;
|
||||
}
|
||||
|
||||
void PCL6Driver::write(const uint8 *data, uint32 size)
|
||||
{
|
||||
writeSpoolData(data, size);
|
||||
}
|
||||
|
||||
bool PCL6Driver::startDoc()
|
||||
{
|
||||
try {
|
||||
jobStart();
|
||||
fHalftone = new Halftone(getJobData()->getSurfaceType(), getJobData()->getGamma(), getJobData()->getInkDensity(), getJobData()->getDitherType());
|
||||
return true;
|
||||
}
|
||||
catch (TransportException &err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PCL6Driver::endDoc(bool)
|
||||
{
|
||||
try {
|
||||
if (fHalftone) {
|
||||
delete fHalftone;
|
||||
}
|
||||
jobEnd();
|
||||
return true;
|
||||
}
|
||||
catch (TransportException &err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PCL6Driver::nextBand(BBitmap *bitmap, BPoint *offset)
|
||||
{
|
||||
DBGMSG(("> nextBand\n"));
|
||||
|
||||
try {
|
||||
int y = (int)offset->y;
|
||||
|
||||
PCL6Rasterizer *rasterizer;
|
||||
if (getJobData()->getColor() == JobData::kColor) {
|
||||
#if COLOR_DEPTH == 8
|
||||
rasterizer = new ColorRGBRasterizer(fHalftone);
|
||||
#elif COLOR_DEPTH == 1
|
||||
rasterizer = new ColorRasterizer(fHalftone);
|
||||
#else
|
||||
#error COLOR_DEPTH must be either 1 or 8!
|
||||
#endif
|
||||
} else {
|
||||
rasterizer = new MonochromeRasterizer(fHalftone);
|
||||
}
|
||||
auto_ptr<Rasterizer> _rasterizer(rasterizer);
|
||||
bool valid = rasterizer->SetBitmap((int)offset->x, (int)offset->y, bitmap, getPageHeight());
|
||||
|
||||
if (valid) {
|
||||
rasterizer->InitializeBuffer();
|
||||
|
||||
// Use compressor to calculate delta row size
|
||||
DeltaRowCompressor *deltaRowCompressor = NULL;
|
||||
if (supportsDeltaRowCompression()) {
|
||||
deltaRowCompressor = new DeltaRowCompressor(rasterizer->GetOutRowSize(), 0);
|
||||
if (deltaRowCompressor->InitCheck() != B_OK) {
|
||||
delete deltaRowCompressor;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
auto_ptr<DeltaRowCompressor> _deltaRowCompressor(deltaRowCompressor);
|
||||
int deltaRowSize = 0;
|
||||
|
||||
// remember position
|
||||
int xPage = rasterizer->GetX();
|
||||
int yPage = rasterizer->GetY();
|
||||
|
||||
while (rasterizer->HasNextLine()) {
|
||||
const uchar *rowBuffer = (uchar*)rasterizer->RasterizeNextLine();
|
||||
|
||||
if (deltaRowCompressor != NULL) {
|
||||
int size = deltaRowCompressor->CalculateSize(rowBuffer, true);
|
||||
deltaRowSize += size + 2; // two bytes for the row byte count
|
||||
}
|
||||
}
|
||||
|
||||
y = rasterizer->GetY();
|
||||
|
||||
uchar *outBuffer = rasterizer->GetOutBuffer();
|
||||
int outBufferSize = rasterizer->GetOutBufferSize();
|
||||
int outRowSize = rasterizer->GetOutRowSize();
|
||||
int width = rasterizer->GetWidth();
|
||||
int height = rasterizer->GetHeight();
|
||||
writeBitmap(outBuffer, outBufferSize, outRowSize, xPage, yPage, width, height, deltaRowSize);
|
||||
}
|
||||
|
||||
if (y >= getPageHeight()) {
|
||||
offset->x = -1.0;
|
||||
offset->y = -1.0;
|
||||
} else {
|
||||
offset->y += bitmap->Bounds().IntegerHeight()+1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (TransportException &err) {
|
||||
BAlert *alert = new BAlert("", err.what(), "OK");
|
||||
alert->Go();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void PCL6Driver::writeBitmap(const uchar* buffer, int outSize, int rowSize, int x, int y, int width, int height, int deltaRowSize)
|
||||
{
|
||||
// choose the best compression method
|
||||
PCL6Writer::Compression compressionMethod = PCL6Writer::kNoCompression;
|
||||
int dataSize = outSize;
|
||||
|
||||
#if ENABLE_DELTA_ROW_COMPRESSION
|
||||
if (supportsDeltaRowCompression() && deltaRowSize < dataSize) {
|
||||
compressionMethod = PCL6Writer::kDeltaRowCompression;
|
||||
dataSize = deltaRowSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_RLE_COMPRESSION
|
||||
int rleSize = pack_bits_size(buffer, outSize);
|
||||
if (rleSize < dataSize) {
|
||||
compressionMethod = PCL6Writer::kRLECompression;
|
||||
dataSize = rleSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
// write bitmap
|
||||
move(x, y);
|
||||
|
||||
startRasterGraphics(x, y, width, height, compressionMethod);
|
||||
|
||||
rasterGraphics(buffer, outSize, dataSize, rowSize, height, compressionMethod);
|
||||
|
||||
endRasterGraphics();
|
||||
|
||||
#if DISPLAY_COMPRESSION_STATISTICS
|
||||
fprintf(stderr, "Out Size %d %2.2f\n", (int)outSize, 100.0);
|
||||
#if ENABLE_RLE_COMPRESSION
|
||||
fprintf(stderr, "RLE Size %d %2.2f\n", (int)rleSize, 100.0 * rleSize / outSize);
|
||||
#endif
|
||||
#if ENABLE_DELTA_ROW_COMPRESSION
|
||||
fprintf(stderr, "Delta Row Size %d %2.2f\n", (int)deltaRowSize, 100.0 * deltaRowSize / outSize);
|
||||
#endif
|
||||
fprintf(stderr, "Data Size %d %2.2f\n", (int)dataSize, 100.0 * dataSize / outSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PCL6Driver::jobStart()
|
||||
{
|
||||
// PCL6 begin
|
||||
fWriter = new PCL6Writer(this);
|
||||
PCL6Writer::ProtocolClass pc = (PCL6Writer::ProtocolClass)getProtocolClass();
|
||||
fWriter->PJLHeader(pc, getJobData()->getXres(), "Copyright (c) 2003, 2004 Haiku");
|
||||
fWriter->BeginSession(getJobData()->getXres(), getJobData()->getYres(), PCL6Writer::kInch, PCL6Writer::kBackChAndErrPage);
|
||||
fWriter->OpenDataSource();
|
||||
fMediaSide = PCL6Writer::kFrontMediaSide;
|
||||
}
|
||||
|
||||
bool PCL6Driver::startPage(int)
|
||||
{
|
||||
PCL6Writer::Orientation orientation = PCL6Writer::kPortrait;
|
||||
if (getJobData()->getOrientation() == JobData::kLandscape) {
|
||||
orientation = PCL6Writer::kLandscape;
|
||||
}
|
||||
|
||||
PCL6Writer::MediaSize mediaSize = PCL6Driver::mediaSize(getJobData()->getPaper());
|
||||
PCL6Writer::MediaSource mediaSource = PCL6Driver::mediaSource(getJobData()->getPaperSource());
|
||||
if (getJobData()->getPrintStyle() == JobData::kSimplex) {
|
||||
fWriter->BeginPage(orientation, mediaSize, mediaSource);
|
||||
} else if (getJobData()->getPrintStyle() == JobData::kDuplex) {
|
||||
fWriter->BeginPage(orientation, mediaSize, mediaSource,
|
||||
PCL6Writer::kDuplexHorizontalBinding, fMediaSide);
|
||||
|
||||
if (fMediaSide == PCL6Writer::kFrontMediaSide) {
|
||||
fMediaSide = PCL6Writer::kBackMediaSide;
|
||||
} else {
|
||||
fMediaSide = PCL6Writer::kFrontMediaSide;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// PageOrigin from Windows NT printer driver
|
||||
int x = 142 * getJobData()->getXres() / 600;
|
||||
int y = 100 * getJobData()->getYres() / 600;
|
||||
bool color = getJobData()->getColor() == JobData::kColor;
|
||||
fWriter->SetPageOrigin(x, y);
|
||||
fWriter->SetColorSpace(color ? PCL6Writer::kRGB : PCL6Writer::kGray);
|
||||
fWriter->SetPaintTxMode(PCL6Writer::kOpaque);
|
||||
fWriter->SetSourceTxMode(PCL6Writer::kOpaque);
|
||||
fWriter->SetROP(204);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PCL6Driver::startRasterGraphics(int x, int y, int width, int height, PCL6Writer::Compression compressionMethod)
|
||||
{
|
||||
bool color = getJobData()->getColor() == JobData::kColor;
|
||||
PCL6Writer::ColorDepth colorDepth;
|
||||
if (color) {
|
||||
#if COLOR_DEPTH == 8
|
||||
colorDepth = PCL6Writer::k8Bit;
|
||||
#elif COLOR_DEPTH == 1
|
||||
colorDepth = PCL6Writer::k1Bit;
|
||||
#else
|
||||
#error COLOR_DEPTH must be either 1 or 8!
|
||||
#endif
|
||||
} else {
|
||||
colorDepth = PCL6Writer::k1Bit;
|
||||
}
|
||||
fWriter->BeginImage(PCL6Writer::kDirectPixel, colorDepth, width, height, width, height);
|
||||
fWriter->ReadImage(compressionMethod, 0, height);
|
||||
}
|
||||
|
||||
void PCL6Driver::endRasterGraphics()
|
||||
{
|
||||
fWriter->EndImage();
|
||||
}
|
||||
|
||||
void PCL6Driver::rasterGraphics(
|
||||
const uchar *buffer,
|
||||
int bufferSize,
|
||||
int dataSize,
|
||||
int rowSize,
|
||||
int height,
|
||||
int compressionMethod
|
||||
)
|
||||
{
|
||||
// write bitmap byte size
|
||||
fWriter->EmbeddedDataPrefix32(dataSize);
|
||||
|
||||
// write data
|
||||
if (compressionMethod == PCL6Writer::kRLECompression) {
|
||||
// use RLE compression
|
||||
uchar *outBuffer = new uchar[dataSize];
|
||||
pack_bits(outBuffer, buffer, bufferSize);
|
||||
fWriter->Append(outBuffer, dataSize);
|
||||
delete outBuffer;
|
||||
return;
|
||||
} else if (compressionMethod == PCL6Writer::kDeltaRowCompression) {
|
||||
// use delta row compression
|
||||
DeltaRowStreamCompressor compressor(rowSize, 0, fWriter);
|
||||
if (compressor.InitCheck() != B_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8* row = buffer;
|
||||
for (int i = 0; i < height; i ++) {
|
||||
// write row byte count
|
||||
int32 size = compressor.CalculateSize(row);
|
||||
fWriter->Append((uint16)size);
|
||||
|
||||
if (size > 0) {
|
||||
// write delta row
|
||||
compressor.Compress(row);
|
||||
}
|
||||
|
||||
row += rowSize;
|
||||
}
|
||||
} else {
|
||||
// write raw data
|
||||
fWriter->Append(buffer, bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
bool PCL6Driver::endPage(int)
|
||||
{
|
||||
try {
|
||||
fWriter->EndPage(getJobData()->getCopies());
|
||||
return true;
|
||||
}
|
||||
catch (TransportException &err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void PCL6Driver::jobEnd()
|
||||
{
|
||||
fWriter->CloseDataSource();
|
||||
fWriter->EndSession();
|
||||
fWriter->PJLFooter();
|
||||
fWriter->Flush();
|
||||
delete fWriter;
|
||||
fWriter = NULL;
|
||||
}
|
||||
|
||||
void PCL6Driver::move(int x, int y)
|
||||
{
|
||||
fWriter->SetCursor(x, y);
|
||||
}
|
||||
|
||||
bool
|
||||
PCL6Driver::supportsDeltaRowCompression()
|
||||
{
|
||||
return getProtocolClass() >= PCL6Writer::kProtocolClass2_1;
|
||||
}
|
||||
|
||||
PCL6Writer::MediaSize PCL6Driver::mediaSize(JobData::Paper paper)
|
||||
{
|
||||
switch (paper) {
|
||||
case JobData::kLetter: return PCL6Writer::kLetterPaper;
|
||||
case JobData::kLegal: return PCL6Writer::kLegalPaper;
|
||||
case JobData::kA4: return PCL6Writer::kA4Paper;
|
||||
case JobData::kExecutive: return PCL6Writer::kExecPaper;
|
||||
case JobData::kLedger: return PCL6Writer::kLedgerPaper;
|
||||
case JobData::kA3: return PCL6Writer::kA3Paper;
|
||||
case JobData::kB5: return PCL6Writer::kB5Paper;
|
||||
case JobData::kJapanesePostcard:
|
||||
return PCL6Writer::kJPostcard;
|
||||
case JobData::kA5: return PCL6Writer::kA5Paper;
|
||||
case JobData::kB4: return PCL6Writer::kJB4Paper;
|
||||
/*
|
||||
case : return PCL6Writer::kCOM10Envelope;
|
||||
case : return PCL6Writer::kMonarchEnvelope;
|
||||
case : return PCL6Writer::kC5Envelope;
|
||||
case : return PCL6Writer::kDLEnvelope;
|
||||
case : return PCL6Writer::kJB4Paper;
|
||||
case : return PCL6Writer::kJB5Paper;
|
||||
case : return PCL6Writer::kB5Envelope;
|
||||
case : return PCL6Writer::kJPostcard;
|
||||
case : return PCL6Writer::kJDoublePostcard;
|
||||
case : return PCL6Writer::kA5Paper;
|
||||
case : return PCL6Writer::kA6Paper;
|
||||
case : return PCL6Writer::kJB6Paper;
|
||||
case : return PCL6Writer::kJIS8KPaper;
|
||||
case : return PCL6Writer::kJIS16KPaper;
|
||||
case : return PCL6Writer::kJISExecPaper;
|
||||
*/
|
||||
default:
|
||||
return PCL6Writer::kLegalPaper;
|
||||
}
|
||||
}
|
||||
|
||||
PCL6Writer::MediaSource PCL6Driver::mediaSource(JobData::PaperSource source)
|
||||
{
|
||||
switch (source) {
|
||||
case JobData::kAuto: return PCL6Writer::kAutoSelect;
|
||||
case JobData::kCassette1: return PCL6Writer::kDefaultSource;
|
||||
case JobData::kCassette2: return PCL6Writer::kEnvelopeTray;
|
||||
case JobData::kLower: return PCL6Writer::kLowerCassette;
|
||||
case JobData::kUpper: return PCL6Writer::kUpperCassette;
|
||||
case JobData::kMiddle: return PCL6Writer::kThirdCassette;
|
||||
case JobData::kManual: return PCL6Writer::kManualFeed;
|
||||
case JobData::kCassette3: return PCL6Writer::kMultiPurposeTray;
|
||||
|
||||
default:
|
||||
return PCL6Writer::kAutoSelect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,53 +1,54 @@
|
||||
/*
|
||||
* PCL6.h
|
||||
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
||||
* Copyright 2003 Michael Pfeiffer.
|
||||
*/
|
||||
|
||||
#ifndef __PCL6_H
|
||||
#define __PCL6_H
|
||||
|
||||
|
||||
#include "GraphicsDriver.h"
|
||||
#include "PCL6Writer.h"
|
||||
|
||||
class Halftone;
|
||||
|
||||
class PCL6Driver : public GraphicsDriver, public PCL6WriterStream
|
||||
{
|
||||
public:
|
||||
PCL6Driver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap);
|
||||
|
||||
void write(const uint8 *data, uint32 size);
|
||||
|
||||
protected:
|
||||
virtual bool startDoc();
|
||||
virtual bool startPage(int page);
|
||||
virtual bool nextBand(BBitmap *bitmap, BPoint *offset);
|
||||
virtual bool endPage(int page);
|
||||
virtual bool endDoc(bool success);
|
||||
|
||||
private:
|
||||
bool supportsDeltaRowCompression();
|
||||
PCL6Writer::MediaSize mediaSize(JobData::Paper paper);
|
||||
PCL6Writer::MediaSource mediaSource(JobData::PaperSource source);
|
||||
void move(int x, int y);
|
||||
void jobStart();
|
||||
void writeBitmap(const uchar* buffer, int outSize, int rowSize, int x, int y, int width, int height, int deltaRowSize);
|
||||
void startRasterGraphics(int x, int y, int width, int height, PCL6Writer::Compression compressionMethod);
|
||||
void endRasterGraphics();
|
||||
void rasterGraphics(
|
||||
const uchar *buffer,
|
||||
int bufferSize,
|
||||
int dataSize,
|
||||
int rowSize,
|
||||
int height,
|
||||
int compression_method);
|
||||
void jobEnd();
|
||||
|
||||
PCL6Writer *fWriter;
|
||||
PCL6Writer::MediaSide fMediaSide; // side if in duplex mode
|
||||
Halftone *fHalftone;
|
||||
};
|
||||
|
||||
#endif /* __PCL6_H */
|
||||
/*
|
||||
* PCL6.h
|
||||
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
||||
* Copyright 2003 Michael Pfeiffer.
|
||||
*/
|
||||
|
||||
#ifndef __PCL6_H
|
||||
#define __PCL6_H
|
||||
|
||||
|
||||
#include "GraphicsDriver.h"
|
||||
#include "PCL6Cap.h"
|
||||
#include "PCL6Writer.h"
|
||||
|
||||
class Halftone;
|
||||
|
||||
class PCL6Driver : public GraphicsDriver, public PCL6WriterStream
|
||||
{
|
||||
public:
|
||||
PCL6Driver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap);
|
||||
|
||||
void write(const uint8 *data, uint32 size);
|
||||
|
||||
protected:
|
||||
virtual bool startDoc();
|
||||
virtual bool startPage(int page);
|
||||
virtual bool nextBand(BBitmap *bitmap, BPoint *offset);
|
||||
virtual bool endPage(int page);
|
||||
virtual bool endDoc(bool success);
|
||||
|
||||
private:
|
||||
bool supportsDeltaRowCompression();
|
||||
PCL6Writer::MediaSize mediaSize(JobData::Paper paper);
|
||||
PCL6Writer::MediaSource mediaSource(JobData::PaperSource source);
|
||||
void move(int x, int y);
|
||||
void jobStart();
|
||||
void writeBitmap(const uchar* buffer, int outSize, int rowSize, int x, int y, int width, int height, int deltaRowSize);
|
||||
void startRasterGraphics(int x, int y, int width, int height, PCL6Writer::Compression compressionMethod);
|
||||
void endRasterGraphics();
|
||||
void rasterGraphics(
|
||||
const uchar *buffer,
|
||||
int bufferSize,
|
||||
int dataSize,
|
||||
int rowSize,
|
||||
int height,
|
||||
int compression_method);
|
||||
void jobEnd();
|
||||
|
||||
PCL6Writer *fWriter;
|
||||
PCL6Writer::MediaSide fMediaSide; // side if in duplex mode
|
||||
Halftone *fHalftone;
|
||||
};
|
||||
|
||||
#endif /* __PCL6_H */
|
||||
|
||||
Binary file not shown.
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "PCL6Cap.h"
|
||||
#include "PCL6Config.h"
|
||||
#include "PCL6Writer.h"
|
||||
#include "PrinterData.h"
|
||||
|
||||
#define TO72DPI(a) (a * 72.0f / 600.0f)
|
||||
@@ -38,7 +39,7 @@ const PaperCap a4(
|
||||
// since 1.1
|
||||
const PaperCap exec(
|
||||
"Executive",
|
||||
true,
|
||||
false,
|
||||
JobData::kA4,
|
||||
BRect(0.0f, 0.0f, TO72DPI(4960.0f), TO72DPI(7014.0f)),
|
||||
BRect(TO72DPI(120.0f), TO72DPI(120.0f), TO72DPI(4840.0f), TO72DPI(6894.0f)));
|
||||
@@ -142,7 +143,7 @@ const PaperSourceCap envelopeTray("Envelope Tray", false, JobData::kCassette2)
|
||||
// since 2.0:
|
||||
const PaperSourceCap thridCassette("Thrid Cassette", false, JobData::kMiddle);
|
||||
|
||||
const ResolutionCap dpi150("150dpi", true, 150, 150);
|
||||
const ResolutionCap dpi150("150dpi", false, 150, 150);
|
||||
const ResolutionCap dpi300("300dpi", true, 300, 300);
|
||||
const ResolutionCap dpi600("600dpi", false, 600, 600);
|
||||
const ResolutionCap dpi1200("1200dpi", false, 1200, 1200);
|
||||
@@ -150,26 +151,38 @@ const ResolutionCap dpi1200("1200dpi", false, 1200, 1200);
|
||||
const PrintStyleCap simplex("Simplex", true, JobData::kSimplex);
|
||||
const PrintStyleCap duplex("Duplex", false, JobData::kDuplex);
|
||||
|
||||
const ProtocolClassCap pc1_1("PCL 6 Protocol Class 1.1", true, kProtocolClass1_1,
|
||||
"Protocol Class 1.1\n"
|
||||
"* No compression"
|
||||
const ProtocolClassCap pc1_1("PCL 6 Protocol Class 1.1", true, PCL6Writer::kProtocolClass1_1,
|
||||
"The printer driver supports the following features of protocol class 1.1:\n"
|
||||
"* Monochrome and Color Printing.\n"
|
||||
"* Paper Formats: Letter, Legal, A4, A3, A5 and Japanese Postcard.\n"
|
||||
"* Paper Sources: Auto, Default, Manual Feed, Multi Purpose Tray, Upper and Lower Cassette and Envelope Tray.\n"
|
||||
"* Resolutions: 150, 300, 600 and 1200 DPI."
|
||||
#if ENABLE_RLE_COMPRESSION
|
||||
"\n* RLE compression"
|
||||
"\n* Compression Method: RLE."
|
||||
#else
|
||||
"\n* Compression Method: None."
|
||||
#endif
|
||||
);
|
||||
const ProtocolClassCap pc2_0("PCL 6 Protocol Class 2.0", false, kProtocolClass2_0,
|
||||
"Protocol Class 2.0\n"
|
||||
"* Additonal Paper Source: Third Cassette\n"
|
||||
"* JPEG compression (not implemented yet)");
|
||||
const ProtocolClassCap pc2_1("PCL 6 Protocol Class 2.1", false, kProtocolClass2_1,
|
||||
"Protocol Class 2.1\n"
|
||||
"* Additional Paper Format: B5\n"
|
||||
|
||||
const ProtocolClassCap pc2_0("PCL 6 Protocol Class 2.0", false, PCL6Writer::kProtocolClass2_0,
|
||||
"Additionally to features of protocol class 1.1, the printer driver supports the "
|
||||
"following features of protocol class 2.0:\n"
|
||||
"* Additonal Paper Source: Third Cassette."
|
||||
// "\n* JPEG compression (not implemented yet)"
|
||||
);
|
||||
|
||||
const ProtocolClassCap pc2_1("PCL 6 Protocol Class 2.1", false, PCL6Writer::kProtocolClass2_1,
|
||||
"Additionally to features of previous protocol classes, the printer driver supports the "
|
||||
"following features of protocol class 2.1:\n"
|
||||
"* Additional Paper Format: B5."
|
||||
#if ENABLE_DELTA_ROW_COMPRESSION
|
||||
"* Delta Row Compression"
|
||||
"\n* Additional Compression Method: Delta Row Compression."
|
||||
#endif
|
||||
);
|
||||
const ProtocolClassCap pc3_0("PCL 6 Protocol Class 3.0", false, kProtocolClass3_0,
|
||||
"Protocol Class 3.0");
|
||||
|
||||
// Disable until driver supports new features of protocol class 3.0
|
||||
//const ProtocolClassCap pc3_0("PCL 6 Protocol Class 3.0", false, PCL6Writer::kProtocolClass3_0,
|
||||
//"Protocol Class 3.0");
|
||||
|
||||
const PaperCap *papers1_1[] = {
|
||||
&letter,
|
||||
@@ -228,8 +241,9 @@ const PrintStyleCap *printStyles[] = {
|
||||
const ProtocolClassCap *protocolClasses[] = {
|
||||
&pc1_1,
|
||||
&pc2_0,
|
||||
&pc2_1,
|
||||
&pc3_0
|
||||
&pc2_1
|
||||
// Disabled until driver supports features of protocol class 3.0
|
||||
// &pc3_0
|
||||
};
|
||||
|
||||
const ColorCap color("Color", false, JobData::kColor);
|
||||
@@ -249,12 +263,12 @@ int PCL6Cap::countCap(CapID capid) const
|
||||
{
|
||||
switch (capid) {
|
||||
case kPaper:
|
||||
if (getProtocolClass() >= kProtocolClass2_1) {
|
||||
if (getProtocolClass() >= PCL6Writer::kProtocolClass2_1) {
|
||||
return sizeof(papers2_1) / sizeof(papers2_1[0]);
|
||||
}
|
||||
return sizeof(papers1_1) / sizeof(papers1_1[0]);
|
||||
case kPaperSource:
|
||||
if (getProtocolClass() >= kProtocolClass2_0) {
|
||||
if (getProtocolClass() >= PCL6Writer::kProtocolClass2_0) {
|
||||
return sizeof(paperSources2_0) / sizeof(paperSources2_0[0]);
|
||||
}
|
||||
return sizeof(paperSources1_1) / sizeof(paperSources1_1[0]);
|
||||
@@ -275,12 +289,12 @@ const BaseCap **PCL6Cap::enumCap(CapID capid) const
|
||||
{
|
||||
switch (capid) {
|
||||
case kPaper:
|
||||
if (getProtocolClass() >= kProtocolClass2_1) {
|
||||
if (getProtocolClass() >= PCL6Writer::kProtocolClass2_1) {
|
||||
return (const BaseCap **)papers2_1;
|
||||
}
|
||||
return (const BaseCap **)papers1_1;
|
||||
case kPaperSource:
|
||||
if (getProtocolClass() >= kProtocolClass2_0) {
|
||||
if (getProtocolClass() >= PCL6Writer::kProtocolClass2_0) {
|
||||
return (const BaseCap **)paperSources2_0;
|
||||
}
|
||||
return (const BaseCap **)paperSources1_1;
|
||||
|
||||
@@ -8,13 +8,6 @@
|
||||
|
||||
#include "PrinterCap.h"
|
||||
|
||||
enum ProtocolClass {
|
||||
kProtocolClass1_1,
|
||||
kProtocolClass2_0,
|
||||
kProtocolClass2_1,
|
||||
kProtocolClass3_0,
|
||||
};
|
||||
|
||||
class PCL6Cap : public PrinterCap {
|
||||
public:
|
||||
PCL6Cap(const PrinterData *printer_data);
|
||||
|
||||
Reference in New Issue
Block a user