3 * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
4 * Copyright 2010 Michael Pfeiffer.
21 #include "GPCapabilities.h"
23 #include "PrinterData.h"
25 #include "ValidRect.h"
31 GPDriver::GPDriver(BMessage
* message
, PrinterData
* printerData
,
32 const PrinterCap
* printerCap
)
34 GraphicsDriver(message
, printerData
, printerCap
)
39 GPDriver::Write(const void* buffer
, size_t size
)
40 throw (TransportException
)
42 WriteSpoolData(buffer
, size
);
46 GPDriver::StartDocument()
49 const GPData
* data
= dynamic_cast<const GPData
*>(GetPrinterData());
51 fConfiguration
.fDriver
= data
->fGutenprintDriverName
;
53 SetParameter(fConfiguration
.fPageSize
, PrinterCap::kPaper
,
54 GetJobData()->GetPaper());
56 SetParameter(fConfiguration
.fResolution
, PrinterCap::kResolution
,
57 GetJobData()->GetResolutionID());
59 fConfiguration
.fXDPI
= GetJobData()->GetXres();
60 fConfiguration
.fYDPI
= GetJobData()->GetYres();
62 SetParameter(fConfiguration
.fInputSlot
, PrinterCap::kPaperSource
,
63 GetJobData()->GetPaperSource());
65 SetParameter(fConfiguration
.fPrintingMode
, PrinterCap::kColor
,
66 GetJobData()->GetColor());
68 if (GetPrinterCap()->Supports(PrinterCap::kDriverSpecificCapabilities
))
69 SetDriverSpecificSettings();
71 fprintf(stderr
, "Driver: %s\n", fConfiguration
.fDriver
.String());
72 fprintf(stderr
, "PageSize %s\n", fConfiguration
.fPageSize
.String());
73 fprintf(stderr
, "Resolution %s\n", fConfiguration
.fResolution
.String());
74 fprintf(stderr
, "InputSlot %s\n", fConfiguration
.fInputSlot
.String());
75 fprintf(stderr
, "PrintingMode %s\n", fConfiguration
.fPrintingMode
.String());
77 return fBinding
.BeginJob(&fConfiguration
, this) == B_OK
;
79 catch (TransportException
& err
) {
86 GPDriver::SetParameter(BString
& parameter
, PrinterCap::CapID category
,
89 const EnumCap
* capability
;
90 capability
= GetPrinterCap()->FindCap(category
, value
);
91 if (capability
!= NULL
&& capability
->fKey
!= "")
92 parameter
= capability
->Key();
97 GPDriver::SetDriverSpecificSettings()
99 PrinterCap::CapID category
= PrinterCap::kDriverSpecificCapabilities
;
100 int count
= GetPrinterCap()->CountCap(category
);
101 const BaseCap
** capabilities
= GetPrinterCap()->GetCaps(category
);
102 for (int i
= 0; i
< count
; i
++) {
103 const DriverSpecificCap
* capability
=
104 dynamic_cast<const DriverSpecificCap
*>(capabilities
[i
]);
105 if (capability
== NULL
) {
106 fprintf(stderr
, "Internal error: DriverSpecificCap name='%s' "
107 "has wrong type!\n", capabilities
[i
]->Label());
111 PrinterCap::CapID id
= static_cast<PrinterCap::CapID
>(capability
->ID());
112 const char* key
= capability
->fKey
.c_str();
113 switch (capability
->fType
) {
114 case DriverSpecificCap::kList
:
115 AddDriverSpecificSetting(id
, key
);
117 case DriverSpecificCap::kBoolean
:
118 AddDriverSpecificBooleanSetting(id
, key
);
120 case DriverSpecificCap::kIntRange
:
121 AddDriverSpecificIntSetting(id
, key
);
123 case DriverSpecificCap::kIntDimension
:
124 AddDriverSpecificDimensionSetting(id
, key
);
126 case DriverSpecificCap::kDoubleRange
:
127 AddDriverSpecificDoubleSetting(id
, key
);
135 GPDriver::AddDriverSpecificSetting(PrinterCap::CapID category
, const char* key
) {
136 const EnumCap
* capability
= NULL
;
137 if (GetJobData()->Settings().HasString(key
))
139 const string
& value
= GetJobData()->Settings().GetString(key
);
140 capability
= GetPrinterCap()->FindCapWithKey(category
, value
.c_str());
143 if (capability
== NULL
) {
144 // job data should contain a value;
145 // try to use the default value anyway
146 capability
= GetPrinterCap()->GetDefaultCap(category
);
149 if (capability
== NULL
) {
150 // should not reach here!
154 fConfiguration
.fStringSettings
[key
] = capability
->fKey
;
159 GPDriver::AddDriverSpecificBooleanSetting(PrinterCap::CapID category
,
161 if (GetJobData()->Settings().HasBoolean(key
))
162 fConfiguration
.fBooleanSettings
[key
] =
163 GetJobData()->Settings().GetBoolean(key
);
168 GPDriver::AddDriverSpecificIntSetting(PrinterCap::CapID category
,
170 if (GetJobData()->Settings().HasInt(key
))
171 fConfiguration
.fIntSettings
[key
] =
172 GetJobData()->Settings().GetInt(key
);
177 GPDriver::AddDriverSpecificDimensionSetting(PrinterCap::CapID category
,
179 if (GetJobData()->Settings().HasInt(key
))
180 fConfiguration
.fDimensionSettings
[key
] =
181 GetJobData()->Settings().GetInt(key
);
186 GPDriver::AddDriverSpecificDoubleSetting(PrinterCap::CapID category
,
188 if (GetJobData()->Settings().HasDouble(key
))
189 fConfiguration
.fDoubleSettings
[key
] =
190 GetJobData()->Settings().GetDouble(key
);
195 GPDriver::StartPage(int)
197 fBinding
.BeginPage();
203 GPDriver::EndPage(int)
209 catch (TransportException
& err
) {
210 ShowError(err
.What());
217 GPDriver::EndDocument(bool)
223 catch (TransportException
& err
) {
224 ShowError(err
.What());
231 GPDriver::NextBand(BBitmap
* bitmap
, BPoint
* offset
)
233 DBGMSG(("> nextBand\n"));
235 BRect bounds
= bitmap
->Bounds();
238 rc
.left
= (int)bounds
.left
;
239 rc
.top
= (int)bounds
.top
;
240 rc
.right
= (int)bounds
.right
;
241 rc
.bottom
= (int)bounds
.bottom
;
243 int height
= rc
.bottom
- rc
.top
+ 1;
245 int x
= (int)offset
->x
;
246 int y
= (int)offset
->y
;
248 int pageHeight
= GetPageHeight();
250 if (y
+ height
> pageHeight
)
251 height
= pageHeight
- y
;
253 rc
.bottom
= height
- 1;
255 DBGMSG(("height = %d\n", height
));
256 DBGMSG(("x = %d\n", x
));
257 DBGMSG(("y = %d\n", y
));
259 if (get_valid_rect(bitmap
, &rc
)) {
261 DBGMSG(("validate rect = %d, %d, %d, %d\n",
262 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
));
267 int width
= rc
.right
- rc
.left
+ 1;
268 int height
= rc
.bottom
- rc
.top
+ 1;
269 fprintf(stderr
, "GPDriver nextBand x %d, y %d, width %d,"
271 x
, y
, width
, height
);
272 BRect
imageRect(rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
274 status
= fBinding
.AddBitmapToPage(bitmap
, imageRect
, BPoint(x
, y
));
275 if (status
== B_NO_MEMORY
) {
276 ShowError("Out of memory");
278 } else if (status
!= B_OK
) {
279 ShowError("Unknown error");
284 DBGMSG(("band bitmap is empty.\n"));
287 if (y
>= pageHeight
) {
293 DBGMSG(("< nextBand\n"));
296 catch (TransportException
& err
) {
297 ShowError(err
.What());
304 GPDriver::ShowError(const char* message
)
307 text
<< "An error occurred attempting to print with Gutenprint:";
310 BAlert
* alert
= new BAlert("", text
.String(), "OK");
311 alert
->SetFlags(alert
->Flags() | B_CLOSE_ON_ESCAPE
);