Saturday, February 11, 2006

So, what exactly should be the architecture in the layout engine to support printing (as well as page setup)? On MacOS X, I already have something working. I simply handle the menuitem click for Print internally, and then tell the NSView for the window to print itself. Like this:

case MenuItemClassPrint:
NSView *nsView;

// get the view of the containing window

WidgetImpl *top = GetRootWidget();

if (top) {
CocoaWindowImpl *winImpl = dynamic_cast<CocoaWindowImpl *>(top);
if (winImpl) {
nsView = winImpl->GetView();
if (nsView)
[[NSPrintOperation printOperationWithView:nsView] runOperation];

At least I am hoping it is that easy :-) Print setup on MacOS X is even easier -- displaying the print setup dialog is all that seems to be needed; the results are remembered by MacOS X and apply to subsequent print operations. In Windows .NET, it appears things are a bit more complicated. There is a PrintDialog object that will post a UI on behalf of the client, and will, should the user go thru with the print operations, callback on a class that inherits from System.Drawing.Printing.PrintController. The class inheriting from the PrintController interface implements methods allowing it to monitor printing process, and to draw the content being printed to a graphics device that represents the printer. I'm not really experienced with this yet -- I'll need to prototype to become more clear. I am not yet sure what methods support print setup, or if the result of the print setup needs to be maintained by the application or if it is system wide like on MacOS X.

On Gtk+, it's all bare bones. When the user clicks print setup, I will need to display a dialog of my own creation. I will also need to store the results of that dialog in the application. Similarly, when print is clicked, I will need to refer back to these settings, and post my own print dialog. When the user clicks ok in the print dialog, I will need to send the Window a message asking it to print itself.

This implies the following. First, there is no intrinsic need for the user to assign a JavaScript callback to either the page setup or print dialogs (I'll make an exception to this below, but the page setup and print functions can operate on their own). Second, it implies that I need to design some interface class called Printable that allows the toolkit to call methods on an object to, at a minimum, print itself.

I mentioned that the client need not be called on JavaScript listeners when the page setup or print dialogs are invoked. In reality, it would be nice to callback a JavaScript function when printing is started, as each page is printed, when printing has completed, and should an error occur, some indication of the problem (an error code at least, a string to go along with it at most), so that the application can monitor the complete printing process and communicate it back to the user.

A nice discovery today was that CUPS comes with a C-based library that allows me to do a wide variety of things, such a querying for the list of configured printers, as well as the default, communicate print settings, and initiate a print job. I'm sure that the backend to the Gtk+ widget I will need to create will use this library; had it existed back when I worked on the Netscape/Mozilla printing system, I am sure it would have been a part of the solution there too.


Post a Comment

<< Home