diff options
48 files changed, 1746 insertions, 527 deletions
@@ -790,7 +790,8 @@ list of possible build targets. <exclude name="**/intermediate/*"/> </patternset> </target> - <target name="junit-compile" depends="package, transcoder-pkg, junit-with-xmlunit, junit-without-xmlunit" description="Runs FOP's JUnit tests" if="junit.present"> + + <target name="junit-compile-java" depends="package, transcoder-pkg, junit-with-xmlunit, junit-without-xmlunit" if="junit.present"> <mkdir dir="${build.dir}/test-classes"/> <mkdir dir="${build.dir}/test-gensrc"/> <mkdir dir="${junit.reports.dir}"/> @@ -807,6 +808,9 @@ list of possible build targets. </fileset> </classpath> </javac> + </target> + + <target name="junit-compile-copy-resources" if="junit.present"> <eventResourceGenerator modelfile="${build.dir}/test-gensrc/org/apache/fop/events/test-event-model.xml"> <fileset dir="${basedir}/test/java"> <include name="**/*.java"/> @@ -823,6 +827,8 @@ list of possible build targets. </copy> </target> + <target name="junit-compile" depends="junit-compile-java, junit-compile-copy-resources" description="Compiles FOP's JUnit tests" if="junit.present"/> + <target name="junit-transcoder" depends="junit-compile" description="Runs FOP's JUnit transcoder tests" if="junit.present"> <echo message="Running basic functionality tests for fop-transcoder.jar"/> <junit dir="${basedir}" haltonfailure="${junit.haltonfailure}" fork="${junit.fork}"> diff --git a/src/codegen/java/org/apache/fop/tools/EventConventionException.java b/src/codegen/java/org/apache/fop/tools/EventConventionException.java index 675f4a0ca..27a7fcd50 100644 --- a/src/codegen/java/org/apache/fop/tools/EventConventionException.java +++ b/src/codegen/java/org/apache/fop/tools/EventConventionException.java @@ -19,8 +19,17 @@ package org.apache.fop.tools; +/** + * This exception is used to indicate a violation of the conventions for event producers. + */ public class EventConventionException extends Exception { + private static final long serialVersionUID = 117244726033986628L; + + /** + * Creates a new EventConventionException + * @param message the error message + */ public EventConventionException(String message) { super(message); } diff --git a/src/codegen/java/org/apache/fop/tools/EventProducerCollector.java b/src/codegen/java/org/apache/fop/tools/EventProducerCollector.java index e42395ae7..ebb960a8e 100644 --- a/src/codegen/java/org/apache/fop/tools/EventProducerCollector.java +++ b/src/codegen/java/org/apache/fop/tools/EventProducerCollector.java @@ -63,15 +63,29 @@ public class EventProducerCollector { private DocletTagFactory tagFactory; private EventModel model = new EventModel(); + /** + * Creates a new EventProducerCollector. + */ public EventProducerCollector() { this.tagFactory = createDocletTagFactory(); } + /** + * Creates the {@link DocletTagFactory} to be used by the collector. + * @return the doclet tag factory + */ protected DocletTagFactory createDocletTagFactory() { return new DefaultDocletTagFactory(); } - public void scanFile(File src, String filename) + /** + * Scans a file and processes it if it extends the {@link EventProducer} interface. + * @param src the source file (a Java source file) + * @throws IOException if an I/O error occurs + * @throws EventConventionException if the EventProducer conventions are violated + * @throws ClassNotFoundException if a required class cannot be found + */ + public void scanFile(File src) throws IOException, EventConventionException, ClassNotFoundException { JavaDocBuilder builder = new JavaDocBuilder(this.tagFactory); builder.addSource(src); @@ -79,7 +93,7 @@ public class EventProducerCollector { for (int i = 0, c = classes.length; i < c; i++) { JavaClass clazz = classes[i]; if (clazz.isInterface() && implementsInterface(clazz, CLASSNAME_EVENT_PRODUCER)) { - processEventProducerInterface(clazz, filename); + processEventProducerInterface(clazz); } } } @@ -98,11 +112,10 @@ public class EventProducerCollector { /** * Processes an EventProducer interface and creates an EventProducerModel from it. * @param clazz the EventProducer interface - * @param javaFilename the filename of the Java source of the interface * @throws EventConventionException if the event producer conventions are violated * @throws ClassNotFoundException if a required class cannot be found */ - protected void processEventProducerInterface(JavaClass clazz, String javaFilename) + protected void processEventProducerInterface(JavaClass clazz) throws EventConventionException, ClassNotFoundException { EventProducerModel prodMeta = new EventProducerModel(clazz.getFullyQualifiedName()); JavaMethod[] methods = clazz.getMethods(true); @@ -172,10 +185,19 @@ public class EventProducerCollector { return methodMeta; } + /** + * Returns the event model that has been accumulated. + * @return the event model. + */ public EventModel getModel() { return this.model; } + /** + * Saves the accumulated event model to an XML file. + * @param modelFile the target model file + * @throws IOException if an I/O error occurs + */ public void saveModelToXML(File modelFile) throws IOException { getModel().saveToXML(modelFile); } diff --git a/src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java b/src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java index 755e3da0b..60ffaf103 100644 --- a/src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java +++ b/src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java @@ -45,6 +45,12 @@ import org.apache.tools.ant.Task; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.selectors.FilenameSelector; +/** + * Ant task which inspects a file set for Java interfaces which extend the + * {@link org.apache.fop.events.EventProducer} interface. For all such interfaces an event model + * file and a translation file for the human-readable messages generated by the events is + * created and/or updated. + */ public class EventProducerCollectorTask extends Task { private List filesets = new java.util.ArrayList(); @@ -74,6 +80,10 @@ public class EventProducerCollectorTask extends Task { private static final String MODEL2TRANSLATION = "model2translation.xsl"; private static final String MERGETRANSLATION = "merge-translation.xsl"; + /** + * Updates the translation file with new entries for newly found event producer methods. + * @throws IOException if an I/O error occurs + */ protected void updateTranslationFile() throws IOException { try { boolean resultExists = getTranslationFile().exists(); @@ -136,6 +146,13 @@ public class EventProducerCollectorTask extends Task { } } + /** + * Processes the file sets defined for the task. + * @param collector the collector to use for collecting the event producers + * @throws IOException if an I/O error occurs + * @throws EventConventionException if the EventProducer conventions are violated + * @throws ClassNotFoundException if a required class cannot be found + */ protected void processFileSets(EventProducerCollector collector) throws IOException, EventConventionException, ClassNotFoundException { Iterator iter = filesets.iterator(); @@ -147,31 +164,55 @@ public class EventProducerCollectorTask extends Task { for (int i = 0, c = srcFiles.length; i < c; i++) { String filename = srcFiles[i]; File src = new File(directory, filename); - collector.scanFile(src, filename); + collector.scanFile(src); } } } + /** + * Adds a file set. + * @param set the file set + */ public void addFileset(FileSet set) { filesets.add(set); } + /** + * Sets the model file to be written. + * @param f the model file + */ public void setModelFile(File f) { this.modelFile = f; } + /** + * Returns the model file to be written. + * @return the model file + */ public File getModelFile() { return this.modelFile; } + /** + * Sets the translation file for the event producer methods. + * @param f the translation file + */ public void setTranslationFile(File f) { this.translationFile = f; } + /** + * Returns the translation file for the event producer methods. + * @return the translation file + */ public File getTranslationFile() { return this.translationFile; } + /** + * Command-line interface for testing purposes. + * @param args the command-line arguments + */ public static void main(String[] args) { try { Project project = new Project(); diff --git a/src/java/org/apache/fop/events/EventFormatter.xml b/src/java/org/apache/fop/events/EventFormatter.xml index f17da1161..f5e4609e9 100644 --- a/src/java/org/apache/fop/events/EventFormatter.xml +++ b/src/java/org/apache/fop/events/EventFormatter.xml @@ -33,6 +33,7 @@ Required content model: {contentModel}]{{locator}}</message> <message key="org.apache.fop.fo.FOValidationEventProducer.missingProperty">Element "{elementName}" is missing required property "{propertyName}"!{{locator}}</message> <message key="org.apache.fop.fo.FOValidationEventProducer.idNotUnique">Property ID "{id}" (found on "{elementName}") previously used; ID values must be unique within a document!{severity,equals,EventSeverity:FATAL,, Any reference to it will be considered a reference to the first occurrence in the document.}{{locator}}</message> + <message key="org.apache.fop.fo.FOValidationEventProducer.markerBlockContainerAbsolutePosition">Only an fo:block-container that does not generate absolutely positioned areas may have one or more fo:markers as its initial children.{{locator}}</message> <message key="org.apache.fop.fo.FOValidationEventProducer.markerNotInitialChild">fo:marker must be an initial child: {mcname}{{locator}}</message> <message key="org.apache.fop.fo.FOValidationEventProducer.markerNotUniqueForSameParent">fo:marker "marker-class-name" must be unique for same parent: {mcname}{{locator}}</message> <message key="org.apache.fop.fo.FOValidationEventProducer.invalidProperty">Invalid property encountered on "{elementName}": {attr}{{locator}}</message> diff --git a/src/java/org/apache/fop/fo/FOValidationEventProducer.java b/src/java/org/apache/fop/fo/FOValidationEventProducer.java index aa7b14941..61bd68340 100644 --- a/src/java/org/apache/fop/fo/FOValidationEventProducer.java +++ b/src/java/org/apache/fop/fo/FOValidationEventProducer.java @@ -150,6 +150,15 @@ public interface FOValidationEventProducer extends EventProducer { Locator loc) throws ValidationException; /** + * An fo:marker appears as initial descendant in an fo:block-container + * that generates absolutely positioned areas + * @param source the event source + * @param loc the location of the error (possibly null) + * @event.severity ERROR + */ + void markerBlockContainerAbsolutePosition(Object source, Locator loc); + + /** * A marker is not an initial child on a node. * @param source the event source * @param elementName the name of the context node diff --git a/src/java/org/apache/fop/fo/expr/RelativeNumericProperty.java b/src/java/org/apache/fop/fo/expr/RelativeNumericProperty.java index ae140b6b7..647528692 100755 --- a/src/java/org/apache/fop/fo/expr/RelativeNumericProperty.java +++ b/src/java/org/apache/fop/fo/expr/RelativeNumericProperty.java @@ -23,6 +23,7 @@ import org.apache.fop.datatypes.Length; import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.datatypes.Numeric; import org.apache.fop.fo.properties.Property; +import org.apache.fop.fo.properties.TableColLength; /** @@ -31,7 +32,7 @@ import org.apache.fop.fo.properties.Property; * to delay evaluation of the operation until the time where getNumericValue() * or getValue() is called. */ -public class RelativeNumericProperty extends Property implements Numeric, Length { +public class RelativeNumericProperty extends Property implements Length { public static final int ADDITION = 1; public static final int SUBTRACTION = 2; public static final int MULTIPLY = 3; @@ -56,7 +57,7 @@ public class RelativeNumericProperty extends Property implements Numeric, Length /** * The second operand. */ - private Numeric op2; + private Numeric op2 = null; /** * The dimension of the result. */ @@ -99,6 +100,7 @@ public class RelativeNumericProperty extends Property implements Numeric, Length /** * Return a resolved (calculated) Numeric with the value of the expression. * @param context Evaluation context + * @return the resolved {@link Numeric} corresponding to the value of the expression * @throws PropertyException when an exception occur during evaluation. */ private Numeric getResolved(PercentBaseContext context) throws PropertyException { @@ -196,6 +198,64 @@ public class RelativeNumericProperty extends Property implements Numeric, Length } /** + * Return the number of table units which are included in this length + * specification. This will always be 0 unless the property specification + * used the proportional-column-width() function (only on table column FOs). + * <p> + * If this value is not 0, the actual value of the Length cannot be known + * without looking at all of the columns in the table to determine the value + * of a "table-unit". + * + * @return The number of table units which are included in this length + * specification. + */ + public double getTableUnits() { + double tu1 = 0.0, tu2 = 0.0; + if (op1 instanceof RelativeNumericProperty) { + tu1 = ((RelativeNumericProperty) op1).getTableUnits(); + } else if (op1 instanceof TableColLength) { + tu1 = ((TableColLength) op1).getTableUnits(); + } + if (op2 instanceof RelativeNumericProperty) { + tu2 = ((RelativeNumericProperty) op2).getTableUnits(); + } else if (op2 instanceof TableColLength) { + tu2 = ((TableColLength) op2).getTableUnits(); + } + if (tu1 != 0.0 && tu2 != 0.0) { + switch (operation) { + case ADDITION: + return tu1 + tu2; + case SUBTRACTION: + return tu1 - tu2; + case MULTIPLY: + return tu1 * tu2; + case DIVIDE: + return tu1 / tu2; + case MODULO: + return tu1 % tu2; + case MIN: + return Math.min(tu1, tu2); + case MAX: + return Math.max(tu1, tu2); + default: + assert false; + } + } else if (tu1 != 0.0) { + switch (operation) { + case NEGATE: + return -tu1; + case ABS: + return Math.abs(tu1); + default: + return tu1; + } + } else if (tu2 != 0.0) { + return tu2; + } + return 0.0; + } + + /** * Return a string represention of the expression. Only used for debugging. * @return the string representation. */ diff --git a/src/java/org/apache/fop/fo/flow/BlockContainer.java b/src/java/org/apache/fop/fo/flow/BlockContainer.java index f1180ac16..5e8957299 100644 --- a/src/java/org/apache/fop/fo/flow/BlockContainer.java +++ b/src/java/org/apache/fop/fo/flow/BlockContainer.java @@ -35,7 +35,8 @@ import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.LengthRangeProperty; /** - * Class modelling the fo:block-container object. + * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_block-container"> + * <code>fo:block-container</code></a> object. */ public class BlockContainer extends FObj { // The value of properties relevant for fo:block-container. @@ -66,15 +67,16 @@ public class BlockContainer extends FObj { private boolean blockItemFound = false; /** - * @param parent FONode that is the parent of this object + * Creates a new BlockContainer instance as a child of + * the given {@link FONode}. + * + * @param parent {@link FONode} that is the parent of this object */ public BlockContainer(FONode parent) { super(parent); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void bind(PropertyList pList) throws FOPException { super.bind(pList); commonAbsolutePosition = pList.getAbsolutePositionProps(); @@ -97,9 +99,7 @@ public class BlockContainer extends FObj { writingMode = pList.get(PR_WRITING_MODE).getEnum(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void startOfNode() throws FOPException { super.startOfNode(); getFOEventHandler().startBlockContainer(this); @@ -107,30 +107,34 @@ public class BlockContainer extends FObj { /** * {@inheritDoc} - * XSL Content Model: marker* (%block;)+ - * But: "In addition an fo:block-container that does not generate an + * <br>XSL Content Model: marker* (%block;)+ + * <br><i><b>BUT</b>: "In addition an fo:block-container that does not generate an * absolutely positioned area may have a sequence of zero or more * fo:markers as its initial children." - * @todo - implement above restriction if possible + * The latter refers to block-containers with absolute-position="absolute" + * or absolute-position="fixed". */ protected void validateChildNode(Locator loc, String nsURI, String localName) - throws ValidationException { + throws ValidationException { if (FO_URI.equals(nsURI)) { - if (localName.equals("marker")) { + if ("marker".equals(localName)) { + if (commonAbsolutePosition.absolutePosition == EN_ABSOLUTE + || commonAbsolutePosition.absolutePosition == EN_FIXED) { + getFOValidationEventProducer() + .markerBlockContainerAbsolutePosition(this, locator); + } if (blockItemFound) { nodesOutOfOrderError(loc, "fo:marker", "(%block;)"); } - } else if (!isBlockItem(nsURI, localName)) { - invalidChildError(loc, nsURI, localName); + } else if (!isBlockItem(FO_URI, localName)) { + invalidChildError(loc, FO_URI, localName); } else { blockItemFound = true; } } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void endOfNode() throws FOPException { if (!blockItemFound) { missingChildElementError("marker* (%block;)+"); @@ -139,30 +143,22 @@ public class BlockContainer extends FObj { getFOEventHandler().endBlockContainer(this); } - /** - * @return true (BlockContainer can generate Reference Areas) - */ + /** @return <code>true</code> (BlockContainer can generate Reference Areas) */ public boolean generatesReferenceAreas() { return true; } - /** - * @return the Common Absolute Position Properties. - */ + /** @return the {@link CommonAbsolutePosition} */ public CommonAbsolutePosition getCommonAbsolutePosition() { return commonAbsolutePosition; } - /** - * @return the Common Margin Properties-Block. - */ + /** @return the {@link CommonMarginBlock} */ public CommonMarginBlock getCommonMarginBlock() { return commonMarginBlock; } - /** - * @return the Common Border, Padding, and Background Properties. - */ + /** @return the {@link CommonBorderPaddingBackground} */ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() { return commonBorderPaddingBackground; } @@ -174,7 +170,7 @@ public class BlockContainer extends FObj { return blockProgressionDimension; } - /** @return the display-align property. */ + /** @return the "display-align" property. */ public int getDisplayAlign() { return displayAlign; } @@ -204,51 +200,37 @@ public class BlockContainer extends FObj { return keepTogether; } - /** - * @return the "inline-progression-dimension" property. - */ + /** @return the "inline-progression-dimension" property */ public LengthRangeProperty getInlineProgressionDimension() { return inlineProgressionDimension; } - /** - * @return the "overflow" property. - */ + /** @return the "overflow" property */ public int getOverflow() { return overflow; } - /** - * @return the "reference-orientation" property. - */ + /** @return the "reference-orientation" property */ public int getReferenceOrientation() { return referenceOrientation.getValue(); } - /** - * @return the "span" property. - */ + /** @return the "span" property */ public int getSpan() { return this.span; } - /** - * @return the "writing-mode" property. - */ + /** @return the "writing-mode" property */ public int getWritingMode() { return writingMode; } - /** - * @return the width property - */ + /** @return the "width" property */ public Length getWidth() { return width; } - /** - * @return the height property - */ + /** @return the "height" property */ public Length getHeight() { return height; } @@ -260,6 +242,7 @@ public class BlockContainer extends FObj { /** * {@inheritDoc} + * @return {@link org.apache.fop.fo.Constants#FO_BLOCK_CONTAINER} */ public int getNameId() { return FO_BLOCK_CONTAINER; diff --git a/src/java/org/apache/fop/fo/flow/table/EffRow.java b/src/java/org/apache/fop/fo/flow/table/EffRow.java index 31a8260cc..fc8209b01 100644 --- a/src/java/org/apache/fop/fo/flow/table/EffRow.java +++ b/src/java/org/apache/fop/fo/flow/table/EffRow.java @@ -165,55 +165,47 @@ public class EffRow { } /** - * Returns true if the enclosing (if any) fo:table-row element of this row, or if any - * of the cells starting on this row, have keep-with-previous set. + * Returns the strength of the keep constraint if the enclosing (if any) fo:table-row element + * of this row, or if any of the cells starting on this row, have keep-with-previous set. * - * @return true if this row must be kept with the previous content + * @return the strength of the keep-with-previous constraint */ - public boolean mustKeepWithPrevious() { - boolean keepWithPrevious = false; + public int getKeepWithPreviousStrength() { + int strength = BlockLevelLayoutManager.KEEP_AUTO; TableRow row = getTableRow(); if (row != null) { - keepWithPrevious = row.mustKeepWithPrevious(); + strength = Math.max(strength, + KeepUtil.getCombinedBlockLevelKeepStrength(row.getKeepWithPrevious())); } for (Iterator iter = gridUnits.iterator(); iter.hasNext();) { GridUnit gu = (GridUnit) iter.next(); if (gu.isPrimary()) { - keepWithPrevious |= gu.getPrimary().mustKeepWithPrevious(); + strength = Math.max(strength, gu.getPrimary().getKeepWithPreviousStrength()); } } - return keepWithPrevious; + return strength; } /** - * Returns true if the enclosing (if any) fo:table-row element of this row, or if any - * of the cells ending on this row, have keep-with-next set. + * Returns the strength of the keep constraint if the enclosing (if any) fo:table-row element + * of this row, or if any of the cells ending on this row, have keep-with-next set. * - * @return true if this row must be kept with the next content + * @return the strength of the keep-with-next constraint */ - public boolean mustKeepWithNext() { - boolean keepWithNext = false; + public int getKeepWithNextStrength() { + int strength = BlockLevelLayoutManager.KEEP_AUTO; TableRow row = getTableRow(); if (row != null) { - keepWithNext = row.mustKeepWithNext(); + strength = Math.max(strength, + KeepUtil.getCombinedBlockLevelKeepStrength(row.getKeepWithNext())); } for (Iterator iter = gridUnits.iterator(); iter.hasNext();) { GridUnit gu = (GridUnit) iter.next(); if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) { - keepWithNext |= gu.getPrimary().mustKeepWithNext(); + strength = Math.max(strength, gu.getPrimary().getKeepWithNextStrength()); } } - return keepWithNext; - } - - /** - * Returns true if this row is enclosed by an fo:table-row element that has - * keep-together set. - * - * @return true if this row must be kept together - */ - public boolean mustKeepTogether() { - return getKeepTogetherStrength() != BlockLevelLayoutManager.KEEP_AUTO; + return strength; } /** diff --git a/src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java b/src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java index 8af896fa2..55bcfa44e 100644 --- a/src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java +++ b/src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java @@ -25,6 +25,7 @@ import java.util.List; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.table.TableCellLayoutManager; @@ -53,8 +54,8 @@ public class PrimaryGridUnit extends GridUnit { private boolean isSeparateBorderModel; private int halfBorderSeparationBPD; - private boolean keepWithPrevious; - private boolean keepWithNext; + private int keepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO; + private int keepWithNext = BlockLevelLayoutManager.KEEP_AUTO; private int breakBefore = Constants.EN_AUTO; private int breakAfter = Constants.EN_AUTO; @@ -328,37 +329,39 @@ public class PrimaryGridUnit extends GridUnit { } /** - * Returns true if the first child block (or its descendants) of this cell has - * keep-with-previous. + * Returns the strength of the keep constraint if the first child block (or its descendants) + * of this cell has keep-with-previous. * - * @return the value of keep-with-previous + * @return the keep-with-previous strength */ - public boolean mustKeepWithPrevious() { + public int getKeepWithPreviousStrength() { return keepWithPrevious; } /** * Don't use, reserved for TableCellLM. TODO + * @param strength the keep strength */ - public void setKeepWithPrevious() { - this.keepWithPrevious = true; + public void setKeepWithPreviousStrength(int strength) { + this.keepWithPrevious = strength; } /** - * Returns true if the last child block (or its descendants) of this cell has - * keep-with-next. + * Returns the strength of the keep constraint if the last child block (or its descendants) of + * this cell has keep-with-next. * - * @return the value of keep-with-next + * @return the keep-with-next strength */ - public boolean mustKeepWithNext() { + public int getKeepWithNextStrength() { return keepWithNext; } /** * Don't use, reserved for TableCellLM. TODO + * @param strength the keep strength */ - public void setKeepWithNext() { - this.keepWithNext = true; + public void setKeepWithNextStrength(int strength) { + this.keepWithNext = strength; } /** diff --git a/src/java/org/apache/fop/fo/pagination/PageSequence.java b/src/java/org/apache/fop/fo/pagination/PageSequence.java index 3c7cfb197..c8f7c66d7 100644 --- a/src/java/org/apache/fop/fo/pagination/PageSequence.java +++ b/src/java/org/apache/fop/fo/pagination/PageSequence.java @@ -30,7 +30,8 @@ import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; /** - * Abstract base implementation for page sequences. + * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_page-sequence"> + * <code>fo:page-sequence</code></a> object. */ public class PageSequence extends AbstractPageSequence { @@ -70,9 +71,10 @@ public class PageSequence extends AbstractPageSequence { private Flow mainFlow = null; /** - * Create a page sequence FO node. + * Create a PageSequence instance that is a child of the + * given {@link FONode}. * - * @param parent the parent FO node + * @param parent the parent {@link FONode} */ public PageSequence(FONode parent) { super(parent); @@ -172,6 +174,9 @@ public class PageSequence extends AbstractPageSequence { * The flow-name is used to associate the flow with a region on a page, * based on the region-names given to the regions in the page-master * used to generate that page. + * @param flow the {@link Flow} instance to be added + * @throws org.apache.fop.fo.ValidationException if the fo:flow maps + * to an invalid page-region */ private void addFlow(Flow flow) throws ValidationException { String flowName = flow.getFlowName(); @@ -189,133 +194,6 @@ public class PageSequence extends AbstractPageSequence { } } -// /** -// * Returns true when there is more flow elements left to lay out. -// */ -// private boolean flowsAreIncomplete() { -// boolean isIncomplete = false; - -// for (Iterator e = flowMap.values().iterator(); e.hasNext(); ) { -// Flow flow = (Flow)e.next(); -// if (flow instanceof StaticContent) { -// continue; -// } - -// Status status = flow.getStatus(); -// isIncomplete |= status.isIncomplete(); -// } -// return isIncomplete; -// } - -// /** -// * Returns the flow that maps to the given region class for the current -// * page master. -// */ -// private Flow getCurrentFlow(String regionClass) { -// Region region = getCurrentSimplePageMaster().getRegion(regionClass); -// if (region != null) { -// Flow flow = (Flow)flowMap.get(region.getRegionName()); -// return flow; - -// } else { - -// getLogger().error("flow is null. regionClass = '" + regionClass -// + "' currentSPM = " -// + getCurrentSimplePageMaster()); - -// return null; -// } - -// } - -// private boolean isFlowForMasterNameDone(String masterName) { -// // parameter is master-name of PMR; we need to locate PM -// // referenced by this, and determine whether flow(s) are OK -// if (isForcing) -// return false; -// if (masterName != null) { - -// SimplePageMaster spm = -// root.getLayoutMasterSet().getSimplePageMaster(masterName); -// Region region = spm.getRegion(FO_REGION_BODY); - - -// Flow flow = (Flow)flowMap.get(region.getRegionName()); -// /*if ((null == flow) || flow.getStatus().isIncomplete()) -// return false; -// else -// return true;*/ -// } -// return false; -// } - -// private void forcePage(AreaTree areaTree, int firstAvailPageNumber) { -// boolean makePage = false; -// if (this.forcePageCount == ForcePageCount.AUTO) { -// PageSequence nextSequence = -// this.root.getSucceedingPageSequence(this); -// if (nextSequence != null) { -// if (nextSequence.getIpnValue().equals("auto")) { -// // do nothing special -// } -// else if (nextSequence.getIpnValue().equals("auto-odd")) { -// if (firstAvailPageNumber % 2 == 0) { -// makePage = true; -// } -// } else if (nextSequence.getIpnValue().equals("auto-even")) { -// if (firstAvailPageNumber % 2 != 0) { -// makePage = true; -// } -// } else { -// int nextSequenceStartPageNumber = -// nextSequence.getCurrentPageNumber(); -// if ((nextSequenceStartPageNumber % 2 == 0) -// && (firstAvailPageNumber % 2 == 0)) { -// makePage = true; -// } else if ((nextSequenceStartPageNumber % 2 != 0) -// && (firstAvailPageNumber % 2 != 0)) { -// makePage = true; -// } -// } -// } -// } else if ((this.forcePageCount == ForcePageCount.EVEN) -// && (this.pageCount % 2 != 0)) { -// makePage = true; -// } else if ((this.forcePageCount == ForcePageCount.ODD) -// && (this.pageCount % 2 == 0)) { -// makePage = true; -// } else if ((this.forcePageCount == ForcePageCount.END_ON_EVEN) -// && (firstAvailPageNumber % 2 == 0)) { -// makePage = true; -// } else if ((this.forcePageCount == ForcePageCount.END_ON_ODD) -// && (firstAvailPageNumber % 2 != 0)) { -// makePage = true; -// } else if (this.forcePageCount == ForcePageCount.NO_FORCE) { -// // do nothing -// } - -// if (makePage) { -// try { -// this.isForcing = true; -// this.currentPageNumber++; -// firstAvailPageNumber = this.currentPageNumber; -// currentPage = makePage(areaTree, firstAvailPageNumber, false, -// true); -// String formattedPageNumber = -// pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber); -// currentPage.setFormattedNumber(formattedPageNumber); -// currentPage.setPageSequence(this); -// formatStaticContent(areaTree); -// log.debug("[forced-" + firstAvailPageNumber + "]"); -// areaTree.addPage(currentPage); -// this.root.setRunningPageNumberCounter(this.currentPageNumber); -// this.isForcing = false; -// } catch (FOPException fopex) { -// log.debug("'force-page-count' failure"); -// } -// } -// } - /** * Get the static content FO node from the flow map. * This gets the static content flow for the given flow name. @@ -328,7 +206,7 @@ public class PageSequence extends AbstractPageSequence { } /** - * Accessor method for titleFO + * Accessor method for the fo:title associated with this fo:page-sequence * @return titleFO for this object */ public Title getTitleFO() { @@ -425,7 +303,10 @@ public class PageSequence extends AbstractPageSequence { } } - /** @return the "master-reference" property. */ + /** + * Get the value of the <code>master-reference</code> property. + * @return the "master-reference" property + */ public String getMasterReference() { return masterReference; } @@ -435,17 +316,26 @@ public class PageSequence extends AbstractPageSequence { return "page-sequence"; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + * @return {@link org.apache.fop.fo.Constants#FO_PAGE_SEQUENCE} + */ public int getNameId() { return FO_PAGE_SEQUENCE; } - /** @return the country property value */ + /** + * Get the value of the <code>country</code> property. + * @return the country property value + */ public String getCountry() { return this.country; } - /** @return the language property value */ + /** + * Get the value of the <code>language</code> property. + * @return the language property value + */ public String getLanguage() { return this.language; } diff --git a/src/java/org/apache/fop/fo/properties/LengthProperty.java b/src/java/org/apache/fop/fo/properties/LengthProperty.java index 495e8d8ea..697aa75a7 100644 --- a/src/java/org/apache/fop/fo/properties/LengthProperty.java +++ b/src/java/org/apache/fop/fo/properties/LengthProperty.java @@ -71,22 +71,6 @@ public abstract class LengthProperty extends Property } - /** - * Return the number of table units which are included in this - * length specification. - * This will always be 0 unless the property specification used - * the proportional-column-width() function (only only table - * column FOs). - * <p>If this value is not 0, the actual value of the Length cannot - * be known without looking at all of the columns in the table to - * determine the value of a "table-unit". - * @return The number of table units which are included in this - * length specification. - */ - public double getTableUnits() { - return 0.0; - } - /** @return the numeric dimension. Length always a dimension of 1 */ public int getDimension() { return 1; diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index c0220e75e..a44669371 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -263,6 +263,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager if (!firstVisibleMarkServed) { addKnuthElementsForSpaceBefore(returnList, alignment); + context.updateKeepWithPreviousPending(getKeepWithPreviousStrength()); } addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); @@ -284,6 +285,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager // get elements from curLM returnedList = curLM.getNextKnuthElements(childLC, alignment); + if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) { + //Propagate keep-with-previous up from the first child + context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); + childLC.clearKeepWithPreviousPending(); + } if (returnedList.size() == 1 && ((ListElement)returnedList.getFirst()).isForcedBreak()) { // a descendant of this block has break-before @@ -329,6 +335,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager return returnList; } } + // propagate and clear + context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); + childLC.clearKeepsPending(); prevLM = curLM; } @@ -377,6 +386,8 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager context.clearPendingMarks(); addKnuthElementsForBreakAfter(returnList, context); + context.updateKeepWithNextPending(getKeepWithNextStrength()); + setFinished(true); return returnList; } @@ -990,26 +1001,22 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager /** {@inheritDoc} */ public int getKeepTogetherStrength() { - int strength = KEEP_AUTO; - strength = Math.max(strength, KeepUtil.getKeepStrength( - getBlockContainerFO().getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - getBlockContainerFO().getKeepTogether().getWithinColumn())); + int strength = KeepUtil.getCombinedBlockLevelKeepStrength( + getBlockContainerFO().getKeepTogether()); strength = Math.max(strength, getParentKeepTogetherStrength()); return strength; } /** {@inheritDoc} */ - public boolean mustKeepWithPrevious() { - //TODO Keeps will have to be more sophisticated sooner or later - return !getBlockContainerFO().getKeepWithPrevious().getWithinPage().isAuto() - || !getBlockContainerFO().getKeepWithPrevious().getWithinColumn().isAuto(); + public int getKeepWithNextStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength( + getBlockContainerFO().getKeepWithNext()); } /** {@inheritDoc} */ - public boolean mustKeepWithNext() { - return !getBlockContainerFO().getKeepWithNext().getWithinPage().isAuto() - || !getBlockContainerFO().getKeepWithNext().getWithinColumn().isAuto(); + public int getKeepWithPreviousStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength( + getBlockContainerFO().getKeepWithPrevious()); } /** @@ -1021,16 +1028,12 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager // --------- Property Resolution related functions --------- // - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean getGeneratesReferenceArea() { return true; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean getGeneratesBlockArea() { return true; } diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index 253ec2af1..48bf47caf 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -30,6 +30,7 @@ import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.area.LineArea; import org.apache.fop.datatypes.Length; +import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; @@ -209,26 +210,20 @@ public class BlockLayoutManager extends BlockStackingLayoutManager /** {@inheritDoc} */ public int getKeepTogetherStrength() { - int strength = KEEP_AUTO; - strength = Math.max(strength, KeepUtil.getKeepStrength( - getBlockFO().getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - getBlockFO().getKeepTogether().getWithinColumn())); + KeepProperty keep = getBlockFO().getKeepTogether(); + int strength = KeepUtil.getCombinedBlockLevelKeepStrength(keep); strength = Math.max(strength, getParentKeepTogetherStrength()); return strength; } /** {@inheritDoc} */ - public boolean mustKeepWithPrevious() { - //TODO Keeps will have to be more sophisticated sooner or later - return !getBlockFO().getKeepWithPrevious().getWithinPage().isAuto() - || !getBlockFO().getKeepWithPrevious().getWithinColumn().isAuto(); + public int getKeepWithNextStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength(getBlockFO().getKeepWithNext()); } /** {@inheritDoc} */ - public boolean mustKeepWithNext() { - return !getBlockFO().getKeepWithNext().getWithinPage().isAuto() - || !getBlockFO().getKeepWithNext().getWithinColumn().isAuto(); + public int getKeepWithPreviousStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength(getBlockFO().getKeepWithPrevious()); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java index 3dc7ed46e..765bb1086 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java @@ -56,11 +56,23 @@ public interface BlockLevelLayoutManager extends LayoutManager { boolean mustKeepTogether(); /** + * Returns the keep-with-previous strength for this element. + * @return the keep-with-previous strength + */ + int getKeepWithPreviousStrength(); + + /** * @return true if this element must be kept with the previous element. */ boolean mustKeepWithPrevious(); /** + * Returns the keep-with-next strength for this element. + * @return the keep-with-next strength + */ + int getKeepWithNextStrength(); + + /** * @return true if this element must be kept with the next element. */ boolean mustKeepWithNext(); diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index c6ead8d59..e9d529ebe 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -265,6 +265,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager if (!firstVisibleMarkServed) { addKnuthElementsForSpaceBefore(returnList, alignment); + context.updateKeepWithPreviousPending(getKeepWithPreviousStrength()); } addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); @@ -296,8 +297,9 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager // get elements from curLM returnedList = curLM.getNextKnuthElements(childLC, alignment); if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) { - context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING); - childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); + //Propagate keep-with-previous up from the first child + context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); + childLC.clearKeepWithPreviousPending(); } if (returnedList != null && returnedList.size() == 1 @@ -364,9 +366,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } } // propagate and clear - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, childLC.isKeepWithNextPending()); - childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); - childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); + context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); + childLC.clearKeepsPending(); prevLM = curLM; } @@ -400,12 +401,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager wrapPositionElement(forcedBreakAfterLast, returnList, false); } - if (mustKeepWithNext()) { - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING); - } - if (mustKeepWithPrevious()) { - context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING); - } + context.updateKeepWithNextPending(getKeepWithNextStrength()); setFinished(true); @@ -425,14 +421,15 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager || childLC.isKeepWithPreviousPending()) { int strength = getKeepTogetherStrength(); - if (context.isKeepWithNextPending()) { - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); - strength = KEEP_ALWAYS; - } - if (childLC.isKeepWithPreviousPending()) { - childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); - strength = KEEP_ALWAYS; - } + + //Handle pending keep-with-next + strength = Math.max(strength, context.getKeepWithNextPending()); + context.clearKeepWithNextPending(); + + //Handle pending keep-with-previous from child LM + strength = Math.max(strength, childLC.getKeepWithPreviousPending()); + childLC.clearKeepWithPreviousPending(); + int penalty = KeepUtil.getPenaltyForKeep(strength); // add a penalty to forbid or discourage a break between blocks @@ -823,12 +820,12 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { - return false; + return getKeepWithPreviousStrength() > KEEP_AUTO; } /** {@inheritDoc} */ public boolean mustKeepWithNext() { - return false; + return getKeepWithNextStrength() > KEEP_AUTO; } /** diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java index ecfcbe2b4..c54f0ce12 100644 --- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java @@ -107,8 +107,8 @@ public class FlowLayoutManager extends BlockStackingLayoutManager returnedList = curLM.getNextKnuthElements(childLC, alignment); //log.debug("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size()); if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) { - context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING); - childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); + context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); + childLC.clearKeepWithPreviousPending(); } // "wrap" the Position inside each element @@ -124,20 +124,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager return returnList; } else { if (returnList.size() > 0) { - // there is a block before this one - if (context.isKeepWithNextPending() - || childLC.isKeepWithPreviousPending()) { - //Clear pending keep flag - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); - childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); - // add an infinite penalty to forbid a break between blocks - returnList.add(new BreakElement( - new Position(this), KnuthElement.INFINITE, context)); - } else if (!((ListElement) returnList.getLast()).isGlue()) { - // add a null penalty to allow a break between blocks - returnList.add(new BreakElement( - new Position(this), 0, context)); - } + addInBetweenBreak(returnList, context, childLC); } if (returnedList.size() > 0) { returnList.addAll(returnedList); @@ -155,11 +142,12 @@ public class FlowLayoutManager extends BlockStackingLayoutManager } } } - if (childLC.isKeepWithNextPending()) { - //Clear and propagate - childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING); - } + + //Propagate and clear + context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); + childLC.clearKeepWithNextPending(); + + context.updateKeepWithNextPending(getKeepWithNextStrength()); } SpaceResolver.resolveElementList(returnList); @@ -213,18 +201,16 @@ public class FlowLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - public boolean mustKeepWithPrevious() { - return false; + public int getKeepWithNextStrength() { + return KEEP_AUTO; } /** {@inheritDoc} */ - public boolean mustKeepWithNext() { - return false; + public int getKeepWithPreviousStrength() { + return KEEP_AUTO; } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public LinkedList getChangedKnuthElements(List oldList, /*int flaggedPenalty,*/ int alignment) { ListIterator oldListIterator = oldList.listIterator(); KnuthElement returnedElement; @@ -357,6 +343,6 @@ public class FlowLayoutManager extends BlockStackingLayoutManager public int getContentAreaBPD() { return (int) getCurrentPV().getBodyRegion().getBPD(); } - + } diff --git a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java index 351504cd7..34b931c03 100644 --- a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java @@ -96,4 +96,14 @@ public class FootnoteBodyLayoutManager extends BlockStackingLayoutManager { return getParentKeepTogetherStrength(); } + /** {@inheritDoc} */ + public int getKeepWithNextStrength() { + return KEEP_AUTO; + } + + /** {@inheritDoc} */ + public int getKeepWithPreviousStrength() { + return KEEP_AUTO; + } + } diff --git a/src/java/org/apache/fop/layoutmgr/KeepUtil.java b/src/java/org/apache/fop/layoutmgr/KeepUtil.java index 1fd595ae0..8c80a1b10 100644 --- a/src/java/org/apache/fop/layoutmgr/KeepUtil.java +++ b/src/java/org/apache/fop/layoutmgr/KeepUtil.java @@ -20,6 +20,7 @@ package org.apache.fop.layoutmgr; import org.apache.fop.fo.Constants; +import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.Property; /** @@ -47,6 +48,29 @@ public class KeepUtil { } /** + * Returns the combined block-level keep strength from a keep property. + * <p> + * Note: This is a temporary method to be used until it is possible to differentiate between + * page and column keeps! + * @param keep the keep property + * @return the combined keep strength + */ + public static int getCombinedBlockLevelKeepStrength(KeepProperty keep) { + return Math.max( + getKeepStrength(keep.getWithinPage()), + getKeepStrength(keep.getWithinColumn())); + } + + /** + * Indicates whether a keep strength indicates a keep constraint. + * @param strength the keep strength + * @return true if the keep is not "auto" + */ + public static boolean hasKeep(int strength) { + return strength > BlockLevelLayoutManager.KEEP_AUTO; + } + + /** * Returns the penalty value to be used for a certain keep strength. * <ul> * <li>"auto": returns 0</li> @@ -67,4 +91,19 @@ public class KeepUtil { return penalty; } + /** + * Returns a string representation of a keep strength value. + * @param keepStrength the keep strength + * @return the string representation + */ + public static String keepStrengthToString(int keepStrength) { + if (keepStrength == BlockLevelLayoutManager.KEEP_AUTO) { + return "auto"; + } else if (keepStrength == BlockLevelLayoutManager.KEEP_ALWAYS) { + return "always"; + } else { + return Integer.toString(keepStrength); + } + } + } diff --git a/src/java/org/apache/fop/layoutmgr/LayoutContext.java b/src/java/org/apache/fop/layoutmgr/LayoutContext.java index 79b5e232f..5ac9808f2 100644 --- a/src/java/org/apache/fop/layoutmgr/LayoutContext.java +++ b/src/java/org/apache/fop/layoutmgr/LayoutContext.java @@ -63,12 +63,12 @@ public class LayoutContext { * 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; + //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 KEEP_WITH_PREVIOUS_PENDING = 0x400; private int flags; // Contains some set of flags defined above @@ -135,7 +135,6 @@ public class LayoutContext { /** Amount of space before / start */ private int spaceBefore = 0; - /** Amount of space after / end */ private int spaceAfter = 0; @@ -145,9 +144,11 @@ public class LayoutContext { private int lineEndBorderAndPaddingWidth = 0; private int breakBefore; - private int breakAfter; + private int pendingKeepWithNext = BlockLevelLayoutManager.KEEP_AUTO; + private int pendingKeepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO; + /** * Copy constructor for creating child layout contexts. * @param parentLC the parent layout context to copy from @@ -167,6 +168,8 @@ public class LayoutContext { this.lineStartBorderAndPaddingWidth = parentLC.lineStartBorderAndPaddingWidth; this.lineEndBorderAndPaddingWidth = parentLC.lineEndBorderAndPaddingWidth; copyPendingMarksFrom(parentLC); + this.pendingKeepWithNext = parentLC.pendingKeepWithNext; + this.pendingKeepWithPrevious = parentLC.pendingKeepWithPrevious; // Copy other fields as necessary. } @@ -228,12 +231,74 @@ public class LayoutContext { return ((this.flags & SUPPRESS_LEADING_SPACE) != 0); } + /** + * Returns the strength of a keep-with-next currently pending. + * @return the keep-with-next strength + */ + public int getKeepWithNextPending() { + return this.pendingKeepWithNext; + } + + /** + * Returns the strength of a keep-with-previous currently pending. + * @return the keep-with-previous strength + */ + public int getKeepWithPreviousPending() { + return this.pendingKeepWithPrevious; + } + + /** + * Clears any pending keep-with-next strength. + */ + public void clearKeepWithNextPending() { + this.pendingKeepWithNext = BlockLevelLayoutManager.KEEP_AUTO; + } + + /** + * Clears any pending keep-with-previous strength. + */ + public void clearKeepWithPreviousPending() { + this.pendingKeepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO; + } + + /** + * Clears both keep-with-previous and keep-with-next strengths. + */ + public void clearKeepsPending() { + clearKeepWithPreviousPending(); + clearKeepWithNextPending(); + } + + /** + * Updates the currently pending keep-with-next strength. + * @param strength the new strength to consider + */ + public void updateKeepWithNextPending(int strength) { + this.pendingKeepWithNext = Math.max(this.pendingKeepWithNext, strength); + } + + /** + * Updates the currently pending keep-with-previous strength. + * @param strength the new strength to consider + */ + public void updateKeepWithPreviousPending(int strength) { + this.pendingKeepWithPrevious = Math.max(this.pendingKeepWithPrevious, strength); + } + + /** + * Indicates whether a keep-with-next constraint is pending. + * @return true if a keep-with-next constraint is pending + */ public boolean isKeepWithNextPending() { - return ((this.flags & KEEP_WITH_NEXT_PENDING) != 0); + return getKeepWithNextPending() != BlockLevelLayoutManager.KEEP_AUTO; } + /** + * Indicates whether a keep-with-previous constraint is pending. + * @return true if a keep-with-previous constraint is pending + */ public boolean isKeepWithPreviousPending() { - return ((this.flags & KEEP_WITH_PREVIOUS_PENDING) != 0); + return getKeepWithPreviousPending() != BlockLevelLayoutManager.KEEP_AUTO; } public void setLeadingSpace(SpaceSpecifier space) { @@ -595,8 +660,9 @@ public class LayoutContext { + "\nStarts New Area: \t" + startsNewArea() + "\nIs Last Area: \t" + isLastArea() + "\nTry Hyphenate: \t" + tryHyphenate() - + "\nKeeps: \t[" + (isKeepWithNextPending() ? "keep-with-next" : "") + "][" - + (isKeepWithPreviousPending() ? "keep-with-previous" : "") + "] pending" + + "\nKeeps: \t[keep-with-next=" + KeepUtil.keepStrengthToString(getKeepWithNextPending()) + + "][keep-with-previous=" + + KeepUtil.keepStrengthToString(getKeepWithPreviousPending()) + "] pending" + "\nBreaks: \tforced [" + (breakBefore != Constants.EN_AUTO ? "break-before" : "") + "][" + (breakAfter != Constants.EN_AUTO ? "break-after" : "") + "]"; } diff --git a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java index 0d88f2a1d..42ddcc220 100644 --- a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java @@ -410,5 +410,15 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager { return KEEP_AUTO; } + /** {@inheritDoc} */ + public int getKeepWithNextStrength() { + return KEEP_AUTO; + } + + /** {@inheritDoc} */ + public int getKeepWithPreviousStrength() { + return KEEP_AUTO; + } + } diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java index e9919e02f..f3bb66022 100755 --- a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java @@ -314,7 +314,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { // get KnuthElements from curLM returnedList = curLM.getNextKnuthElements(childLC, alignment); if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) { - childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); + childLC.clearKeepWithPreviousPending(); } if (returnedList == null || returnedList.size() == 0) { @@ -324,7 +324,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { } if (curLM instanceof InlineLevelLayoutManager) { - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); + context.clearKeepWithNextPending(); // "wrap" the Position stored in each element of returnedList ListIterator seqIter = returnedList.listIterator(); while (seqIter.hasNext()) { @@ -365,10 +365,8 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { returnList.add(sequence); } // propagate and clear - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, - childLC.isKeepWithNextPending()); - childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); - childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); + context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); + childLC.clearKeepsPending(); } lastSequence = (KnuthSequence) returnList.getLast(); lastChildLM = curLM; diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index 08a3f3eff..8c46796eb 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -1281,23 +1281,27 @@ public class LineLayoutManager extends InlineStackingLayoutManager return ((BlockLevelLayoutManager) getParent()).getKeepTogetherStrength(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { - return false; + return getKeepWithPreviousStrength() > KEEP_AUTO; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean mustKeepWithNext() { - return false; + return getKeepWithNextStrength() > KEEP_AUTO; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + public int getKeepWithNextStrength() { + return KEEP_AUTO; + } + + /** {@inheritDoc} */ + public int getKeepWithPreviousStrength() { + return KEEP_AUTO; + } + + /** {@inheritDoc} */ public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) { LeafPosition pos = (LeafPosition)lastElement.getPosition(); int totalAdj = adj; diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java index eb64e0bf0..57114eee2 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -280,26 +280,20 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager /** {@inheritDoc} */ public int getKeepTogetherStrength() { - int strength = KEEP_AUTO; - strength = Math.max(strength, KeepUtil.getKeepStrength( - getListBlockFO().getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - getListBlockFO().getKeepTogether().getWithinColumn())); + int strength = KeepUtil.getCombinedBlockLevelKeepStrength( + getListBlockFO().getKeepTogether()); strength = Math.max(strength, getParentKeepTogetherStrength()); return strength; } /** {@inheritDoc} */ - public boolean mustKeepWithPrevious() { - //TODO Keeps will have to be more sophisticated sooner or later - return !getListBlockFO().getKeepWithPrevious().getWithinPage().isAuto() - || !getListBlockFO().getKeepWithPrevious().getWithinColumn().isAuto(); + public int getKeepWithNextStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength(getListBlockFO().getKeepWithNext()); } /** {@inheritDoc} */ - public boolean mustKeepWithNext() { - return !getListBlockFO().getKeepWithNext().getWithinPage().isAuto() - || !getListBlockFO().getKeepWithNext().getWithinColumn().isAuto(); + public int getKeepWithPreviousStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength(getListBlockFO().getKeepWithPrevious()); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java index be7dbdbba..e3b88b0ac 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java @@ -222,14 +222,20 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { /** {@inheritDoc} */ public int getKeepTogetherStrength() { - int strength = KEEP_AUTO; - strength = Math.max(strength, KeepUtil.getKeepStrength( - getPartFO().getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - getPartFO().getKeepTogether().getWithinColumn())); + int strength = KeepUtil.getCombinedBlockLevelKeepStrength(getPartFO().getKeepTogether()); strength = Math.max(strength, getParentKeepTogetherStrength()); return strength; } + /** {@inheritDoc} */ + public int getKeepWithNextStrength() { + return KEEP_AUTO; + } + + /** {@inheritDoc} */ + public int getKeepWithPreviousStrength() { + return KEEP_AUTO; + } + } diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java index b727f8860..5e7288f04 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -32,6 +32,7 @@ import org.apache.fop.area.Block; import org.apache.fop.fo.flow.ListItem; import org.apache.fop.fo.flow.ListItemBody; import org.apache.fop.fo.flow.ListItemLabel; +import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.ConditionalElementListener; @@ -80,8 +81,8 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager private MinOptMax effSpaceBefore; private MinOptMax effSpaceAfter; - private boolean keepWithNextPendingOnLabel; - private boolean keepWithNextPendingOnBody; + private int keepWithNextPendingOnLabel; + private int keepWithNextPendingOnBody; private int listItemHeight; @@ -223,10 +224,8 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager SpaceResolver.resolveElementList(labelList); ElementListObserver.observe(labelList, "list-item-label", label.getPartFO().getId()); - if (childLC.isKeepWithPreviousPending()) { - context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING); - } - this.keepWithNextPendingOnLabel = childLC.isKeepWithNextPending(); + context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); + this.keepWithNextPendingOnLabel = childLC.getKeepWithNextPending(); // body childLC = new LayoutContext(0); @@ -239,10 +238,8 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager SpaceResolver.resolveElementList(bodyList); ElementListObserver.observe(bodyList, "list-item-body", body.getPartFO().getId()); - if (childLC.isKeepWithPreviousPending()) { - context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING); - } - this.keepWithNextPendingOnBody = childLC.isKeepWithNextPending(); + context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); + this.keepWithNextPendingOnBody = childLC.getKeepWithNextPending(); // create a combined list LinkedList returnedList = getCombinedKnuthElementsForListItem(labelList, bodyList, context); @@ -254,12 +251,10 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager addKnuthElementsForSpaceAfter(returnList, alignment); addKnuthElementsForBreakAfter(returnList, context); - if (keepWithNextPendingOnLabel || keepWithNextPendingOnBody || mustKeepWithNext()) { - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING); - } - if (mustKeepWithPrevious()) { - context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING); - } + context.updateKeepWithNextPending(this.keepWithNextPendingOnLabel); + context.updateKeepWithNextPending(this.keepWithNextPendingOnBody); + context.updateKeepWithNextPending(getKeepWithNextStrength()); + context.updateKeepWithPreviousPending(getKeepWithPreviousStrength()); setFinished(true); resetSpaces(); @@ -281,21 +276,17 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager int totalHeight = Math.max(fullHeights[0], fullHeights[1]); int step; int addedBoxHeight = 0; - boolean keepWithNextActive = false; + int keepWithNextActive = BlockLevelLayoutManager.KEEP_AUTO; LinkedList returnList = new LinkedList(); while ((step = getNextStep(elementLists, start, end, partialHeights)) > 0) { if (end[0] + 1 == elementLists[0].size()) { - if (keepWithNextPendingOnLabel) { - keepWithNextActive = true; - } + keepWithNextActive = Math.max(keepWithNextActive, keepWithNextPendingOnLabel); } if (end[1] + 1 == elementLists[1].size()) { - if (keepWithNextPendingOnBody) { - keepWithNextActive = true; - } + keepWithNextActive = Math.max(keepWithNextActive, keepWithNextPendingOnBody); } // compute penalty height and box height @@ -327,12 +318,12 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager start[0], end[0], start[1], end[1]); returnList.add(new KnuthBox(boxHeight, stepPosition, false)); if (addedBoxHeight < totalHeight) { + int strength = BlockLevelLayoutManager.KEEP_AUTO; + strength = Math.max(strength, keepWithNextActive); + strength = Math.max(strength, getKeepTogetherStrength()); int p = stepPenalty; - if (keepWithNextActive) { - p = KnuthPenalty.INFINITE; - } - if (mustKeepTogether()) { - p = Math.max(p, KeepUtil.getPenaltyForKeep(getKeepTogetherStrength())); + if (p > -KnuthElement.INFINITE) { + p = Math.max(p, KeepUtil.getPenaltyForKeep(strength)); } returnList.add(new BreakElement(stepPosition, penaltyHeight, p, -1, context)); } @@ -637,26 +628,20 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager /** {@inheritDoc} */ public int getKeepTogetherStrength() { - int strength = KEEP_AUTO; - strength = Math.max(strength, KeepUtil.getKeepStrength( - getListItemFO().getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - getListItemFO().getKeepTogether().getWithinColumn())); + int strength = KeepUtil.getCombinedBlockLevelKeepStrength( + getListItemFO().getKeepTogether()); strength = Math.max(strength, getParentKeepTogetherStrength()); return strength; } /** {@inheritDoc} */ - public boolean mustKeepWithPrevious() { - //TODO Keeps will have to be more sophisticated sooner or later - return !getListItemFO().getKeepWithPrevious().getWithinPage().isAuto() - || !getListItemFO().getKeepWithPrevious().getWithinColumn().isAuto(); + public int getKeepWithNextStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength(getListItemFO().getKeepWithNext()); } /** {@inheritDoc} */ - public boolean mustKeepWithNext() { - return !getListItemFO().getKeepWithNext().getWithinPage().isAuto() - || !getListItemFO().getKeepWithNext().getWithinColumn().isAuto(); + public int getKeepWithPreviousStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength(getListItemFO().getKeepWithPrevious()); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java b/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java index 61d0f8e6f..1e5120700 100644 --- a/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java +++ b/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java @@ -24,11 +24,13 @@ import java.util.ListIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.fop.fo.Constants; import org.apache.fop.fo.flow.table.ConditionalBorder; import org.apache.fop.fo.flow.table.EffRow; import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; @@ -70,7 +72,7 @@ class ActiveCell { /** True if the next CellPart that will be created will be the last one for this cell. */ private boolean lastCellPart; - private boolean keepWithNextSignal; + private int keepWithNextStrength; private int spanIndex = 0; @@ -202,7 +204,7 @@ class ActiveCell { includedLength = -1; // Avoid troubles with cells having content of zero length totalLength = previousRowsLength + ElementListUtils.calcContentLength(elementList); endRowIndex = rowIndex + pgu.getCell().getNumberRowsSpanned() - 1; - keepWithNextSignal = false; + keepWithNextStrength = BlockLevelLayoutManager.KEEP_AUTO; remainingLength = totalLength - previousRowsLength; afterNextStep = new Step(previousRowsLength); @@ -506,14 +508,14 @@ class ActiveCell { */ CellPart createCellPart() { if (nextStep.end + 1 == elementList.size()) { - keepWithNextSignal = pgu.mustKeepWithNext(); + keepWithNextStrength = pgu.getKeepWithNextStrength(); // TODO if keep-with-next is set on the row, must every cell of the row // contribute some content from children blocks? // see http://mail-archives.apache.org/mod_mbox/xmlgraphics-fop-dev/200802.mbox/ // %3c47BDA379.4050606@anyware-tech.com%3e // Assuming no, but if yes the following code should enable this behaviour // if (pgu.getRow() != null && pgu.getRow().mustKeepWithNext()) { -// keepWithNextSignal = true; +// keepWithNextSignal = true; //to be converted to integer strengths // } } int bpBeforeFirst; @@ -536,8 +538,8 @@ class ActiveCell { } } - boolean keepWithNextSignal() { - return keepWithNextSignal; + int getKeepWithNextStrength() { + return keepWithNextStrength; } diff --git a/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java b/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java index bd032e610..9dbd31653 100644 --- a/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java +++ b/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java @@ -29,6 +29,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.datatypes.Length; import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.fo.FONode; +import org.apache.fop.fo.expr.RelativeNumericProperty; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableColumn; import org.apache.fop.fo.properties.TableColLength; @@ -196,7 +197,9 @@ public class ColumnSetup { Length colWidth = (Length) i.next(); if (colWidth != null) { sumCols += colWidth.getValue(tlm); - if (colWidth instanceof TableColLength) { + if (colWidth instanceof RelativeNumericProperty) { + factors += ((RelativeNumericProperty) colWidth).getTableUnits(); + } else if (colWidth instanceof TableColLength) { factors += ((TableColLength) colWidth).getTableUnits(); } } diff --git a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java index 72e78b84f..19b97322c 100644 --- a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java @@ -33,7 +33,6 @@ import org.apache.fop.fo.flow.table.TableColumn; import org.apache.fop.fo.flow.table.TableRow; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.LengthRangeProperty; -import org.apache.fop.layoutmgr.BlockLevelEventProducer; import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.MinOptMaxUtil; @@ -61,10 +60,8 @@ class RowGroupLayoutManager { LinkedList returnList = new LinkedList(); createElementsForRowGroup(context, alignment, bodyType, returnList); - context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, - rowGroup[0].mustKeepWithPrevious()); - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, - rowGroup[rowGroup.length - 1].mustKeepWithNext()); + context.updateKeepWithPreviousPending(rowGroup[0].getKeepWithPreviousStrength()); + context.updateKeepWithNextPending(rowGroup[rowGroup.length - 1].getKeepWithNextStrength()); int breakBefore = Constants.EN_AUTO; TableRow firstRow = rowGroup[0].getTableRow(); diff --git a/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java index fc0d587ff..c20060723 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java @@ -49,6 +49,14 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager { } /** + * Returns the table-and-caption formatting object. + * @return the table-and-caption formatting object + */ + public TableAndCaption getTableAndCaptionFO() { + return (TableAndCaption)this.fobj; + } + + /** * Get the next break possibility. * * @param context the layout context for getting breaks @@ -196,13 +204,29 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager { public int getKeepTogetherStrength() { int strength = KEEP_AUTO; /* TODO Complete me! - strength = Math.max(strength, KeepUtil.getKeepStrength( - getTableAndCaption().getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - getTableAndCaption().getKeepTogether().getWithinColumn())); + int strength = KeepUtil.getCombinedBlockLevelKeepStrength( + getTableAndCaptionFO().getKeepTogether()); */ strength = Math.max(strength, getParentKeepTogetherStrength()); return strength; } + /** {@inheritDoc} */ + public int getKeepWithNextStrength() { + return KEEP_AUTO; + /* TODO Complete me! + return KeepUtil.getCombinedBlockLevelKeepStrength( + getTableAndCaptionFO().getKeepWithNext()); + */ + } + + /** {@inheritDoc} */ + public int getKeepWithPreviousStrength() { + return KEEP_AUTO; + /* TODO Complete me! + return KeepUtil.getCombinedBlockLevelKeepStrength( + getTableAndCaptionFO().getKeepWithPrevious()); + */ + } + }
\ No newline at end of file diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java index 8c4908547..615145fa1 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java @@ -47,7 +47,7 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager { } /** @return the table-caption FO */ - public TableCaption getTableCaption() { + public TableCaption getTableCaptionFO() { return (TableCaption)this.fobj; } @@ -201,13 +201,31 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager { int strength = KEEP_AUTO; /* TODO Complete me! strength = Math.max(strength, KeepUtil.getKeepStrength( - getTableCaption().getKeepTogether().getWithinPage())); + getTableCaptionFO().getKeepTogether().getWithinPage())); strength = Math.max(strength, KeepUtil.getKeepStrength( - getTableCaption().getKeepTogether().getWithinColumn())); + getTableCaptionFO().getKeepTogether().getWithinColumn())); */ strength = Math.max(strength, getParentKeepTogetherStrength()); return strength; } + /** {@inheritDoc} */ + public int getKeepWithNextStrength() { + return KEEP_AUTO; + /* TODO Complete me! + return KeepUtil.getCombinedBlockLevelKeepStrength( + getTableCaptionFO().getKeepWithNext()); + */ + } + + /** {@inheritDoc} */ + public int getKeepWithPreviousStrength() { + return KEEP_AUTO; + /* TODO Complete me! + return KeepUtil.getCombinedBlockLevelKeepStrength( + getTableCaptionFO().getKeepWithPrevious()); + */ + } + } diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java index 291e27ae2..6067af4bc 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java @@ -153,8 +153,8 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager log.debug("child LM signals pending keep with next"); } if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) { - primaryGridUnit.setKeepWithPrevious(); - childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); + primaryGridUnit.setKeepWithPreviousStrength(childLC.getKeepWithPreviousPending()); + childLC.clearKeepWithPreviousPending(); } if (prevLM != null) { @@ -169,14 +169,12 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager } if (childLC.isKeepWithNextPending()) { //Clear and propagate - childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING); + context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); + childLC.clearKeepWithNextPending(); } prevLM = curLM; } - if (context.isKeepWithNextPending()) { - primaryGridUnit.setKeepWithNext(); - } + primaryGridUnit.setKeepWithNextStrength(context.getKeepWithNextPending()); returnedList = new LinkedList(); if (contentList.size() > 0) { @@ -569,24 +567,15 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - public boolean mustKeepWithPrevious() { - //TODO Keeps will have to be more sophisticated sooner or later - return false; //TODO FIX ME - /* - return !fobj.getKeepWithPrevious().getWithinPage().isAuto() - || !fobj.getKeepWithPrevious().getWithinColumn().isAuto(); - */ + public int getKeepWithNextStrength() { + return KEEP_AUTO; //TODO FIX ME (table-cell has no keep-with-next!) } /** {@inheritDoc} */ - public boolean mustKeepWithNext() { - return false; //TODO FIX ME - /* - return !fobj.getKeepWithNext().getWithinPage().isAuto() - || !fobj.getKeepWithNext().getWithinColumn().isAuto(); - */ + public int getKeepWithPreviousStrength() { + return KEEP_AUTO; //TODO FIX ME (table-cell has no keep-with-previous!) } - + // --------- Property Resolution related functions --------- // /** diff --git a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java index 235bc1fd2..7a2ee171c 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java @@ -35,6 +35,7 @@ import org.apache.fop.fo.flow.table.EffRow; import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableBody; +import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.KeepUtil; @@ -208,31 +209,37 @@ public class TableContentLayoutManager implements PercentBaseContext { LinkedList returnList = new LinkedList(); EffRow[] rowGroup = iter.getNextRowGroup(); // TODO homogenize the handling of keeps and breaks - context.unsetFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING - | LayoutContext.KEEP_WITH_NEXT_PENDING); + context.clearKeepsPending(); context.setBreakBefore(Constants.EN_AUTO); context.setBreakAfter(Constants.EN_AUTO); - boolean keepWithPrevious = false; + int keepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO; int breakBefore = Constants.EN_AUTO; if (rowGroup != null) { RowGroupLayoutManager rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup, stepper); List nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType); - keepWithPrevious = context.isKeepWithPreviousPending(); - boolean keepBetween = context.isKeepWithNextPending(); + keepWithPrevious = Math.max(keepWithPrevious, context.getKeepWithPreviousPending()); breakBefore = context.getBreakBefore(); int breakBetween = context.getBreakAfter(); returnList.addAll(nextRowGroupElems); while ((rowGroup = iter.getNextRowGroup()) != null) { rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup, stepper); + + //Note previous pending keep-with-next and clear the strength + //(as the layout context is reused) + int keepWithNextPending = context.getKeepWithNextPending(); + context.clearKeepWithNextPending(); + + //Get elements for next row group nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType); - int penaltyValue = 0; - keepBetween |= context.isKeepWithPreviousPending(); - if (keepBetween) { - penaltyValue = KnuthElement.INFINITE; - } - penaltyValue = Math.max(penaltyValue, - KeepUtil.getPenaltyForKeep(getTableLM().getKeepTogetherStrength())); + + //Determine keep constraints + int penaltyStrength = BlockLevelLayoutManager.KEEP_AUTO; + penaltyStrength = Math.max(penaltyStrength, keepWithNextPending); + penaltyStrength = Math.max(penaltyStrength, context.getKeepWithPreviousPending()); + context.clearKeepWithPreviousPending(); + penaltyStrength = Math.max(penaltyStrength, getTableLM().getKeepTogetherStrength()); + int penaltyValue = KeepUtil.getPenaltyForKeep(penaltyStrength); breakBetween = BreakUtil.compareBreakClasses(breakBetween, context.getBreakBefore()); @@ -255,10 +262,9 @@ public class TableContentLayoutManager implements PercentBaseContext { penaltyLen, penaltyValue, breakBetween, context)); returnList.addAll(nextRowGroupElems); breakBetween = context.getBreakAfter(); - keepBetween = context.isKeepWithNextPending(); } } - context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, keepWithPrevious); + context.updateKeepWithPreviousPending(keepWithPrevious); context.setBreakBefore(breakBefore); //fox:widow-content-limit diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java index 5738a027c..75189a6b9 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -256,12 +256,11 @@ public class TableLayoutManager extends BlockStackingLayoutManager log.debug(contentKnuthElements); wrapPositionElements(contentKnuthElements, returnList); - if (mustKeepWithPrevious() || childLC.isKeepWithPreviousPending()) { - context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING); - } - if (mustKeepWithNext() || childLC.isKeepWithNextPending()) { - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING); - } + context.updateKeepWithPreviousPending(getKeepWithPreviousStrength()); + context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); + + context.updateKeepWithNextPending(getKeepWithNextStrength()); + context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); if (getTable().isSeparateBorderModel()) { addKnuthElementsForBorderPaddingAfter(returnList, true); @@ -448,29 +447,19 @@ public class TableLayoutManager extends BlockStackingLayoutManager /** {@inheritDoc} */ public int getKeepTogetherStrength() { - int strength = KEEP_AUTO; - strength = Math.max(strength, KeepUtil.getKeepStrength( - getTable().getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - getTable().getKeepTogether().getWithinColumn())); + int strength = KeepUtil.getCombinedBlockLevelKeepStrength(getTable().getKeepTogether()); strength = Math.max(strength, getParentKeepTogetherStrength()); return strength; } - /** - * {@inheritDoc} - */ - public boolean mustKeepWithPrevious() { - return !getTable().getKeepWithPrevious().getWithinPage().isAuto() - || !getTable().getKeepWithPrevious().getWithinColumn().isAuto(); + /** {@inheritDoc} */ + public int getKeepWithNextStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength(getTable().getKeepWithNext()); } - /** - * {@inheritDoc} - */ - public boolean mustKeepWithNext() { - return !getTable().getKeepWithNext().getWithinPage().isAuto() - || !getTable().getKeepWithNext().getWithinColumn().isAuto(); + /** {@inheritDoc} */ + public int getKeepWithPreviousStrength() { + return KeepUtil.getCombinedBlockLevelKeepStrength(getTable().getKeepWithPrevious()); } // --------- Property Resolution related functions --------- // diff --git a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java index 07894a07b..2d3c990f8 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java @@ -30,9 +30,11 @@ import org.apache.fop.fo.Constants; import org.apache.fop.fo.flow.table.EffRow; import org.apache.fop.fo.flow.table.GridUnit; import org.apache.fop.fo.flow.table.PrimaryGridUnit; +import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.KnuthBox; +import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.KnuthPenalty; import org.apache.fop.layoutmgr.LayoutContext; @@ -198,11 +200,20 @@ public class TableStepper { } //Put all involved grid units into a list + int stepPenalty = 0; List cellParts = new java.util.ArrayList(columnCount); for (Iterator iter = activeCells.iterator(); iter.hasNext();) { ActiveCell activeCell = (ActiveCell) iter.next(); CellPart part = activeCell.createCellPart(); cellParts.add(part); + + //Record highest penalty value of part + if (part.end >= 0) { + KnuthElement endEl = (KnuthElement)part.pgu.getElements().get(part.end); + if (endEl instanceof KnuthPenalty) { + stepPenalty = Math.max(stepPenalty, endEl.getP()); + } + } } //Create elements for step @@ -230,39 +241,37 @@ public class TableStepper { } } - int p = 0; - boolean keepWithNext = false; + int strength = BlockLevelLayoutManager.KEEP_AUTO; for (Iterator iter = activeCells.iterator(); iter.hasNext();) { ActiveCell activeCell = (ActiveCell) iter.next(); - keepWithNext |= activeCell.keepWithNextSignal(); - } - if (keepWithNext) { - p = KnuthPenalty.INFINITE; + strength = Math.max(strength, activeCell.getKeepWithNextStrength()); } if (!rowFinished) { - p = Math.max(p, KeepUtil.getPenaltyForKeep( - rowGroup[activeRowIndex].getKeepTogetherStrength())); + strength = Math.max(strength, rowGroup[activeRowIndex].getKeepTogetherStrength()); //The above call doesn't take the penalty from the table into account, so... - p = Math.max(p, KeepUtil.getPenaltyForKeep( - getTableLM().getKeepTogetherStrength())); + strength = Math.max(strength, getTableLM().getKeepTogetherStrength()); } else if (activeRowIndex < rowGroup.length - 1) { - if (rowGroup[activeRowIndex].mustKeepWithNext() - || rowGroup[activeRowIndex + 1].mustKeepWithPrevious()) { - p = KnuthPenalty.INFINITE; - } + strength = Math.max(strength, + rowGroup[activeRowIndex].getKeepWithNextStrength()); + strength = Math.max(strength, + rowGroup[activeRowIndex + 1].getKeepWithPreviousStrength()); nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass, rowGroup[activeRowIndex].getBreakAfter()); nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass, rowGroup[activeRowIndex + 1].getBreakBefore()); } - if (nextBreakClass != Constants.EN_AUTO) { - log.trace("Forced break encountered"); - p = -KnuthPenalty.INFINITE; //Overrides any keeps (see 4.8 in XSL 1.0) - } + int p = KeepUtil.getPenaltyForKeep(strength); if (rowHeightSmallerThanFirstStep) { rowHeightSmallerThanFirstStep = false; p = KnuthPenalty.INFINITE; } + if (p > -KnuthElement.INFINITE) { + p = Math.max(p, stepPenalty); + } + if (nextBreakClass != Constants.EN_AUTO) { + log.trace("Forced break encountered"); + p = -KnuthPenalty.INFINITE; //Overrides any keeps (see 4.8 in XSL 1.0) + } returnList.add(new BreakElement(penaltyPos, effPenaltyLen, p, nextBreakClass, context)); if (penaltyOrGlueLen < 0) { returnList.add(new KnuthGlue(-penaltyOrGlueLen, 0, 0, new Position(null), true)); diff --git a/status.xml b/status.xml index df47e25da..0b2b2ac38 100644 --- a/status.xml +++ b/status.xml @@ -59,6 +59,11 @@ <action context="Renderers" dev="AC" importance="high" type="add"> Added de-duplication and externalization support for IOCA and GOCA data resource objects. </action> + <action context="Layout" dev="JM" type="add"> + Added minimal support for integer keep values on the various keep properties on block-level + FOs. For now, all integer values are treated the same (i.e. without strength distinction). + Using integers allows to avoid overflows that can happen when "always" is used extensively. + </action> <action context="Renderers" dev="JM" type="add"> Added support for rendering pages using JPS (Java Printing System). See new example: examples/embedding/java/ExamplesFO2JPSPrint.java diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml index b4de16ef4..12d7ed1aa 100644 --- a/test/layoutengine/disabled-testcases.xml +++ b/test/layoutengine/disabled-testcases.xml @@ -165,18 +165,6 @@ <reference>http://www.nabble.com/leaders-with-leader-pattern%3D%22use-content%22-t546244.html</reference> </testcase> <testcase> - <name>keep-with-previous doesn't work in lists</name> - <file>list-block_keep-with-previous.xml</file> - <description>Keep-with-previous doesn't work inside tables and - lists, yet.</description> - </testcase> - <testcase> - <name>keep-with-previous doesn't work in lists</name> - <file>list-item_block_keep-with-previous.xml</file> - <description>Keep-with-previous doesn't work inside tables and - lists, yet.</description> - </testcase> - <testcase> <name>Page breaking doesn't deal with IPD changes</name> <file>page-breaking_4.xml</file> <description>Page breaking currently doesn't support changing available IPD diff --git a/test/layoutengine/standard-testcases/block-container_keep-with-next_1.xml b/test/layoutengine/standard-testcases/block-container_keep-with-next_1.xml new file mode 100644 index 000000000..c43e06359 --- /dev/null +++ b/test/layoutengine/standard-testcases/block-container_keep-with-next_1.xml @@ -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 keep-with-next on fo:block-container. + </p> + <p> + Widows and Orphans are disabled in this test to avoid side-effects. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" widows="0" orphans="0"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="12 * 14.4pt"> + <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-container keep-with-next.within-column="always"> + <fo:block>block1</fo:block> + <fo:block>block2</fo:block> + </fo:block-container> + <fo:block-container keep-with-next.within-column="1"> + <fo:block>block3</fo:block> + <fo:block>block4</fo:block> + </fo:block-container> + <fo:block-container> + <fo:block>block5</fo:block> + </fo:block-container> + <fo:block-container> + <fo:block>block6</fo:block> + <fo:block keep-with-next.within-column="1">block7</fo:block> + </fo:block-container> + <fo:block keep-with-next.within-column="always">block8</fo:block> + <fo:block-container keep-with-next.within-column="1"> + <fo:block>block9</fo:block> + <fo:block keep-with-next.within-column="always">block10</fo:block> + </fo:block-container> + <fo:block>block11</fo:block> + <fo:block-container keep-with-next.within-column="always"> + <fo:block>block12</fo:block> + <fo:block keep-with-next.within-column="1">block13</fo:block> + </fo:block-container> + <fo:block>block14</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <element-list category="breaker"> + <box/> <!-- 1 --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> <!-- 5 --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <box/> <!-- 10 --> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="INF"/> + <box/> + + <skip>3</skip> + </element-list> + + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/block-container_keep-with-previous_1.xml b/test/layoutengine/standard-testcases/block-container_keep-with-previous_1.xml new file mode 100644 index 000000000..1c318ca0c --- /dev/null +++ b/test/layoutengine/standard-testcases/block-container_keep-with-previous_1.xml @@ -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 keep-with-previous on fo:block-container. + </p> + <p> + Widows and Orphans are disabled in this test to avoid side-effects. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" widows="0" orphans="0"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="12 * 14.4pt"> + <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>block1</fo:block> + <fo:block-container keep-with-previous.within-column="always"> + <fo:block>block2</fo:block> + <fo:block>block3</fo:block> + </fo:block-container> + <fo:block-container keep-with-previous.within-column="1"> + <fo:block>block4</fo:block> + <fo:block>block5</fo:block> + </fo:block-container> + <fo:block-container> + <fo:block>block6</fo:block> + </fo:block-container> + <fo:block-container> + <fo:block keep-with-previous.within-column="1">block7</fo:block> + <fo:block>block8</fo:block> + </fo:block-container> + <fo:block keep-with-previous.within-column="always">block9</fo:block> + <fo:block-container keep-with-previous.within-column="1"> + <fo:block keep-with-previous.within-column="always">block10</fo:block> + <fo:block>block11</fo:block> + </fo:block-container> + <fo:block>block12</fo:block> + <fo:block-container keep-with-previous.within-column="always"> + <fo:block keep-with-previous.within-column="1">block13</fo:block> + <fo:block>block14</fo:block> + </fo:block-container> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <element-list category="breaker"> + <box/> <!-- 1 --> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <box/> <!-- 5 --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="INF"/> + <box/> <!-- 10 --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <box/> + + <skip>3</skip> + </element-list> + + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/block_keep-with-next_integers_1.xml b/test/layoutengine/standard-testcases/block_keep-with-next_integers_1.xml new file mode 100644 index 000000000..a1e89f3c2 --- /dev/null +++ b/test/layoutengine/standard-testcases/block_keep-with-next_integers_1.xml @@ -0,0 +1,99 @@ +<?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 keep-with-next.wuithin-column with integer values. + </p> + <p> + Widows and Orphans are disabled in this test to avoid side-effects. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" widows="0" orphans="0"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="4.5 * 14.4pt"> + <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>block1</fo:block> + <fo:block keep-with-next.within-column="always">block2</fo:block> + <fo:block keep-with-next.within-column="1">block3</fo:block> + <fo:block>block4</fo:block> + <fo:block keep-with-next.within-column="1"> + <fo:block>block5</fo:block> + <fo:block>block6</fo:block> + </fo:block> + <fo:block>block7</fo:block> + <fo:block keep-with-next.within-column="1"> + <fo:block>block8</fo:block> + <fo:block keep-with-next.within-column="always">block9</fo:block> + </fo:block> + <fo:block>block10</fo:block> + <fo:block keep-with-next.within-column="always"> + <fo:block>block11</fo:block> + <fo:block keep-with-next.within-column="1">block12</fo:block> + </fo:block> + <fo:block>block13</fo:block> + <fo:block> + <fo:block keep-with-next.within-column="1">block14</fo:block> + <fo:block>block15</fo:block> + </fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <element-list category="breaker"> + <box/> <!-- 1 --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <box/> <!-- 5 --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="INF"/> + <box/> <!-- 10 --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + + <skip>3</skip> + </element-list> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/block_keep-with-previous_integers_1.xml b/test/layoutengine/standard-testcases/block_keep-with-previous_integers_1.xml new file mode 100644 index 000000000..d43d45608 --- /dev/null +++ b/test/layoutengine/standard-testcases/block_keep-with-previous_integers_1.xml @@ -0,0 +1,116 @@ +<?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 keep-with-previous.wuithin-column with integer values. + </p> + <p> + Widows and Orphans are disabled in this test to avoid side-effects. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" widows="0" orphans="0"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="4.5 * 14.4pt"> + <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>block1</fo:block> + <fo:block keep-with-previous.within-column="always">block2</fo:block> + <fo:block keep-with-previous.within-column="1">block3</fo:block> + <fo:block>block4</fo:block> + <fo:block keep-with-previous.within-column="1"> + <fo:block>block5</fo:block> + <fo:block>block6</fo:block> + </fo:block> + <fo:block>block7</fo:block> + <fo:block keep-with-previous.within-column="1"> + <fo:block keep-with-previous.within-column="always">block8</fo:block> + <fo:block>block9</fo:block> + </fo:block> + <fo:block>block10</fo:block> + <fo:block keep-with-previous.within-column="always"> + <fo:block keep-with-previous.within-column="1">block11</fo:block> + <fo:block>block12</fo:block> + </fo:block> + <fo:block>block13</fo:block> + <fo:block> + <fo:block>block14</fo:block> + <fo:block keep-with-previous.within-column="1">block15</fo:block> + </fo:block> + <fo:block>block16</fo:block> + <fo:block keep-with-previous.within-column="1"> + <fo:block>block17</fo:block> + <fo:block break-before="page">block18</fo:block> + <fo:block>block19</fo:block> + </fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <element-list category="breaker" index="0"> + <box/> <!-- 1 --> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> <!-- 5 --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <box/> <!-- 10 --> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> <!-- 15 --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + + <skip>3</skip> + </element-list> + <element-list category="breaker" index="1"> + <box/> <!-- 18 --> + <penalty w="0" p="0"/> + <box/> + + <skip>3</skip> + </element-list> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/list-block_keep-with-next_integers_1.xml b/test/layoutengine/standard-testcases/list-block_keep-with-next_integers_1.xml new file mode 100644 index 000000000..2c02806a3 --- /dev/null +++ b/test/layoutengine/standard-testcases/list-block_keep-with-next_integers_1.xml @@ -0,0 +1,155 @@ +<?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 keep-with-next with lists. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" widows="0" orphans="0"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="10 * 14.4pt"> + <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>block1</fo:block> + <fo:list-block + provisional-distance-between-starts="25mm" + provisional-label-separation="5mm" + keep-with-next.within-column="1"> + <fo:list-item> + <fo:list-item-label end-indent="label-end()"> + <fo:block>label1</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item1</fo:block> + </fo:list-item-body> + </fo:list-item> + <fo:list-item> + <fo:list-item-label end-indent="label-end()"> + <fo:block>label2</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item2</fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + <fo:block>block2</fo:block> + <fo:list-block + provisional-distance-between-starts="25mm" + provisional-label-separation="5mm"> + <fo:list-item keep-with-next.within-column="1"> + <fo:list-item-label end-indent="label-end()"> + <fo:block>label1</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item1</fo:block> + <fo:block keep-with-next.within-column="1">item1</fo:block> + <fo:block>item1</fo:block> + <fo:block>item1</fo:block> + </fo:list-item-body> + </fo:list-item> + <fo:list-item> + <fo:list-item-label end-indent="label-end()"> + <fo:block>label2</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item2</fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + <fo:block>block3</fo:block> + <fo:list-block keep-with-next.within-column="1" + provisional-distance-between-starts="25mm" + provisional-label-separation="5mm"> + <fo:list-item keep-with-next.within-column="2"> + <fo:list-item-label end-indent="label-end()"> + <fo:block keep-with-next.within-column="always">label1</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item1</fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + <fo:block>block4</fo:block> + <fo:list-block + provisional-distance-between-starts="25mm" + provisional-label-separation="5mm"> + <fo:list-item > + <fo:list-item-label end-indent="label-end()"> + <fo:block keep-with-next.within-column="1">label1</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item1</fo:block> + <fo:block>item1</fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + <fo:block>block5</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <element-list category="breaker"> + <box/> + <penalty w="0" p="0"/> + <!-- list 1 starts --> + <box/> + <penalty w="0" p="0"/> + <box/> + <!-- list 1 end --> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <!-- list 2 starts --> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <!-- list 2 end --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <!-- list 3 starts --> + <box/> + <!-- list 3 end --> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <!-- list 4 starts --> + <box/> + <penalty w="0" p="999"/> + <box/> + <!-- list 4 end --> + <penalty w="0" p="999"/> + <box/> + + <skip>3</skip> + </element-list> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/list-block_keep-with-previous.xml b/test/layoutengine/standard-testcases/list-block_keep-with-previous.xml index 62b0f634c..cec98836a 100644 --- a/test/layoutengine/standard-testcases/list-block_keep-with-previous.xml +++ b/test/layoutengine/standard-testcases/list-block_keep-with-previous.xml @@ -63,7 +63,6 @@ </fo:list-item-label> <fo:list-item-body start-indent="body-start()"> <fo:block>item1</fo:block> - <fo:block>item1</fo:block> </fo:list-item-body> </fo:list-item> <fo:list-item keep-with-previous.within-page="always"> @@ -117,8 +116,6 @@ <box w="14400"/> <penalty w="0" p="INF"/> <box w="14400"/> - <penalty w="0" p="INF"/> - <box w="14400"/> <!-- list 2 end --> <penalty w="0" p="0"/> <box w="14400"/> diff --git a/test/layoutengine/standard-testcases/list-block_keep-with-previous_integers_1.xml b/test/layoutengine/standard-testcases/list-block_keep-with-previous_integers_1.xml new file mode 100644 index 000000000..7b9c9fb0f --- /dev/null +++ b/test/layoutengine/standard-testcases/list-block_keep-with-previous_integers_1.xml @@ -0,0 +1,127 @@ +<?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 keep-with-previous with lists. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" widows="0" orphans="0"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="10 * 14.4pt"> + <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>block1</fo:block> + <fo:list-block + provisional-distance-between-starts="25mm" + provisional-label-separation="5mm" + keep-with-previous.within-column="1"> + <fo:list-item> + <fo:list-item-label end-indent="label-end()"> + <fo:block>label1</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item1</fo:block> + </fo:list-item-body> + </fo:list-item> + <fo:list-item> + <fo:list-item-label end-indent="label-end()"> + <fo:block>label2</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item2</fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + <fo:block>block2</fo:block> + <fo:list-block + provisional-distance-between-starts="25mm" + provisional-label-separation="5mm"> + <fo:list-item keep-with-previous.within-column="1"> + <fo:list-item-label end-indent="label-end()"> + <fo:block>label1</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item1</fo:block> + <fo:block>item1</fo:block> + </fo:list-item-body> + </fo:list-item> + <fo:list-item keep-with-previous.within-column="1"> + <fo:list-item-label end-indent="label-end()"> + <fo:block>label2</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item2</fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + <fo:block>block3</fo:block> + <fo:list-block keep-with-previous.within-column="1" + provisional-distance-between-starts="25mm" + provisional-label-separation="5mm"> + <fo:list-item keep-with-previous.within-column="2"> + <fo:list-item-label end-indent="label-end()"> + <fo:block keep-with-previous.within-column="always">label1</fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()"> + <fo:block>item1</fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + <fo:block>block4</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <element-list category="breaker"> + <box/> + <penalty w="0" p="999"/> + <!-- list 1 starts --> + <box/> + <penalty w="0" p="0"/> + <box/> + <!-- list 1 end --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <!-- list 2 starts --> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <!-- list 2 end --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="INF"/> + <!-- list 3 starts --> + <box/> + <!-- list 3 end --> + <penalty w="0" p="0"/> + <box/> + + <skip>3</skip> + </element-list> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/list-item_block_keep-with-previous.xml b/test/layoutengine/standard-testcases/list-item_block_keep-with-previous.xml index 5c0a5da16..d2f5a18a8 100644 --- a/test/layoutengine/standard-testcases/list-item_block_keep-with-previous.xml +++ b/test/layoutengine/standard-testcases/list-item_block_keep-with-previous.xml @@ -41,7 +41,6 @@ </fo:list-item-label> <fo:list-item-body start-indent="body-start()"> <fo:block>item1</fo:block> - <fo:block>item2</fo:block> </fo:list-item-body> </fo:list-item> <fo:list-item> @@ -88,8 +87,6 @@ <box w="14400"/> <penalty w="0" p="INF"/> <box w="14400"/> - <penalty w="0" p="INF"/> - <box w="14400"/> <!-- list 1 end --> <penalty w="0" p="0"/> <box w="14400"/> diff --git a/test/layoutengine/standard-testcases/table-cell_table-units_mixed.xml b/test/layoutengine/standard-testcases/table-cell_table-units_mixed.xml new file mode 100644 index 000000000..868b14388 --- /dev/null +++ b/test/layoutengine/standard-testcases/table-cell_table-units_mixed.xml @@ -0,0 +1,61 @@ +<?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 the calculation of table units when the column + widths are a mixture of fixed and proportional widths. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="normal" white-space-collapse="true"> + <fo:flow flow-name="xsl-region-body"> + <fo:table table-layout="fixed" width="100%"> + <fo:table-column column-number="1" column-width="2pt + proportional-column-width(1)" /> + <fo:table-column column-number="2" column-width="proportional-column-width(1) + 2pt" /> + <fo:table-column column-number="3" + column-width="proportional-column-width(.5) + 2pt + proportional-column-width(.5)" /> + <fo:table-body> + <fo:table-cell border="solid 0.5pt black" starts-row="true"> + <fo:block>Cell 1.1</fo:block> + </fo:table-cell> + <fo:table-cell border="solid 0.5pt red"> + <fo:block>Cell 2.2</fo:block> + </fo:table-cell> + <fo:table-cell border="solid 0.5pt yellow" ends-row="true"> + <fo:block>Cell 3.3</fo:block> + </fo:table-cell> + </fo:table-body> + </fo:table> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <eval expected="119500" xpath="//flow/block/block[1]/@ipd"/> + <eval expected="119500" xpath="//flow/block/block[2]/@ipd"/> + <eval expected="119500" xpath="//flow/block/block[3]/@ipd"/> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/table_keep-with-next_integers_1.xml b/test/layoutengine/standard-testcases/table_keep-with-next_integers_1.xml new file mode 100644 index 000000000..9774feb53 --- /dev/null +++ b/test/layoutengine/standard-testcases/table_keep-with-next_integers_1.xml @@ -0,0 +1,184 @@ +<?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 keep-with-next works on tables. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" widows="0" orphans="0"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="10 * 14.4pt"> + <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>block1</fo:block> + <fo:table width="100%" table-layout="fixed" keep-with-next.within-column="1"> + <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>block2</fo:block> + <fo:table width="100%" table-layout="fixed"> + <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/> + <fo:table-body> + <fo:table-row keep-with-next.within-column="1"> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell> + <fo:block keep-with-next.within-column="1">cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row keep-with-next.within-column="1"> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>block3</fo:block> + <fo:table width="100%" table-layout="fixed"> + <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block keep-with-next.within-column="1">cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>block4</fo:block> + <fo:table width="100%" table-layout="fixed" keep-with-next.within-column="1"> + <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/> + <fo:table-body> + <fo:table-row keep-with-next.within-column="2"> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block keep-with-next.within-column="always">cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>block5</fo:block> + <fo:table width="100%" table-layout="fixed"> + <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <!-- Check that keeps are processed correctly inside the cell --> + <fo:block keep-with-next.within-column="1">cell1/2</fo:block> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell> + <!-- This cell stops earlier than the one next to it --> + <fo:block keep-with-next.within-column="1">cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>block6</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <element-list category="breaker"> + <box/> + <penalty w="0" p="0"/> + <!-- table 1 starts --> + <box/> + <!-- table 1 end --> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <!-- table 2 starts --> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <!-- table 2 end --> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <!-- table 3 starts --> + <box/> + <!-- table 3 end --> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <!-- table 4 starts --> + <box/> + <!-- table 4 end --> + <penalty w="0" p="INF"/> + <box/> + <penalty w="0" p="0"/> + <!-- table 5 starts --> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <!-- table 5 end --> + <penalty w="0" p="999"/> + <box/> + + <skip>3</skip> + </element-list> + </checks> +</testcase> diff --git a/test/layoutengine/standard-testcases/table_keep-with-previous_integers_1.xml b/test/layoutengine/standard-testcases/table_keep-with-previous_integers_1.xml new file mode 100644 index 000000000..ea5fada5f --- /dev/null +++ b/test/layoutengine/standard-testcases/table_keep-with-previous_integers_1.xml @@ -0,0 +1,146 @@ +<?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 keep-with-previous works on tables. + </p> + </info> + <fo> + <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" widows="0" orphans="0"> + <fo:layout-master-set> + <fo:simple-page-master master-name="normal" page-width="5in" page-height="10 * 14.4pt"> + <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>block1</fo:block> + <fo:table width="100%" table-layout="fixed" keep-with-previous.within-column="1"> + <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>block2</fo:block> + <fo:table width="100%" table-layout="fixed"> + <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row keep-with-previous.within-column="1"> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell> + <fo:block keep-with-previous.within-column="1">cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>block3</fo:block> + <fo:table width="100%" table-layout="fixed"> + <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/> + <fo:table-body> + <fo:table-row> + <fo:table-cell> + <fo:block>cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block>cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block keep-with-previous.within-column="1">block4</fo:block> + <fo:table width="100%" table-layout="fixed" keep-with-previous.within-column="1"> + <fo:table-column number-columns-repeated="2" column-width="proportional-column-width(1)"/> + <fo:table-body> + <fo:table-row keep-with-previous.within-column="2"> + <fo:table-cell> + <fo:block keep-with-previous.within-column="3">cell1/1</fo:block> + </fo:table-cell> + <fo:table-cell> + <fo:block keep-with-previous.within-column="always">cell1/2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block>block5</fo:block> + </fo:flow> + </fo:page-sequence> + </fo:root> + </fo> + <checks> + <element-list category="breaker"> + <box/> + <penalty w="0" p="999"/> + <!-- table 1 starts --> + <box/> + <!-- table 1 end --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <!-- table 2 starts --> + <box/> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="999"/> + <box/> + <!-- table 2 end --> + <penalty w="0" p="0"/> + <box/> + <penalty w="0" p="0"/> + <!-- table 3 starts --> + <box/> + <!-- table 3 end --> + <penalty w="0" p="999"/> + <box/> + <penalty w="0" p="INF"/> + <!-- table 4 starts --> + <box/> + <!-- table 4 end --> + <penalty w="0" p="0"/> + <box/> + + <skip>3</skip> + </element-list> + </checks> +</testcase> |