On Thu, Feb 19, 2004 at 08:52:41AM +0100, Finn Bock wrote:
> If an expression reference another expression in a parent fo, the parent 
> fo expression must be evaluated against the LayoutContext that was in 
> effect for the parent fo and *not* against the child fo LayoutContext.
> 
> <fo:block id="a" border-start-width="10%">
>    <fo:block id="b" border-start-width="inherit">
> 
>    </fo:block>
> </fo:block>
> 
> It must be the LayoutContex for 'a' that is used when we evaluate the 
> 10% even when we call:
>     propertyList.get(PR_BORDER_START_WIDTH).getValue(lc)
> with the layout context for 'b'.

The present code contains a partial implementation of percent based
properties, e.g. in fo:leader, leader-length. This implementation
indeed uses the context layout for the base dimensions with respect to
which a relative property is calculated. The ipd of the containing
block is retrieved from it and is propagated to the method that
calculates the actual leader length:

LeafNodeLayoutManager.getNextBreakPoss:
  ipd = getAllocationIPD(context.getRefIPD());
AddLMVisitor.getLeaderAllocIPD:
  node.getLength(Constants.PR_LEADER_LENGTH | Constants.CP_MAXIMUM, ipd);
Leader.getLength:
  length = (int)(((PercentLength) maxlength).value() * dim);

where dim = ipd = context.getRefIPD().

I realized that this is wrong for exactly the above reasons. If the
percent expression is specified on an ancestral FO, the current
implementation fails to see this and always calculates it on the basis
of the ipd of the current containing block. See this example:

<fo:flow flow-name="xsl-region-body">
  <fo:block leader-length="30%" leader-pattern="rule">
    <fo:leader/>
    <fo:block margin-left="60pt" margin-right="60pt">
      <fo:leader/>
      <fo:block>This is a block with a leader and a block with left
  and right margins of 60pt. The latter block contains a leader and
  this text. The leader length is specified as 30% on the topmost
  block.</fo:block>
    </fo:block>
  </fo:block>
</fo:flow>

The 30% must be calculated w.r.t. the page width for both leaders, and
both leaders must be equally wide. This is not the current result.

When I tried to remedy this, I got confused by the sets of symbols on
PercentBase and on LengthBase. Why are there 2 sets of symbols?  They
are mapped onto each other in LengthBase.getBaseLength(), but not all
symbols are mapped, e.g. LengthBase.CONTAINING_BOX, which is used by
leader-length, has no corresponding action. Some further integration
of old and new code must be done here.

Question: What to do if I insert a fo:wrapper between fo:flow and
fo:block? That makes it the parent of fo:block, but it has no layout
manager corresponding to it. Override getLayoutDimension on it?

> But for now I think we should just use the FO tree and later change the 
> signature of getValue() to take some kind of context parameter when a 
> real need arise.

I agree.  I am now convinced that your solution is simple, practical
and robust. You demonstrated that it deals properly with FOs that
generate more than one area. You also demonstrated that the
LayoutContext idea is insufficient. Holding layout information in the
Layout Managers is more pure, but indeed not absolutely necessary.

Regards,
Simon Pepping

-- 
Simon Pepping
home page: http://www.leverkruid.nl

Reply via email to