Browse Source

Merged revisions 651323,651333,651538,651540,651543-651544,651551,651558 via svnmerge from

https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk

........
  r651323 | spepping | 2008-04-24 18:46:31 +0100 (Thu, 24 Apr 2008) | 3 lines
  
  Improve table-unit computation if proportional-column-width() is used
  as a subexpression. Fixes bug 44658.
........
  r651333 | spepping | 2008-04-24 19:19:06 +0100 (Thu, 24 Apr 2008) | 4 lines
  
  Make the eventResourceGenerator task for the test files a separate
  task. Now one can do: ant codegen, compile outside of ant, ant
  compile-copy-resources, ant junit-compile-copy-resources.
........
  r651538 | jeremias | 2008-04-25 09:42:02 +0100 (Fri, 25 Apr 2008) | 1 line
  
  Javadocs
........
  r651540 | jeremias | 2008-04-25 09:44:39 +0100 (Fri, 25 Apr 2008) | 1 line
  
  Cleanup
........
  r651543 | adelmelle | 2008-04-25 09:59:56 +0100 (Fri, 25 Apr 2008) | 3 lines
  
  Removed TODO: New validation event to generate an error in case an fo:marker appears as a child of an fo:block-container with absolutely positioned areas.
  Additionally: some javadoc updates in BlockContainer.java
........
  r651544 | acumiskey | 2008-04-25 10:04:06 +0100 (Fri, 25 Apr 2008) | 1 line
  
  Removed the tab characters that were causing a big moan from eclipse
........
  r651551 | adelmelle | 2008-04-25 10:30:09 +0100 (Fri, 25 Apr 2008) | 3 lines
  
  Cleanup: removal of commented block/methods + some javadoc updates
........
  r651558 | jeremias | 2008-04-25 11:07:58 +0100 (Fri, 25 Apr 2008) | 1 line
  
  Second part of the implementation of stage 1 for advanced keeps (see Wiki): Integer values are treated differently from "always" values in keep-with-next/previous.within-column for all block-level FOs.
........


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@651570 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-1_0
Adrian Cumiskey 16 years ago
parent
commit
25a8131ea6
48 changed files with 1746 additions and 527 deletions
  1. 7
    1
      build.xml
  2. 9
    0
      src/codegen/java/org/apache/fop/tools/EventConventionException.java
  3. 26
    4
      src/codegen/java/org/apache/fop/tools/EventProducerCollector.java
  4. 42
    1
      src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java
  5. 1
    0
      src/java/org/apache/fop/events/EventFormatter.xml
  6. 9
    0
      src/java/org/apache/fop/fo/FOValidationEventProducer.java
  7. 62
    2
      src/java/org/apache/fop/fo/expr/RelativeNumericProperty.java
  8. 35
    52
      src/java/org/apache/fop/fo/flow/BlockContainer.java
  9. 18
    26
      src/java/org/apache/fop/fo/flow/table/EffRow.java
  10. 17
    14
      src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java
  11. 25
    135
      src/java/org/apache/fop/fo/pagination/PageSequence.java
  12. 0
    16
      src/java/org/apache/fop/fo/properties/LengthProperty.java
  13. 21
    18
      src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
  14. 7
    12
      src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
  15. 12
    0
      src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java
  16. 18
    21
      src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
  17. 16
    30
      src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
  18. 10
    0
      src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java
  19. 39
    0
      src/java/org/apache/fop/layoutmgr/KeepUtil.java
  20. 74
    8
      src/java/org/apache/fop/layoutmgr/LayoutContext.java
  21. 10
    0
      src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
  22. 4
    6
      src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
  23. 15
    11
      src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
  24. 6
    12
      src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
  25. 11
    5
      src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
  26. 25
    40
      src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
  27. 8
    6
      src/java/org/apache/fop/layoutmgr/table/ActiveCell.java
  28. 4
    1
      src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
  29. 2
    5
      src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
  30. 28
    4
      src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java
  31. 21
    3
      src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java
  32. 10
    21
      src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
  33. 20
    14
      src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
  34. 12
    23
      src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
  35. 27
    18
      src/java/org/apache/fop/layoutmgr/table/TableStepper.java
  36. 5
    0
      status.xml
  37. 0
    12
      test/layoutengine/disabled-testcases.xml
  38. 101
    0
      test/layoutengine/standard-testcases/block-container_keep-with-next_1.xml
  39. 101
    0
      test/layoutengine/standard-testcases/block-container_keep-with-previous_1.xml
  40. 99
    0
      test/layoutengine/standard-testcases/block_keep-with-next_integers_1.xml
  41. 116
    0
      test/layoutengine/standard-testcases/block_keep-with-previous_integers_1.xml
  42. 155
    0
      test/layoutengine/standard-testcases/list-block_keep-with-next_integers_1.xml
  43. 0
    3
      test/layoutengine/standard-testcases/list-block_keep-with-previous.xml
  44. 127
    0
      test/layoutengine/standard-testcases/list-block_keep-with-previous_integers_1.xml
  45. 0
    3
      test/layoutengine/standard-testcases/list-item_block_keep-with-previous.xml
  46. 61
    0
      test/layoutengine/standard-testcases/table-cell_table-units_mixed.xml
  47. 184
    0
      test/layoutengine/standard-testcases/table_keep-with-next_integers_1.xml
  48. 146
    0
      test/layoutengine/standard-testcases/table_keep-with-previous_integers_1.xml

+ 7
- 1
build.xml View File

<exclude name="**/intermediate/*"/> <exclude name="**/intermediate/*"/>
</patternset> </patternset>
</target> </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-classes"/>
<mkdir dir="${build.dir}/test-gensrc"/> <mkdir dir="${build.dir}/test-gensrc"/>
<mkdir dir="${junit.reports.dir}"/> <mkdir dir="${junit.reports.dir}"/>
</fileset> </fileset>
</classpath> </classpath>
</javac> </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"> <eventResourceGenerator modelfile="${build.dir}/test-gensrc/org/apache/fop/events/test-event-model.xml">
<fileset dir="${basedir}/test/java"> <fileset dir="${basedir}/test/java">
<include name="**/*.java"/> <include name="**/*.java"/>
</copy> </copy>
</target> </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"> <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"/> <echo message="Running basic functionality tests for fop-transcoder.jar"/>
<junit dir="${basedir}" haltonfailure="${junit.haltonfailure}" fork="${junit.fork}"> <junit dir="${basedir}" haltonfailure="${junit.haltonfailure}" fork="${junit.fork}">

+ 9
- 0
src/codegen/java/org/apache/fop/tools/EventConventionException.java View File



package org.apache.fop.tools; package org.apache.fop.tools;


