return this.startOn;
}
- public BlockSequence endBlockSequence() {
- KnuthSequence temp = super.endSequence();
+ public BlockSequence endBlockSequence(Position breakPosition) {
+ KnuthSequence temp = super.endSequence(breakPosition);
if (temp != null) {
BlockSequence returnSequence = new BlockSequence(startOn);
returnSequence.addAll(temp);
int displayAlign = getCurrentDisplayAlign();
+ //The following is needed by SpaceResolver.performConditionalsNotification()
+ //further down as there may be important Position elements in the element list trailer
+ int notificationEndElementIndex = endElementIndex;
+
// ignore the last elements added by the
// PageSequenceLayoutManager
endElementIndex -= (endElementIndex == (originalList.size() - 1))
while (effectiveListIterator.hasNext()
&& !(firstElement = (KnuthElement) effectiveListIterator.next())
.isBox()) {
+ /*
if (firstElement.isGlue() && firstElement.getLayoutManager() != null) {
// discard the space representd by the glue element
((BlockLevelLayoutManager) firstElement
.getLayoutManager())
.discardSpace((KnuthGlue) firstElement);
- }
+ }*/
startElementIndex++;
}
// Handle SpaceHandling(Break)Positions, see SpaceResolver!
SpaceResolver.performConditionalsNotification(effectiveList,
- startElementIndex, endElementIndex, lastBreak);
+ startElementIndex, notificationEndElementIndex, lastBreak);
// Add areas now!
addAreas(new KnuthPossPosIter(effectiveList,
//Only implemented by the PSLM
nextSequenceStartsOn = handleSpanChange(childLC, nextSequenceStartsOn);
+ Position breakPosition = null;
if (((KnuthElement) returnedList.getLast()).isPenalty()
&& ((KnuthPenalty) returnedList.getLast()).getP() == -KnuthElement.INFINITE) {
KnuthPenalty breakPenalty = (KnuthPenalty) returnedList
.removeLast();
+ breakPosition = breakPenalty.getPosition();
switch (breakPenalty.getBreakClass()) {
case Constants.EN_PAGE:
log.debug("PLM> break - PAGE");
}
blockList.addAll(returnedList);
BlockSequence seq = null;
- seq = blockList.endBlockSequence();
+ seq = blockList.endBlockSequence(breakPosition);
if (seq != null) {
blockLists.add(seq);
}
}
}
- if (!bSpaceBeforeServed) {
- addKnuthElementsForSpaceBefore(returnList, alignment);
- bSpaceBeforeServed = true;
- }
+ addKnuthElementsForSpaceBefore(returnList, alignment);
- addKnuthElementsForBorderPaddingBefore(returnList);
+ addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
+ firstVisibleMarkServed = true;
if (autoHeight) {
//Spaces, border and padding to be repeated at each break
if (returnedList.size() == 1
&& ((KnuthElement)returnedList.getFirst()).isForcedBreak()) {
// a descendant of this block has break-before
+ /*
if (returnList.size() == 0) {
// the first child (or its first child ...) has
// break-before;
// the
// following page
bSpaceBeforeServed = false;
- }
+ }*/
contentList.addAll(returnedList);
// "wrap" the Position inside each element
}
}
}
- addKnuthElementsForBorderPaddingAfter(returnList);
+ addKnuthElementsForBorderPaddingAfter(returnList, true);
addKnuthElementsForSpaceAfter(returnList, alignment);
addKnuthElementsForBreakAfter(returnList, context);
protected LinkedList storedList = null;
/** Indicates whether break before has been served or not */
protected boolean bBreakBeforeServed = false;
- /** Indicates whether space before has been served or not */
- protected boolean bSpaceBeforeServed = false;
+ /** Indicates whether the first visible mark has been returned by this LM, yet */
+ protected boolean firstVisibleMarkServed = false;
/** Reference IPD available */
protected int referenceIPD = 0;
/**
}
}
- if (!bSpaceBeforeServed) {
- addKnuthElementsForSpaceBefore(returnList, alignment);
- bSpaceBeforeServed = true;
- }
+ addKnuthElementsForSpaceBefore(returnList, alignment);
- addKnuthElementsForBorderPaddingBefore(returnList);
+ addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
+ firstVisibleMarkServed = true;
//Spaces, border and padding to be repeated at each break
addPendingMarks(context);
&& returnedList.size() == 1
&& ((ListElement) returnedList.getFirst()).isForcedBreak()) {
// a descendant of this block has break-before
+ /*
if (returnList.size() == 0) {
// the first child (or its first child ...) has
// break-before;
// the
// following page
bSpaceBeforeServed = false;
- }
+ }*/
contentList.addAll(returnedList);
/* extension: conversione di tutta la sequenza fin'ora ottenuta */
returnList.add(new KnuthBox(0, notifyPos(new Position(this)), true));
}
- addKnuthElementsForBorderPaddingAfter(returnList);
+ addKnuthElementsForBorderPaddingAfter(returnList, true);
addKnuthElementsForSpaceAfter(returnList, alignment);
addKnuthElementsForBreakAfter(returnList, context);
* Creates Knuth elements for before border padding and adds them to the return list.
* @param returnList return list to add the additional elements to
*/
- protected void addKnuthElementsForBorderPaddingBefore(LinkedList returnList) {
+ protected void addKnuthElementsForBorderPaddingBefore(LinkedList returnList, boolean isFirst) {
//Border and Padding (before)
CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
if (borderAndPadding != null) {
returnList.add(new BorderElement(
getAuxiliaryPosition(),
borderAndPadding.getBorderInfo(CommonBorderPaddingBackground.BEFORE)
- .getWidth(), RelSide.BEFORE, true, false, this));
+ .getWidth(),
+ RelSide.BEFORE, isFirst, false, this));
}
if (borderAndPadding.getPaddingBefore(false, this) > 0) {
returnList.add(new PaddingElement(
getAuxiliaryPosition(),
borderAndPadding.getPaddingLengthProperty(
CommonBorderPaddingBackground.BEFORE),
- RelSide.BEFORE, true, false, this));
+ RelSide.BEFORE, isFirst, false, this));
}
//TODO Handle conditionality
/*
* Creates Knuth elements for after border padding and adds them to the return list.
* @param returnList return list to add the additional elements to
*/
- protected void addKnuthElementsForBorderPaddingAfter(LinkedList returnList) {
+ protected void addKnuthElementsForBorderPaddingAfter(LinkedList returnList, boolean isLast) {
//Border and Padding (after)
CommonBorderPaddingBackground borderAndPadding = getBorderPaddingBackground();
if (borderAndPadding != null) {
returnList.add(new PaddingElement(
getAuxiliaryPosition(),
borderAndPadding.getPaddingLengthProperty(
- CommonBorderPaddingBackground.AFTER), RelSide.AFTER, false, true, this));
+ CommonBorderPaddingBackground.AFTER),
+ RelSide.AFTER, false, isLast, this));
}
if (borderAndPadding.getBorderAfterWidth(false) > 0) {
returnList.add(new BorderElement(
getAuxiliaryPosition(),
borderAndPadding.getBorderInfo(CommonBorderPaddingBackground.AFTER)
- .getWidth(), RelSide.AFTER, false, true, this));
+ .getWidth(),
+ RelSide.AFTER, false, isLast, this));
}
//TODO Handle conditionality
/*
}
if (returnedList.size() > 0) {
returnList.addAll(returnedList);
- if (ElementListUtils.endsWithForcedBreak(returnedList)) {
+ if (ElementListUtils.endsWithForcedBreak(returnList)) {
// a descendant of this flow has break-after
SpaceResolver.resolveElementList(returnList);
return returnList;
}
/**
+ * Finalizes a Knuth sequence.
* @return a finalized sequence.
*/
public KnuthSequence endSequence() {
+ return endSequence(null);
+ }
+
+ /**
+ * Finalizes a Knuth sequence.
+ * @param breakPosition a Position instance for the last penalty (may be null)
+ * @return a finalized sequence.
+ */
+ public KnuthSequence endSequence(Position breakPosition) {
// remove glue and penalty item at the end of the paragraph
while (this.size() > ignoreAtStart
&& !((KnuthElement)this.get(this.size() - 1)).isBox()) {
// and the forced break
this.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, false));
this.add(new KnuthGlue(0, 10000000, 0, null, false));
- this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false));
+ this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, breakPosition, false));
ignoreAtEnd = 3;
return this;
} else {
package org.apache.fop.layoutmgr;
+import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
int i = 0;
ListIterator iter;
if (first != null) {
- iter = first.listIterator(first.size());
- while (iter.hasPrevious()) {
- noBreak[i] = (UnresolvedListElementWithLength)iter.previous();
+ iter = first.listIterator();
+ while (iter.hasNext()) {
+ noBreak[i] = (UnresolvedListElementWithLength)iter.next();
noBreakLengths[i] = noBreak[i].getLength();
i++;
}
}
private void removeConditionalBorderAndPadding(
- UnresolvedListElement[] elems, MinOptMax[] lengths) {
+ UnresolvedListElement[] elems, MinOptMax[] lengths, boolean reverse) {
for (int i = 0; i < elems.length; i++) {
- if (elems[i] instanceof BorderOrPaddingElement) {
- BorderOrPaddingElement bop = (BorderOrPaddingElement)elems[i];
+ int effIndex;
+ if (reverse) {
+ effIndex = elems.length - 1 - i;
+ } else {
+ effIndex = i;
+ }
+ if (elems[effIndex] instanceof BorderOrPaddingElement) {
+ BorderOrPaddingElement bop = (BorderOrPaddingElement)elems[effIndex];
if (bop.isConditional() && !(bop.isFirst() || bop.isLast())) {
if (log.isDebugEnabled()) {
log.debug("Nulling conditional element: " + bop);
}
- lengths[i] = null;
+ lengths[effIndex] = null;
}
}
}
}
}
- private void performSpaceResolutionRule1(UnresolvedListElement[] elems, MinOptMax[] lengths) {
+ private void performSpaceResolutionRule1(UnresolvedListElement[] elems, MinOptMax[] lengths,
+ boolean reverse) {
for (int i = 0; i < elems.length; i++) {
- if (lengths[i] == null) {
+ int effIndex;
+ if (reverse) {
+ effIndex = elems.length - 1 - i;
+ } else {
+ effIndex = i;
+ }
+ if (lengths[effIndex] == null) {
//Zeroed border or padding doesn't create a fence
continue;
- } else if (elems[i] instanceof BorderOrPaddingElement) {
+ } else if (elems[effIndex] instanceof BorderOrPaddingElement) {
//Border or padding form fences!
break;
- } else if (!elems[i].isConditional()) {
+ } else if (!elems[effIndex].isConditional()) {
break;
}
if (log.isDebugEnabled()) {
- log.debug("Nulling conditional element using 4.3.1, rule 1: " + elems[i]);
+ log.debug("Nulling conditional element using 4.3.1, rule 1: " + elems[effIndex]);
}
- lengths[i] = null;
+ lengths[effIndex] = null;
}
if (log.isTraceEnabled() && elems.length > 0) {
log.trace("-->Resulting list: " + toString(elems, lengths));
}
}
+ private boolean hasFirstPart() {
+ return firstPart != null && firstPart.length > 0;
+ }
+
+ private boolean hasSecondPart() {
+ return secondPart != null && secondPart.length > 0;
+ }
+
private void resolve() {
if (breakPoss != null) {
- if (firstPart != null) {
- removeConditionalBorderAndPadding(firstPart, firstPartLengths);
- performSpaceResolutionRule1(firstPart, firstPartLengths);
+ if (hasFirstPart()) {
+ removeConditionalBorderAndPadding(firstPart, firstPartLengths, true);
+ performSpaceResolutionRule1(firstPart, firstPartLengths, true);
performSpaceResolutionRules2to3(firstPart, firstPartLengths);
}
- if (secondPart != null) {
- removeConditionalBorderAndPadding(secondPart, secondPartLengths);
- performSpaceResolutionRule1(secondPart, secondPartLengths);
+ if (hasSecondPart()) {
+ removeConditionalBorderAndPadding(secondPart, secondPartLengths, false);
+ performSpaceResolutionRule1(secondPart, secondPartLengths, false);
performSpaceResolutionRules2to3(secondPart, secondPartLengths);
}
if (noBreak != null) {
performSpaceResolutionRules2to3(noBreak, noBreakLengths);
}
} else {
- if (isFirst || isLast) {
- performSpaceResolutionRule1(secondPart, secondPartLengths);
+ if (isFirst) {
+ removeConditionalBorderAndPadding(secondPart, secondPartLengths, false);
+ performSpaceResolutionRule1(secondPart, secondPartLengths, false);
+ }
+ if (isLast) {
+ removeConditionalBorderAndPadding(firstPart, firstPartLengths, true);
+ performSpaceResolutionRule1(firstPart, firstPartLengths, true);
+ }
+
+ if (hasFirstPart()) {
+ //Now that we've handled isFirst/isLast conditions, we need to look at the
+ //active part in its normal order so swap it back.
+ log.trace("Swapping first and second parts.");
+ UnresolvedListElementWithLength[] tempList;
+ MinOptMax[] tempLengths;
+ tempList = secondPart;
+ tempLengths = secondPartLengths;
+ secondPart = firstPart;
+ secondPartLengths = firstPartLengths;
+ firstPart = tempList;
+ firstPartLengths = tempLengths;
+ if (hasFirstPart()) {
+ throw new IllegalStateException("Didn't expect more than one parts in a"
+ + "no-break condition.");
+ }
}
performSpaceResolutionRules2to3(secondPart, secondPartLengths);
}
glue2shrink -= glue1.opt - glue1.min;
glue2shrink -= glue3.opt - glue3.min;
-
+ boolean hasPrecedingNonBlock = false;
if (log.isDebugEnabled()) {
log.debug("noBreakLength=" + noBreakLength
+ ", glue1=" + glue1
false, (Position)null, true));
iter.add(new KnuthGlue(glue3.opt, glue3.max - glue3.opt, glue3.opt - glue3.min,
(Position)null, true));
+ hasPrecedingNonBlock = true;
}
- if (isLast) {
+ if (isLast && hasPrecedingNonBlock) {
//Otherwise, the preceding penalty and glue will be cut off
iter.add(new KnuthBox(0, (Position)null, true));
}
}
} else {
for (int i = 0; i < resolver.noBreak.length; i++) {
- if (resolver.noBreak[i] instanceof SpaceElement) {
- resolver.noBreak[i].notifyLayoutManager(resolver.noBreakLengths[i]);
- }
+ resolver.noBreak[i].notifyLayoutManager(resolver.noBreakLengths[i]);
}
}
}
throw new IllegalStateException("Only applicable to no-break situations");
}
for (int i = 0; i < resolver.secondPart.length; i++) {
- if (resolver.secondPart[i] instanceof SpaceElement) {
- resolver.secondPart[i].notifyLayoutManager(resolver.secondPartLengths[i]);
- }
+ resolver.secondPart[i].notifyLayoutManager(resolver.secondPartLengths[i]);
}
}
}
}
//last = !iter.hasNext();
- if (breakPoss == null & unresolvedSecond.size() == 0) {
+ if (breakPoss == null && unresolvedSecond.size() == 0 && !last) {
+ log.trace("Swap first and second parts in no-break condition,"
+ + " second part is empty.");
//The first list is reversed, so swap if this shouldn't happen
List swapList = unresolvedSecond;
unresolvedSecond = unresolvedFirst;
unresolvedFirst = swapList;
}
- //Need to reverse the order of the first part
- //From here on further down, the first part in the unresolved list is
- //always the one nearest to the break.
- if (unresolvedFirst.size() > 0) {
- Collections.reverse(unresolvedFirst);
- }
log.debug("----start space resolution (first=" + first + ", last=" + last + ")...");
SpaceResolver resolver = new SpaceResolver(
LinkedList returnList = new LinkedList();
- if (!bSpaceBeforeServed) {
- addKnuthElementsForSpaceBefore(returnList, alignment);
- bSpaceBeforeServed = true;
- }
+ addKnuthElementsForSpaceBefore(returnList, alignment);
//Spaces, border and padding to be repeated at each break
addPendingMarks(context);
addKnuthElementsForSpaceBefore(returnList, alignment);
if (getTable().isSeparateBorderModel()) {
- addKnuthElementsForBorderPaddingBefore(returnList);
+ addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
+ firstVisibleMarkServed = true;
}
//Spaces, border and padding to be repeated at each break
}
wrapPositionElements(contentList, returnList);
if (getTable().isSeparateBorderModel()) {
- addKnuthElementsForBorderPaddingAfter(returnList);
+ addKnuthElementsForBorderPaddingAfter(returnList, true);
}
addKnuthElementsForSpaceAfter(returnList, alignment);
addKnuthElementsForBreakAfter(returnList, context);
<box w="0"/> <!-- SpaceHandlingPosition-bearing helper box -->
- <box w="0"/> <!-- This is used to make sure the preceding glue is not cut off -->
-
<skip>3</skip>
</element-list>
</checks>
<box w="0"/> <!-- SpaceHandlingPosition-bearing helper box -->
- <box w="0"/> <!-- This is used to make sure the preceding glue is not cut off -->
-
<skip>3</skip>
</element-list>
</checks>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 The Apache Software Foundation
+
+ Licensed 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 if the isLast case is properly handled. In this case the part list has to be
+ reversed to do the conditionals removal, but then has to be reversed again to its natural order
+ so space resolution rules 2 and 3 are properly performed.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="1in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-before="11pt" space-after="11pt">
+ <fo:block space-before="12pt" space-after="12pt">
+ <fo:block space-before="13pt" space-after="13pt" border="solid 1pt">
+ Apache FOP!
+ </fo:block>
+ </fo:block>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <element-list category="breaker">
+ <box w="0"/>
+ <penalty w="0" p="INF"/>
+ <glue w="1000"/>
+
+ <box w="14400"/>
+
+ <box w="0"/>
+ <penalty w="0" p="INF"/>
+ <glue w="1000"/>
+
+ <box w="0"/>
+ <skip>3</skip>
+ </element-list>
+ <true xpath="not(boolean(//flow/block[1]/@space-before))"/>
+ <true xpath="not(boolean(//flow/block[1]/@space-after))"/>
+ <true xpath="not(boolean(//flow/block[1]/block[1]/@space-before))"/>
+ <true xpath="not(boolean(//flow/block[1]/block[1]/@space-after))"/>
+ <true xpath="not(boolean(//flow/block[1]/block[1]/block[1]/@space-before))"/>
+ <true xpath="not(boolean(//flow/block[1]/block[1]/block[1]/@space-after))"/>
+ <eval expected="1000 1000 1000 1000" xpath="//flow/block[1]/block[1]/block[1]/@bap"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 The Apache Software Foundation
+
+ Licensed 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 if the isLast case is properly handled. In this case the part list has to be
+ reversed to do the conditionals removal, but then has to be reversed again to its natural order
+ so space resolution rules 2 and 3 are properly performed.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="1in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-before="11pt" space-after="11pt">
+ <fo:block space-before="12pt" space-after="12pt">
+ <fo:block space-before="13pt" space-after="13pt" border="solid 1pt">
+ Apache FOP!
+ <fo:block break-before="page"/>
+ Apache FOP!!!
+ </fo:block>
+ </fo:block>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <element-list category="breaker" index="0">
+ <box w="0"/> <!-- SpaceHandlingPosition -->
+ <penalty w="0" p="INF"/>
+ <glue w="1000"/>
+
+ <box w="14400"/>
+
+ <skip>3</skip> <!-- the last of the three holds a SpaceHandlingBreakPosition -->
+ </element-list>
+ <element-list category="breaker" index="1">
+ <box w="0"/> <!-- SpaceHandlingPosition -->
+
+ <box w="0"/> <!-- empty block used to cause the break-before -->
+ <penalty w="0" p="0"/>
+
+ <box w="14400"/>
+
+ <box w="0"/>
+ <penalty w="0" p="INF"/>
+ <glue w="1000"/>
+ <box w="0"/> <!-- SpaceHandlingPosition -->
+
+ <skip>3</skip>
+ </element-list>
+
+ <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/@space-before))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/@space-after))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@space-before))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@space-after))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@space-before))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@space-after))"/>
+ <eval expected="1000 1000 1000 0" xpath="//pageViewport[@nr=1]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@bap"/>
+
+ <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/@space-before))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/@space-after))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@space-before))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@space-after))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@space-before))"/>
+ <true xpath="not(boolean(//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@space-after))"/>
+ <eval expected="1000 1000 0 1000" xpath="//pageViewport[@nr=2]/page/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/block[1]/@bap"/>
+ </checks>
+</testcase>
<box w="0"/> <!-- SpaceHandlingPosition-bearing helper box -->
- <box w="0"/> <!-- This is used to make sure the preceding glue is not cut off -->
-
<skip>3</skip>
</element-list>
<box w="14400"/>
<box w="0"/> <!-- SpaceHandlingPosition -->
- <box w="0"/>
<skip>3</skip>
</element-list>
<box w="0"/> <!-- SpaceHandlingPosition-bearing helper box -->
- <box w="0"/> <!-- This is used to make sure the preceding glue is not cut off -->
-
<skip>3</skip>
</element-list>