gen1986 | 3 Jan 2011 16:55
Picon

how to extend the rendering part of fop


Hi,

I'm working on a project where I have to extend FO to support custom tags
for drawing charts.
For doing so I've extended ElementMapping and created my custom
ContentHandlerFactory, etc.
Until here it's ok. I can get all the infos about the chart from the xsl-fo
template.

My problem is that I want now to write the chart as a stream to the PDF, but
I don't know which fop classes to use for doing it the right way. Any help
is welcome.

If my problem isn't clear enough I can give more explanations, just let me
know ;)

Thanks,

Eugen
--

-- 
View this message in context: http://old.nabble.com/how-to-extend-the-rendering-part-of-fop-tp30579066p30579066.html
Sent from the FOP - Users mailing list archive at Nabble.com.
Jeremias Maerki | 3 Jan 2011 17:53
Picon
Gravatar

Re: how to extend the rendering part of fop

Hi Eugen

Assuming you're using Apache FOP 1.0 or later, I would suggest to you to
write a set of plug-ins for the Apache XML Graphics Commons image loader
framework. The documentation for that is found here:
http://xmlgraphics.apache.org/commons/image-loader.html

That's our new infrastructure for handling images. And your charting XML
is nothing other than an image in XML. A good example of such a set of
plug-ins can be found in Barcode4J:
http://barcode4j.cvs.sourceforge.net/viewvc/barcode4j/barcode4j/src/xmlgraphics-commons/

You can see multiple ImageConverter implementations there. One converts
[1] a generic XML document into an ImageBarcode [2]. And you would
create something like an ImageChart. Furthermore, I'd go the Java2D
route (Graphics2D), so you'd add an ImageConverter which takes an
ImageChart and produces an ImageGraphics2D [3] (The code in there
basically paints your chart against a Graphics2D object). The latter can
be processed by FOP's PDF support to create high-quality vector graphics
without you having to learn about PDF specifics. The nice side-effect is
that it won't only work for PDF, but also for all other output formats
supported by FOP.

[1] http://barcode4j.cvs.sourceforge.net/viewvc/barcode4j/barcode4j/src/xmlgraphics-commons/java/org/krysalis/barcode4j/image/loader/ImageConverterBarcodeXML2Barcode.java?view=markup
[2] http://barcode4j.cvs.sourceforge.net/viewvc/barcode4j/barcode4j/src/xmlgraphics-commons/java/org/krysalis/barcode4j/image/loader/ImageBarcode.java?view=markup
[3] http://barcode4j.cvs.sourceforge.net/viewvc/barcode4j/barcode4j/src/xmlgraphics-commons/java/org/krysalis/barcode4j/image/loader/ImageConverterBarcode2G2D.java?view=markup

If you don't plan to put charts in external files (i.e. you use only
fo:instream-foreign-object), you can omit the Preloader, LoaderFactory
and Loader, I think. The image converters should be enough.
(Continue reading)

gen1986 | 3 Jan 2011 20:34
Picon

Re: how to extend the rendering part of fop


Hi Jeremias,

Thanks for your quick response.
However I'll give some more informations about what I'm trying to achieve.

A sketch of the template :

... XSL-FO tags ...
<fo:instream-foreign-object...

<chart:chart xmlns:c="www...charts..">
 <c:pie width=".." height="..">
 <c:title value="Hello Piechart"/>
 ... some custom tags to retrieve data ...
</c:pie>
</chart:chart>

... XSL-FO tags ...

My elementMapping extension handles those tags and creates my objects
describing the chart. 

1) Actually I'm extending FONode, should I rather extend
InstreamForeignObject?

At some point (when the pdf is rendered) I'll use my objects to draw the
chart to Graphics2D. But I will not create an Image.

As you mentioned, it looks a lot like what you are doing here :
(Continue reading)

Stepan RYBAR | 3 Jan 2011 22:18
Picon
Favicon

Re: Re: how to extend the rendering part of fop

Hi, Eugen, 

try to look for a minute on the XSL-T 2.0 library "graph2svg", could be found on
"http://graph2svg.jinak.cz/examples_en.html". It is pure XSL-T 2.0 from XML to SVG (when using
two-phase transformation even inline SVG). The source XML code of graph2svg looks very similar to Your
example code. 

