Dear XSL Editors,

The XSL-FO 1.1 Recommendation gives some details about how the 
border-separation property for tables should be handled, but it is not 
clear in my opinion where the half of it associated to the table should 

As a picture is still the simplest way to illustrate the problem, please 
have a look at the following example and the attached picture (see below 
for the formulas):
    <fo:root xmlns:fo="";>
        <fo:simple-page-master master-name="page"
          page-height="10cm" page-width="15cm" margin="1cm">
          <fo:region-body background-color="#ffc000"/>
      <fo:page-sequence master-reference="page" font-size="12pt">
        <fo:flow flow-name="xsl-region-body">
          <fo:table width="100%" table-layout="fixed"
            border-separation="8pt" border="4pt solid black">
            <fo:table-column number-columns-repeated="2"
                <fo:table-cell border="4pt solid black">
                  <fo:block>Cell 1</fo:block>
                <fo:table-cell border="4pt solid black">
                  <fo:block>Cell 2</fo:block>

So, in the attached picture, which version is correct?

First, in section 4.4.1, “Stacked Block-areas”, the graphic shows 
a space-start trait but it is explained nowhere how its value should be 
computed. From the graphic we can infer the following formula:
    space-start = start-indent − border-start − padding-start
Still, it is not clear whether we are referring to traits or properties 
for border and padding. If I’m correct the padding-start property always  
directly maps to the padding-start trait. But this may not be the case 
for border-start, see below. So, let’s assume the following:

    (1) space-start(trait) = start-indent − border-start(trait) − padding-start

(Let’s note that Section 4.2.2 does not define any trait called 
start-indent, so this is always the property which will be used.)

Then Section 4.2.3, “Geometric Definitions”, states that, for 
block-level areas, “the allocation-rectangle extends [...] outside the 
content-rectangle in the inline-progression-direction by an amount equal 
to the end-indent, and in the opposite direction by an amount equal to 
the start-indent.”

For simplicity, let’s assume that the writing direction never changes. 
Given a block-area B, let’s call xa the offset of the start-edge of its 
allocation rectangle from the start-edge of the content-rectangle of its 
closest ancestor reference-area. Likewise, let’s call xc the offset of 
the start-edge of its content-rectangle.

Section 4.2.3 states that:
    (2) xa = xc − start-indent

Then Section 4.4.1 states that:
        xa = start-indent + start-intrusion-adjustment
             − border-start − padding-start − space-start
Since this section is all about traits, let’s assume we have the 
    (3) xa = start-indent + start-intrusion-adjustment
             − border-start(trait) − padding-start 
             − space-start

But since space-start can be inferred from start-indent thanks to 
equation (2), we can simplify (3) into the following:
        xa = start-indent + start-intrusion-adjustment
             − border-start(trait) − padding-start 
             − (start-indent − border-start(trait) − padding-start)
which will simplify into the following:
        xa = start-intrusion-adjustment
        xc = start-intrusion-adjustment + start-indent
which means that if start-indent = 0, then the start-edge of B’s 
content-rectangle will coincide with the start-edge of the 
content-rectangle of the closest ancestor reference-area.

Buth then, why having kept the formula in its original, unsimplified 

Now about tables. Section 6.7.3, “fo:table” says that in the separate 
border model the border of the table is composed of half the value of 
the border-separation property plus the border as specified by the 
property. Which would mean that the border-start(trait) would, in this 
particular case, be different from the border-start(property):
    border-start(trait) = border-start(property) + 
border-separation.inline-progression-dimension / 2

That’s why it seems important to me to know whether we are speaking of 
traits or properties in the formulas above. If both formulas use the 
same value (trait or property), then we have the result #1 on the 
attached picture. If formula (1) uses the trait and formula (3) uses the 
property, then the simplification will give:
    xa = start-indent + start-intrusion-adjustment
         − border-start(property) − padding-start 
         − (start-indent − border-start(trait) − padding-start)
       = start-intrusion-adjustment + border-separation.i-p-d / 2
Leading to result #2 in the attached picture, which is a sensible 

And if formula (1) uses the property and formula (3) the trait, we get 
result #3 which is probably less likely to be expected.

Finally, Section 6.7.3, “fo:table” and Section 6.7.10, “fo:table-cell” 
mention the “table grid boundary line”, but it is unclear where this 
line should actually lie, especially with respect to the table padding. 
There seems to be an inconsistency since Section 6.7.3 states that “the 
first [border component], which is placed with the inside edge 
coincident with the outermost table grid boundary line, has the width of 
half the value for the ‘border-separation’ property”. And Section 6.7.10 
states that “the first [border component], which is placed with the 
outside edge coincident with the table grid boundary line, has the width 
of half the value for the border-separation trait”. Then where shall the 
padding be placed? The only consistent way to resolve this issue in my 
opinion is to make the padding coincide with the table outermost grid 
boundary line. See the attached picture as an illustration (where 
case #1 from above has been selected). It might be helpful to add an 
indication with this respect in the Recommendation.

Vincent Hennebert

Vincent Hennebert                            Anyware Technologies
Apache FOP Committer                         FOP Development/Consulting

<<inline: border-separation.png>>

<<inline: table-grid-boundary-line.png>>

Reply via email to