Bug 42049

Summary: RTF (and PDF) tables incorrectly handle margin-left inheritance
Product: Fop - Now in Jira Reporter: V Schappert <vschappert>
Component: rtfAssignee: fop-dev
Status: NEW ---    
Severity: normal    
Priority: P3    
Version: all   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Attachments: Indent inheritance test - PDF generated by fop 0.20.5
Indent inheritance test - PDF generated by fop 0.94

Description V Schappert 2007-04-04 10:50:04 UTC
RTF rendering of tables inside a block with a positive "margin-left" property 
is exhibiting different behaviour than rendering of AWT/PS/&c.  In particular, 
in the RTF render, tables always seem to be left-aligned even if their parent 
has a positive margin-left.  However, the same tables are indented as one would 
expect in the other render modes.

Consider this stylesheet (it will work with any XML file if you run fop -xml 
any_file -xsl file_provided_below -rtf output_file.rtf

<?xml version="1.0" encoding="ISO-8859-1"?>

<!-- desc: reproduce problem where RTF table is rendered with incorrect -->
<!--       margin but PS/AWT versions rendered with correct margin.     -->

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="A4">
                    <fo:region-body margin-left="0.26in" margin-right="0.25in" 
margin-top="0.17in" margin-bottom="0.17in"/>
                </fo:simple-page-master>
            </fo:layout-master-set>

            <fo:page-sequence master-reference="A4">
                <fo:flow flow-name="xsl-region-body">
                    <fo:block margin-left="0.8in" padding-left="0in" font-
family="arial" font-size="8pt">

                        <!-- a block indented by the margin, correctly. -->
                        <fo:block padding-bottom="10pt">Some correctly indented 
text.</fo:block>

                        <!-- a table incorrectly indented. -->
                        <fo:table table-layout="fixed" padding-bottom="2.7pt">
                            <fo:table-column column-width="2in"/>
                            <fo:table-column column-width="2in"/>
                            <fo:table-body>
                                <fo:table-row>
                                    <fo:table-cell margin-left="0in">
                                        <fo:block>Should align with</fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell margin-left="0in">
                                        <fo:block>Text above</fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </fo:table-body>
                        </fo:table>
                    </fo:block>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
</xsl:stylesheet>
Comment 1 V Schappert 2007-04-04 10:52:06 UTC
RTF rendering of tables inside a block with a positive "margin-left" property 
is exhibiting different behaviour than rendering of AWT/PS/&c.  In particular, 
in the RTF render, tables always seem to be left-aligned even if their parent 
has a positive margin-left.  However, the same tables are indented as one would 
expect in the other render modes.

Consider this stylesheet (it will work with any XML file if you run fop -xml 
any_file -xsl file_provided_below -rtf output_file.rtf

<?xml version="1.0" encoding="ISO-8859-1"?>

<!-- desc: reproduce problem where RTF table is rendered with incorrect -->
<!--       margin but PS/AWT versions rendered with correct margin.     -->

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="A4">
                    <fo:region-body margin-left="0.26in" margin-right="0.25in" 
margin-top="0.17in" margin-bottom="0.17in"/>
                </fo:simple-page-master>
            </fo:layout-master-set>

            <fo:page-sequence master-reference="A4">
                <fo:flow flow-name="xsl-region-body">
                    <fo:block margin-left="0.8in" padding-left="0in" font-
family="arial" font-size="8pt">

                        <!-- a block indented by the margin, correctly. -->
                        <fo:block padding-bottom="10pt">Some correctly indented 
text.</fo:block>

                        <!-- a table incorrectly indented. -->
                        <fo:table table-layout="fixed" padding-bottom="2.7pt">
                            <fo:table-column column-width="2in"/>
                            <fo:table-column column-width="2in"/>
                            <fo:table-body>
                                <fo:table-row>
                                    <fo:table-cell margin-left="0in">
                                        <fo:block>Should align with</fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell margin-left="0in">
                                        <fo:block>Text above</fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </fo:table-body>
                        </fo:table>
                    </fo:block>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
</xsl:stylesheet>
Comment 2 V Schappert 2007-08-16 15:24:26 UTC
An additional point: there is a general bug in the entire FOP processor in which
indent properties are being passed to the children of tables.  In PDF, this
manifests itself by a rightward shifting of the table cells out of the content
area of the table itself.  In RTF, this means that even though the table is
incorrectly NOT indented by its start-indent figure, the cells inside it ARE
indented!  This is the opposite of what should happen.  Try the following fo
snippet under RTF and PDF.  Using Altsoft's free XSL-FO Debugger, you can see
how things should be.

<fo:table table-layout="fixed" width="50%">
    <fo:table-column width="50%"/>
    <fo:table-column width="50%"/>
    <fo:table-body>
        <fo:table-row>
            <fo:table-cell><fo:block>XXX</fo:block></fo:table-cell>
            <fo:table-cell><fo:block>YYY</fo:block></fo:table-cell>
        </fo:table-row>
    </fo:table-body>
</fo:table>
Comment 3 V Schappert 2007-08-16 15:26:13 UTC
Pardon me.  In above example, I forgot to add a 'start-indent="2in"' onto the
table.  The opening table node should read:

<fo:table table-layout="fixed" width="50%" start-indent="2in">
Comment 4 Chris Bowditch 2007-08-17 07:25:07 UTC
V Schappert;

FOP does not have a bug wrt Indent inheritence. FOP implements indent 
inheritence according to the XSL-FO specification. Other implementations are 
not compliant. Although perhaps they are more along the lines of what Users 
would expect. See the following Wiki for a detailed explanation of indent 
inheritence:

http://wiki.apache.org/xmlgraphics-fop/IndentInheritance
Comment 5 V Schappert 2007-08-17 07:48:32 UTC
Hi,

If FOP has no bugs for indent inheritance, I suggest running this snippet:

    <fo:table
        space-before="1in"
        margin-left="2in"
        border-width="10%"
        border-color="black"
        border-style="solid"
        background-color="lightblue"
        padding="0.5in"
        table-layout="fixed" width="60%">
        <fo:table-column column-width="1in"/>
        <fo:table-column column-width="1in"/>
        <fo:table-body>
        <fo:table-row>
             <fo:table-cell background-color="blue">
                 <fo:block>XXXX</fo:block></fo:table-cell>
             <fo:table-cell background-color="gray">
                 <fo:block>YYYY</fo:block>
             </fo:table-cell>
        </fo:table-row>
        </fo:table-body>
    </fo:table>

I'm curious why the cell backgrounds are painted where they are expected, and
then the cell TEXT is painted outside and to the right of the cell backgrounds.
 Surely this must be a bug.

Secondly, if margin-left isn't inherited, then while you are correct that the
original behaviour in RTF I mentioned is wrong, the table snippet causes FOP to
generate incorrect RTF, b/c the \par paragraph elements (e.g. blocks) are
inheriting the margin-left, causing the text "XXXX" and "YYYY" to be indented so
far into the cell that it is invisible...

Interested in your comments.

Best,

V
Comment 6 V Schappert 2007-08-17 07:49:42 UTC
Hi,

If FOP has no bugs for indent inheritance, I suggest running this snippet:

    <fo:table
        space-before="1in"
        margin-left="2in"
        border-width="10%"
        border-color="black"
        border-style="solid"
        background-color="lightblue"
        padding="0.5in"
        table-layout="fixed" width="60%">
        <fo:table-column column-width="1in"/>
        <fo:table-column column-width="1in"/>
        <fo:table-body>
        <fo:table-row>
             <fo:table-cell background-color="blue">
                 <fo:block>XXXX</fo:block></fo:table-cell>
             <fo:table-cell background-color="gray">
                 <fo:block>YYYY</fo:block>
             </fo:table-cell>
        </fo:table-row>
        </fo:table-body>
    </fo:table>

I'm curious why the cell backgrounds are painted where they are expected, and
then the cell TEXT is painted outside and to the right of the cell backgrounds.
 Surely this must be a bug.

Secondly, if margin-left isn't inherited, then while you are correct that the
original behaviour in RTF I mentioned is wrong, the table snippet causes FOP to
generate incorrect RTF, b/c the \par paragraph elements (e.g. blocks) are
inheriting the margin-left, causing the text "XXXX" and "YYYY" to be indented so
far into the cell that it is invisible...

Interested in your comments.

Best,

V
Comment 7 V Schappert 2007-08-17 07:52:12 UTC
Well, I'm not a huge fan of Bugzilla, that's for sure!

In the above post, I mention: "Secondly, if margin-left isn't inherited, then
while you are correct that the original behaviour in RTF I mentioned is
wrong...".  My meaning isn't very clear.  What I mean to say is that you are
correct that the original behaviour I mentioned about RTF is **correct
behaviour**...  However, the other issues still stand!
Comment 8 Johannes Midgren 2007-09-05 07:31:14 UTC
Created attachment 20775 [details]
Indent inheritance test - PDF generated by fop 0.20.5
Comment 9 Johannes Midgren 2007-09-05 07:31:42 UTC
Created attachment 20776 [details]
Indent inheritance test - PDF generated by fop 0.94
Comment 10 Johannes Midgren 2007-09-05 07:36:47 UTC
(In reply to comment #4)
> V Schappert;
> 
> FOP does not have a bug wrt Indent inheritence. FOP implements indent 
> inheritence according to the XSL-FO specification. Other implementations are 
> not compliant. Although perhaps they are more along the lines of what Users 
> would expect. See the following Wiki for a detailed explanation of indent 
> inheritence:
> 
> http://wiki.apache.org/xmlgraphics-fop/IndentInheritance

It's not clear what version of fop (any of you) are referring to. I tried to
generate the examples
(http://people.apache.org/~jeremias/fop/indent-inheritance2.fo) found on the
Wiki mentioned above and got different results for the versions I tried. The
versions I tried were 0.20.5 and 0.94.

I'm not sure which one is correct, but I assume fop 0.20.5 got it right (0.94
seems to give nested blocks where start-indent has been reset a negative indent
relative its containing block - or did I miss something :-).
Comment 11 Andreas L. Delmelle 2007-09-05 12:09:06 UTC
(In reply to comment #10)
> It's not clear what version of fop (any of you) are referring to. I tried to
> generate the examples
> (http://people.apache.org/~jeremias/fop/indent-inheritance2.fo) found on the
> Wiki mentioned above and got different results for the versions I tried. The
> versions I tried were 0.20.5 and 0.94.
> 
> I'm not sure which one is correct, but I assume fop 0.20.5 got it right (0.94
> seems to give nested blocks where start-indent has been reset a negative indent
> relative its containing block - or did I miss something :-).

Yes, you seem to have missed the point on the Wiki :-) 
Indent-inheritance precisely means that a descendant block of another block with start-indent > 0 will 
inherit the indent from its ancestor. Since this ancestor is already 'displaced', the nested block will in 
fact appear to have *twice* the indent of the ancestor. Jeremias verified this with the XSL-FO editors, 
and they agreed that that unexpected behavior is in fact correct. To achieve the effect that seems to be 
generally expected, an author would always need to reset the indent on the block in question. Its 
descendants then inherit the zero indent etc.

So, the real problem seems to be limited to the RTF renderer here, which currently behaves non-
compliant.

There is a configuration option you can use to make FOP behave as expected, but I would only really 
use it if it's too much trouble to reset the start-indents.

Hope it makes sense now.

Cheers

Andreas
Comment 12 Johannes Midgren 2007-09-06 00:22:00 UTC
(In reply to comment #11)

Thanks for your reply, Andreas! I can see that the example generated by fop 0.94
is correct when it comes to inheriting start-indent.

The concern I had was with the second table of the example. The code looks like
this:

      <fo:block space-before="10pt" font-style="italic">start-indent specified
on outer block, table inside (start-indent reset on fo:table)</fo:block>
      <fo:block background-color="#FFFFCC">unindented block</fo:block>
      <fo:block background-color="yellow" start-indent="10pt">fo:block
        <fo:table table-layout="fixed" start-indent="0pt">
          <fo:table-column number-columns-repeated="2"/>
          <fo:table-body>
            <fo:table-row>
              <fo:table-cell>
                <fo:block background-color="orange">cell 1</fo:block>
              </fo:table-cell>
              <fo:table-cell>
                <fo:block background-color="red">cell 2</fo:block>
              </fo:table-cell>
            </fo:table-row>
          </fo:table-body>
        </fo:table>
      </fo:block>

and the result is like this:

unindented block
  fo:block
cell 1 cell 2

I expected the result to be like this:

unindented block
  fo:block
  cell 1 cell 2

I now realize that it may have to do with "viewport/reference pair" (as
mentioned in the Wiki, referenced to 6.5.3 of the spec.). What I like to do is
to achieve my expect result above. I have now learned this can be accomplished
with the following construction:

<fo:block>unindented block</fo:block>
<fo:block-container margin-left="10mm">
  <fo:table start-indent="0mm" table-layout="fixed">
    <fo:table-column number-columns-repeated="2"/>
    <fo:table-body>
      <fo:table-row>
        <fo:table-cell>
          <fo:block background-color="orange">cell 1</fo:block>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block background-color="red">cell 2</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
</fo:block-container>

I would be grateful if someone could verify that I got it right, so my style
sheet will still be working as expected with coming versions of fop :-)

Thank you!
Comment 13 Andreas L. Delmelle 2007-09-06 10:33:44 UTC
(In reply to comment #12)
<snip /> 
> and the result is like this:
> 
> unindented block
>   fo:block
> cell 1 cell 2

Yep, because the block does not establish its own reference area, the indent of 0pt on the table is 
relative to the ancestor reference area of the block.

> 
> I expected the result to be like this:
> 
> unindented block
>   fo:block
>   cell 1 cell 2

... and a lot of users/authors with you, I think. That's precisely why Jeremias dedicated a Wiki page to 
the issue.

> I now realize that it may have to do with "viewport/reference pair" (as
> mentioned in the Wiki, referenced to 6.5.3 of the spec.). What I like to do is
> to achieve my expect result above. I have now learned this can be accomplished
> with the following construction:
> 
> <fo:block>unindented block</fo:block>
> <fo:block-container margin-left="10mm">
>   <fo:table start-indent="0mm" table-layout="fixed">

Correct. The block-container establishes a new reference area, that will serve as a basis for computing 
the offset of the enclosed table. 
One small remark: using 'start-indent' instead of 'margin-left' is considered slightly better style, since 
start-indent is a 'native' XSL-FO property. 
margin-left is defined to preserve compatibility with CSS; it is translated into start-indent behind the 
scenes anyway... margin-left is not inherited, but the computed start-indent is, so it really makes no 
difference.

Cheers

Andreas
Comment 14 Andreas L. Delmelle 2007-09-06 10:48:37 UTC
(In reply to comment #13)

BTW, forgot to mention, another way of achieving the result you seek is specifying the start-indent directly 
on the fo:table. In that case, one does need to reset the indent on the fo:table-body, -header and -footer 
to prevent it from being inherited by the table-cells and their content.
Comment 15 Glenn Adams 2012-04-07 01:42:24 UTC
resetting P2 open bugs to P3 pending further review