git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1362226 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_0
@@ -329,7 +329,7 @@ public abstract class AbstractBreaker { | |||
* @return the top-level LayoutContext | |||
*/ | |||
protected LayoutContext createLayoutContext() { | |||
return new LayoutContext(0); | |||
return LayoutContext.newInstance(); | |||
} | |||
/** | |||
@@ -481,6 +481,11 @@ public abstract class AbstractBreaker { | |||
addAreas(alg, 0, partCount, originalList, effectiveList); | |||
} | |||
protected void addAreas(PageBreakingAlgorithm alg, int startPart, int partCount, | |||
BlockSequence originalList, BlockSequence effectiveList) { | |||
addAreas(alg, startPart, partCount, originalList, effectiveList, LayoutContext.newInstance()); | |||
} | |||
/** | |||
* Phase 3 of Knuth algorithm: Adds the areas | |||
* @param alg PageBreakingAlgorithm instance which determined the breaks | |||
@@ -490,8 +495,7 @@ public abstract class AbstractBreaker { | |||
* @param effectiveList effective Knuth element list (after adjustments) | |||
*/ | |||
protected void addAreas(PageBreakingAlgorithm alg, int startPart, int partCount, | |||
BlockSequence originalList, BlockSequence effectiveList) { | |||
LayoutContext childLC; | |||
BlockSequence originalList, BlockSequence effectiveList, final LayoutContext childLC) { | |||
int startElementIndex = 0; | |||
int endElementIndex = 0; | |||
int lastBreak = -1; | |||
@@ -566,7 +570,6 @@ public abstract class AbstractBreaker { | |||
log.debug(" addAreas from " + startElementIndex | |||
+ " to " + endElementIndex); | |||
} | |||
childLC = new LayoutContext(0); | |||
// set the space adjustment ratio | |||
childLC.setSpaceAdjust(pbp.bpdAdjust); | |||
// add space before if display-align is center or bottom |
@@ -40,7 +40,7 @@ public final class AreaAdditionUtil { | |||
public static void addAreas(BlockStackingLayoutManager bslm, | |||
PositionIterator parentIter, LayoutContext layoutContext) { | |||
LayoutManager childLM; | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.offspringOf(layoutContext); | |||
LayoutManager firstLM = null; | |||
LayoutManager lastLM = null; | |||
Position firstPos = null; |
@@ -193,7 +193,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl | |||
*/ | |||
@Override | |||
protected LayoutContext makeChildLayoutContext(LayoutContext context) { | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
childLC.setStackLimitBP( | |||
context.getStackLimitBP().minus(MinOptMax.getInstance(relDims.bpd))); | |||
childLC.setRefIPD(relDims.ipd); | |||
@@ -707,7 +707,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl | |||
return curChildLM; | |||
} | |||
public void addContainedAreas() { | |||
public void addContainedAreas(LayoutContext layoutContext) { | |||
if (isEmpty()) { | |||
return; | |||
} | |||
@@ -715,8 +715,10 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl | |||
//overflow should be visible. | |||
this.deferredAlg.removeAllPageBreaks(); | |||
this.addAreas(this.deferredAlg, | |||
0, | |||
this.deferredAlg.getPageBreaks().size(), | |||
this.deferredOriginalList, this.deferredEffectiveList); | |||
this.deferredOriginalList, this.deferredEffectiveList, | |||
LayoutContext.offspringOf(layoutContext)); | |||
} | |||
} | |||
@@ -754,7 +756,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl | |||
LayoutManager childLM; | |||
LayoutManager lastLM = null; | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.offspringOf(layoutContext); | |||
lc.setSpaceAdjust(layoutContext.getSpaceAdjust()); | |||
// set space after in the LayoutContext for children | |||
if (layoutContext.getSpaceAfter() > 0) { | |||
@@ -821,7 +823,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl | |||
} | |||
} else { | |||
//Add child areas inside the reference area | |||
bcpos.getBreaker().addContainedAreas(); | |||
bcpos.getBreaker().addContainedAreas(layoutContext); | |||
} | |||
addMarkersToPage(false, isFirst(firstPos), isLast(lastPos)); |
@@ -272,7 +272,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co | |||
LayoutManager childLM; | |||
LayoutManager lastLM = null; | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.offspringOf(layoutContext); | |||
lc.setSpaceAdjust(layoutContext.getSpaceAdjust()); | |||
// set space after in the LayoutContext for children | |||
if (layoutContext.getSpaceAfter() > 0) { |
@@ -383,7 +383,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager | |||
* @return a new child layout context | |||
*/ | |||
protected LayoutContext makeChildLayoutContext(LayoutContext context) { | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
childLC.copyPendingMarksFrom(context); | |||
childLC.setStackLimitBP(context.getStackLimitBP()); | |||
childLC.setRefIPD(referenceIPD); |
@@ -200,7 +200,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager | |||
*/ | |||
@Override | |||
protected LayoutContext makeChildLayoutContext(LayoutContext context) { | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
childLC.setStackLimitBP(context.getStackLimitBP()); | |||
childLC.setRefIPD(context.getRefIPD()); | |||
childLC.setWritingMode(getCurrentPage().getSimplePageMaster().getWritingMode()); |
@@ -42,7 +42,7 @@ public class FootnoteBodyLayoutManager extends BlockStackingLayoutManager { | |||
public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { | |||
LayoutManager childLM; | |||
LayoutManager lastLM = null; | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.newInstance(); | |||
// "unwrap" the NonLeafPositions stored in parentIter | |||
// and put them in a new list; |
@@ -33,47 +33,27 @@ import org.apache.fop.traits.WritingMode; | |||
* This class is used to pass information to the getNextKnuthElements() | |||
* method. It is set up by higher level LM and used by lower level LM. | |||
*/ | |||
public class LayoutContext { | |||
public final class LayoutContext { | |||
/** linebreak at line feed only flag */ | |||
public static final int LINEBREAK_AT_LF_ONLY = 0x01; | |||
/** Generated break possibility is first in a new area */ | |||
public static final int NEW_AREA = 0x02; | |||
/** ipd unknown flag */ | |||
public static final int IPD_UNKNOWN = 0x04; | |||
/** Signal to a Line LM that a higher level LM may provoke a change | |||
* in the reference area, thus ref area IPD. The LineLM should return | |||
* without looking for a line break. | |||
*/ | |||
public static final int CHECK_REF_AREA = 0x08; | |||
public static final int NEW_AREA = 0x01; | |||
/** | |||
* If this flag is set, it indicates that any break-before values other than "auto" should | |||
* not cause a mandatory break as this break was already handled by a parent layout manager. | |||
*/ | |||
public static final int SUPPRESS_BREAK_BEFORE = 0x10; | |||
/** first area flag */ | |||
public static final int FIRST_AREA = 0x20; | |||
/** try hypenate flag */ | |||
public static final int TRY_HYPHENATE = 0x40; | |||
/** last area flag */ | |||
public static final int LAST_AREA = 0x80; | |||
/** resolve leading space flag */ | |||
public static final int RESOLVE_LEADING_SPACE = 0x100; | |||
public static final int SUPPRESS_BREAK_BEFORE = 0x02; | |||
/** | |||
* This flag indicates that there's a keep-with-next that hasn't | |||
* been processed, yet. | |||
*/ | |||
//public static final int KEEP_WITH_NEXT_PENDING = 0x200; | |||
/** | |||
* This flag indicates that there's a keep-with-previous that hasn't | |||
* been processed, yet. | |||
*/ | |||
//public static final int KEEP_WITH_PREVIOUS_PENDING = 0x400; | |||
public static final int FIRST_AREA = 0x04; | |||
public static final int LAST_AREA = 0x08; | |||
public static final int RESOLVE_LEADING_SPACE = 0x10; | |||
private static final int TREAT_AS_ARTIFACT = 0x20; | |||
private int flags; // Contains some set of flags defined above | |||
/** | |||
* Total available stacking dimension for a "galley-level" layout | |||
* manager in block-progression-direction. It is passed by the | |||
@@ -145,11 +125,27 @@ public class LayoutContext { | |||
private int disableColumnBalancing; | |||
public static LayoutContext newInstance() { | |||
return new LayoutContext(0); | |||
} | |||
public static LayoutContext copyOf(LayoutContext copy) { | |||
return new LayoutContext(copy); | |||
} | |||
/** | |||
* Copy constructor for creating child layout contexts. | |||
* @param parentLC the parent layout context to copy from | |||
* Returns a descendant of the given layout context. The new context is the same as | |||
* what would have been created by {@link #newInstance()}, except for inheritable | |||
* properties that are passed on by the parent. At the moment, the only inheritable | |||
* property is the value returned by {@link #treatAsArtifact()}. | |||
*/ | |||
public LayoutContext(LayoutContext parentLC) { | |||
public static LayoutContext offspringOf(LayoutContext parent) { | |||
LayoutContext offspring = new LayoutContext(0); | |||
offspring.setTreatAsArtifact(parent.treatAsArtifact()); | |||
return offspring; | |||
} | |||
private LayoutContext(LayoutContext parentLC) { | |||
this.flags = parentLC.flags; | |||
this.refIPD = parentLC.refIPD; | |||
this.writingMode = parentLC.writingMode; | |||
@@ -170,11 +166,7 @@ public class LayoutContext { | |||
this.disableColumnBalancing = parentLC.disableColumnBalancing; | |||
} | |||
/** | |||
* Main constructor. | |||
* @param flags the initial flags | |||
*/ | |||
public LayoutContext(int flags) { | |||
private LayoutContext(int flags) { | |||
this.flags = flags; | |||
this.refIPD = 0; | |||
stackLimitBP = MinOptMax.ZERO; | |||
@@ -435,11 +427,6 @@ public class LayoutContext { | |||
return hyphContext; | |||
} | |||
/** @return true if try hyphenate is set */ | |||
public boolean tryHyphenate() { | |||
return ((this.flags & TRY_HYPHENATE) != 0); | |||
} | |||
/** | |||
* Sets the currently applicable alignment in BP direction. | |||
* @param alignment one of EN_START, EN_JUSTIFY etc. | |||
@@ -673,7 +660,6 @@ public class LayoutContext { | |||
+ "\nIs First Area: \t" + isFirstArea() | |||
+ "\nStarts New Area: \t" + startsNewArea() | |||
+ "\nIs Last Area: \t" + isLastArea() | |||
+ "\nTry Hyphenate: \t" + tryHyphenate() | |||
+ "\nKeeps: \t[keep-with-next=" + getKeepWithNextPending() | |||
+ "][keep-with-previous=" + getKeepWithPreviousPending() + "] pending" | |||
+ "\nBreaks: \tforced [" + (breakBefore != Constants.EN_AUTO ? "break-before" : "") + "][" | |||
@@ -698,5 +684,13 @@ public class LayoutContext { | |||
public void setDisableColumnBalancing(int disableColumnBalancing) { | |||
this.disableColumnBalancing = disableColumnBalancing; | |||
} | |||
public boolean treatAsArtifact() { | |||
return (flags & TREAT_AS_ARTIFACT) != 0; | |||
} | |||
public void setTreatAsArtifact(boolean treatAsArtifact) { | |||
setFlags(TREAT_AS_ARTIFACT, treatAsArtifact); | |||
} | |||
} | |||
@@ -167,7 +167,7 @@ public class PageBreaker extends AbstractBreaker { | |||
&& ((KnuthBlockBox) element).hasAnchors()) { | |||
// element represents a line with footnote citations | |||
containsFootnotes = true; | |||
LayoutContext footnoteContext = new LayoutContext(context); | |||
LayoutContext footnoteContext = LayoutContext.copyOf(context); | |||
footnoteContext.setStackLimitBP(context.getStackLimitBP()); | |||
footnoteContext.setRefIPD(pslm.getCurrentPV() | |||
.getRegionReference(Constants.FO_REGION_BODY).getIPD()); | |||
@@ -473,7 +473,7 @@ public class PageBreaker extends AbstractBreaker { | |||
SpaceResolver.performConditionalsNotification(elementList, | |||
firstIndex, lastIndex, -1); | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
AreaAdditionUtil.addAreas(null, | |||
new KnuthPossPosIter(elementList, firstIndex, lastIndex + 1), | |||
childLC); |
@@ -232,7 +232,7 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager { | |||
List returnList = new LinkedList(); | |||
while ((curLM = getChildLM()) != null) { | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
childLC.setStackLimitBP(context.getStackLimitBP()); | |||
childLC.setRefIPD(context.getRefIPD()); | |||
childLC.setWritingMode(context.getWritingMode()); |
@@ -24,6 +24,7 @@ import java.awt.Rectangle; | |||
import java.util.List; | |||
import org.apache.fop.area.Area; | |||
import org.apache.fop.area.inline.InlineArea; | |||
import org.apache.fop.area.inline.InlineViewport; | |||
import org.apache.fop.datatypes.LengthBase; | |||
import org.apache.fop.fo.FObj; | |||
@@ -92,7 +93,6 @@ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManage | |||
transferForeignAttributes(viewportArea); | |||
InlineViewport vp = new InlineViewport(viewportArea, bidiLevel); | |||
TraitSetter.addStructureTreeElement(vp, fobj.getStructureTreeElement()); | |||
TraitSetter.setProducerID(vp, fobj.getId()); | |||
vp.setIPD(imageLayout.getViewportSize().width); | |||
vp.setBPD(imageLayout.getViewportSize().height); | |||
@@ -118,6 +118,21 @@ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManage | |||
return super.getNextKnuthElements(context, alignment); | |||
} | |||
@Override | |||
protected InlineArea getEffectiveArea(LayoutContext layoutContext) { | |||
/* | |||
* If an image is in a repeated table heading, then it must be treated as real | |||
* content the first time and then as artifact. Therefore we cannot re-use the | |||
* area, as we have to account for the likely different values of treatAsArtifact. | |||
*/ | |||
InlineArea area = curArea != null ? curArea : getInlineArea(); | |||
curArea = null; | |||
if (!layoutContext.treatAsArtifact()) { | |||
TraitSetter.addStructureTreeElement(area, ((AbstractGraphics) fobj).getStructureTreeElement()); | |||
} | |||
return area; | |||
} | |||
/** {@inheritDoc} */ | |||
protected AlignmentContext makeAlignmentContext(LayoutContext context) { | |||
final AbstractGraphics fobj = (AbstractGraphics)this.fobj; |
@@ -19,17 +19,18 @@ | |||
package org.apache.fop.layoutmgr.inline; | |||
import org.apache.fop.area.Resolvable; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.area.Trait; | |||
import org.apache.fop.area.inline.InlineArea; | |||
import org.apache.fop.area.inline.TextArea; | |||
import org.apache.fop.area.inline.UnresolvedPageNumber; | |||
import org.apache.fop.fo.flow.AbstractPageNumberCitation; | |||
import org.apache.fop.fonts.Font; | |||
import org.apache.fop.fonts.FontInfo; | |||
import org.apache.fop.fonts.FontTriplet; | |||
import org.apache.fop.layoutmgr.LayoutContext; | |||
import org.apache.fop.layoutmgr.PositionIterator; | |||
import org.apache.fop.layoutmgr.TraitSetter; | |||
import org.apache.fop.traits.MinOptMax; | |||
/** | |||
* LayoutManager for the fo:page-number-citation(-last) formatting object | |||
@@ -42,7 +43,9 @@ public abstract class AbstractPageNumberCitationLayoutManager extends LeafNodeLa | |||
protected Font font; | |||
/** Indicates whether the page referred to by the citation has been resolved yet */ | |||
protected boolean resolved = false; | |||
private boolean resolved; | |||
private String citationString; | |||
/** | |||
* Constructor | |||
@@ -78,46 +81,78 @@ public abstract class AbstractPageNumberCitationLayoutManager extends LeafNodeLa | |||
); | |||
} | |||
/** {@inheritDoc} */ | |||
public abstract InlineArea get(LayoutContext context); | |||
@Override | |||
protected MinOptMax getAllocationIPD(int refIPD) { | |||
determineCitationString(); | |||
int ipd = getStringWidth(citationString); | |||
return MinOptMax.getInstance(ipd); | |||
} | |||
/** | |||
* {@inheritDoc} | |||
* , LayoutContext) | |||
*/ | |||
public void addAreas(PositionIterator posIter, LayoutContext context) { | |||
super.addAreas(posIter, context); | |||
if (!resolved) { | |||
getPSLM().addUnresolvedArea(fobj.getRefId(), (Resolvable) curArea); | |||
private void determineCitationString() { | |||
assert citationString == null; | |||
PageViewport page = getCitedPage(); | |||
if (page != null) { | |||
resolved = true; | |||
citationString = page.getPageNumberString(); | |||
} else { | |||
resolved = false; | |||
citationString = "MMM"; // Use a place holder | |||
} | |||
} | |||
private int getStringWidth(String str) { | |||
int width = 0; | |||
for (int count = 0; count < str.length(); count++) { | |||
width += font.getCharWidth(str.charAt(count)); | |||
} | |||
return width; | |||
} | |||
protected abstract PageViewport getCitedPage(); | |||
@Override | |||
protected InlineArea getEffectiveArea(LayoutContext layoutContext) { | |||
InlineArea area = getPageNumberCitationArea(); | |||
if (!layoutContext.treatAsArtifact()) { | |||
TraitSetter.addStructureTreeElement(area, fobj.getStructureTreeElement()); | |||
} | |||
return area; | |||
} | |||
private InlineArea getPageNumberCitationArea() { | |||
TextArea text; | |||
if (resolved) { | |||
text = new TextArea(); | |||
text.addWord(citationString, 0); | |||
} else { | |||
UnresolvedPageNumber unresolved = new UnresolvedPageNumber(fobj.getRefId(), font, | |||
getReferenceType()); | |||
getPSLM().addUnresolvedArea(fobj.getRefId(), unresolved); | |||
text = unresolved; | |||
} | |||
setTraits(text); | |||
return text; | |||
} | |||
/** | |||
* Updates the traits for the generated text area. | |||
* @param text the text area | |||
* @return {@link org.apache.fop.area.inline.UnresolvedPageNumber#FIRST} or | |||
* {@linkorg.apache.fop.area.inline.UnresolvedPageNumber#LAST} | |||
*/ | |||
protected void updateTextAreaTraits(TextArea text) { | |||
protected abstract boolean getReferenceType(); | |||
private void setTraits(TextArea text) { | |||
TraitSetter.setProducerID(text, fobj.getId()); | |||
int bidiLevel = getBidiLevel(); | |||
text.setBidiLevel(bidiLevel); | |||
int width = getStringWidth(citationString); // TODO: [GA] !I18N! | |||
text.setIPD(width); // TODO: [GA] !I18N! | |||
text.setBPD(font.getAscender() - font.getDescender()); | |||
text.setBaselineOffset(font.getAscender()); | |||
TraitSetter.addFontTraits(text, font); | |||
text.addTrait(Trait.COLOR, fobj.getColor()); | |||
TraitSetter.addStructureTreeElement(text, fobj.getStructureTreeElement()); | |||
TraitSetter.addTextDecoration(text, fobj.getTextDecoration()); | |||
} | |||
/** | |||
* @param str string to be measured | |||
* @return width (in millipoints ??) of the string | |||
*/ | |||
protected int getStringWidth(String str) { | |||
int width = 0; | |||
for (int count = 0; count < str.length(); count++) { | |||
width += font.getCharWidth(str.charAt(count)); | |||
} | |||
return width; | |||
} | |||
/** | |||
* @return bidi level governing abstract page number citation | |||
*/ |
@@ -23,6 +23,7 @@ import java.util.LinkedList; | |||
import java.util.List; | |||
import org.apache.fop.area.Trait; | |||
import org.apache.fop.area.inline.InlineArea; | |||
import org.apache.fop.area.inline.TextArea; | |||
import org.apache.fop.fo.flow.Character; | |||
import org.apache.fop.fo.properties.CommonBorderPaddingBackground; | |||
@@ -69,17 +70,15 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { | |||
hyphIPD = fobj.getCommonHyphenation().getHyphIPD(font); | |||
borderProps = fobj.getCommonBorderPaddingBackground(); | |||
setCommonBorderPaddingBackground(borderProps); | |||
TextArea chArea = getCharacterInlineArea(fobj); | |||
chArea.setBaselineOffset(font.getAscender()); | |||
setCurrentArea(chArea); | |||
} | |||
private TextArea getCharacterInlineArea(Character node) { | |||
private TextArea createCharacterArea() { | |||
Character fobj = (Character) this.fobj; | |||
TextArea text = new TextArea(); | |||
char ch = node.getCharacter(); | |||
char ch = fobj.getCharacter(); | |||
int ipd = font.getCharWidth(ch); | |||
int blockProgressionOffset = 0; | |||
int level = node.getBidiLevel(); | |||
int level = fobj.getBidiLevel(); | |||
if (CharUtilities.isAnySpace(ch)) { | |||
// add space unless it's zero-width: | |||
if (!CharUtilities.isZeroWidthSpace(ch)) { | |||
@@ -90,32 +89,29 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { | |||
int[] levels = ( level >= 0 ) ? new int[] {level} : null; | |||
text.addWord(String.valueOf(ch), ipd, null, levels, null, blockProgressionOffset); | |||
} | |||
TraitSetter.setProducerID(text, node.getId()); | |||
TraitSetter.addTextDecoration(text, node.getTextDecoration()); | |||
TraitSetter.addStructureTreeElement(text, node.getStructureTreeElement()); | |||
TraitSetter.setProducerID(text, fobj.getId()); | |||
TraitSetter.addTextDecoration(text, fobj.getTextDecoration()); | |||
text.setIPD(font.getCharWidth(fobj.getCharacter())); | |||
text.setBPD(font.getAscender() - font.getDescender()); | |||
text.setBaselineOffset(font.getAscender()); | |||
TraitSetter.addFontTraits(text, font); | |||
text.addTrait(Trait.COLOR, fobj.getColor()); | |||
return text; | |||
} | |||
/** {@inheritDoc} */ | |||
@Override | |||
public List getNextKnuthElements(LayoutContext context, int alignment) { | |||
MinOptMax ipd; | |||
curArea = get(context); | |||
KnuthSequence seq = new InlineKnuthSequence(); | |||
if (curArea == null) { | |||
setFinished(true); | |||
return null; | |||
protected InlineArea getEffectiveArea(LayoutContext layoutContext) { | |||
InlineArea area = createCharacterArea(); | |||
if (!layoutContext.treatAsArtifact()) { | |||
TraitSetter.addStructureTreeElement(area, ((Character) fobj).getStructureTreeElement()); | |||
} | |||
return area; | |||
} | |||
Character fobj = (Character)this.fobj; | |||
ipd = MinOptMax.getInstance(curArea.getIPD()); | |||
curArea.setBPD(font.getAscender() - font.getDescender()); | |||
TraitSetter.addFontTraits(curArea, font); | |||
curArea.addTrait(Trait.COLOR, fobj.getColor()); | |||
/** {@inheritDoc} */ | |||
public List getNextKnuthElements(LayoutContext context, int alignment) { | |||
Character fobj = (Character) this.fobj; | |||
// TODO: may need some special handling for fo:character | |||
alignmentContext = new AlignmentContext(font | |||
@@ -126,9 +122,11 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { | |||
, fobj.getDominantBaseline() | |||
, context.getAlignmentContext()); | |||
KnuthSequence seq = new InlineKnuthSequence(); | |||
addKnuthElementsForBorderPaddingStart(seq); | |||
// create the AreaInfo object to store the computed values | |||
MinOptMax ipd = MinOptMax.getInstance(font.getCharWidth(fobj.getCharacter())); | |||
areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext); | |||
// node is a fo:Character | |||
@@ -162,7 +160,7 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { | |||
/** {@inheritDoc} */ | |||
@Override | |||
public String getWordChars(Position pos) { | |||
return ((TextArea) curArea).getText(); | |||
return String.valueOf(((Character) fobj).getCharacter()); | |||
} | |||
/** {@inheritDoc} */ |
@@ -110,7 +110,8 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager | |||
int ipd = 1000000; | |||
LayoutContext childLC = new LayoutContext(LayoutContext.NEW_AREA); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
childLC.setFlags(LayoutContext.NEW_AREA); | |||
childLC.setLeadingSpace(new SpaceSpecifier(false)); | |||
childLC.setTrailingSpace(new SpaceSpecifier(false)); | |||
childLC.setRefIPD(ipd); | |||
@@ -143,7 +144,7 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager | |||
middlefollow = maxtb - lineLead; | |||
} | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.newInstance(); | |||
lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); | |||
lc.setLeadingSpace(new SpaceSpecifier(false)); | |||
@@ -160,7 +161,7 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager | |||
int savedIPD = ((InlineArea)holder).getIPD(); | |||
// set to zero the ipd adjustment ratio, to avoid spaces in the pattern | |||
// to be modified | |||
LayoutContext childContext = new LayoutContext(context); | |||
LayoutContext childContext = LayoutContext.copyOf(context); | |||
childContext.setIPDAdjust(0.0); | |||
childLM.addAreas(posIter, childContext); | |||
((InlineArea)holder).setIPD(savedIPD); |
@@ -151,7 +151,7 @@ public class FootnoteLayoutManager extends InlineStackingLayoutManager { | |||
citationLM.setParent(getParent()); | |||
// make the citationLM add its areas | |||
LayoutContext childContext = new LayoutContext(context); | |||
LayoutContext childContext = LayoutContext.copyOf(context); | |||
PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); | |||
LayoutManager childLM; | |||
while ((childLM = childPosIter.getNextChildLM()) != null) { |
@@ -283,7 +283,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { | |||
, context.getAlignmentContext()); | |||
} | |||
childLC = new LayoutContext(context); | |||
childLC = LayoutContext.copyOf(context); | |||
childLC.setAlignmentContext(alignmentContext); | |||
if (context.startsNewArea()) { | |||
@@ -439,7 +439,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { | |||
addId(); | |||
setChildContext(new LayoutContext(context)); // Store current value | |||
setChildContext(LayoutContext.copyOf(context)); // Store current value | |||
// "Unwrap" the NonLeafPositions stored in parentIter and put | |||
// them in a new list. Set lastLM to be the LayoutManager |
@@ -191,7 +191,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { | |||
clm.addChildLM(lm); | |||
lm.initialize(); | |||
LayoutContext childContext = new LayoutContext(0); | |||
LayoutContext childContext = LayoutContext.newInstance(); | |||
childContext.setAlignmentContext(context.getAlignmentContext()); | |||
contentList = clm.getNextKnuthElements(childContext, 0); | |||
int width = clm.getStackingSize(); |
@@ -188,7 +188,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager | |||
public void addAreas(PositionIterator posIter, LayoutContext context) { | |||
addId(); | |||
InlineArea area = getEffectiveArea(); | |||
InlineArea area = getEffectiveArea(context); | |||
if (area.getAllocIPD() > 0 || area.getAllocBPD() > 0) { | |||
offsetArea(area, context); | |||
widthAdjustArea(area, context); | |||
@@ -211,7 +211,7 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager | |||
* @return the effective area to be added to the area tree. Normally, this is simply "curArea" | |||
* but in the case of page-number(-citation) curArea is cloned, updated and returned. | |||
*/ | |||
protected InlineArea getEffectiveArea() { | |||
protected InlineArea getEffectiveArea(LayoutContext layoutContext) { | |||
return curArea; | |||
} | |||
@@ -264,11 +264,6 @@ public abstract class LeafNodeLayoutManager extends AbstractLayoutManager | |||
public List getNextKnuthElements(LayoutContext context, int alignment) { | |||
curArea = get(context); | |||
if (curArea == null) { | |||
setFinished(true); | |||
return null; | |||
} | |||
alignmentContext = makeAlignmentContext(context); | |||
MinOptMax ipd = getAllocationIPD(context.getRefIPD()); |
@@ -674,7 +674,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager | |||
* @param context the LayoutContext | |||
*/ | |||
private void collectInlineKnuthElements(LayoutContext context) { | |||
LayoutContext inlineLC = new LayoutContext(context); | |||
LayoutContext inlineLC = LayoutContext.copyOf(context); | |||
// convert all the text in a sequence of paragraphs made | |||
// of KnuthBox, KnuthGlue and KnuthPenalty objects | |||
@@ -1522,7 +1522,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager | |||
PositionIterator inlinePosIter = new KnuthPossPosIter(seq, startElementIndex, | |||
endElementIndex + 1); | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.offspringOf(context); | |||
lc.setAlignmentContext(alignmentContext); | |||
lc.setSpaceAdjust(lbp.dAdjust); | |||
lc.setIPDAdjust(lbp.ipdAdjust); | |||
@@ -1577,12 +1577,12 @@ public class LineLayoutManager extends InlineStackingLayoutManager | |||
LineArea lineArea = new LineArea(); | |||
setCurrentArea(lineArea); | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.newInstance(); | |||
lc.setAlignmentContext(alignmentContext); | |||
setChildContext(lc); | |||
PositionIterator childPosIter = new PositionIterator(positionList.listIterator()); | |||
LayoutContext blocklc = new LayoutContext(0); | |||
LayoutContext blocklc = LayoutContext.offspringOf(context); | |||
blocklc.setLeadingSpace(new SpaceSpecifier(true)); | |||
blocklc.setTrailingSpace(new SpaceSpecifier(false)); | |||
blocklc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); |
@@ -20,65 +20,36 @@ | |||
package org.apache.fop.layoutmgr.inline; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.area.Resolvable; | |||
import org.apache.fop.area.inline.InlineArea; | |||
import org.apache.fop.area.inline.TextArea; | |||
import org.apache.fop.area.inline.UnresolvedPageNumber; | |||
import org.apache.fop.fo.flow.PageNumberCitationLast; | |||
import org.apache.fop.layoutmgr.LayoutContext; | |||
import org.apache.fop.layoutmgr.LayoutManager; | |||
/** | |||
* LayoutManager for the fo:page-number-citation-last formatting object | |||
* LayoutManager for the fo:page-number-citation-last formatting object. | |||
*/ | |||
public class PageNumberCitationLastLayoutManager extends AbstractPageNumberCitationLayoutManager { | |||
/** | |||
* Constructor | |||
* Constructor. | |||
* | |||
* @param node the formatting object that creates this area | |||
* TODO better retrieval of font info | |||
*/ | |||
public PageNumberCitationLastLayoutManager(PageNumberCitationLast node) { | |||
super(node); | |||
fobj = node; | |||
} | |||
/** {@inheritDoc} */ | |||
public InlineArea get(LayoutContext context) { | |||
curArea = getPageNumberCitationLastInlineArea(parentLayoutManager); | |||
return curArea; | |||
} | |||
/** | |||
* if id can be resolved then simply return a word, otherwise | |||
* return a resolvable area | |||
*/ | |||
private InlineArea getPageNumberCitationLastInlineArea(LayoutManager parentLM) { | |||
TextArea text = null; | |||
int level = getBidiLevel(); | |||
if (!getPSLM().associateLayoutManagerID(fobj.getRefId())) { | |||
text = new UnresolvedPageNumber(fobj.getRefId(), font, UnresolvedPageNumber.LAST); | |||
getPSLM().addUnresolvedArea(fobj.getRefId(), (Resolvable)text); | |||
String str = "MMM"; // reserve three spaces for page number | |||
int width = getStringWidth(str); | |||
text.setBidiLevel(level); | |||
text.setIPD(width); | |||
resolved = false; | |||
@Override | |||
protected PageViewport getCitedPage() { | |||
if (getPSLM().associateLayoutManagerID(fobj.getRefId())) { | |||
return getPSLM().getLastPVWithID(fobj.getRefId()); | |||
} else { | |||
PageViewport page = getPSLM().getLastPVWithID(fobj.getRefId()); | |||
String str = page.getPageNumberString(); | |||
// get page string from parent, build area | |||
text = new TextArea(); | |||
int width = getStringWidth(str); | |||
text.setBidiLevel(level); | |||
text.addWord(str, 0, level); | |||
text.setIPD(width); | |||
resolved = true; | |||
return null; | |||
} | |||
} | |||
updateTextAreaTraits(text); | |||
return text; | |||
@Override | |||
protected boolean getReferenceType() { | |||
return UnresolvedPageNumber.LAST; | |||
} | |||
} |
@@ -20,19 +20,16 @@ | |||
package org.apache.fop.layoutmgr.inline; | |||
import org.apache.fop.area.PageViewport; | |||
import org.apache.fop.area.inline.InlineArea; | |||
import org.apache.fop.area.inline.TextArea; | |||
import org.apache.fop.area.inline.UnresolvedPageNumber; | |||
import org.apache.fop.fo.flow.PageNumberCitation; | |||
import org.apache.fop.layoutmgr.LayoutContext; | |||
/** | |||
* LayoutManager for the fo:page-number-citation formatting object | |||
* LayoutManager for the fo:page-number-citation formatting object. | |||
*/ | |||
public class PageNumberCitationLayoutManager extends AbstractPageNumberCitationLayoutManager { | |||
/** | |||
* Constructor | |||
* Constructor. | |||
* | |||
* @param node the formatting object that creates this area | |||
* TODO better retrieval of font info | |||
@@ -41,42 +38,14 @@ public class PageNumberCitationLayoutManager extends AbstractPageNumberCitationL | |||
super(node); | |||
} | |||
/** {@inheritDoc} */ | |||
public InlineArea get(LayoutContext context) { | |||
curArea = getPageNumberCitationInlineArea(); | |||
return curArea; | |||
@Override | |||
protected PageViewport getCitedPage() { | |||
return getPSLM().getFirstPVWithID(fobj.getRefId()); | |||
} | |||
/** | |||
* if id can be resolved then simply return a word, otherwise | |||
* return a resolvable area | |||
* | |||
* TODO: [GA] May need to run bidi algorithm and script processor | |||
* on resolved page number. | |||
*/ | |||
private InlineArea getPageNumberCitationInlineArea() { | |||
PageViewport page = getPSLM().getFirstPVWithID(fobj.getRefId()); | |||
TextArea text = null; | |||
int level = getBidiLevel(); | |||
if (page != null) { | |||
String str = page.getPageNumberString(); | |||
// get page string from parent, build area | |||
text = new TextArea(); | |||
int width = getStringWidth(str); // TODO: [GA] !I18N! | |||
text.setBidiLevel(level); | |||
text.addWord(str, 0, level); | |||
text.setIPD(width); // TODO: [GA] !I18N! | |||
resolved = true; | |||
} else { | |||
text = new UnresolvedPageNumber(fobj.getRefId(), font); | |||
String str = "MMM"; // reserve three spaces for page number | |||
int width = getStringWidth(str); // TODO: [GA] !I18N! | |||
text.setBidiLevel(level); | |||
text.setIPD(width); // TODO: [GA] !I18N! | |||
resolved = false; | |||
} | |||
updateTextAreaTraits(text); | |||
return text; | |||
@Override | |||
protected boolean getReferenceType() { | |||
return UnresolvedPageNumber.FIRST; | |||
} | |||
} |
@@ -85,14 +85,13 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { | |||
text.setBaselineOffset(font.getAscender()); | |||
TraitSetter.addFontTraits(text, font); | |||
text.addTrait(Trait.COLOR, fobj.getColor()); | |||
TraitSetter.addStructureTreeElement(text, fobj.getStructureTreeElement()); | |||
TraitSetter.addTextDecoration(text, fobj.getTextDecoration()); | |||
return text; | |||
} | |||
/** {@inheritDoc} */ | |||
protected InlineArea getEffectiveArea() { | |||
protected InlineArea getEffectiveArea(LayoutContext layoutContext) { | |||
TextArea baseArea = (TextArea)curArea; | |||
//TODO Maybe replace that with a clone() call or better, a copy constructor | |||
//TODO or even better: delay area creation until addAreas() stage | |||
@@ -105,6 +104,9 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { | |||
ta.setBaselineOffset(baseArea.getBaselineOffset()); | |||
ta.addTrait(Trait.COLOR, fobj.getColor()); //only to initialize the trait map | |||
ta.getTraits().putAll(baseArea.getTraits()); | |||
if (!layoutContext.treatAsArtifact()) { | |||
TraitSetter.addStructureTreeElement(ta, fobj.getStructureTreeElement()); | |||
} | |||
updateContent(ta); | |||
return ta; | |||
} |
@@ -469,7 +469,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager { | |||
TraitSetter.addFontTraits(textArea, font); | |||
textArea.addTrait(Trait.COLOR, foText.getColor()); | |||
TraitSetter.addTextDecoration(textArea, foText.getTextDecoration()); | |||
TraitSetter.addStructureTreeElement(textArea, foText.getStructureTreeElement()); | |||
if (!context.treatAsArtifact()) { | |||
TraitSetter.addStructureTreeElement(textArea, foText.getStructureTreeElement()); | |||
} | |||
return textArea; | |||
} | |||
@@ -71,7 +71,7 @@ public class WrapperLayoutManager extends LeafNodeLayoutManager { | |||
TraitSetter.setProducerID(helperBlock, fobj.getId()); | |||
parentLayoutManager.addChildArea(helperBlock); | |||
} else { | |||
InlineArea area = getEffectiveArea(); | |||
InlineArea area = getEffectiveArea(context); | |||
parentLayoutManager.addChildArea(area); | |||
} | |||
} |
@@ -141,7 +141,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager | |||
// the list block contains areas stacked from each list item | |||
LayoutManager childLM; | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.offspringOf(layoutContext); | |||
LayoutManager firstLM = null; | |||
LayoutManager lastLM = null; | |||
Position firstPos = null; |
@@ -101,7 +101,7 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager imp | |||
addId(); | |||
LayoutManager childLM; | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.offspringOf(layoutContext); | |||
LayoutManager firstLM = null; | |||
LayoutManager lastLM = null; | |||
Position firstPos = null; |
@@ -488,7 +488,7 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements | |||
addId(); | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.offspringOf(layoutContext); | |||
Position firstPos = null; | |||
Position lastPos = null; | |||
@@ -112,7 +112,7 @@ class RowGroupLayoutManager { | |||
spanWidth += ((TableColumn) colIter.next()).getColumnWidth().getValue( | |||
tableLM); | |||
} | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
childLC.setStackLimitBP(context.getStackLimitBP()); //necessary? | |||
childLC.setRefIPD(spanWidth); | |||
@@ -81,7 +81,7 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager { | |||
int ipd = context.getRefIPD(); | |||
BreakPoss bp; | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
// if line layout manager then set stack limit to ipd | |||
// line LM actually generates a LineArea which is a block | |||
childLC.setStackLimit( | |||
@@ -145,7 +145,7 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager { | |||
/* TODO: Reimplement using Knuth approach | |||
LayoutManager childLM; | |||
int iStartPos = 0; | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.newInstance(); | |||
while (parentIter.hasNext()) { | |||
LeafPosition lfp = (LeafPosition) parentIter.next(); | |||
// Add the block areas to Area |
@@ -76,7 +76,7 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager { | |||
int ipd = context.getRefIPD(); | |||
BreakPoss bp; | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
// if line layout manager then set stack limit to ipd | |||
// line LM actually generates a LineArea which is a block | |||
childLC.setStackLimit( | |||
@@ -141,7 +141,7 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager { | |||
/* TODO: Reimplement using Knuth approach | |||
LayoutManager childLM; | |||
int iStartPos = 0; | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.newInstance(); | |||
while (parentIter.hasNext()) { | |||
LeafPosition lfp = (LeafPosition) parentIter.next(); | |||
// Add the block areas to Area |
@@ -144,7 +144,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager | |||
LayoutManager curLM; // currently active LM | |||
LayoutManager prevLM = null; // previously active LM | |||
while ((curLM = getChildLM()) != null) { | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
// curLM is a ? | |||
childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit)); | |||
childLC.setRefIPD(cellIPD); |
@@ -71,6 +71,8 @@ public class TableContentLayoutManager implements PercentBaseContext { | |||
private TableStepper stepper; | |||
private boolean headerIsBeingRepeated; | |||
/** | |||
* Main constructor | |||
* @param parent Parent layout manager | |||
@@ -383,6 +385,7 @@ public class TableContentLayoutManager implements PercentBaseContext { | |||
} | |||
} | |||
} | |||
boolean treatFooterAsArtifact = layoutContext.treatAsArtifact(); | |||
if (lastPos instanceof TableHFPenaltyPosition) { | |||
TableHFPenaltyPosition penaltyPos = (TableHFPenaltyPosition)lastPos; | |||
LOG.debug("Break at penalty!"); | |||
@@ -393,6 +396,7 @@ public class TableContentLayoutManager implements PercentBaseContext { | |||
} | |||
if (penaltyPos.footerElements != null) { | |||
footerElements = penaltyPos.footerElements; | |||
treatFooterAsArtifact = true; | |||
} | |||
} | |||
@@ -403,10 +407,18 @@ public class TableContentLayoutManager implements PercentBaseContext { | |||
} | |||
if (headerElements != null) { | |||
boolean ancestorTreatAsArtifact = layoutContext.treatAsArtifact(); | |||
if (headerIsBeingRepeated) { | |||
layoutContext.setTreatAsArtifact(true); | |||
} | |||
//header positions for the last part are the second-to-last element and need to | |||
//be handled first before all other TableContentPositions | |||
addHeaderFooterAreas(headerElements, tableLM.getTable().getTableHeader(), painter, | |||
false); | |||
if (!ancestorTreatAsArtifact) { | |||
headerIsBeingRepeated = true; | |||
} | |||
layoutContext.setTreatAsArtifact(ancestorTreatAsArtifact); | |||
} | |||
if (tablePositions.isEmpty()) { | |||
@@ -419,9 +431,12 @@ public class TableContentLayoutManager implements PercentBaseContext { | |||
} | |||
if (footerElements != null) { | |||
boolean ancestorTreatAsArtifact = layoutContext.treatAsArtifact(); | |||
layoutContext.setTreatAsArtifact(treatFooterAsArtifact); | |||
//Positions for footers are simply added at the end | |||
addHeaderFooterAreas(footerElements, tableLM.getTable().getTableFooter(), painter, | |||
true); | |||
layoutContext.setTreatAsArtifact(ancestorTreatAsArtifact); | |||
} | |||
this.usedBPD += painter.getAccumulatedBPD(); |
@@ -242,7 +242,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager | |||
// Elements for the table-header/footer/body | |||
List contentKnuthElements; | |||
contentLM = new TableContentLayoutManager(this); | |||
LayoutContext childLC = new LayoutContext(0); | |||
LayoutContext childLC = LayoutContext.newInstance(); | |||
/* | |||
childLC.setStackLimit( | |||
MinOptMax.subtract(context.getStackLimit(), | |||
@@ -355,7 +355,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager | |||
// BPD of the table, i.e., height of its content; table's borders and paddings not counted | |||
int tableHeight = 0; | |||
//Body childLM; | |||
LayoutContext lc = new LayoutContext(0); | |||
LayoutContext lc = LayoutContext.offspringOf(layoutContext); | |||
lc.setRefIPD(getContentAreaIPD()); |
@@ -72,9 +72,7 @@ public class PDFStructElem extends PDFDictionary implements StructureTreeElement | |||
} | |||
/** | |||
* Add a kid to this structure element. This element will then add itself to | |||
* its parent structure element if it has not already, and so will the | |||
* parent, and so on. | |||
* Adds a kid to this structure element. | |||
* | |||
* @param kid element to be added | |||
*/ |
@@ -63,6 +63,12 @@ | |||
documents. Example: the fix of marks layering will be such a case when it's done. | |||
--> | |||
<release version="FOP Trunk" date="TBD"> | |||
<action context="Renderers" dev="VH" type="add" importance="high"> | |||
When PDF accessibility is enabled, treat repeated table headings as artifacts. This allows | |||
screen readers to read the header only once at the beginning of the table and the footer | |||
once at the end of a table. Reading the headings at every column or page break is likely to | |||
disturb the user. This follows Section 508 recommendations. | |||
</action> | |||
<action context="Layout" dev="VH" type="fix"> | |||
An IllegalArgumentException was thrown when break-before was used inside a list. | |||
</action> |