/**
* This exception is used to indicate a violation of the conventions for event producers.
*/
public class EventConventionException extends Exception { public class EventConventionException extends Exception {


private static final long serialVersionUID = 117244726033986628L;

/**
* Creates a new EventConventionException
* @param message the error message
*/
public EventConventionException(String message) { public EventConventionException(String message) {
super(message); super(message);
} }

+ 26
- 4
src/codegen/java/org/apache/fop/tools/EventProducerCollector.java View File

private DocletTagFactory tagFactory; private DocletTagFactory tagFactory;
private EventModel model = new EventModel(); private EventModel model = new EventModel();


/**
* Creates a new EventProducerCollector.
*/
public EventProducerCollector() { public EventProducerCollector() {
this.tagFactory = createDocletTagFactory(); this.tagFactory = createDocletTagFactory();
} }


/**
* Creates the {@link DocletTagFactory} to be used by the collector.
* @return the doclet tag factory
*/
protected DocletTagFactory createDocletTagFactory() { protected DocletTagFactory createDocletTagFactory() {
return new DefaultDocletTagFactory(); 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 { throws IOException, EventConventionException, ClassNotFoundException {
JavaDocBuilder builder = new JavaDocBuilder(this.tagFactory); JavaDocBuilder builder = new JavaDocBuilder(this.tagFactory);
builder.addSource(src); builder.addSource(src);
for (int i = 0, c = classes.length; i < c; i++) { for (int i = 0, c = classes.length; i < c; i++) {
JavaClass clazz = classes[i]; JavaClass clazz = classes[i];
if (clazz.isInterface() && implementsInterface(clazz, CLASSNAME_EVENT_PRODUCER)) { if (clazz.isInterface() && implementsInterface(clazz, CLASSNAME_EVENT_PRODUCER)) {
processEventProducerInterface(clazz, filename);
processEventProducerInterface(clazz);
} }
} }
} }
/** /**
* Processes an EventProducer interface and creates an EventProducerModel from it. * Processes an EventProducer interface and creates an EventProducerModel from it.
* @param clazz the EventProducer interface * @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 EventConventionException if the event producer conventions are violated
* @throws ClassNotFoundException if a required class cannot be found * @throws ClassNotFoundException if a required class cannot be found
*/ */
protected void processEventProducerInterface(JavaClass clazz, String javaFilename)
protected void processEventProducerInterface(JavaClass clazz)
throws EventConventionException, ClassNotFoundException { throws EventConventionException, ClassNotFoundException {
EventProducerModel prodMeta = new EventProducerModel(clazz.getFullyQualifiedName()); EventProducerModel prodMeta = new EventProducerModel(clazz.getFullyQualifiedName());
JavaMethod[] methods = clazz.getMethods(true); JavaMethod[] methods = clazz.getMethods(true);
return methodMeta; return methodMeta;
} }


/**
* Returns the event model that has been accumulated.
* @return the event model.
*/
public EventModel getModel() { public EventModel getModel() {
return this.model; 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 { public void saveModelToXML(File modelFile) throws IOException {
getModel().saveToXML(modelFile); getModel().saveToXML(modelFile);
} }

+ 42
- 1
src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java View File

import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.selectors.FilenameSelector; 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 { public class EventProducerCollectorTask extends Task {


private List filesets = new java.util.ArrayList(); private List filesets = new java.util.ArrayList();
private static final String MODEL2TRANSLATION = "model2translation.xsl"; private static final String MODEL2TRANSLATION = "model2translation.xsl";
private static final String MERGETRANSLATION = "merge-translation.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 { protected void updateTranslationFile() throws IOException {
try { try {
boolean resultExists = getTranslationFile().exists(); boolean resultExists = getTranslationFile().exists();
} }
} }


/**
* 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) protected void processFileSets(EventProducerCollector collector)
throws IOException, EventConventionException, ClassNotFoundException { throws IOException, EventConventionException, ClassNotFoundException {
Iterator iter = filesets.iterator(); Iterator iter = filesets.iterator();
for (int i = 0, c = srcFiles.length; i < c; i++) { for (int i = 0, c = srcFiles.length; i < c; i++) {
String filename = srcFiles[i]; String filename = srcFiles[i];
File src = new File(directory, filename); 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) { public void addFileset(FileSet set) {
filesets.add(set); filesets.add(set);
} }
/**
* Sets the model file to be written.
* @param f the model file
*/
public void setModelFile(File f) { public void setModelFile(File f) {
this.modelFile = f; this.modelFile = f;
} }
/**
* Returns the model file to be written.
* @return the model file
*/
public File getModelFile() { public File getModelFile() {
return this.modelFile; return this.modelFile;
} }
/**
* Sets the translation file for the event producer methods.
* @param f the translation file
*/
public void setTranslationFile(File f) { public void setTranslationFile(File f) {
this.translationFile = f; this.translationFile = f;
} }
/**
* Returns the translation file for the event producer methods.
* @return the translation file
*/
public File getTranslationFile() { public File getTranslationFile() {
return this.translationFile; return this.translationFile;
} }
/**
* Command-line interface for testing purposes.
* @param args the command-line arguments
*/
public static void main(String[] args) { public static void main(String[] args) {
try { try {
Project project = new Project(); Project project = new Project();

+ 1
- 0
src/java/org/apache/fop/events/EventFormatter.xml View File

<message key="org.apache.fop.fo.FOValidationEventProducer.missingProperty">Element "{elementName}" is missing required property "{propertyName}"!{{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,, <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> 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.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.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> <message key="org.apache.fop.fo.FOValidationEventProducer.invalidProperty">Invalid property encountered on "{elementName}": {attr}{{locator}}</message>

+ 9
- 0
src/java/org/apache/fop/fo/FOValidationEventProducer.java View File

void masterNameNotUnique(Object source, String elementName, String name, void masterNameNotUnique(Object source, String elementName, String name,
Locator loc) throws ValidationException; 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. * A marker is not an initial child on a node.
* @param source the event source * @param source the event source

+ 62
- 2
src/java/org/apache/fop/fo/expr/RelativeNumericProperty.java View File

import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.datatypes.Numeric; import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.properties.Property; import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.TableColLength;




/** /**
* to delay evaluation of the operation until the time where getNumericValue() * to delay evaluation of the operation until the time where getNumericValue()
* or getValue() is called. * 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 ADDITION = 1;
public static final int SUBTRACTION = 2; public static final int SUBTRACTION = 2;
public static final int MULTIPLY = 3; public static final int MULTIPLY = 3;
/** /**
* The second operand. * The second operand.
*/ */
private Numeric op2;
private Numeric op2 = null;
/** /**
* The dimension of the result. * The dimension of the result.
*/ */
/** /**
* Return a resolved (calculated) Numeric with the value of the expression. * Return a resolved (calculated) Numeric with the value of the expression.
* @param context Evaluation context * @param context Evaluation context
* @return the resolved {@link Numeric} corresponding to the value of the expression
* @throws PropertyException when an exception occur during evaluation. * @throws PropertyException when an exception occur during evaluation.
*/ */
private Numeric getResolved(PercentBaseContext context) throws PropertyException { private Numeric getResolved(PercentBaseContext context) throws PropertyException {
return 0; return 0;
} }


/**
* 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 a string represention of the expression. Only used for debugging.
* @return the string representation. * @return the string representation.

+ 35
- 52
src/java/org/apache/fop/fo/flow/BlockContainer.java View File

import org.apache.fop.fo.properties.LengthRangeProperty; 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 { public class BlockContainer extends FObj {
// The value of properties relevant for fo:block-container. // The value of properties relevant for fo:block-container.
private boolean blockItemFound = false; 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) { public BlockContainer(FONode parent) {
super(parent); super(parent);
} }


/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
public void bind(PropertyList pList) throws FOPException { public void bind(PropertyList pList) throws FOPException {
super.bind(pList); super.bind(pList);
commonAbsolutePosition = pList.getAbsolutePositionProps(); commonAbsolutePosition = pList.getAbsolutePositionProps();
writingMode = pList.get(PR_WRITING_MODE).getEnum(); writingMode = pList.get(PR_WRITING_MODE).getEnum();
} }


/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
protected void startOfNode() throws FOPException { protected void startOfNode() throws FOPException {
super.startOfNode(); super.startOfNode();
getFOEventHandler().startBlockContainer(this); getFOEventHandler().startBlockContainer(this);


/** /**
* {@inheritDoc} * {@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 * absolutely positioned area may have a sequence of zero or more
* fo:markers as its initial children." * 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) protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
throws ValidationException {
if (FO_URI.equals(nsURI)) { 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) { if (blockItemFound) {
nodesOutOfOrderError(loc, "fo:marker", "(%block;)"); 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 { } else {
blockItemFound = true; blockItemFound = true;
} }
} }
} }


/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
protected void endOfNode() throws FOPException { protected void endOfNode() throws FOPException {
if (!blockItemFound) { if (!blockItemFound) {
missingChildElementError("marker* (%block;)+"); missingChildElementError("marker* (%block;)+");
getFOEventHandler().endBlockContainer(this); getFOEventHandler().endBlockContainer(this);
} }


/**
* @return true (BlockContainer can generate Reference Areas)
*/
/** @return <code>true</code> (BlockContainer can generate Reference Areas) */
public boolean generatesReferenceAreas() { public boolean generatesReferenceAreas() {
return true; return true;
} }


/**
* @return the Common Absolute Position Properties.
*/
/** @return the {@link CommonAbsolutePosition} */
public CommonAbsolutePosition getCommonAbsolutePosition() { public CommonAbsolutePosition getCommonAbsolutePosition() {
return commonAbsolutePosition; return commonAbsolutePosition;
} }
/**
* @return the Common Margin Properties-Block.
*/
/** @return the {@link CommonMarginBlock} */
public CommonMarginBlock getCommonMarginBlock() { public CommonMarginBlock getCommonMarginBlock() {
return commonMarginBlock; return commonMarginBlock;
} }


/**
* @return the Common Border, Padding, and Background Properties.
*/
/** @return the {@link CommonBorderPaddingBackground} */
public CommonBorderPaddingBackground getCommonBorderPaddingBackground() { public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
return commonBorderPaddingBackground; return commonBorderPaddingBackground;
} }
return blockProgressionDimension; return blockProgressionDimension;
} }


/** @return the display-align property. */
/** @return the "display-align" property. */
public int getDisplayAlign() { public int getDisplayAlign() {
return displayAlign; return displayAlign;
} }
return keepTogether; return keepTogether;
} }


/**
* @return the "inline-progression-dimension" property.
*/
/** @return the "inline-progression-dimension" property */
public LengthRangeProperty getInlineProgressionDimension() { public LengthRangeProperty getInlineProgressionDimension() {
return inlineProgressionDimension; return inlineProgressionDimension;
} }


/**
* @return the "overflow" property.
*/
/** @return the "overflow" property */
public int getOverflow() { public int getOverflow() {
return overflow; return overflow;
} }


/**
* @return the "reference-orientation" property.
*/
/** @return the "reference-orientation" property */
public int getReferenceOrientation() { public int getReferenceOrientation() {
return referenceOrientation.getValue(); return referenceOrientation.getValue();
} }


/**
* @return the "span" property.
*/
/** @return the "span" property */
public int getSpan() { public int getSpan() {
return this.span; return this.span;
} }


/**
* @return the "writing-mode" property.
*/
/** @return the "writing-mode" property */
public int getWritingMode() { public int getWritingMode() {
return writingMode; return writingMode;
} }
/**
* @return the width property
*/
/** @return the "width" property */
public Length getWidth() { public Length getWidth() {
return width; return width;
} }


/**
* @return the height property
*/
/** @return the "height" property */
public Length getHeight() { public Length getHeight() {
return height; return height;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
* @return {@link org.apache.fop.fo.Constants#FO_BLOCK_CONTAINER}
*/ */
public int getNameId() { public int getNameId() {
return FO_BLOCK_CONTAINER; return FO_BLOCK_CONTAINER;

+ 18
- 26
src/java/org/apache/fop/fo/flow/table/EffRow.java View File

} }


/** /**
* 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(); TableRow row = getTableRow();
if (row != null) { if (row != null) {
keepWithPrevious = row.mustKeepWithPrevious();
strength = Math.max(strength,
KeepUtil.getCombinedBlockLevelKeepStrength(row.getKeepWithPrevious()));
} }
for (Iterator iter = gridUnits.iterator(); iter.hasNext();) { for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
GridUnit gu = (GridUnit) iter.next(); GridUnit gu = (GridUnit) iter.next();
if (gu.isPrimary()) { 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(); TableRow row = getTableRow();
if (row != null) { if (row != null) {
keepWithNext = row.mustKeepWithNext();
strength = Math.max(strength,
KeepUtil.getCombinedBlockLevelKeepStrength(row.getKeepWithNext()));
} }
for (Iterator iter = gridUnits.iterator(); iter.hasNext();) { for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
GridUnit gu = (GridUnit) iter.next(); GridUnit gu = (GridUnit) iter.next();
if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) { 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;
} }


/** /**

+ 17
- 14
src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java View File

import org.apache.fop.fo.Constants; import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode; import org.apache.fop.fo.FONode;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.table.TableCellLayoutManager; import org.apache.fop.layoutmgr.table.TableCellLayoutManager;


private boolean isSeparateBorderModel; private boolean isSeparateBorderModel;
private int halfBorderSeparationBPD; 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 breakBefore = Constants.EN_AUTO;
private int breakAfter = Constants.EN_AUTO; private int breakAfter = Constants.EN_AUTO;


} }


/** /**
* 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; return keepWithPrevious;
} }


/** /**
* Don't use, reserved for TableCellLM. TODO * 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; return keepWithNext;
} }


/** /**
* Don't use, reserved for TableCellLM. TODO * 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;
} }


/** /**

+ 25
- 135
src/java/org/apache/fop/fo/pagination/PageSequence.java View File

import org.apache.fop.fo.ValidationException; 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 { public class PageSequence extends AbstractPageSequence {
private Flow mainFlow = null; 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) { public PageSequence(FONode parent) {
super(parent); super(parent);
* The flow-name is used to associate the flow with a region on a page, * 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 * based on the region-names given to the regions in the page-master
* used to generate that page. * 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 { private void addFlow(Flow flow) throws ValidationException {
String flowName = flow.getFlowName(); String flowName = flow.getFlowName();
} }
} }


// /**
// * 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. * Get the static content FO node from the flow map.
* This gets the static content flow for the given flow name. * This gets the static content flow for the given flow name.
} }


/** /**
* Accessor method for titleFO
* Accessor method for the fo:title associated with this fo:page-sequence
* @return titleFO for this object * @return titleFO for this object
*/ */
public Title getTitleFO() { public Title getTitleFO() {
} }
} }
/** @return the "master-reference" property. */
/**
* Get the value of the <code>master-reference</code> property.
* @return the "master-reference" property
*/
public String getMasterReference() { public String getMasterReference() {
return masterReference; return masterReference;
} }
return "page-sequence"; return "page-sequence";
} }


/** {@inheritDoc} */
/**
* {@inheritDoc}
* @return {@link org.apache.fop.fo.Constants#FO_PAGE_SEQUENCE}
*/
public int getNameId() { public int getNameId() {
return FO_PAGE_SEQUENCE; 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() { public String getCountry() {
return this.country; 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() { public String getLanguage() {
return this.language; return this.language;
} }

+ 0
- 16
src/java/org/apache/fop/fo/properties/LengthProperty.java View File



} }


/**
* 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 */ /** @return the numeric dimension. Length always a dimension of 1 */
public int getDimension() { public int getDimension() {
return 1; return 1;

+ 21
- 18
src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java View File



if (!firstVisibleMarkServed) { if (!firstVisibleMarkServed) {
addKnuthElementsForSpaceBefore(returnList, alignment); addKnuthElementsForSpaceBefore(returnList, alignment);
context.updateKeepWithPreviousPending(getKeepWithPreviousStrength());
} }
addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);


// get elements from curLM // get elements from curLM
returnedList = curLM.getNextKnuthElements(childLC, alignment); 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 if (returnedList.size() == 1
&& ((ListElement)returnedList.getFirst()).isForcedBreak()) { && ((ListElement)returnedList.getFirst()).isForcedBreak()) {
// a descendant of this block has break-before // a descendant of this block has break-before
return returnList; return returnList;
} }
} }
// propagate and clear
context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
childLC.clearKeepsPending();
prevLM = curLM; prevLM = curLM;
} }


context.clearPendingMarks(); context.clearPendingMarks();
addKnuthElementsForBreakAfter(returnList, context); addKnuthElementsForBreakAfter(returnList, context);


context.updateKeepWithNextPending(getKeepWithNextStrength());

setFinished(true); setFinished(true);
return returnList; return returnList;
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
public int getKeepTogetherStrength() { 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()); strength = Math.max(strength, getParentKeepTogetherStrength());
return strength; return strength;
} }


/** {@inheritDoc} */ /** {@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} */ /** {@inheritDoc} */
public boolean mustKeepWithNext() {
return !getBlockContainerFO().getKeepWithNext().getWithinPage().isAuto()
|| !getBlockContainerFO().getKeepWithNext().getWithinColumn().isAuto();
public int getKeepWithPreviousStrength() {
return KeepUtil.getCombinedBlockLevelKeepStrength(
getBlockContainerFO().getKeepWithPrevious());
} }


/** /**


// --------- Property Resolution related functions --------- // // --------- Property Resolution related functions --------- //
/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
public boolean getGeneratesReferenceArea() { public boolean getGeneratesReferenceArea() {
return true; return true;
} }
/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
public boolean getGeneratesBlockArea() { public boolean getGeneratesBlockArea() {
return true; return true;
} }

+ 7
- 12
src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java View File

import org.apache.fop.area.Block; import org.apache.fop.area.Block;
import org.apache.fop.area.LineArea; import org.apache.fop.area.LineArea;
import org.apache.fop.datatypes.Length; import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fonts.Font; import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet; import org.apache.fop.fonts.FontTriplet;


/** {@inheritDoc} */ /** {@inheritDoc} */
public int getKeepTogetherStrength() { 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()); strength = Math.max(strength, getParentKeepTogetherStrength());
return strength; return strength;
} }
/** {@inheritDoc} */ /** {@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} */ /** {@inheritDoc} */
public boolean mustKeepWithNext() {
return !getBlockFO().getKeepWithNext().getWithinPage().isAuto()
|| !getBlockFO().getKeepWithNext().getWithinColumn().isAuto();
public int getKeepWithPreviousStrength() {
return KeepUtil.getCombinedBlockLevelKeepStrength(getBlockFO().getKeepWithPrevious());
} }


/** {@inheritDoc} */ /** {@inheritDoc} */

+ 12
- 0
src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java View File

*/ */
boolean mustKeepTogether(); 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. * @return true if this element must be kept with the previous element.
*/ */
boolean mustKeepWithPrevious(); 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. * @return true if this element must be kept with the next element.
*/ */

+ 18
- 21
src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java View File



if (!firstVisibleMarkServed) { if (!firstVisibleMarkServed) {
addKnuthElementsForSpaceBefore(returnList, alignment); addKnuthElementsForSpaceBefore(returnList, alignment);
context.updateKeepWithPreviousPending(getKeepWithPreviousStrength());
} }
addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
// get elements from curLM // get elements from curLM
returnedList = curLM.getNextKnuthElements(childLC, alignment); returnedList = curLM.getNextKnuthElements(childLC, alignment);
if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) { 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 if (returnedList != null
&& returnedList.size() == 1 && returnedList.size() == 1
} }
} }
// propagate and clear // 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; prevLM = curLM;
} }


