]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Hacked support for changing IPD in block-container. Only normally positioned block...
authorVincent Hennebert <vhennebert@apache.org>
Wed, 22 Jul 2009 11:20:24 +0000 (11:20 +0000)
committerVincent Hennebert <vhennebert@apache.org>
Wed, 22 Jul 2009 11:20:24 +0000 (11:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_ChangingIPDHack@796670 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
test/layoutengine/standard-testcases/flow_changing-ipd_block-container_1.xml [new file with mode: 0644]
test/layoutengine/standard-testcases/flow_changing-ipd_block-container_2.xml [new file with mode: 0644]

index b6dd4d082c2d4f2caca9971f61136e75b2c9ff77..d6c04401db3c1dc3a94f027b54c92b0a266df391 100644 (file)
@@ -24,6 +24,7 @@ import java.awt.geom.Rectangle2D;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Stack;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -397,6 +398,311 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
         return returnList;
     }
 
+    /** {@inheritDoc} */
+    public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
+            Position restartPosition, LayoutManager restartAtLM) {
+        resetSpaces();
+        if (isAbsoluteOrFixed()) {
+            return getNextKnuthElementsAbsolute(context, alignment);
+        }
+
+        autoHeight = false;
+        //boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
+        int maxbpd = context.getStackLimitBP().opt;
+        int allocBPD;
+        if (height.getEnum() == EN_AUTO
+                || (!height.isAbsolute() && getAncestorBlockAreaBPD() <= 0)) {
+            //auto height when height="auto" or "if that dimension is not specified explicitly
+            //(i.e., it depends on content's block-progression-dimension)" (XSL 1.0, 7.14.1)
+            allocBPD = maxbpd;
+            autoHeight = true;
+            if (getBlockContainerFO().getReferenceOrientation() == 0) {
+                //Cannot easily inline element list when ref-or="180"
+                inlineElementList = true;
+            }
+        } else {
+            allocBPD = height.getValue(this); //this is the content-height
+            allocBPD += getBPIndents();
+        }
+        vpContentBPD = allocBPD - getBPIndents();
+
+        referenceIPD = context.getRefIPD();
+        if (width.getEnum() == EN_AUTO) {
+            updateContentAreaIPDwithOverconstrainedAdjust();
+        } else {
+            int contentWidth = width.getValue(this);
+            updateContentAreaIPDwithOverconstrainedAdjust(contentWidth);
+        }
+
+        double contentRectOffsetX = 0;
+        contentRectOffsetX += getBlockContainerFO()
+                .getCommonMarginBlock().startIndent.getValue(this);
+        double contentRectOffsetY = 0;
+        contentRectOffsetY += getBlockContainerFO()
+                .getCommonBorderPaddingBackground().getBorderBeforeWidth(false);
+        contentRectOffsetY += getBlockContainerFO()
+                .getCommonBorderPaddingBackground().getPaddingBefore(false, this);
+
+        updateRelDims(contentRectOffsetX, contentRectOffsetY, autoHeight);
+
+        int availableIPD = referenceIPD - getIPIndents();
+        if (getContentAreaIPD() > availableIPD) {
+            BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
+                    getBlockContainerFO().getUserAgent().getEventBroadcaster());
+            eventProducer.objectTooWide(this, getBlockContainerFO().getName(),
+                    getContentAreaIPD(), context.getRefIPD(),
+                    getBlockContainerFO().getLocator());
+        }
+
+        MinOptMax stackLimit = new MinOptMax(relDims.bpd);
+
+        List returnedList;
+        List contentList = new LinkedList();
+        List returnList = new LinkedList();
+
+        if (!breakBeforeServed) {
+            breakBeforeServed = true;
+            if (!context.suppressBreakBefore()) {
+                if (addKnuthElementsForBreakBefore(returnList, context)) {
+                    return returnList;
+                }
+            }
+        }
+
+        if (!firstVisibleMarkServed) {
+            addKnuthElementsForSpaceBefore(returnList, alignment);
+            context.updateKeepWithPreviousPending(getKeepWithPreviousStrength());
+        }
+
+        addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
+        firstVisibleMarkServed = true;
+
+        if (autoHeight && inlineElementList) {
+            //Spaces, border and padding to be repeated at each break
+            addPendingMarks(context);
+
+            BlockLevelLayoutManager curLM; // currently active LM
+            BlockLevelLayoutManager prevLM = null; // previously active LM
+
+            LayoutContext childLC = new LayoutContext(0);
+            if (lmStack.isEmpty()) {
+                assert restartAtLM != null && restartAtLM.getParent() == this;
+                curLM = (BlockLevelLayoutManager) restartAtLM;
+                curLM.reset();
+                setCurrentChildLM(curLM);
+
+                childLC.copyPendingMarksFrom(context);
+                childLC.setStackLimitBP(MinOptMax.subtract(context.getStackLimitBP(), stackLimit));
+                childLC.setRefIPD(relDims.ipd);
+                childLC.setWritingMode(getBlockContainerFO().getWritingMode());
+                if (curLM == this.childLMs.get(0)) {
+                    childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
+                    //Handled already by the parent (break collapsing, see above)
+                }
+
+                // get elements from curLM
+                returnedList = curLM.getNextKnuthElements(childLC, alignment);
+            } else {
+                curLM = (BlockLevelLayoutManager) lmStack.pop();
+                setCurrentChildLM(curLM);
+
+                childLC.copyPendingMarksFrom(context);
+                childLC.setStackLimitBP(MinOptMax.subtract(context.getStackLimitBP(), stackLimit));
+                childLC.setRefIPD(relDims.ipd);
+                childLC.setWritingMode(getBlockContainerFO().getWritingMode());
+                if (curLM == this.childLMs.get(0)) {
+                    childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
+                    //Handled already by the parent (break collapsing, see above)
+                }
+
+                // get elements from curLM
+                returnedList = curLM.getNextKnuthElements(childLC, alignment, lmStack,
+                        restartPosition, restartAtLM);
+            }
+            if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) {
+                //Propagate keep-with-previous up from the first child
+                context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
+                childLC.clearKeepWithPreviousPending();
+            }
+            if (returnedList.size() == 1
+                    && ((ListElement)returnedList.get(0)).isForcedBreak()) {
+                // a descendant of this block has break-before
+                /*
+                if (returnList.size() == 0) {
+                    // the first child (or its first child ...) has
+                    // break-before;
+                    // all this block, including space before, will be put in
+                    // the
+                    // following page
+                    bSpaceBeforeServed = false;
+                }*/
+                contentList.addAll(returnedList);
+
+                // "wrap" the Position inside each element
+                // moving the elements from contentList to returnList
+                returnedList = new LinkedList();
+                wrapPositionElements(contentList, returnList);
+
+                return returnList;
+            } else {
+                if (prevLM != null) {
+                    // there is a block handled by prevLM
+                    // before the one handled by curLM
+                    addInBetweenBreak(contentList, context, childLC);
+                }
+                contentList.addAll(returnedList);
+                if (!returnedList.isEmpty()) {
+                    if (((ListElement) ListUtil.getLast(returnedList))
+                            .isForcedBreak()) {
+                        // a descendant of this block has break-after
+                        if (curLM.isFinished()) {
+                            // there is no other content in this block;
+                            // it's useless to add space after before a page break
+                            setFinished(true);
+                        }
+
+                        returnedList = new LinkedList();
+                        wrapPositionElements(contentList, returnList);
+
+                        return returnList;
+                    }
+                }
+            }
+            // propagate and clear
+            context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
+            childLC.clearKeepsPending();
+            prevLM = curLM;
+
+            while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
+                curLM.reset();
+                childLC = new LayoutContext(0);
+                childLC.copyPendingMarksFrom(context);
+                // curLM is a ?
+                childLC.setStackLimitBP(MinOptMax.subtract(context.getStackLimitBP(), stackLimit));
+                childLC.setRefIPD(relDims.ipd);
+                childLC.setWritingMode(getBlockContainerFO().getWritingMode());
+                if (curLM == this.childLMs.get(0)) {
+                    childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
+                    //Handled already by the parent (break collapsing, see above)
+                }
+
+                // get elements from curLM
+                returnedList = curLM.getNextKnuthElements(childLC, alignment);
+                if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) {
+                    //Propagate keep-with-previous up from the first child
+                    context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
+                    childLC.clearKeepWithPreviousPending();
+                }
+                if (returnedList.size() == 1
+                        && ((ListElement)returnedList.get(0)).isForcedBreak()) {
+                    // a descendant of this block has break-before
+                    /*
+                    if (returnList.size() == 0) {
+                        // the first child (or its first child ...) has
+                        // break-before;
+                        // all this block, including space before, will be put in
+                        // the
+                        // following page
+                        bSpaceBeforeServed = false;
+                    }*/
+                    contentList.addAll(returnedList);
+
+                    // "wrap" the Position inside each element
+                    // moving the elements from contentList to returnList
+                    returnedList = new LinkedList();
+                    wrapPositionElements(contentList, returnList);
+
+                    return returnList;
+                } else {
+                    if (prevLM != null) {
+                        // there is a block handled by prevLM
+                        // before the one handled by curLM
+                        addInBetweenBreak(contentList, context, childLC);
+                    }
+                    contentList.addAll(returnedList);
+                    if (returnedList.isEmpty()) {
+                        //Avoid NoSuchElementException below (happens with empty blocks)
+                        continue;
+                    }
+                    if (((ListElement) ListUtil.getLast(returnedList))
+                            .isForcedBreak()) {
+                        // a descendant of this block has break-after
+                        if (curLM.isFinished()) {
+                            // there is no other content in this block;
+                            // it's useless to add space after before a page break
+                            setFinished(true);
+                        }
+
+                        returnedList = new LinkedList();
+                        wrapPositionElements(contentList, returnList);
+
+                        return returnList;
+                    }
+                }
+                // propagate and clear
+                context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
+                childLC.clearKeepsPending();
+                prevLM = curLM;
+            }
+
+            returnedList = new LinkedList();
+            wrapPositionElements(contentList, returnList);
+
+        } else {
+            MinOptMax range = new MinOptMax(relDims.ipd);
+            BlockContainerBreaker breaker = new BlockContainerBreaker(this, range);
+            breaker.doLayout(relDims.bpd, autoHeight);
+            boolean contentOverflows = breaker.isOverflow();
+            if (autoHeight) {
+                //Update content BPD now that it is known
+                int newHeight = breaker.deferredAlg.totalWidth;
+                boolean switchedProgressionDirection
+                    = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
+                if (switchedProgressionDirection) {
+                    setContentAreaIPD(newHeight);
+                } else {
+                    vpContentBPD = newHeight;
+                }
+                updateRelDims(contentRectOffsetX, contentRectOffsetY, false);
+            }
+
+            Position bcPosition = new BlockContainerPosition(this, breaker);
+            returnList.add(new KnuthBox(vpContentBPD, notifyPos(bcPosition), false));
+            //TODO Handle min/opt/max for block-progression-dimension
+            /* These two elements will be used to add stretchability to the above box
+            returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
+                                   false, returnPosition, false));
+            returnList.add(new KnuthGlue(0, 1 * constantLineHeight, 0,
+                                   LINE_NUMBER_ADJUSTMENT, returnPosition, false));
+            */
+
+            if (contentOverflows) {
+                BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
+                        getBlockContainerFO().getUserAgent().getEventBroadcaster());
+                boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
+                eventProducer.viewportOverflow(this, getBlockContainerFO().getName(),
+                        breaker.getOverflowAmount(), needClip(), canRecover,
+                        getBlockContainerFO().getLocator());
+            }
+        }
+        addKnuthElementsForBorderPaddingAfter(returnList, true);
+        addKnuthElementsForSpaceAfter(returnList, alignment);
+
+        //All child content is processed. Only break-after can occur now, so...
+        context.clearPendingMarks();
+        addKnuthElementsForBreakAfter(returnList, context);
+
+        context.updateKeepWithNextPending(getKeepWithNextStrength());
+
+        setFinished(true);
+        return returnList;
+    }
+
+    /** {@inheritDoc} */
+    public boolean isRestartable() {
+        return true;
+    }
+
     private List getNextKnuthElementsAbsolute(LayoutContext context, int alignment) {
         autoHeight = false;
 
diff --git a/test/layoutengine/standard-testcases/flow_changing-ipd_block-container_1.xml b/test/layoutengine/standard-testcases/flow_changing-ipd_block-container_1.xml
new file mode 100644 (file)
index 0000000..82b757d
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks that block-container elements correctly support an IPD change.
+    </p>
+    <!-- NOTE: This test case is a copy of flow_changing-ipd_1.xml, modified to simply surround 
+    block 3 with a block-container. -->
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="narrow"
+          page-height="300pt" page-width="400pt" margin="50pt">
+          <fo:region-body background-color="#F0F0F0"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="wide"
+          page-height="300pt" page-width="600pt" margin="50pt">
+          <fo:region-body background-color="#F0F0F0"/>
+        </fo:simple-page-master>
+        <fo:page-sequence-master master-name="pages">
+          <fo:single-page-master-reference master-reference="narrow"/>
+          <fo:repeatable-page-master-reference master-reference="wide"/>
+        </fo:page-sequence-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="pages">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block text-align="justify" id="surrounding"
+            space-before.minimum="10pt"
+            space-before.optimum="12pt"
+            space-before.maximum="50pt">
+            <fo:block space-before="inherit" id="b1">In olden times when wishing still helped one, 
+              there lived a king whose daughters were all beautiful, but the youngest was so 
+              beautiful that the sun itself, which has seen so much, was astonished whenever it 
+              shone in her face.</fo:block>
+            <fo:block space-before="inherit" id="b2">In olden times when wishing still helped one, 
+              there lived a king whose daughters were all beautiful, but the youngest was so 
+              beautiful that the sun itself, which has seen so much, was astonished whenever it 
+              shone in her face.</fo:block>
+            <fo:block-container space-before="inherit">
+              <fo:block id="b3" border-top="1pt solid black" 
+                border-before-width.conditionality="retain">In olden times when wishing still helped 
+                one, there lived a king whose daughters were all beautiful, but the youngest was so 
+                beautiful that the sun itself, which has seen so much, was astonished whenever it 
+                shone in her face. In olden times when wishing still helped one, there lived a king 
+                whose daughters were all beautiful, but the youngest was so beautiful that the sun 
+                itself, which has seen so much, was astonished whenever it shone in her 
+                face.</fo:block>
+            </fo:block-container>
+            <fo:block space-before="inherit" id="b4" border-top="1pt solid black">In olden times 
+              when wishing still helped one, there lived a king whose daughters were all beautiful, 
+              but the youngest was so beautiful that the sun itself, which has seen so much, was 
+              astonished whenever it shone in her face.</fo:block>
+            <fo:block space-before="inherit" id="b5">In olden times when wishing still helped one, 
+              there lived a king whose daughters were all beautiful, but the youngest was so 
+              beautiful that the sun itself, which has seen so much, was astonished whenever it 
+              shone in her face.</fo:block>
+          </fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="13100"  xpath="//pageViewport[1]//flow/block/block[2]/@space-before"/>
+    <eval expected="13100"  xpath="//pageViewport[1]//flow/block/block[3]/@space-before"/>
+    <eval expected="(solid,#000000,1000)"
+                            xpath="//pageViewport[1]//flow/block/block[3]/block/block/@border-before"/>
+    <eval expected="In"     xpath="//pageViewport[1]//flow/block/block[3]/block/block/lineArea[4]/text/word[position()=last()]"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/@ipd"/>
+    <eval expected="(solid,#000000,1000)"
+                            xpath="//pageViewport[2]//flow/block/block[1]/block/block/@border-before"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block[1]/block/block/@ipd"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block[1]/block/block/lineArea[1]/@ipd"/>
+    <eval expected="olden"  xpath="//pageViewport[2]//flow/block/block[1]/block/block/lineArea[1]/text/word[1]"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block[2]/@ipd"/>
+    <eval expected="12000"  xpath="//pageViewport[2]//flow/block/block[2]/@space-before"/>
+    <eval expected="(solid,#000000,1000)"
+                            xpath="//pageViewport[2]//flow/block/block[2]/@border-before"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block[2]/lineArea[1]/@ipd"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block[3]/@ipd"/>
+    <eval expected="12000"  xpath="//pageViewport[2]//flow/block/block[3]/@space-before"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block[3]/lineArea[1]/@ipd"/>
+  </checks>
+</testcase>
diff --git a/test/layoutengine/standard-testcases/flow_changing-ipd_block-container_2.xml b/test/layoutengine/standard-testcases/flow_changing-ipd_block-container_2.xml
new file mode 100644 (file)
index 0000000..7a2bb9b
--- /dev/null
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks that a change of IPD between two blocks surrounded by a block-container is 
+      correctly handled.
+    </p>
+    <!-- NOTE: This test case is a copy of flow_changing-ipd_3.xml, with the surrounding block 
+    replaced with a block-container. -->
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="narrow"
+          page-height="300pt" page-width="400pt" margin="50pt">
+          <fo:region-body background-color="#F0F0F0"/>
+        </fo:simple-page-master>
+        <fo:simple-page-master master-name="wide"
+          page-height="300pt" page-width="600pt" margin="50pt">
+          <fo:region-body background-color="#F0F0F0"/>
+        </fo:simple-page-master>
+        <fo:page-sequence-master master-name="pages">
+          <fo:single-page-master-reference master-reference="narrow"/>
+          <fo:repeatable-page-master-reference master-reference="wide"/>
+        </fo:page-sequence-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="pages">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block-container text-align="justify" id="surrounding"
+            space-before.minimum="10pt"
+            space-before.optimum="12pt"
+            space-before.maximum="50pt">
+            <fo:block space-before="inherit" id="b1">In olden times when wishing still helped one, 
+              there lived a king whose daughters were all beautiful, but the youngest was so 
+              beautiful that the sun itself, which has seen so much, was astonished whenever it 
+              shone in her face.</fo:block>
+            <fo:block space-before="inherit" id="b2">In olden times when wishing still helped one, 
+              there lived a king whose daughters were all beautiful, but the youngest was so 
+              beautiful that the sun itself, which has seen so much, was astonished whenever it 
+              shone in her face.</fo:block>
+            <fo:block space-before="inherit" id="b3">In olden times when wishing still helped one, 
+              there lived a king whose daughters were all beautiful, but the youngest was so 
+              beautiful that the sun itself, which has seen so much, was astonished whenever it 
+              shone in her face.</fo:block>
+            <fo:block border-top="1pt solid black" space-before.minimum="10pt" 
+              space-before.optimum="12pt" space-before.maximum="50pt" 
+              space-before.conditionality="retain" id="b4">In olden times when wishing still helped 
+              one, there lived a king whose daughters were all beautiful, but the youngest was so 
+              beautiful that the sun itself, which has seen so much, was astonished whenever it 
+              shone in her face.</fo:block>
+            <fo:block space-before="inherit" id="b5">In olden times when wishing still helped one, 
+              there lived a king whose daughters were all beautiful, but the youngest was so 
+              beautiful that the sun itself, which has seen so much, was astonished whenever it 
+              shone in her face.</fo:block>
+          </fo:block-container>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <eval expected="face."  xpath="//pageViewport[1]//flow/block/block/block[3]/lineArea[4]/text/word[position()=last()]"/>
+    <eval expected="12000"  xpath="//pageViewport[2]//flow/block/block/block[1]/@space-before"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block/block[1]/@ipd"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block/block[1]/lineArea[1]/@ipd"/>
+    <eval expected="(solid,#000000,1000)"                       
+                            xpath="//pageViewport[2]//flow/block/block/block[1]/@border-before"/>
+    <eval expected="In"     xpath="//pageViewport[2]//flow/block/block/block[1]/lineArea[1]/text/word[1]"/>
+    <eval expected="olden"  xpath="//pageViewport[2]//flow/block/block/block[1]/lineArea[1]/text/word[2]"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block/block[2]/@ipd"/>
+    <eval expected="500000" xpath="//pageViewport[2]//flow/block/block/block[2]/lineArea[1]/@ipd"/>
+  </checks>
+</testcase>