Cheers, Stepan 

> ------------ Původní zpráva ------------
> Od: gen1986 <cepoi.eugen <at> gmail.com>
> Předmět: Re: how to extend the rendering part of fop
> Datum: 03.1.2011 20:34:39
> ----------------------------------------
> 
> Hi Jeremias,
> 
> Thanks for your quick response.
> However I'll give some more informations about what I'm trying to achieve.
> 
> A sketch of the template :
> 
> ... XSL-FO tags ...
> <fo:instream-foreign-object...
> 
> <chart:chart xmlns:c="www...charts..">
>  <c:pie width=".." height="..">
>  <c:title value="Hello Piechart"/>
>  ... some custom tags to retrieve data ...
> </c:pie>
(Continue reading)

Jeremias Maerki | 3 Jan 2011 22:41
Picon
Gravatar

Re: how to extend the rendering part of fop

On 03.01.2011 20:34:03 gen1986 wrote:
> 
> Hi Jeremias,
> 
> Thanks for your quick response.
> However I'll give some more informations about what I'm trying to achieve.
> 
> A sketch of the template :
> 
> ... XSL-FO tags ...
> <fo:instream-foreign-object...
> 
> <chart:chart xmlns:c="www...charts..">
>  <c:pie width=".." height="..">
>  <c:title value="Hello Piechart"/>
>  ... some custom tags to retrieve data ...
> </c:pie>
> </chart:chart>
> 
> ... XSL-FO tags ...
> 
> My elementMapping extension handles those tags and creates my objects
> describing the chart. 
> 
> 1) Actually I'm extending FONode, should I rather extend
> InstreamForeignObject?

You basically need a "ChartObj extends XMLObj" (XMLObj is a subclass of
FONode) and a "ChartElement extends ChartObj". ChartElement represents
the top-level chart:chart elements and all its child elements can use
(Continue reading)

Eric Douglas | 3 Jan 2011 22:55
Favicon

RE: Re: how to extend the rendering part of fop

I was going to suggest SVG, the simplest way to produce a chart, but the OP asked about extensions like they
already had something more complicated in mind with their mind made up about how they want to do
it.

http://blog.trivadis.com/blogs/andreasmengel/archive/2008/03/14/generating-svg-pie-charts-in-pdf-documents.aspx 

-----Original Message-----
From: Stepan RYBAR [mailto:xrybs01 <at> seznam.cz] 
Sent: Monday, January 03, 2011 4:19 PM
To: fop-users <at> xmlgraphics.apache.org
Subject: Re: Re: how to extend the rendering part of fop

Hi, Eugen, 

try to look for a minute on the XSL-T 2.0 library "graph2svg", could be found on
"http://graph2svg.jinak.cz/examples_en.html". It is pure XSL-T 2.0 from XML to SVG (when using
two-phase transformation even inline SVG). The source XML code of graph2svg looks very similar to Your
example code. 

Cheers, Stepan 

> ------------ Původní zpráva ------------
> Od: gen1986 <cepoi.eugen <at> gmail.com>
> Předmět: Re: how to extend the rendering part of fop
> Datum: 03.1.2011 20:34:39
> ----------------------------------------
> 
> Hi Jeremias,
> 
> Thanks for your quick response.
(Continue reading)

gen1986 | 5 Jan 2011 11:52
Picon

Re: how to extend the rendering part of fop


Stepan and Eric thanks for the suggestions but the whole thing must be done
in java (the charting is only a part of the app).
Jeremias solution is close to what I must do.

After following the explanations of Jeremias and reading the sources of
Barcode4J, etc. I manage to get something out, but it still doesn't work and
I'm not sure about some points.

1) I don't have to call imageManager.convertImage(image, flavors) right ?
It's the fop framework who will do that. However if it's true, something is
going wrong because my converters are not executed.

2) When I'm running the transformation I've got an error
GRAVE: Image not available. URI: (instream-object). Reason:
org.apache.xmlgraphics.image.loader.ImageException: The file format is not
supported. No ImagePreloader found for null (No context info available). 