wrapPositionElement(forcedBreakAfterLast, returnList, false); 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); setFinished(true);


|| childLC.isKeepWithPreviousPending()) { || childLC.isKeepWithPreviousPending()) {
int strength = getKeepTogetherStrength(); 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); int penalty = KeepUtil.getPenaltyForKeep(strength);


// add a penalty to forbid or discourage a break between blocks // add a penalty to forbid or discourage a break between blocks


/** {@inheritDoc} */ /** {@inheritDoc} */
public boolean mustKeepWithPrevious() { public boolean mustKeepWithPrevious() {
return false;
return getKeepWithPreviousStrength() > KEEP_AUTO;
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
public boolean mustKeepWithNext() { public boolean mustKeepWithNext() {
return false;
return getKeepWithNextStrength() > KEEP_AUTO;
} }


/** /**

+ 16
- 30
src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java View File

returnedList = curLM.getNextKnuthElements(childLC, alignment); returnedList = curLM.getNextKnuthElements(childLC, alignment);
//log.debug("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size()); //log.debug("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size());
if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) { 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 // "wrap" the Position inside each element
return returnList; return returnList;
} else { } else {
if (returnList.size() > 0) { 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) { if (returnedList.size() > 0) {
returnList.addAll(returnedList); returnList.addAll(returnedList);
} }
} }
} }
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); SpaceResolver.resolveElementList(returnList);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public boolean mustKeepWithPrevious() {
return false;
public int getKeepWithNextStrength() {
return KEEP_AUTO;
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
public boolean mustKeepWithNext() {
return false;
public int getKeepWithPreviousStrength() {
return KEEP_AUTO;
} }

/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
public LinkedList getChangedKnuthElements(List oldList, /*int flaggedPenalty,*/ int alignment) { public LinkedList getChangedKnuthElements(List oldList, /*int flaggedPenalty,*/ int alignment) {
ListIterator oldListIterator = oldList.listIterator(); ListIterator oldListIterator = oldList.listIterator();
KnuthElement returnedElement; KnuthElement returnedElement;
public int getContentAreaBPD() { public int getContentAreaBPD() {
return (int) getCurrentPV().getBodyRegion().getBPD(); return (int) getCurrentPV().getBodyRegion().getBPD();
} }
} }



+ 10
- 0
src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java View File

return getParentKeepTogetherStrength(); return getParentKeepTogetherStrength();
} }
/** {@inheritDoc} */
public int getKeepWithNextStrength() {
return KEEP_AUTO;
}

