Rachel,

I think this is not the ideal approach. I'm not sure where the
differences come from but fetching the heights directly in the renderer
in FOP 0.20.5 is probably problematic in itself. But I have a different
proposal for your problem:

If you download FOP Trunk (latest development code, available via
Subversion), you could use the area tree renderer (-at on the
command-line, org.apache.fop.render.xml.XMLRenderer) to retrieve the
heights much more easily using the same approach we use to test out
layout engine, i.e. via XPath evaluations. The area tree renderer also
exists in 0.20.5 but provides much less information and is essentially
useless for this. Looking at your example file, I don't think your
layouts will be so complicated that FOP Trunk may not be ready for your
documents. The only problem is that a few things changed since 0.20.5
and the new documentation is not yet online. But upgrading should not be
undoable.

I'd suggest that you render each question separately and retrieve the
"bpda" (=allocated block-progression-dimension=height) value from the
top-level block area just under the flow element. The value is given in
millipoints. That said, you should enclose each question properly in a
block, not just use empty blocks to generate line breaks. Otherwise, you
will not be able to reliably determine the height of a question.

Not good:
<fo:block>
  Queston 1
  <fo:block/>
  Queston 2
  <fo:block/>
  Queston 3
</fo:block>

Better:
<fo:block>
  Question 1
</fo:block>
<fo:block>
  Question 2
</fo:block>
<fo:block>
  Question 3
</fo:block>

One caveat: If you use space-before and space-after in FOP Trunk, you
need to be aware that space-resolution is now implemented and a
space-after from block 1 might be removed in favor of a space-before on
block 2. This has an influence on the bpda value. If that's an issue and
you don't understand what I mean I can go into more detail. 

Another problem: If you don't have a keep-together for the whole
question, the question might be broken over more than one page. That may
make it more difficult to determine the expected number of pages. BTW,
keep-together works on blocks in FOP Trunk.

Maybe that helps.

On 26.10.2005 22:48:23 Rachel C. Turpen wrote:
> Hello,
> 
> I have an application which generates surveys and converts the contents to
> a PDF via FOP for printing.  There is a maximum allowable number of pages
> for any given survey.  Since each survey generated is dynamic and unique
> based on outside information it is necessary for me to calculate the exact
> number of inches that each potential question may consume on the resulting
> PDF file.  The number of inches for each potential question is stored on
> the database with the question content.
> 
> When the question is saved, I need to render a PDF in order to determine
> the content height in inches.  We have started off by extending the
> PDFRenderer class and adding several methods.  The application basically
> sends the FO file for conversion and the renderer class ("MyRenderer.java")
> provides a method to calculate height in inches.
> 
> I am encountering a problem with the calculation - when the final PDF is
> printed the actual number of inches (when measured manually) is somewhat
> smaller than what the application gives as the content height in inches.  I
> am having trouble figuring out what is actually happening here in the
> PDFRenderer.  The renderWordArea method seems to be called many times even
> though there should only be a single word Area.
> 
> In the example below we are printing the survey on a 8.5 x 14 (Legal) size
> paper.  The question itself manually measures out to be approximately 6.9
> or 7 inches in height with the margins specified in the FO file.  However,
> the calculated height in inches is 6.88 inches.  When the size of the
> question is increased the accuracy gets worse.
> 
> I have outlined my code and test case information below.  Is there
> something out of place within my FO file that is causing this increase in
> height amount?  Any help you are able to provide is greatly appreciated
> 
> The FO file that is being used in this case is as follows:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format";>
> <fo:layout-master-set>
> <fo:simple-page-master master-name="simple" page-width="612px"
> page-height="1008px">
> <fo:region-body margin-top="22.0px" margin-left="60.0px"
> margin-bottom="60.0px" margin-right="64.0px"/>
> </fo:simple-page-master>
> </fo:layout-master-set>
> <fo:page-sequence master-reference="simple">
> <fo:static-content flow-name="xsl-region-after"/>
> <fo:flow flow-name="xsl-region-body">
> <fo:block>
> <fo:inline white-space-collapse="false"
> font-family="verdana,arial,helvetica,sans-serif" font-size="10pt">Have you
> had your blood pressure checked during the last 2 years?<fo:block/> line
> 2<fo:block/> line 3<fo:block/> line 2<fo:block/> line 3<fo:block/> line
> 2<fo:block/> line 3Have you had your blood pressure checked during the last
> 2 years?<fo:block/> line 2<fo:block/> line 3<fo:block/> line 2<fo:block/>
> line 3<fo:block/> line 2<fo:block/> line 3Have you had your blood pressure
> checked during the last 2 years?<fo:block/> line 2<fo:block/> line
> 3<fo:block/> line 2<fo:block/> line 3<fo:block/> line 2<fo:block/> line
> 3Have you had your blood pressure checked during the last 2
> years?<fo:block/> line 2<fo:block/> line 3<fo:block/> line 2<fo:block/>
> line 3<fo:block/> line 2<fo:block/> line 3Have you had your blood pressure
> checked during the last 2 years?<fo:block/> line 2<fo:block/> line
> 3<fo:block/> line 2<fo:block/> line 3<fo:block/> line 2<fo:block/> line
> 3Have you had your blood pressure checked during the last 2
> years?<fo:block/> line 2<fo:block/> line 3<fo:block/> line 2<fo:block/>
> line 3<fo:block/> line 2<fo:block/> line 3</fo:inline>
> </fo:block>
> </fo:flow>
> </fo:page-sequence>
> </fo:root>
> 
> The MyRenderer.java class that I am using is as follows:
> 
> public class MyRenderer extends PDFRenderer {
> 
>       public static final int MILLIPOINTS_PER_INCH = 72000;
> 
>       private HashMap heights = new HashMap();
> 
>       public void renderWordArea(WordArea area) {
>             super.renderWordArea(area);
> 
>             Page page = getPage(area);
> 
>             if (page != null) {
>                   double max =
> page.getBody().getMainReferenceArea().getYPosition();
> 
>                   double y = max - currentYPosition;
> 
>                   setCurrentY(page, y);
>             }
>       }
> 
>       public double getHeightInInches() {
>             double height = 0;
>             Iterator iter = heights.values().iterator();
>             int count = 0;
>             while (iter.hasNext()) {
>                   count++;
>                   height += ((Number) iter.next()).doubleValue();
>             }
>             return height / MILLIPOINTS_PER_INCH;
>       }
> 
>       private void setCurrentY(Page page, double y) {
>             Double num = new Double(page.getNumber());
>             Double curr = (Double) heights.get(num);
> 
>             if (curr == null) {
>                   curr = new Double(y);
>             } else {
>                   curr = new Double(Math.max(y, curr.doubleValue()));
>             }
>             heights.put(num, curr);
>       }
> 
>       private Page getPage(Area area) {
>             Page page = area.getPage();
>             Area parent = area.getParent();
>             if (page == null && parent != null) {
>                   return getPage(parent);
>             }
>             return page;
>       }
> }
> 
> My test case sends the FO file into the "in" variable and from there runs
> the driver...
> 
>                   //this results in the FO file
>                   InputStream in = builder.createFo(tempXML);
>                   InputSource inputSource = new InputSource(in);
> 
>                   MyRenderer r = new MyRenderer();
> 
>                   Driver driver =
>                         new Driver(inputSource, new FileOutputStream(
> "test3.pdf"));
>                   driver.setRenderer(r);
>                   driver.run();
> 
>                   System.err.println("height = " + r.getHeightInInches());
> 
> 
> 
> Thank You!
> Rachel

Jeremias Maerki


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to