After googling a bit I've found that we have to add the following line to
the fop conf :  <prefer-renderer>true</prefer-renderer>

If I'm doing so I've got another error : No handler defined for my
namespace...

So instead asking a lot of questions I've uploaded a basic test project so
you can see what I'm doing wrong.
http://old.nabble.com/file/p30594894/Fop-ChartExtension.rar
Fop-ChartExtension.rar 

Thanks for your help!
(Continue reading)

Chris Bowditch | 5 Jan 2011 15:38
Picon
Favicon

Re: how to extend the rendering part of fop

On 05/01/2011 10:52, gen1986 wrote:

Hello,
> Stepan and Eric thanks for the suggestions but the whole thing must be done
> in java (the charting is only a part of the app).
> Jeremias solution is close to what I must do.
>
> After following the explanations of Jeremias and reading the sources of
> Barcode4J, etc. I manage to get something out, but it still doesn't work and
> I'm not sure about some points.
>
> 1) I don't have to call imageManager.convertImage(image, flavors) right ?
> It's the fop framework who will do that. However if it's true, something is
> going wrong because my converters are not executed.

Right, the Image Loader framework takes care of that. Did you add the 
file named "org.apache.xmlgraphics.image.loader.spi.ImageConverter" to 
the JAR containing your code in META-INF\services sub directory as 
suggested by Jeremias? This is needed in order for the Image Loader 
Framework to be made aware of your converter.
> 2) When I'm running the transformation I've got an error
> GRAVE: Image not available. URI: (instream-object). Reason:
> org.apache.xmlgraphics.image.loader.ImageException: The file format is not
> supported. No ImagePreloader found for null (No context info available).
>
> After googling a bit I've found that we have to add the following line to
> the fop conf :<prefer-renderer>true</prefer-renderer>
That is not the correct solution. The prefer-renderer option forces use 
of the older renderers. The old Renderers don't benefit from the latest 
bug fixes and improvements that have been made to the painters.
(Continue reading)

gen1986 | 5 Jan 2011 16:25
Picon

Re: how to extend the rendering part of fop


Hi Chris,

> Did you add the 
> file named "org.apache.xmlgraphics.image.loader.spi.ImageConverter" to 
> the JAR containing your code in META-INF\services sub directory as 
> suggested by Jeremias?

Yep (you can see it in the attachment).

I have created a ImageChartPreloader to preload the ImageInfo from
DOMSource. 
What I can see is that the originalURI is null. 

1) Should I do something at some place to specifiy that uri? (where, how...)

2) However even if the originalURI is null as I can get all the infos from
the source it's ok.
But what MimeType should I give to the created ImageInfo? (I've tried some,
but I always get the same error : no suitable loader/converter
combination...etc)

3) I've tried to solve my problem with the preloader, but if it's not the
right way for doing it (ex: maybe
setting some attributes to the Document is?) tell me.

4) Please take à look at the attachment, so you can tell me what is missing.

Eugen

(Continue reading)

Jeremias Maerki | 5 Jan 2011 23:49
Picon
Gravatar

Re: how to extend the rendering part of fop

On 05.01.2011 16:25:20 gen1986 wrote:
> 
> Hi Chris,
> 
> > Did you add the 
> > file named "org.apache.xmlgraphics.image.loader.spi.ImageConverter" to 
> > the JAR containing your code in META-INF\services sub directory as 
> > suggested by Jeremias?
> 
> Yep (you can see it in the attachment).

the attachment seems to be missing.

> I have created a ImageChartPreloader to preload the ImageInfo from
> DOMSource. 
> What I can see is that the originalURI is null. 

Yeah, looks like I gave bad advice here, that the Preloader isn't
necessary. Obviously, it is.

> 1) Should I do something at some place to specifiy that uri? (where, how...)

No, no URI is involved when fo:insteam-foreign-object is used.

> 2) However even if the originalURI is null as I can get all the infos from
> the source it's ok.
> But what MimeType should I give to the created ImageInfo? (I've tried some,
> but I always get the same error : no suitable loader/converter
> combination...etc)

(Continue reading)


Gmane