/** {@inheritDoc} */
public int getKeepWithPreviousStrength() {
return KEEP_AUTO;
}
} }

+ 39
- 0
src/java/org/apache/fop/layoutmgr/KeepUtil.java View File

package org.apache.fop.layoutmgr; package org.apache.fop.layoutmgr;


import org.apache.fop.fo.Constants; import org.apache.fop.fo.Constants;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.Property; import org.apache.fop.fo.properties.Property;


/** /**
} }
} }
/**
* 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. * Returns the penalty value to be used for a certain keep strength.
* <ul> * <ul>
return penalty; 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);
}
}
} }

+ 74
- 8
src/java/org/apache/fop/layoutmgr/LayoutContext.java View File

* This flag indicates that there's a keep-with-next that hasn't * This flag indicates that there's a keep-with-next that hasn't
* been processed, yet. * 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 * This flag indicates that there's a keep-with-previous that hasn't
* been processed, yet. * 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 private int flags; // Contains some set of flags defined above
/** Amount of space before / start */ /** Amount of space before / start */
private int spaceBefore = 0; private int spaceBefore = 0;
/** Amount of space after / end */ /** Amount of space after / end */
private int spaceAfter = 0; private int spaceAfter = 0;
private int lineEndBorderAndPaddingWidth = 0; private int lineEndBorderAndPaddingWidth = 0;


