In trying to track down the cause for the printing bug that’s been harassing me lately, I’ve been simplifying the printing code as much as is possible. In the process, I’ve been cleaning up and evaluating the different implementation details. What functionality, for example, is absolutely necessary when implementing both print preview and general printing support? What’s required to print to multiple devices, such as both a printer and a PDF?
An Interface for Printing Documents
In my trimmed-down version of the print preview component, I’ve tried to eliminate everything that’s unnecessary and cleanup the supporting code. I ended up with the following requirements which form the IPrintableDocument interface:
- nextPage, previousPage – Switches pages in the document
- validNextPage, validPreviousPage – Indicates whether or not there are more pages in the document
- moveToFirstPage – Switches to the first page in the document. Though perhaps not as obvious, if you’re previewing the third page in the document and then choose print, it’s nice not to have to iterate through every page in the document to start printing.
- desiredWidth, desiredHeight – Specify the desired height and width of the document. By specifying 850×1100 (W x H), you indicate that you want a document that has the same ratio as an 8.5″ by 11″ paper, or standard letter size paper. By changing the desired width and height, you could just as easily represent the same ratio as an A2 or A4 size paper. The print engine takes that document and scales it down or up to fit the page. This also serves as a good way to decide how large the document should appear. It’s kind of like deciding between 800×600 or 1280×1024 with a fixed size monitor. The larger the resolution, the smaller everything appears in the document. For us, it turns out that 850×1100 was perfect for letter size paper, giving us a good amount of content without cramming thousands of characters into a single, not-so-respectable line.
- validateNow – Force the redraw of the document after changing pages, etc.
- width, height – When scaling the document to implement zoom, these represent the actual width and height of the document. Generally, desiredWidth and desiredHeight are used to calculate scaling ratios are used when it’s easier to set the width and height directly rather than scaling the document to the correct size.
- x,y – These are the x and y coordinates of the document within the parent container or on the print out. I use these when moving the document around within the print preview.
- scaleX, scaleY – Scale the document in the X or Y direction, respectively. I always set the scale in both directions to maintain the aspect ratio of the document. This is used frequently for zoom and the final printout.
- rotation – Rotates a document, if necessary. After the user clicks on the print button and the print job has been started, the printer dialog pops up, asking the user to choose the printer. Within that printer dialog, the user has the ability to select the orientation of the page. If they select an orientation that does not match that of the document, the document must be rotated by 90 degrees, either clockwise or counterclockwise, to make the document correctly fit on the page. One thing that I found quite annoying was that unless you embed fonts, when you rotate a document, the fonts disappear.
One thing that I do not have in this interface is totalPageCount. It’s not completely necessary, but could be beneficial. Right now, if we want a page-count indicator we perform all the calculations internal to the document; the print preview is completely unaware of the footer changing or doing anything special. However, it would be nice to have a “GoTo Page” option on the print preview, in which case it would be useful. It would also be useful to have a “GoTo First Page” and “GoTo Last Page” options, which are also not implemented, but which could be easily implemented. Right now, the print preview would have to iterate over the document to determine the number of pages.
Supporting Different Devices with Print Engines
When implementing PDF support using AlivePDF, I noticed that we really needed a print engine interface. When dealing with PDFs, or “printing” to other non-printer devices, they don’t need any knowledge of the PrintJob, because the PrintJob is strictly for printing to a physical printer. So, I created a print engine interface to allow other engines, such as a SaveToPDFPrintEngine, to be easily created and used.
Miscellaneous Details
Once the document is complete, and represents a page that should be printed, it’s only necessary to scale the document so that it will fit on the page, and then tell the PrintJob which area of the document to print. Despite having scaled the document, the area of the rectangle must be represented by the size of the unscaled document, thus I use desiredWidth and desiredHeight.
You can take a look at the revised version here or download the source here.
Hi,
the source download link is broken :P. This component looks good, any demo around ?
Thanks
Fabien
http://www.flex-tutorial.fr
Sorry for the delay, you managed to make my spam folder :(. The download link is fixed. The “revised version” links to a demo that prints the same page twice. My first version (the prior post) links to a version at the end of the first paragraph that shows how you can do a header, footer with page numbers, and then make the header only show up on page 1.
Thanks.
–Kaleb
Any updates on this?
I’m not sure exactly what kind of update you’re refering to. I haven’t received any reports of problems or successes but we still see the problem on the same machine and browser combinations. Updating to the Flex-4.3 SDK didn’t resolve the issue at all… and the issue disappears if we don’t compile for (i.e. targeting) Flash Player 10. I’d love to hear from anybody who has tried it.
Hi,Kaleb:
thans for sharing ,it’s really a better component than FlexReport. no more “Ugly Pixelization”, better augmentability. :)
by the way, I can’t reproduce the bug you mentioned in your blog, my Flash Player verion is 10.0 debug version. I printed the doc via my Fuji printer and pdf virtual printer, and there’s no grey block found in the doc.
do you have any updates these days?
Thanks.
Anthony
Hi Anthony,
I haven’t yet tried Flex 4 nor some of the recent versions of the Flash Player but I’m glad to hear that you haven’t had any problems. FlexReport has a better GUI, but it shouldn’t be that difficult to take their UI and integrate it into my backend. I purposefully designed it so that anybody capable of writing a component would be able to easily create components that represented the different pages, or page types. Let me know if there’s anything particular you’re interested in.
Hi,Kaleb:
sorry to bother you again.
I have some questions about your interface for printing documents.
A. desiredWidth and desiredHeight are designed for setting proper width/height ratio? Only if I set correct ratio of A4 paper for a document , then the document will be printed with a correct format. am I right?
B. rotation, this can be set in the printjob dialog, so If I wanna print a document with landscape orientation, so I must set it both in the printing preview and the printing dialog?
Thanks
-Anthony
and besides the page orientation in the printing dialog, it only change the width and height, it does not change the orientation of characters and images.
by the way, Can I have your e-mail? It’s more efficient.
To respond to your questions:
(A) Yes. The document width:height ratio is intended to match that of the page you’re printing to. However, the document will be scaled proportionally up until either the width or the height matches that of the page. The document will not be distorted.
(B) Landscape. To print and preview landscape pages, simply set the width:height ratio to match that of a landscape document. For a letter document, that ratio is 11:8.5. When the document is printed, the print engine checks to see if the desired orientation matches the selected orientation. If the user chooses portrait, the landscape-formatted document will be rotated 90 degrees and then printed. In other words, it doesn’t matter what orientation the user chooses, the document will be printed correctly.
Caveat: Flash can’t rotate fonts correctly if the font is not embedded within your application. Thus, in order to print a landscape document correctly when the user does not choose landscape orientation, the required fonts must be embedded.
Thank you for example. It very Interesting.
Incoming Links
Trackback this post | Subscribe to the comments via RSS Feed