Last week, I've had some time to hack on my notebook. Fun stuff only. I've finished a few things I started earlier and did some other things. Here's a list of what I've done. Since some of them might be controversial I want to give you a chance to object, just in case. So here are the changes (almost) ready for committing on my notebook:
- Two new constructors for Fop.java: Fop(String) and Fop(String, FOUserAgent) where String is a MIME type. - org.apache.fop.apps.MimeConstants with a comprehensive list of MIME types used in FOP. - Non-standard, FOP-specific MIME types changed to a uniform pattern: application/X-fop-awt-preview, application/X-fop-print, application/X-fop-areatree - RendererFactory now supports manual registration and dynamic discovery of Renderers and FOEventHandlers by their MIME types. Instantiation is done using MIME types everywhere. - The RENDER_* constants are mapped to MIME types in Fop.java. I'd like to remove them but left them where they are for the moment. I'd also like to remove the "implements Constants" from Fop.java. But that's nothing new. :-) - RendererFactory is now an instantiable class whose reference is held by FOUserAgent just like it is done for the XMLHandlers. - Renderers and FOEventHandlers now each have a *Maker class which is also a kind of factory class which is used to register a Renderer/FOEventHandler and additionally serves to provide additional information about the thing, such as which MIME types it supports and if the implementation requires an OutputStream. - The command-line gets a new option: -out application/pdf myfile.pdf is the generic way to create an output file. If someone created a WordXML output handler and provided the right service resource file he could specify "-out text/xml+msword out.xml". "-out list" lists all MIME types that are available for output. - To make things a little more consistent and error reporting easier, I've changed FNode so each FNode can return the namespace URI it belongs to (getNamespaceURI()). Furthermore, it can return the normally used namespace prefix (getNormalNamespacePrefix(), "fo" for XSL-FO) and I've added methods to build the fully qualified name from a local name. For this I've changed getName() to getLocalName() for all descendants of FONode so it is defined to return only the local name and not (in some cases) the fully qualified name. The whole stuff now feels a lot cleaner. - I've started extended support to handle alternative forms of painting graphics. For example, Barcode4J supports SVG, EPS, bitmaps and Java2D as output targets. For PostScript, it's better too use EPS directly. In PDF Java2D could be used instead of SVG to avoid the slow round-trip through Batik. RTF could use Bitmaps. I've started a Graphics2DAdapter which renderers provide if they can provide a Graphics2D instance for painting. XMLHandler can query a Graphics2DAdapter and use that to paint the graphic. The image is passed to the Graphics2DAdapter as a Graphics2DImagePainter instance which essentially provides a paint(Graphics2D, Rectangle) method and a getImageSize() method. While implementing the last point I've had to realize that while this is a step forward, this is not enough in the long run. I believe we need to also refactor the whole image package again to handle a few additional problems. An example: Our JPEG support is currently restricted to PDF and PS renderers where the JPEG can be embedded in undecoded form. The Java2D renderer descendants currently don't support JPEG at all because they can't get a decoded JPEG image. What I would like to do is introduce something similar to the concept already used by the Java Printing System (JPS): The DocFlavor, an object to describe the format (SVG, JPEG, MathML etc.) and manifestation (byte[], DOM etc.). The renderers say what formats they support (with desirability indicators) and the image classes will support providing the images in different flavors, as needed. In between, special converters can convert from one format to another, like converting a MathML DOM to a bitmap image. I'm not going into more detail right now. I'll document everything on the Wiki. I can only say that I had to realize that I will basically need to recreate Nicola Ken Barozzi's Morphos idea again. That's going to be interesting and a lot of fun. :-) Ok, so if anybody is against any of the above points or needs additional information, please tell me. Jeremias Maerki