private int breakBefore; private int breakBefore;

private int breakAfter; private int breakAfter;


private int pendingKeepWithNext = BlockLevelLayoutManager.KEEP_AUTO;
private int pendingKeepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO;
/** /**
* Copy constructor for creating child layout contexts. * Copy constructor for creating child layout contexts.
* @param parentLC the parent layout context to copy from * @param parentLC the parent layout context to copy from
this.lineStartBorderAndPaddingWidth = parentLC.lineStartBorderAndPaddingWidth; this.lineStartBorderAndPaddingWidth = parentLC.lineStartBorderAndPaddingWidth;
this.lineEndBorderAndPaddingWidth = parentLC.lineEndBorderAndPaddingWidth; this.lineEndBorderAndPaddingWidth = parentLC.lineEndBorderAndPaddingWidth;
copyPendingMarksFrom(parentLC); copyPendingMarksFrom(parentLC);
this.pendingKeepWithNext = parentLC.pendingKeepWithNext;
this.pendingKeepWithPrevious = parentLC.pendingKeepWithPrevious;
// Copy other fields as necessary. // Copy other fields as necessary.
} }


return ((this.flags & SUPPRESS_LEADING_SPACE) != 0); 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() { 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() { public boolean isKeepWithPreviousPending() {
return ((this.flags & KEEP_WITH_PREVIOUS_PENDING) != 0);
return getKeepWithPreviousPending() != BlockLevelLayoutManager.KEEP_AUTO;
} }
public void setLeadingSpace(SpaceSpecifier space) { public void setLeadingSpace(SpaceSpecifier space) {
+ "\nStarts New Area: \t" + startsNewArea() + "\nStarts New Area: \t" + startsNewArea()
+ "\nIs Last Area: \t" + isLastArea() + "\nIs Last Area: \t" + isLastArea()
+ "\nTry Hyphenate: \t" + tryHyphenate() + "\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" : "") + "][" + "\nBreaks: \tforced [" + (breakBefore != Constants.EN_AUTO ? "break-before" : "") + "]["
+ (breakAfter != Constants.EN_AUTO ? "break-after" : "") + "]"; + (breakAfter != Constants.EN_AUTO ? "break-after" : "") + "]";
} }

+ 10
- 0
src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java View File

return KEEP_AUTO; return KEEP_AUTO;
} }
/** {@inheritDoc} */
public int getKeepWithNextStrength() {
return KEEP_AUTO;
}

/** {@inheritDoc} */
public int getKeepWithPreviousStrength() {
return KEEP_AUTO;
}
} }



+ 4
- 6
src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java View File

// get KnuthElements from curLM // get KnuthElements from curLM
returnedList = curLM.getNextKnuthElements(childLC, alignment); returnedList = curLM.getNextKnuthElements(childLC, alignment);
if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) { if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) {
childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
childLC.clearKeepWithPreviousPending();
} }
if (returnedList == null if (returnedList == null
|| returnedList.size() == 0) { || returnedList.size() == 0) {
} }
if (curLM instanceof InlineLevelLayoutManager) { if (curLM instanceof InlineLevelLayoutManager) {
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
context.clearKeepWithNextPending();
// "wrap" the Position stored in each element of returnedList // "wrap" the Position stored in each element of returnedList
ListIterator seqIter = returnedList.listIterator(); ListIterator seqIter = returnedList.listIterator();
while (seqIter.hasNext()) { while (seqIter.hasNext()) {
returnList.add(sequence); returnList.add(sequence);
} }
// propagate and clear // 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(); lastSequence = (KnuthSequence) returnList.getLast();
lastChildLM = curLM; lastChildLM = curLM;

+ 15
- 11
src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java View File

return ((BlockLevelLayoutManager) getParent()).getKeepTogetherStrength(); return ((BlockLevelLayoutManager) getParent()).getKeepTogetherStrength();
} }
/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
public boolean mustKeepWithPrevious() { public boolean mustKeepWithPrevious() {
return false;
return getKeepWithPreviousStrength() > KEEP_AUTO;
} }


/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
public boolean mustKeepWithNext() { 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) { public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
LeafPosition pos = (LeafPosition)lastElement.getPosition(); LeafPosition pos = (LeafPosition)lastElement.getPosition();
int totalAdj = adj; int totalAdj = adj;

+ 6
- 12
src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java View File



/** {@inheritDoc} */ /** {@inheritDoc} */
public int getKeepTogetherStrength() { 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()); strength = Math.max(strength, getParentKeepTogetherStrength());
return strength; return strength;
} }
/** {@inheritDoc} */ /** {@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} */ /** {@inheritDoc} */
public boolean mustKeepWithNext() {
return !getListBlockFO().getKeepWithNext().getWithinPage().isAuto()
|| !getListBlockFO().getKeepWithNext().getWithinColumn().isAuto();
public int getKeepWithPreviousStrength() {
return KeepUtil.getCombinedBlockLevelKeepStrength(getListBlockFO().getKeepWithPrevious());
} }


