Hi all,
Here’s a tutorial for printing with Juce.
First of all, as you may know, Juce Graphics is all vector based.
The vector drawing operations you perform on a Graphics object are then simplified to basic primitives, and applied to a LowLevelGraphicsRenderer.
This renderer can be based on an image (typically for a window on screen, or an offscreen bitmap), or using hardware accelerated primitive rendering (OpenGL for one, still not done).
One of these low level renderer is a PostScript renderer, and you’ll need to use this renderer to render your wonderful application graphic to an horrible washed ink-based print.
When you create this renderer, you’ll give a reference to the output stream you’ll later send to the printer, the document title, and the total width and height for the rendered page in arbitary units.
You’ll then create the Graphics object with this renderer, and perform your rendering as usual with your paint method.
Then, if everything goes well, you’ll get an output EPSF stream that you’ll need to send to the printer, through the drivers.
From now, things are getting more complex:
[list]
[*] Under Windows, you’ll have to use code like this:
[code]
void printEPSStream(const OutputStream & stream, const String & printerName, const String & documentName)
{
HANDLE hPrinter = 0;
DOC_INFO_1 doc = { 0 };
doc.pDocName = documentName;
doc.pDatatype = “RAW”;
if( OpenPrinter(printerName, &hPrinter, 0) )
{
// Start a document.
if( StartDocPrinter(hPrinter, 1, (BYTE*)&doc) )
{
// Start a page.
MemoryOutputStream * memStream = dynamic_cast<MemoryOutputStream*>(&stream);
if( memStream && StartPagePrinter(hPrinter) )
{
DWORD dwWritten = 0;
WritePrinter(hPrinter, memStream->getData(), memStream->getDataSize(), &dwWritten);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
}
[/code][/]
[] Under Linux, you’ll simply have to pipe the outputStream to the lpr program with this code (don’t used NamedPipe as they are Fifo not pipe):
[code]
void printEPSStream(const OutputStream & stream, const String & printerName, const String & documentName)
{
MemoryOutputStream * memStream = dynamic_cast<MemoryOutputStream*>(&stream);
if (!memStream) return;
String processName = “lpr -P”+ printerName;
FILE * outputPipe = popen(processName.toUTF8(), “w”);
if (outputPipe != NULL)
{
fwrite(memStream->getData(), 1, memStream->getDataSize(), outputPipe);
pclose(outputPipe));
}
}
[/code][/]
[] I’m not sure about MacOSX, but I guess, the posix way should do it too.[/*][/list]
Concerning the printerName, there is no cross platform code already present. Under Window you’ll use EnumPrinters, under Linux you’ll have to parse /etc/printcap, and under Mac, well I’ve no idea.
Hope it helps.