needs gutenprint8 packages to be uploaded. Change-Id: I1204ff8b1bb85cc0eb615082b205280daabbc290 Signed-off-by: Augustin Cavalier <[email protected]>
313 lines
7.0 KiB
C++
313 lines
7.0 KiB
C++
/*
|
|
* GP.cpp
|
|
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
|
* Copyright 2010 Michael Pfeiffer.
|
|
*/
|
|
|
|
|
|
#include "GPDriver.h"
|
|
|
|
#include <memory>
|
|
|
|
#include <Alert.h>
|
|
#include <Bitmap.h>
|
|
#include <Debug.h>
|
|
#include <File.h>
|
|
|
|
#include "DbgMsg.h"
|
|
#include "Halftone.h"
|
|
#include "JobData.h"
|
|
#include "PackBits.h"
|
|
#include "GPCapabilities.h"
|
|
#include "GPData.h"
|
|
#include "PrinterData.h"
|
|
#include "UIDriver.h"
|
|
#include "ValidRect.h"
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
GPDriver::GPDriver(BMessage* message, PrinterData* printerData,
|
|
const PrinterCap* printerCap)
|
|
:
|
|
GraphicsDriver(message, printerData, printerCap)
|
|
{
|
|
}
|
|
|
|
void
|
|
GPDriver::Write(const void* buffer, size_t size)
|
|
{
|
|
WriteSpoolData(buffer, size);
|
|
}
|
|
|
|
bool
|
|
GPDriver::StartDocument()
|
|
{
|
|
try {
|
|
const GPData* data = dynamic_cast<const GPData*>(GetPrinterData());
|
|
ASSERT(data != NULL);
|
|
fConfiguration.fDriver = data->fGutenprintDriverName;
|
|
|
|
SetParameter(fConfiguration.fPageSize, PrinterCap::kPaper,
|
|
GetJobData()->GetPaper());
|
|
|
|
SetParameter(fConfiguration.fResolution, PrinterCap::kResolution,
|
|
GetJobData()->GetResolutionID());
|
|
|
|
fConfiguration.fXDPI = GetJobData()->GetXres();
|
|
fConfiguration.fYDPI = GetJobData()->GetYres();
|
|
|
|
SetParameter(fConfiguration.fInputSlot, PrinterCap::kPaperSource,
|
|
GetJobData()->GetPaperSource());
|
|
|
|
SetParameter(fConfiguration.fPrintingMode, PrinterCap::kColor,
|
|
GetJobData()->GetColor());
|
|
|
|
if (GetPrinterCap()->Supports(PrinterCap::kDriverSpecificCapabilities))
|
|
SetDriverSpecificSettings();
|
|
|
|
fprintf(stderr, "Driver: %s\n", fConfiguration.fDriver.String());
|
|
fprintf(stderr, "PageSize %s\n", fConfiguration.fPageSize.String());
|
|
fprintf(stderr, "Resolution %s\n", fConfiguration.fResolution.String());
|
|
fprintf(stderr, "InputSlot %s\n", fConfiguration.fInputSlot.String());
|
|
fprintf(stderr, "PrintingMode %s\n", fConfiguration.fPrintingMode.String());
|
|
|
|
return fBinding.BeginJob(&fConfiguration, this) == B_OK;
|
|
}
|
|
catch (TransportException& err) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
GPDriver::SetParameter(BString& parameter, PrinterCap::CapID category,
|
|
int value)
|
|
{
|
|
const EnumCap* capability;
|
|
capability = GetPrinterCap()->FindCap(category, value);
|
|
if (capability != NULL && capability->fKey != "")
|
|
parameter = capability->Key();
|
|
}
|
|
|
|
|
|
void
|
|
GPDriver::SetDriverSpecificSettings()
|
|
{
|
|
PrinterCap::CapID category = PrinterCap::kDriverSpecificCapabilities;
|
|
int count = GetPrinterCap()->CountCap(category);
|
|
const BaseCap** capabilities = GetPrinterCap()->GetCaps(category);
|
|
for (int i = 0; i < count; i++) {
|
|
const DriverSpecificCap* capability =
|
|
dynamic_cast<const DriverSpecificCap*>(capabilities[i]);
|
|
if (capability == NULL) {
|
|
fprintf(stderr, "Internal error: DriverSpecificCap name='%s' "
|
|
"has wrong type!\n", capabilities[i]->Label());
|
|
continue;
|
|
}
|
|
|
|
PrinterCap::CapID id = static_cast<PrinterCap::CapID>(capability->ID());
|
|
const char* key = capability->fKey.c_str();
|
|
switch (capability->fType) {
|
|
case DriverSpecificCap::kList:
|
|
AddDriverSpecificSetting(id, key);
|
|
break;
|
|
case DriverSpecificCap::kBoolean:
|
|
AddDriverSpecificBooleanSetting(id, key);
|
|
break;
|
|
case DriverSpecificCap::kIntRange:
|
|
AddDriverSpecificIntSetting(id, key);
|
|
break;
|
|
case DriverSpecificCap::kIntDimension:
|
|
AddDriverSpecificDimensionSetting(id, key);
|
|
break;
|
|
case DriverSpecificCap::kDoubleRange:
|
|
AddDriverSpecificDoubleSetting(id, key);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
GPDriver::AddDriverSpecificSetting(PrinterCap::CapID category, const char* key) {
|
|
const EnumCap* capability = NULL;
|
|
if (GetJobData()->Settings().HasString(key))
|
|
{
|
|
const string& value = GetJobData()->Settings().GetString(key);
|
|
capability = GetPrinterCap()->FindCapWithKey(category, value.c_str());
|
|
}
|
|
|
|
if (capability == NULL) {
|
|
// job data should contain a value;
|
|
// try to use the default value anyway
|
|
capability = GetPrinterCap()->GetDefaultCap(category);
|
|
}
|
|
|
|
if (capability == NULL) {
|
|
// should not reach here!
|
|
return;
|
|
}
|
|
|
|
fConfiguration.fStringSettings[key] = capability->fKey;
|
|
}
|
|
|
|
|
|
void
|
|
GPDriver::AddDriverSpecificBooleanSetting(PrinterCap::CapID category,
|
|
const char* key) {
|
|
if (GetJobData()->Settings().HasBoolean(key))
|
|
fConfiguration.fBooleanSettings[key] =
|
|
GetJobData()->Settings().GetBoolean(key);
|
|
}
|
|
|
|
|
|
void
|
|
GPDriver::AddDriverSpecificIntSetting(PrinterCap::CapID category,
|
|
const char* key) {
|
|
if (GetJobData()->Settings().HasInt(key))
|
|
fConfiguration.fIntSettings[key] =
|
|
GetJobData()->Settings().GetInt(key);
|
|
}
|
|
|
|
|
|
void
|
|
GPDriver::AddDriverSpecificDimensionSetting(PrinterCap::CapID category,
|
|
const char* key) {
|
|
if (GetJobData()->Settings().HasInt(key))
|
|
fConfiguration.fDimensionSettings[key] =
|
|
GetJobData()->Settings().GetInt(key);
|
|
}
|
|
|
|
|
|
void
|
|
GPDriver::AddDriverSpecificDoubleSetting(PrinterCap::CapID category,
|
|
const char* key) {
|
|
if (GetJobData()->Settings().HasDouble(key))
|
|
fConfiguration.fDoubleSettings[key] =
|
|
GetJobData()->Settings().GetDouble(key);
|
|
}
|
|
|
|
|
|
bool
|
|
GPDriver::StartPage(int)
|
|
{
|
|
fBinding.BeginPage();
|
|
return true;
|
|
}
|
|
|
|
|
|
bool
|
|
GPDriver::EndPage(int)
|
|
{
|
|
try {
|
|
fBinding.EndPage();
|
|
return true;
|
|
}
|
|
catch (TransportException& err) {
|
|
ShowError(err.What());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
bool
|
|
GPDriver::EndDocument(bool)
|
|
{
|
|
try {
|
|
fBinding.EndJob();
|
|
return true;
|
|
}
|
|
catch (TransportException& err) {
|
|
ShowError(err.What());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
bool
|
|
GPDriver::NextBand(BBitmap* bitmap, BPoint* offset)
|
|
{
|
|
DBGMSG(("> nextBand\n"));
|
|
try {
|
|
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 pageHeight = GetPageHeight();
|
|
|
|
if (y + height > pageHeight)
|
|
height = pageHeight - 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 height = rc.bottom - rc.top + 1;
|
|
fprintf(stderr, "GPDriver nextBand x %d, y %d, width %d,"
|
|
" height %d\n",
|
|
x, y, width, height);
|
|
BRect imageRect(rc.left, rc.top, rc.right, rc.bottom);
|
|
status_t status;
|
|
status = fBinding.AddBitmapToPage(bitmap, imageRect, BPoint(x, y));
|
|
if (status == B_NO_MEMORY) {
|
|
ShowError("Out of memory");
|
|
return false;
|
|
} else if (status != B_OK) {
|
|
ShowError("Unknown error");
|
|
return false;
|
|
}
|
|
|
|
} else {
|
|
DBGMSG(("band bitmap is empty.\n"));
|
|
}
|
|
|
|
if (y >= pageHeight) {
|
|
offset->x = -1.0;
|
|
offset->y = -1.0;
|
|
} else
|
|
offset->y += height;
|
|
|
|
DBGMSG(("< nextBand\n"));
|
|
return true;
|
|
}
|
|
catch (TransportException& err) {
|
|
ShowError(err.What());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
GPDriver::ShowError(const char* message)
|
|
{
|
|
BString text;
|
|
text << "An error occurred attempting to print with Gutenprint:";
|
|
text << "\n";
|
|
text << message;
|
|
BAlert* alert = new BAlert("", text.String(), "OK");
|
|
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
|
|
alert->Go();
|
|
}
|