/** {@inheritDoc} */ /** {@inheritDoc} */

+ 11
- 5
src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java View File



/** {@inheritDoc} */ /** {@inheritDoc} */
public int getKeepTogetherStrength() { 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()); strength = Math.max(strength, getParentKeepTogetherStrength());
return strength; return strength;
} }
/** {@inheritDoc} */
public int getKeepWithNextStrength() {
return KEEP_AUTO;
}

/** {@inheritDoc} */
public int getKeepWithPreviousStrength() {
return KEEP_AUTO;
}
} }



+ 25
- 40
src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java View File

import org.apache.fop.fo.flow.ListItem; import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.flow.ListItemBody; import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel; import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ConditionalElementListener;
private MinOptMax effSpaceBefore; private MinOptMax effSpaceBefore;
private MinOptMax effSpaceAfter; private MinOptMax effSpaceAfter;
private boolean keepWithNextPendingOnLabel;
private boolean keepWithNextPendingOnBody;
private int keepWithNextPendingOnLabel;
private int keepWithNextPendingOnBody;


private int listItemHeight; private int listItemHeight;
SpaceResolver.resolveElementList(labelList); SpaceResolver.resolveElementList(labelList);
ElementListObserver.observe(labelList, "list-item-label", label.getPartFO().getId()); 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 // body
childLC = new LayoutContext(0); childLC = new LayoutContext(0);
SpaceResolver.resolveElementList(bodyList); SpaceResolver.resolveElementList(bodyList);
ElementListObserver.observe(bodyList, "list-item-body", body.getPartFO().getId()); 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 // create a combined list
LinkedList returnedList = getCombinedKnuthElementsForListItem(labelList, bodyList, context); LinkedList returnedList = getCombinedKnuthElementsForListItem(labelList, bodyList, context);
addKnuthElementsForSpaceAfter(returnList, alignment); addKnuthElementsForSpaceAfter(returnList, alignment);
addKnuthElementsForBreakAfter(returnList, context); 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); setFinished(true);
resetSpaces(); resetSpaces();
int totalHeight = Math.max(fullHeights[0], fullHeights[1]); int totalHeight = Math.max(fullHeights[0], fullHeights[1]);
int step; int step;
int addedBoxHeight = 0; int addedBoxHeight = 0;
boolean keepWithNextActive = false;
int keepWithNextActive = BlockLevelLayoutManager.KEEP_AUTO;


LinkedList returnList = new LinkedList(); LinkedList returnList = new LinkedList();
while ((step = getNextStep(elementLists, start, end, partialHeights)) while ((step = getNextStep(elementLists, start, end, partialHeights))
> 0) { > 0) {
if (end[0] + 1 == elementLists[0].size()) { if (end[0] + 1 == elementLists[0].size()) {
if (keepWithNextPendingOnLabel) {
keepWithNextActive = true;
}
keepWithNextActive = Math.max(keepWithNextActive, keepWithNextPendingOnLabel);
} }
if (end[1] + 1 == elementLists[1].size()) { if (end[1] + 1 == elementLists[1].size()) {
if (keepWithNextPendingOnBody) {
keepWithNextActive = true;
}
keepWithNextActive = Math.max(keepWithNextActive, keepWithNextPendingOnBody);
} }
// compute penalty height and box height // compute penalty height and box height
start[0], end[0], start[1], end[1]); start[0], end[0], start[1], end[1]);
returnList.add(new KnuthBox(boxHeight, stepPosition, false)); returnList.add(new KnuthBox(boxHeight, stepPosition, false));
if (addedBoxHeight < totalHeight) { if (addedBoxHeight < totalHeight) {
int strength = BlockLevelLayoutManager.KEEP_AUTO;
strength = Math.max(strength, keepWithNextActive);
strength = Math.max(strength, getKeepTogetherStrength());
int p = stepPenalty; 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)); returnList.add(new BreakElement(stepPosition, penaltyHeight, p, -1, context));
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
public int getKeepTogetherStrength() { 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()); strength = Math.max(strength, getParentKeepTogetherStrength());
return strength; return strength;
} }


/** {@inheritDoc} */ /** {@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} */ /** {@inheritDoc} */
public boolean mustKeepWithNext() {
return !getListItemFO().getKeepWithNext().getWithinPage().isAuto()
|| !getListItemFO().getKeepWithNext().getWithinColumn().isAuto();
public int getKeepWithPreviousStrength() {
return KeepUtil.getCombinedBlockLevelKeepStrength(getListItemFO().getKeepWithPrevious());
} }


/** {@inheritDoc} */ /** {@inheritDoc} */

+ 8
- 6
src/java/org/apache/fop/layoutmgr/table/ActiveCell.java View File



import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;

import org.apache.fop.fo.Constants; import org.apache.fop.fo.Constants;
import org.apache.fop.fo.flow.table.ConditionalBorder; import org.apache.fop.fo.flow.table.ConditionalBorder;
import org.apache.fop.fo.flow.table.EffRow; import org.apache.fop.fo.flow.table.EffRow;
import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.fo.flow.table.PrimaryGridUnit;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthElement;
/** True if the next CellPart that will be created will be the last one for this cell. */ /** True if the next CellPart that will be created will be the last one for this cell. */
private boolean lastCellPart; private boolean lastCellPart;


private boolean keepWithNextSignal;
private int keepWithNextStrength;


private int spanIndex = 0; private int spanIndex = 0;


includedLength = -1; // Avoid troubles with cells having content of zero length includedLength = -1; // Avoid troubles with cells having content of zero length
totalLength = previousRowsLength + ElementListUtils.calcContentLength(elementList); totalLength = previousRowsLength + ElementListUtils.calcContentLength(elementList);
endRowIndex = rowIndex + pgu.getCell().getNumberRowsSpanned() - 1; endRowIndex = rowIndex + pgu.getCell().getNumberRowsSpanned() - 1;
keepWithNextSignal = false;
keepWithNextStrength = BlockLevelLayoutManager.KEEP_AUTO;
remainingLength = totalLength - previousRowsLength; remainingLength = totalLength - previousRowsLength;


afterNextStep = new Step(previousRowsLength); afterNextStep = new Step(previousRowsLength);
*/ */
CellPart createCellPart() { CellPart createCellPart() {
if (nextStep.end + 1 == elementList.size()) { 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 // TODO if keep-with-next is set on the row, must every cell of the row
// contribute some content from children blocks? // contribute some content from children blocks?
// see http://mail-archives.apache.org/mod_mbox/xmlgraphics-fop-dev/200802.mbox/ // see http://mail-archives.apache.org/mod_mbox/xmlgraphics-fop-dev/200802.mbox/
// %3c47BDA379.4050606@anyware-tech.com%3e // %3c47BDA379.4050606@anyware-tech.com%3e
// Assuming no, but if yes the following code should enable this behaviour // Assuming no, but if yes the following code should enable this behaviour
// if (pgu.getRow() != null && pgu.getRow().mustKeepWithNext()) { // if (pgu.getRow() != null && pgu.getRow().mustKeepWithNext()) {
// keepWithNextSignal = true;
// keepWithNextSignal = true; //to be converted to integer strengths
// } // }
} }
int bpBeforeFirst; int bpBeforeFirst;
} }
} }


boolean keepWithNextSignal() {
return keepWithNextSignal;
int getKeepWithNextStrength() {
return keepWithNextStrength;
} }





+ 4
- 1
src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java View File

import org.apache.fop.datatypes.Length; import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.FONode; 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.Table;
import org.apache.fop.fo.flow.table.TableColumn; import org.apache.fop.fo.flow.table.TableColumn;
import org.apache.fop.fo.properties.TableColLength; import org.apache.fop.fo.properties.TableColLength;
Length colWidth = (Length) i.next(); Length colWidth = (Length) i.next();
if (colWidth != null) { if (colWidth != null) {
sumCols += colWidth.getValue(tlm); 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(); factors += ((TableColLength) colWidth).getTableUnits();
} }
} }

+ 2
- 5
src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java View File

import org.apache.fop.fo.flow.table.TableRow; import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.LengthRangeProperty; import org.apache.fop.fo.properties.LengthRangeProperty;
import org.apache.fop.layoutmgr.BlockLevelEventProducer;
import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.layoutmgr.ElementListObserver;
import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.MinOptMaxUtil; import org.apache.fop.layoutmgr.MinOptMaxUtil;
LinkedList returnList = new LinkedList(); LinkedList returnList = new LinkedList();
createElementsForRowGroup(context, alignment, bodyType, returnList); 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; int breakBefore = Constants.EN_AUTO;
TableRow firstRow = rowGroup[0].getTableRow(); TableRow firstRow = rowGroup[0].getTableRow();

+ 28
- 4
src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java View File

super(node); super(node);
} }


/**
* 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. * Get the next break possibility.
* *
public int getKeepTogetherStrength() { public int getKeepTogetherStrength() {
int strength = KEEP_AUTO; int strength = KEEP_AUTO;
/* TODO Complete me! /* 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()); strength = Math.max(strength, getParentKeepTogetherStrength());
return strength; 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());
*/
}

} }

+ 21
- 3
src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java View File

} }


/** @return the table-caption FO */ /** @return the table-caption FO */
public TableCaption getTableCaption() {
public TableCaption getTableCaptionFO() {
return (TableCaption)this.fobj; return (TableCaption)this.fobj;
} }
int strength = KEEP_AUTO; int strength = KEEP_AUTO;
/* TODO Complete me! /* TODO Complete me!
strength = Math.max(strength, KeepUtil.getKeepStrength( strength = Math.max(strength, KeepUtil.getKeepStrength(
getTableCaption().getKeepTogether().getWithinPage()));
getTableCaptionFO().getKeepTogether().getWithinPage()));
strength = Math.max(strength, KeepUtil.getKeepStrength( strength = Math.max(strength, KeepUtil.getKeepStrength(
getTableCaption().getKeepTogether().getWithinColumn()));
getTableCaptionFO().getKeepTogether().getWithinColumn()));
*/ */
strength = Math.max(strength, getParentKeepTogetherStrength()); strength = Math.max(strength, getParentKeepTogetherStrength());
return strength; 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());
*/
}

} }



+ 10
- 21
src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java View File

log.debug("child LM signals pending keep with next"); log.debug("child LM signals pending keep with next");
} }
if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) { 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) { if (prevLM != null) {
} }
if (childLC.isKeepWithNextPending()) { if (childLC.isKeepWithNextPending()) {
//Clear and propagate //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; prevLM = curLM;
} }
if (context.isKeepWithNextPending()) {
primaryGridUnit.setKeepWithNext();
}
primaryGridUnit.setKeepWithNextStrength(context.getKeepWithNextPending());


returnedList = new LinkedList(); returnedList = new LinkedList();
if (contentList.size() > 0) { if (contentList.size() > 0) {
} }
/** {@inheritDoc} */ /** {@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} */ /** {@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 --------- // // --------- Property Resolution related functions --------- //


/** /**

+ 20
- 14
src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java View File

import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.fo.flow.table.PrimaryGridUnit;
import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableBody; 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.BreakElement;
import org.apache.fop.layoutmgr.ElementListUtils; import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.KeepUtil;
LinkedList returnList = new LinkedList(); LinkedList returnList = new LinkedList();
EffRow[] rowGroup = iter.getNextRowGroup(); EffRow[] rowGroup = iter.getNextRowGroup();
// TODO homogenize the handling of keeps and breaks // 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.setBreakBefore(Constants.EN_AUTO);
context.setBreakAfter(Constants.EN_AUTO); context.setBreakAfter(Constants.EN_AUTO);
boolean keepWithPrevious = false;
int keepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO;
int breakBefore = Constants.EN_AUTO; int breakBefore = Constants.EN_AUTO;
if (rowGroup != null) { if (rowGroup != null) {
RowGroupLayoutManager rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup, RowGroupLayoutManager rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup,
stepper); stepper);
List nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType); List nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType);
keepWithPrevious = context.isKeepWithPreviousPending();
boolean keepBetween = context.isKeepWithNextPending();
keepWithPrevious = Math.max(keepWithPrevious, context.getKeepWithPreviousPending());
breakBefore = context.getBreakBefore(); breakBefore = context.getBreakBefore();
int breakBetween = context.getBreakAfter(); int breakBetween = context.getBreakAfter();
returnList.addAll(nextRowGroupElems); returnList.addAll(nextRowGroupElems);
while ((rowGroup = iter.getNextRowGroup()) != null) { while ((rowGroup = iter.getNextRowGroup()) != null) {
rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup, stepper); 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); 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, breakBetween = BreakUtil.compareBreakClasses(breakBetween,
context.getBreakBefore()); context.getBreakBefore());
penaltyLen, penaltyValue, breakBetween, context)); penaltyLen, penaltyValue, breakBetween, context));
returnList.addAll(nextRowGroupElems); returnList.addAll(nextRowGroupElems);
breakBetween = context.getBreakAfter(); breakBetween = context.getBreakAfter();
keepBetween = context.isKeepWithNextPending();
} }
} }
context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, keepWithPrevious);
context.updateKeepWithPreviousPending(keepWithPrevious);
context.setBreakBefore(breakBefore); context.setBreakBefore(breakBefore);


//fox:widow-content-limit //fox:widow-content-limit

+ 12
- 23
src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java View File

log.debug(contentKnuthElements); log.debug(contentKnuthElements);
wrapPositionElements(contentKnuthElements, returnList); 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()) { if (getTable().isSeparateBorderModel()) {
addKnuthElementsForBorderPaddingAfter(returnList, true); addKnuthElementsForBorderPaddingAfter(returnList, true);


/** {@inheritDoc} */ /** {@inheritDoc} */
public int getKeepTogetherStrength() { 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()); strength = Math.max(strength, getParentKeepTogetherStrength());
return strength; 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 --------- // // --------- Property Resolution related functions --------- //

+ 27
- 18
src/java/org/apache/fop/layoutmgr/table/TableStepper.java View File

import org.apache.fop.fo.flow.table.EffRow; import org.apache.fop.fo.flow.table.EffRow;
import org.apache.fop.fo.flow.table.GridUnit; import org.apache.fop.fo.flow.table.GridUnit;
import org.apache.fop.fo.flow.table.PrimaryGridUnit; 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.BreakElement;
import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.KeepUtil;
import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.KnuthPenalty; import org.apache.fop.layoutmgr.KnuthPenalty;
import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutContext;
} }


//Put all involved grid units into a list //Put all involved grid units into a list
int stepPenalty = 0;
List cellParts = new java.util.ArrayList(columnCount); List cellParts = new java.util.ArrayList(columnCount);
for (Iterator iter = activeCells.iterator(); iter.hasNext();) { for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
ActiveCell activeCell = (ActiveCell) iter.next(); ActiveCell activeCell = (ActiveCell) iter.next();
CellPart part = activeCell.createCellPart(); CellPart part = activeCell.createCellPart();
cellParts.add(part); 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 //Create elements for step
} }
} }


int p = 0;
boolean keepWithNext = false;
int strength = BlockLevelLayoutManager.KEEP_AUTO;
for (Iterator iter = activeCells.iterator(); iter.hasNext();) { for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
ActiveCell activeCell = (ActiveCell) iter.next(); ActiveCell activeCell = (ActiveCell) iter.next();
keepWithNext |= activeCell.keepWithNextSignal();
}
if (keepWithNext) {
p = KnuthPenalty.INFINITE;
strength = Math.max(strength, activeCell.getKeepWithNextStrength());
} }
if (!rowFinished) { 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... //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) { } 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, nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass,
rowGroup[activeRowIndex].getBreakAfter()); rowGroup[activeRowIndex].getBreakAfter());
nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass, nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass,
rowGroup[activeRowIndex + 1].getBreakBefore()); 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) { if (rowHeightSmallerThanFirstStep) {
rowHeightSmallerThanFirstStep = false; rowHeightSmallerThanFirstStep = false;
p = KnuthPenalty.INFINITE; 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)); returnList.add(new BreakElement(penaltyPos, effPenaltyLen, p, nextBreakClass, context));
if (penaltyOrGlueLen < 0) { if (penaltyOrGlueLen < 0) {
returnList.add(new KnuthGlue(-penaltyOrGlueLen, 0, 0, new Position(null), true)); returnList.add(new KnuthGlue(-penaltyOrGlueLen, 0, 0, new Position(null), true));

+ 5
- 0
status.xml View File

<action context="Renderers" dev="AC" importance="high" type="add"> <action context="Renderers" dev="AC" importance="high" type="add">
Added de-duplication and externalization support for IOCA and GOCA data resource objects. Added de-duplication and externalization support for IOCA and GOCA data resource objects.
</action> </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"> <action context="Renderers" dev="JM" type="add">
Added support for rendering pages using JPS (Java Printing System). See new example: Added support for rendering pages using JPS (Java Printing System). See new example:
examples/embedding/java/ExamplesFO2JPSPrint.java examples/embedding/java/ExamplesFO2JPSPrint.java

+ 0
- 12
test/layoutengine/disabled-testcases.xml View File

line.</description> line.</description>
<reference>http://www.nabble.com/leaders-with-leader-pattern%3D%22use-content%22-t546244.html</reference> <reference>http://www.nabble.com/leaders-with-leader-pattern%3D%22use-content%22-t546244.html</reference>
</testcase> </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> <testcase>
<name>Page breaking doesn't deal with IPD changes</name> <name>Page breaking doesn't deal with IPD changes</name>
<file>page-breaking_4.xml</file> <file>page-breaking_4.xml</file>

+ 101
- 0
test/layoutengine/standard-testcases/block-container_keep-with-next_1.xml View File

<?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>

+ 101
- 0
test/layoutengine/standard-testcases/block-container_keep-with-previous_1.xml View File

<?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>

+ 99
- 0
test/layoutengine/standard-testcases/block_keep-with-next_integers_1.xml View File

<?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>

+ 116
- 0
test/layoutengine/standard-testcases/block_keep-with-previous_integers_1.xml View File

<?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>

+ 155
- 0
test/layoutengine/standard-testcases/list-block_keep-with-next_integers_1.xml View File

<?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>

+ 0
- 3
test/layoutengine/standard-testcases/list-block_keep-with-previous.xml View File

</fo:list-item-label> </fo:list-item-label>
<fo:list-item-body start-indent="body-start()"> <fo:list-item-body start-indent="body-start()">
<fo:block>item1</fo:block> <fo:block>item1</fo:block>
<fo:block>item1</fo:block>
</fo:list-item-body> </fo:list-item-body>
</fo:list-item> </fo:list-item>
<fo:list-item keep-with-previous.within-page="always"> <fo:list-item keep-with-previous.within-page="always">
<box w="14400"/> <box w="14400"/>
<penalty w="0" p="INF"/> <penalty w="0" p="INF"/>
<box w="14400"/> <box w="14400"/>
<penalty w="0" p="INF"/>
<box w="14400"/>
<!-- list 2 end --> <!-- list 2 end -->
<penalty w="0" p="0"/> <penalty w="0" p="0"/>
<box w="14400"/> <box w="14400"/>

+ 127
- 0
test/layoutengine/standard-testcases/list-block_keep-with-previous_integers_1.xml View File

<?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>

+ 0
- 3
test/layoutengine/standard-testcases/list-item_block_keep-with-previous.xml View File

</fo:list-item-label> </fo:list-item-label>
<fo:list-item-body start-indent="body-start()"> <fo:list-item-body start-indent="body-start()">
<fo:block>item1</fo:block> <fo:block>item1</fo:block>
<fo:block>item2</fo:block>
</fo:list-item-body> </fo:list-item-body>
</fo:list-item> </fo:list-item>
<fo:list-item> <fo:list-item>
<box w="14400"/> <box w="14400"/>
<penalty w="0" p="INF"/> <penalty w="0" p="INF"/>
<box w="14400"/> <box w="14400"/>
<penalty w="0" p="INF"/>
<box w="14400"/>
<!-- list 1 end --> <!-- list 1 end -->
<penalty w="0" p="0"/> <penalty w="0" p="0"/>
<box w="14400"/> <box w="14400"/>

+ 61
- 0
test/layoutengine/standard-testcases/table-cell_table-units_mixed.xml View File

<?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>

+ 184
- 0
test/layoutengine/standard-testcases/table_keep-with-next_integers_1.xml View File

<?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>

+ 146
- 0
test/layoutengine/standard-testcases/table_keep-with-previous_integers_1.xml View File

<?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>

Loading…
Cancel
Save