Moved block-progression-unit into the fox: namespace. Implemented new extension properties: fox:orphan-content-limit and fox:widow-content-limit for fo:table and fo:list-block. See documentation for details. Bugfix in ElementListUtils.removeLegalBreaks (concerning box/glue combinations). Added a unit test to cover the problem. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@442282 13f79535-47bb-0310-9956-ffa450edef68pull/25/head
@@ -51,8 +51,11 @@ | |||
<code>http://xml.apache.org/fop/extensions</code> to the root element: | |||
</p> | |||
<source><![CDATA[<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" | |||
xmlns:fox="http://xml.apache.org/fop/extensions">]]></source> | |||
<note>Currently, no extensions are implemented in FOP Trunk which use the FOP extension namespace.</note> | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">]]></source> | |||
<note> | |||
Currently, no extension elements are implemented in FOP Trunk which use the | |||
FOP extension namespace. | |||
</note> | |||
</section> | |||
<section id="bookmarks"> | |||
<title>PDF Bookmarks</title> | |||
@@ -101,6 +104,21 @@ to following pages. Here is an example of FO code creating such a table-header:< | |||
</fo:table-row> | |||
</fo:table-header>]]></source--> | |||
</section> | |||
<section id="widow-orphan-content-limit"> | |||
<title>fox:orphan-content-limit and fox:widow-content-limit</title> | |||
<p> | |||
The two proprietary extension properties, fox:orphan-content-limit and | |||
fox:widow-content-limit, are used to improve the layout of list-blocks and tables. | |||
If you have a table with many entries, you don't want a single row to be left over | |||
on a page. You will want to make sure that at least two or three lines are kept | |||
together. The properties take an absolute length which specifies the area at the | |||
beginning (fox:widow-content-limit) or at the end (fox:orphan-content-limit) of a | |||
table or list-block. The properties are inherited and only have an effect on fo:table | |||
and fo:list-block. An example: fox:widow-content-limit="3 * 1.2em" would make sure | |||
the you'll have at least three lines (assuming line-height="1.2") together on a table | |||
or list-block. | |||
</p> | |||
</section> | |||
</section> | |||
</body> | |||
</document> |
@@ -682,10 +682,14 @@ public interface Constants { | |||
int PR_INDEX_CLASS = 249; | |||
/** Property constant - XSL 1.1 */ | |||
int PR_INDEX_KEY = 250; | |||
/** Property constant - Custom extension */ | |||
/** Property constant - FOP proprietary: Custom extension for line alignment */ | |||
int PR_X_BLOCK_PROGRESSION_UNIT = 251; | |||
/** Property constant - FOP proprietary: limit for widow content in lists and tables */ | |||
int PR_X_WIDOW_CONTENT_LIMIT = 252; | |||
/** Property constant - FOP proprietary: limit for orphan content in lists and tables */ | |||
int PR_X_ORPHAN_CONTENT_LIMIT = 253; | |||
/** Number of property constants defined */ | |||
int PROPERTY_COUNT = 251; | |||
int PROPERTY_COUNT = 253; | |||
// compound property constants | |||
@@ -24,6 +24,7 @@ import java.util.HashMap; | |||
import javax.xml.parsers.DocumentBuilderFactory; | |||
import javax.xml.parsers.ParserConfigurationException; | |||
import org.apache.fop.util.QName; | |||
import org.w3c.dom.DOMImplementation; | |||
/** | |||
@@ -88,6 +89,21 @@ public abstract class ElementMapping { | |||
"Cannot return default DOM implementation: " + e.getMessage()); | |||
} | |||
} | |||
/** @return the standard namespace prefix for this namespace or null if it is not known. */ | |||
public String getStandardPrefix() { | |||
return null; | |||
} | |||
/** | |||
* Indicates whether a particular attribute of the namespace is a property, i.e. the attribute | |||
* value should be converted to a property value. | |||
* @param attributeName the attribute name | |||
* @return true if the attribute should be converted to a property | |||
*/ | |||
public boolean isAttributeProperty(QName attributeName) { | |||
return false; | |||
} | |||
/** | |||
* Initializes the set of maker objects associated with this ElementMapping |
@@ -168,6 +168,16 @@ public class ElementMappingRegistry { | |||
} | |||
} | |||
/** | |||
* Returns an ElementMapping class for a namespace URI if there is one. | |||
* @param namespaceURI the namespace URI | |||
* @return the requested ElementMapping or null, if no ElementMapping for the namespace is | |||
* available. | |||
*/ | |||
public ElementMapping getElementMapping(String namespaceURI) { | |||
return (ElementMapping)this.namespaces.get(namespaceURI); | |||
} | |||
/** | |||
* Indicates whether a namespace is known to FOP. | |||
* @param namespaceURI the namespace URI |
@@ -22,6 +22,8 @@ package org.apache.fop.fo; | |||
// Java | |||
import java.util.HashMap; | |||
import org.apache.fop.util.QName; | |||
/** | |||
* Element mapping class for all XSL-FO elements. | |||
*/ | |||
@@ -136,6 +138,16 @@ public class FOElementMapping extends ElementMapping { | |||
} | |||
} | |||
/** @see org.apache.fop.fo.ElementMapping#getStandardPrefix() */ | |||
public String getStandardPrefix() { | |||
return "fo"; | |||
} | |||
/** @see org.apache.fop.fo.ElementMapping#isAttributeProperty(org.apache.fop.util.QName) */ | |||
public boolean isAttributeProperty(QName attributeName) { | |||
return true; //All XSL-FO attributes are to be converted to properties. | |||
} | |||
static class RootMaker extends ElementMapping.Maker { | |||
public FONode make(FONode parent) { | |||
return new org.apache.fop.fo.pagination.Root(parent); |
@@ -1456,11 +1456,11 @@ public final class FOPropertyMapping implements Constants { | |||
l.setDefault("auto"); | |||
addPropertyMaker("width", l); | |||
/*LF*/ // block-progression-unit (**CUSTOM EXTENSION**) | |||
/*LF*/ l = new LengthProperty.Maker(PR_X_BLOCK_PROGRESSION_UNIT); | |||
/*LF*/ l.setInherited(false); | |||
/*LF*/ l.setDefault("0pt"); | |||
/*LF*/ addPropertyMaker("block-progression-unit", l); | |||
// fox:block-progression-unit (**CUSTOM EXTENSION**) | |||
l = new LengthProperty.Maker(PR_X_BLOCK_PROGRESSION_UNIT); | |||
l.setInherited(false); | |||
l.setDefault("0pt"); | |||
addPropertyMaker("fox:block-progression-unit", l); | |||
} | |||
private void createBlockAndLineProperties() { | |||
@@ -1828,6 +1828,18 @@ public final class FOPropertyMapping implements Constants { | |||
m.setInherited(true); | |||
m.setDefault("2"); | |||
addPropertyMaker("widows", m); | |||
// fox:widow-content-limit | |||
m = new LengthProperty.Maker(PR_X_WIDOW_CONTENT_LIMIT); | |||
m.setInherited(true); | |||
m.setDefault("0pt"); | |||
addPropertyMaker("fox:widow-content-limit", m); | |||
// fox:orphan-content-limit | |||
m = new LengthProperty.Maker(PR_X_ORPHAN_CONTENT_LIMIT); | |||
m.setInherited(true); | |||
m.setDefault("0pt"); | |||
addPropertyMaker("fox:orphan-content-limit", m); | |||
} | |||
private void createLayoutProperties() { |
@@ -513,29 +513,20 @@ public abstract class FObj extends FONode implements Constants { | |||
/** | |||
* Adds a foreign attribute to this FObj. | |||
* @param uri the namespace URI | |||
* @param qName the fully qualified name | |||
* @param attributeName the attribute name as a QName instance | |||
* @param value the attribute value | |||
*/ | |||
public void addForeignAttribute(String uri, | |||
String qName, String value) { | |||
public void addForeignAttribute(QName attributeName, String value) { | |||
/* TODO: Handle this over FOP's property mechanism so we can use | |||
* inheritance. | |||
*/ | |||
if (qName == null) { | |||
throw new NullPointerException("Parameter qName must not be null"); | |||
if (attributeName == null) { | |||
throw new NullPointerException("Parameter attributeName must not be null"); | |||
} | |||
if (foreignAttributes == null) { | |||
foreignAttributes = new java.util.HashMap(); | |||
} | |||
String localName = qName; | |||
String prefix = null; | |||
int p = localName.indexOf(':'); | |||
if (p > 0) { | |||
prefix = localName.substring(0, p); | |||
localName = localName.substring(p + 1); | |||
} | |||
foreignAttributes.put(new QName(uri, prefix, localName), value); | |||
foreignAttributes.put(attributeName, value); | |||
} | |||
/** @return the map of foreign attributes */ |
@@ -39,6 +39,7 @@ import org.apache.fop.fo.properties.CommonRelativePosition; | |||
import org.apache.fop.fo.properties.CommonTextDecoration; | |||
import org.apache.fop.fo.properties.Property; | |||
import org.apache.fop.fo.properties.PropertyMaker; | |||
import org.apache.fop.util.QName; | |||
/** | |||
* Class containing the collection of properties for a given FObj. | |||
@@ -311,8 +312,18 @@ public abstract class PropertyList { | |||
if (attributeNS == null || attributeNS.length() == 0) { | |||
convertAttributeToProperty(attributes, attributeName, attributeValue); | |||
} else if (!factory.isNamespaceIgnored(attributeNS)) { | |||
if (factory.getElementMappingRegistry().isKnownNamespace(attributeNS)) { | |||
getFObj().addForeignAttribute(attributeNS, attributeName, attributeValue); | |||
ElementMapping mapping = factory.getElementMappingRegistry().getElementMapping( | |||
attributeNS); | |||
if (mapping != null) { | |||
QName attName = new QName(attributeNS, attributeName); | |||
if (mapping.isAttributeProperty(attName) | |||
&& mapping.getStandardPrefix() != null) { | |||
convertAttributeToProperty(attributes, | |||
mapping.getStandardPrefix() + ":" + attName.getLocalName(), | |||
attributeValue); | |||
} else { | |||
getFObj().addForeignAttribute(attName, attributeValue); | |||
} | |||
} else { | |||
handleInvalidProperty( | |||
"Error processing foreign attribute: " |
@@ -21,8 +21,10 @@ package org.apache.fop.fo.extensions; | |||
import org.apache.fop.fo.ElementMapping; | |||
import org.apache.fop.fo.UnknownXMLObj; | |||
import org.apache.fop.util.QName; | |||
import java.util.HashMap; | |||
import java.util.Set; | |||
/** | |||
* Element mapping for FOP's proprietary extension to XSL-FO. | |||
@@ -32,6 +34,15 @@ public class ExtensionElementMapping extends ElementMapping { | |||
/** The FOP extension namespace URI */ | |||
public static final String URI = "http://xmlgraphics.apache.org/fop/extensions"; | |||
private static final Set propertyAttributes = new java.util.HashSet(); | |||
static { | |||
//These are FOP's standard extension properties (fox:*) | |||
propertyAttributes.add("block-progression-unit"); | |||
propertyAttributes.add("widow-content-limit"); | |||
propertyAttributes.add("orphan-content-limit"); | |||
} | |||
/** | |||
* Constructor. | |||
*/ | |||
@@ -49,4 +60,18 @@ public class ExtensionElementMapping extends ElementMapping { | |||
foObjs.put("label", new UnknownXMLObj.Maker(URI)); | |||
} | |||
} | |||
/** @see org.apache.fop.fo.ElementMapping#getStandardPrefix() */ | |||
public String getStandardPrefix() { | |||
return "fox"; | |||
} | |||
/** @see org.apache.fop.fo.ElementMapping#isAttributeProperty(org.apache.fop.util.QName) */ | |||
public boolean isAttributeProperty(QName attributeName) { | |||
if (!URI.equals(attributeName.getNamespaceURI())) { | |||
throw new IllegalArgumentException("The namespace URIs don't match"); | |||
} | |||
return propertyAttributes.contains(attributeName.getLocalName()); | |||
} | |||
} |
@@ -86,6 +86,11 @@ public class SVGElementMapping extends ElementMapping { | |||
} | |||
} | |||
/** @see org.apache.fop.fo.ElementMapping#getStandardPrefix() */ | |||
public String getStandardPrefix() { | |||
return "svg"; | |||
} | |||
static class SVGMaker extends ElementMapping.Maker { | |||
public FONode make(FONode parent) { | |||
return new SVGObj(parent); |
@@ -55,6 +55,10 @@ public class ListBlock extends FObj { | |||
private Length provisionalLabelSeparation; | |||
// End of property values | |||
/** extension properties */ | |||
private Length widowContentLimit; | |||
private Length orphanContentLimit; | |||
// used for child node validation | |||
private boolean hasListItem = false; | |||
@@ -85,6 +89,10 @@ public class ListBlock extends FObj { | |||
PR_PROVISIONAL_DISTANCE_BETWEEN_STARTS).getLength(); | |||
provisionalLabelSeparation = pList.get( | |||
PR_PROVISIONAL_LABEL_SEPARATION).getLength(); | |||
//Bind extension properties | |||
widowContentLimit = pList.get(PR_X_WIDOW_CONTENT_LIMIT).getLength(); | |||
orphanContentLimit = pList.get(PR_X_ORPHAN_CONTENT_LIMIT).getLength(); | |||
} | |||
/** | |||
@@ -167,9 +175,17 @@ public class ListBlock extends FObj { | |||
return keepTogether; | |||
} | |||
/** | |||
* @return the "id" property. | |||
*/ | |||
/** @return the "fox:widow-content-limit" extension property */ | |||
public Length getWidowContentLimit() { | |||
return widowContentLimit; | |||
} | |||
/** @return the "fox:orphan-content-limit" extension property */ | |||
public Length getOrphanContentLimit() { | |||
return orphanContentLimit; | |||
} | |||
/** @return the "id" property. */ | |||
public String getId() { | |||
return id; | |||
} | |||
@@ -179,9 +195,7 @@ public class ListBlock extends FObj { | |||
return "list-block"; | |||
} | |||
/** | |||
* @see org.apache.fop.fo.FObj#getNameId() | |||
*/ | |||
/** @see org.apache.fop.fo.FObj#getNameId() */ | |||
public int getNameId() { | |||
return FO_LIST_BLOCK; | |||
} |
@@ -67,6 +67,10 @@ public class Table extends TableFObj { | |||
private int tableOmitFooterAtBreak; | |||
private int tableOmitHeaderAtBreak; | |||
private int writingMode; | |||
/** extension properties */ | |||
private Length widowContentLimit; | |||
private Length orphanContentLimit; | |||
private static final int MINCOLWIDTH = 10000; // 10pt | |||
@@ -126,6 +130,10 @@ public class Table extends TableFObj { | |||
tableOmitHeaderAtBreak = pList.get(PR_TABLE_OMIT_HEADER_AT_BREAK).getEnum(); | |||
writingMode = pList.get(PR_WRITING_MODE).getEnum(); | |||
super.bind(pList); | |||
//Bind extension properties | |||
widowContentLimit = pList.get(PR_X_WIDOW_CONTENT_LIMIT).getLength(); | |||
orphanContentLimit = pList.get(PR_X_ORPHAN_CONTENT_LIMIT).getLength(); | |||
if (borderCollapse != EN_SEPARATE) { | |||
//TODO Remove once the collapsing border is at least marginally working. | |||
@@ -449,10 +457,18 @@ public class Table extends TableFObj { | |||
public LengthPairProperty getBorderSeparation() { | |||
return borderSeparation; | |||
} | |||
/** @return the "fox:widow-content-limit" extension property */ | |||
public Length getWidowContentLimit() { | |||
return widowContentLimit; | |||
} | |||
/** | |||
* @return the "id" property. | |||
*/ | |||
/** @return the "fox:orphan-content-limit" extension property */ | |||
public Length getOrphanContentLimit() { | |||
return orphanContentLimit; | |||
} | |||
/** @return the "id" property. */ | |||
public String getId() { | |||
return id; | |||
} | |||
@@ -462,9 +478,7 @@ public class Table extends TableFObj { | |||
return "table"; | |||
} | |||
/** | |||
* @see org.apache.fop.fo.FObj#getNameId() | |||
*/ | |||
/** @see org.apache.fop.fo.FObj#getNameId() */ | |||
public int getNameId() { | |||
return FO_TABLE; | |||
} |
@@ -43,24 +43,20 @@ public class ElementListUtils { | |||
//Convert all penalties no break inhibitors | |||
if (breakPoss.getPenaltyValue() < KnuthPenalty.INFINITE) { | |||
breakPoss.setPenaltyValue(KnuthPenalty.INFINITE); | |||
/* | |||
i.set(new KnuthPenalty(penalty.getW(), KnuthPenalty.INFINITE, | |||
penalty.isFlagged(), penalty.getPosition(), penalty.isAuxiliary())); | |||
*/ | |||
} | |||
} else if (el.isGlue()) { | |||
i.previous(); | |||
if (el.isBox()) { | |||
i.next(); | |||
i.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, false, | |||
/*new Position(getTableLM())*/null, false)); | |||
null, false)); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Removes all legal breaks in an element list. A constraint can be specified to limit the | |||
* Removes legal breaks in an element list. A constraint can be specified to limit the | |||
* range in which the breaks are removed. Legal breaks occuring before at least | |||
* constraint.opt space is filled will be removed. | |||
* @param elements the element list | |||
@@ -68,29 +64,95 @@ public class ElementListUtils { | |||
* @return true if the opt constraint is bigger than the list contents | |||
*/ | |||
public static boolean removeLegalBreaks(LinkedList elements, MinOptMax constraint) { | |||
return removeLegalBreaks(elements, constraint.opt); | |||
} | |||
/** | |||
* Removes legal breaks in an element list. A constraint can be specified to limit the | |||
* range in which the breaks are removed. Legal breaks occuring before at least | |||
* constraint space is filled will be removed. | |||
* @param elements the element list | |||
* @param constraint value to restrict the range in which the breaks are removed. | |||
* @return true if the constraint is bigger than the list contents | |||
*/ | |||
public static boolean removeLegalBreaks(LinkedList elements, int constraint) { | |||
int len = 0; | |||
ListIterator i = elements.listIterator(); | |||
while (i.hasNext()) { | |||
KnuthElement el = (KnuthElement)i.next(); | |||
ListIterator iter = elements.listIterator(); | |||
while (iter.hasNext()) { | |||
ListElement el = (ListElement)iter.next(); | |||
if (el.isPenalty()) { | |||
KnuthPenalty penalty = (KnuthPenalty)el; | |||
//Convert all penalties no break inhibitors | |||
//Convert all penalties to break inhibitors | |||
if (penalty.getP() < KnuthPenalty.INFINITE) { | |||
iter.set(new KnuthPenalty(penalty.getW(), KnuthPenalty.INFINITE, | |||
penalty.isFlagged(), penalty.getPosition(), penalty.isAuxiliary())); | |||
} | |||
} else if (el.isGlue()) { | |||
KnuthGlue glue = (KnuthGlue)el; | |||
len += glue.getW(); | |||
iter.previous(); | |||
el = (ListElement)iter.previous(); | |||
iter.next(); | |||
if (el.isBox()) { | |||
iter.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, false, | |||
null, false)); | |||
} | |||
iter.next(); | |||
} else if (el instanceof BreakElement) { | |||
BreakElement breakEl = (BreakElement)el; | |||
if (breakEl.getPenaltyValue() < KnuthPenalty.INFINITE) { | |||
breakEl.setPenaltyValue(KnuthPenalty.INFINITE); | |||
} | |||
} else { | |||
KnuthElement kel = (KnuthElement)el; | |||
len += kel.getW(); | |||
} | |||
if (len >= constraint) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
/** | |||
* Removes legal breaks in an element list. A constraint can be specified to limit the | |||
* range in which the breaks are removed. Legal breaks within the space specified through the | |||
* constraint (starting from the end of the element list) will be removed. | |||
* @param elements the element list | |||
* @param constraint value to restrict the range in which the breaks are removed. | |||
* @return true if the constraint is bigger than the list contents | |||
*/ | |||
public static boolean removeLegalBreaksFromEnd(LinkedList elements, int constraint) { | |||
int len = 0; | |||
ListIterator i = elements.listIterator(elements.size()); | |||
while (i.hasPrevious()) { | |||
ListElement el = (ListElement)i.previous(); | |||
if (el.isPenalty()) { | |||
KnuthPenalty penalty = (KnuthPenalty)el; | |||
//Convert all penalties to break inhibitors | |||
if (penalty.getP() < KnuthPenalty.INFINITE) { | |||
i.set(new KnuthPenalty(penalty.getW(), KnuthPenalty.INFINITE, | |||
penalty.isFlagged(), penalty.getPosition(), penalty.isAuxiliary())); | |||
} | |||
} else if (el.isGlue()) { | |||
len += el.getW(); | |||
i.previous(); | |||
KnuthGlue glue = (KnuthGlue)el; | |||
len += glue.getW(); | |||
el = (ListElement)i.previous(); | |||
i.next(); | |||
if (el.isBox()) { | |||
i.next(); | |||
i.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, false, | |||
/*new Position(getTableLM())*/null, false)); | |||
null, false)); | |||
} | |||
} else if (el instanceof BreakElement) { | |||
BreakElement breakEl = (BreakElement)el; | |||
if (breakEl.getPenaltyValue() < KnuthPenalty.INFINITE) { | |||
breakEl.setPenaltyValue(KnuthPenalty.INFINITE); | |||
} | |||
} else { | |||
len += el.getW(); | |||
KnuthElement kel = (KnuthElement)el; | |||
len += kel.getW(); | |||
} | |||
if (len > constraint.opt) { | |||
if (len >= constraint) { | |||
return false; | |||
} | |||
} |
@@ -23,6 +23,7 @@ import org.apache.fop.fo.flow.ListBlock; | |||
import org.apache.fop.layoutmgr.BlockLevelLayoutManager; | |||
import org.apache.fop.layoutmgr.BlockStackingLayoutManager; | |||
import org.apache.fop.layoutmgr.ConditionalElementListener; | |||
import org.apache.fop.layoutmgr.ElementListUtils; | |||
import org.apache.fop.layoutmgr.LayoutManager; | |||
import org.apache.fop.layoutmgr.LayoutContext; | |||
import org.apache.fop.layoutmgr.PositionIterator; | |||
@@ -70,15 +71,6 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager | |||
} | |||
} | |||
/* | |||
private class SectionPosition extends LeafPosition { | |||
protected List list; | |||
protected SectionPosition(LayoutManager lm, int pos, List l) { | |||
super(lm, pos); | |||
list = l; | |||
} | |||
}*/ | |||
/** | |||
* Create a new list block layout manager. | |||
* @param node list-block to create the layout manager for | |||
@@ -117,7 +109,21 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager | |||
/** @see org.apache.fop.layoutmgr.BlockStackingLayoutManager */ | |||
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { | |||
resetSpaces(); | |||
return super.getNextKnuthElements(context, alignment); | |||
LinkedList returnList = super.getNextKnuthElements(context, alignment); | |||
//fox:widow-content-limit | |||
int widowRowLimit = getListBlockFO().getWidowContentLimit().getValue(); | |||
if (widowRowLimit != 0) { | |||
ElementListUtils.removeLegalBreaks(returnList, widowRowLimit); | |||
} | |||
//fox:orphan-content-limit | |||
int orphanRowLimit = getListBlockFO().getOrphanContentLimit().getValue(); | |||
if (orphanRowLimit != 0) { | |||
ElementListUtils.removeLegalBreaksFromEnd(returnList, orphanRowLimit); | |||
} | |||
return returnList; | |||
} | |||
/** @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(java.util.List, int) */ |
@@ -223,8 +223,6 @@ public class TableContentLayoutManager implements PercentBaseContext { | |||
} | |||
} else { | |||
if (!firstBreakBeforeServed) { | |||
//returnList.add(new KnuthPenalty(0, -KnuthPenalty.INFINITE, | |||
// false, rowFO.getBreakBefore(), new Position(getTableLM()), true)); | |||
returnList.add(new BreakElement(new Position(getTableLM()), | |||
0, -KnuthPenalty.INFINITE, rowFO.getBreakBefore(), context)); | |||
iter.backToPreviousRow(); | |||
@@ -291,6 +289,18 @@ public class TableContentLayoutManager implements PercentBaseContext { | |||
} | |||
} | |||
} | |||
//fox:widow-content-limit | |||
int widowContentLimit = getTableLM().getTable().getWidowContentLimit().getValue(); | |||
if (widowContentLimit != 0 && bodyType == TableRowIterator.BODY) { | |||
ElementListUtils.removeLegalBreaks(returnList, widowContentLimit); | |||
} | |||
//fox:orphan-content-limit | |||
int orphanContentLimit = getTableLM().getTable().getOrphanContentLimit().getValue(); | |||
if (orphanContentLimit != 0 && bodyType == TableRowIterator.BODY) { | |||
ElementListUtils.removeLegalBreaksFromEnd(returnList, orphanContentLimit); | |||
} | |||
return returnList; | |||
} | |||
@@ -28,6 +28,10 @@ | |||
<changes> | |||
<release version="FOP Trunk"> | |||
<action context="Code" dev="JM" type="add"> | |||
Extension properties fox:orphan-content-limit and fox:widow-content-limit which | |||
help with list-block and table layout. See the documentation for details. | |||
</action> | |||
<action context="Code" dev="JM" type="add"> | |||
Configuration option in the Java2D-based renderers that allows to disable the default | |||
white background in order to produce bitmap output with transparency. |
@@ -0,0 +1,147 @@ | |||
/* | |||
* 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$ */ | |||
package org.apache.fop.util; | |||
import java.util.LinkedList; | |||
import org.apache.fop.layoutmgr.ElementListUtils; | |||
import org.apache.fop.layoutmgr.KnuthBox; | |||
import org.apache.fop.layoutmgr.KnuthElement; | |||
import org.apache.fop.layoutmgr.KnuthGlue; | |||
import org.apache.fop.layoutmgr.KnuthPenalty; | |||
import junit.framework.TestCase; | |||
/** | |||
* Test class for ElementListUtils. | |||
*/ | |||
public class ElementListUtilsTestCase extends TestCase { | |||
/** | |||
* Tests ElementListUtils.removeLegalBreaks(). | |||
* @throws Exception if the test fails | |||
*/ | |||
public void testRemoveElementPenalty1() throws Exception { | |||
LinkedList lst = new LinkedList(); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, 0, false, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, 200, false, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, 0, false, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, false)); | |||
lst.add(new KnuthGlue(0, Integer.MAX_VALUE, 0, null, false)); | |||
lst.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false)); | |||
boolean res = ElementListUtils.removeLegalBreaks(lst, 9000); | |||
assertFalse(res); | |||
assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(1)).getP()); | |||
assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(3)).getP()); | |||
assertEquals(0, ((KnuthPenalty)lst.get(5)).getP()); | |||
} | |||
/** | |||
* Tests ElementListUtils.removeLegalBreaks(). | |||
* @throws Exception if the test fails | |||
*/ | |||
public void testRemoveElementPenalty2() throws Exception { | |||
LinkedList lst = new LinkedList(); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthGlue(0, 0, 0, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthGlue(0, 0, 0, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthGlue(0, 0, 0, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, false)); | |||
lst.add(new KnuthGlue(0, Integer.MAX_VALUE, 0, null, false)); | |||
lst.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false)); | |||
boolean res = ElementListUtils.removeLegalBreaks(lst, 9000); | |||
assertFalse(res); | |||
//Must insert an INFINITE penalty | |||
assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(1)).getP()); | |||
assertEquals(0, ((KnuthGlue)lst.get(2)).getW()); | |||
assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(4)).getP()); | |||
assertEquals(0, ((KnuthGlue)lst.get(5)).getW()); | |||
assertEquals(0, ((KnuthGlue)lst.get(7)).getW()); | |||
} | |||
/** | |||
* Tests ElementListUtils.removeLegalBreaksFromEnd(). | |||
* @throws Exception if the test fails | |||
*/ | |||
public void testRemoveElementFromEndPenalty1() throws Exception { | |||
LinkedList lst = new LinkedList(); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, 0, false, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, 200, false, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, 0, false, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, false)); | |||
lst.add(new KnuthGlue(0, Integer.MAX_VALUE, 0, null, false)); | |||
lst.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false)); | |||
boolean res = ElementListUtils.removeLegalBreaksFromEnd(lst, 9000); | |||
assertFalse(res); | |||
assertEquals(0, ((KnuthPenalty)lst.get(1)).getP()); | |||
assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(3)).getP()); | |||
assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(5)).getP()); | |||
} | |||
/** | |||
* Tests ElementListUtils.removeLegalBreaksFromEnd(). | |||
* @throws Exception if the test fails | |||
*/ | |||
public void testRemoveElementFromEndPenalty2() throws Exception { | |||
LinkedList lst = new LinkedList(); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, 0, false, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, 200, false, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthGlue(0, 0, 0, null, false)); | |||
lst.add(new KnuthBox(4000, null, false)); | |||
lst.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, false)); | |||
lst.add(new KnuthGlue(0, Integer.MAX_VALUE, 0, null, false)); | |||
lst.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false)); | |||
boolean res = ElementListUtils.removeLegalBreaksFromEnd(lst, 9000); | |||
assertFalse(res); | |||
//Must insert an INFINITE penalty | |||
assertEquals(0, ((KnuthPenalty)lst.get(1)).getP()); | |||
assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(3)).getP()); | |||
assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(5)).getP()); | |||
assertEquals(0, ((KnuthGlue)lst.get(6)).getW()); | |||
} | |||
} |
@@ -0,0 +1,123 @@ | |||
<?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 effect of the proprietary fox:orphan-content-limit property. | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"> | |||
<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" widows="0" orphans="0"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block space-before="5in - (4 * 1.2em)" space-before.conditionality="retain"/> | |||
<fo:list-block | |||
provisional-distance-between-starts="12pt" provisional-label-separation="5pt" | |||
fox:orphan-content-limit="3 * 1.2em"> | |||
<fo:list-item> | |||
<fo:list-item-label end-indent="label-end()"> | |||
<fo:block>•</fo:block> | |||
</fo:list-item-label> | |||
<fo:list-item-body start-indent="body-start()"> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum, viverra ut, aliquam porttitor, convallis id, risus. Fusce malesuada nunc nec orci.</fo:block> | |||
</fo:list-item-body> | |||
</fo:list-item> | |||
<fo:list-item> | |||
<fo:list-item-label end-indent="label-end()"> | |||
<fo:block>•</fo:block> | |||
</fo:list-item-label> | |||
<fo:list-item-body start-indent="body-start()"> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum.</fo:block> | |||
</fo:list-item-body> | |||
</fo:list-item> | |||
</fo:list-block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
<!-- the second page-sequence is without the extension property and just for reference. --> | |||
<fo:page-sequence master-reference="normal" white-space-collapse="true" widows="0" orphans="0"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block space-before="5in - (4 * 1.2em)" space-before.conditionality="retain"/> | |||
<fo:list-block | |||
provisional-distance-between-starts="12pt" provisional-label-separation="5pt"> | |||
<fo:list-item> | |||
<fo:list-item-label end-indent="label-end()"> | |||
<fo:block>•</fo:block> | |||
</fo:list-item-label> | |||
<fo:list-item-body start-indent="body-start()"> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum, viverra ut, aliquam porttitor, convallis id, risus. Fusce malesuada nunc nec orci.</fo:block> | |||
</fo:list-item-body> | |||
</fo:list-item> | |||
<fo:list-item> | |||
<fo:list-item-label end-indent="label-end()"> | |||
<fo:block>•</fo:block> | |||
</fo:list-item-label> | |||
<fo:list-item-body start-indent="body-start()"> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum.</fo:block> | |||
</fo:list-item-body> | |||
</fo:list-item> | |||
</fo:list-block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<element-list category="breaker" index="0"> | |||
<box w="0"/> | |||
<penalty w="0" p="INF"/> | |||
<glue w="302400" y="0" z="0"/> | |||
<box w="0"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<skip>3</skip> | |||
</element-list> | |||
<element-list category="breaker" index="1"> | |||
<box w="0"/> | |||
<penalty w="0" p="INF"/> | |||
<glue w="302400" y="0" z="0"/> | |||
<box w="0"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<skip>3</skip> | |||
</element-list> | |||
</checks> | |||
</testcase> |
@@ -0,0 +1,123 @@ | |||
<?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 effect of the proprietary fox:widow-content-limit property. | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"> | |||
<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" widows="0" orphans="0"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block space-before="5in - (2 * 1.2em)" space-before.conditionality="retain"/> | |||
<fo:list-block | |||
provisional-distance-between-starts="12pt" provisional-label-separation="5pt" | |||
fox:widow-content-limit="3 * 1.2em"> | |||
<fo:list-item> | |||
<fo:list-item-label end-indent="label-end()"> | |||
<fo:block>•</fo:block> | |||
</fo:list-item-label> | |||
<fo:list-item-body start-indent="body-start()"> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum.</fo:block> | |||
</fo:list-item-body> | |||
</fo:list-item> | |||
<fo:list-item> | |||
<fo:list-item-label end-indent="label-end()"> | |||
<fo:block>•</fo:block> | |||
</fo:list-item-label> | |||
<fo:list-item-body start-indent="body-start()"> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum, viverra ut, aliquam porttitor, convallis id, risus. Fusce malesuada nunc nec orci.</fo:block> | |||
</fo:list-item-body> | |||
</fo:list-item> | |||
</fo:list-block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
<!-- the second page-sequence is without the extension property and just for reference. --> | |||
<fo:page-sequence master-reference="normal" white-space-collapse="true" widows="0" orphans="0"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block space-before="5in - (2 * 1.2em)" space-before.conditionality="retain"/> | |||
<fo:list-block | |||
provisional-distance-between-starts="12pt" provisional-label-separation="5pt"> | |||
<fo:list-item> | |||
<fo:list-item-label end-indent="label-end()"> | |||
<fo:block>•</fo:block> | |||
</fo:list-item-label> | |||
<fo:list-item-body start-indent="body-start()"> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum.</fo:block> | |||
</fo:list-item-body> | |||
</fo:list-item> | |||
<fo:list-item> | |||
<fo:list-item-label end-indent="label-end()"> | |||
<fo:block>•</fo:block> | |||
</fo:list-item-label> | |||
<fo:list-item-body start-indent="body-start()"> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum, viverra ut, aliquam porttitor, convallis id, risus. Fusce malesuada nunc nec orci.</fo:block> | |||
</fo:list-item-body> | |||
</fo:list-item> | |||
</fo:list-block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<element-list category="breaker" index="0"> | |||
<box w="0"/> | |||
<penalty w="0" p="INF"/> | |||
<glue w="331200" y="0" z="0"/> | |||
<box w="0"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<skip>3</skip> | |||
</element-list> | |||
<element-list category="breaker" index="1"> | |||
<box w="0"/> | |||
<penalty w="0" p="INF"/> | |||
<glue w="331200" y="0" z="0"/> | |||
<box w="0"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<skip>3</skip> | |||
</element-list> | |||
</checks> | |||
</testcase> |
@@ -0,0 +1,133 @@ | |||
<?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 effect of the proprietary fox:orphan-content-limit property. | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"> | |||
<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" widows="0" orphans="0"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block space-before="5in - (4 * 1.2em)" space-before.conditionality="retain"/> | |||
<fo:table table-layout="fixed" width="100%" border-collapse="separate" | |||
fox:orphan-content-limit="3 * 1.2em"> | |||
<fo:table-column column-width="proportional-column-width(1)"/> | |||
<fo:table-column column-width="proportional-column-width(3)"/> | |||
<fo:table-body> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 1</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum, viverra ut, aliquam porttitor, convallis id, risus. Fusce malesuada nunc nec orci.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 2</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
</fo:table-body> | |||
</fo:table> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
<!-- the second page-sequence is without the extension property and just for reference. --> | |||
<fo:page-sequence master-reference="normal" white-space-collapse="true" widows="0" orphans="0"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block space-before="5in - (4 * 1.2em)" space-before.conditionality="retain"/> | |||
<fo:table table-layout="fixed" width="100%" border-collapse="separate"> | |||
<fo:table-column column-width="proportional-column-width(1)"/> | |||
<fo:table-column column-width="proportional-column-width(3)"/> | |||
<fo:table-body> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 1</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum, viverra ut, aliquam porttitor, convallis id, risus. Fusce malesuada nunc nec orci.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 2</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
</fo:table-body> | |||
</fo:table> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<element-list category="breaker" index="0"> | |||
<box w="0"/> | |||
<penalty w="0" p="INF"/> | |||
<glue w="302400" y="0" z="0"/> | |||
<box w="0"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<skip>3</skip> | |||
</element-list> | |||
<element-list category="breaker" index="1"> | |||
<box w="0"/> | |||
<penalty w="0" p="INF"/> | |||
<glue w="302400" y="0" z="0"/> | |||
<box w="0"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<skip>3</skip> | |||
</element-list> | |||
</checks> | |||
</testcase> |
@@ -0,0 +1,133 @@ | |||
<?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 effect of the proprietary fox:widow-content-limit property. | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"> | |||
<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" widows="0" orphans="0"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block space-before="5in - (2 * 1.2em)" space-before.conditionality="retain"/> | |||
<fo:table table-layout="fixed" width="100%" border-collapse="separate" | |||
fox:widow-content-limit="3 * 1.2em"> | |||
<fo:table-column column-width="proportional-column-width(1)"/> | |||
<fo:table-column column-width="proportional-column-width(3)"/> | |||
<fo:table-body> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 1</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 2</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum, viverra ut, aliquam porttitor, convallis id, risus. Fusce malesuada nunc nec orci.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
</fo:table-body> | |||
</fo:table> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
<!-- the second page-sequence is without the extension property and just for reference. --> | |||
<fo:page-sequence master-reference="normal" white-space-collapse="true" widows="0" orphans="0"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block space-before="5in - (2 * 1.2em)" space-before.conditionality="retain"/> | |||
<fo:table table-layout="fixed" width="100%" border-collapse="separate"> | |||
<fo:table-column column-width="proportional-column-width(1)"/> | |||
<fo:table-column column-width="proportional-column-width(3)"/> | |||
<fo:table-body> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 1</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 2</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec felis ipsum, viverra ut, aliquam porttitor, convallis id, risus. Fusce malesuada nunc nec orci.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
</fo:table-body> | |||
</fo:table> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<element-list category="breaker" index="0"> | |||
<box w="0"/> | |||
<penalty w="0" p="INF"/> | |||
<glue w="331200" y="0" z="0"/> | |||
<box w="0"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<skip>3</skip> | |||
</element-list> | |||
<element-list category="breaker" index="1"> | |||
<box w="0"/> | |||
<penalty w="0" p="INF"/> | |||
<glue w="331200" y="0" z="0"/> | |||
<box w="0"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<skip>3</skip> | |||
</element-list> | |||
</checks> | |||
</testcase> |
@@ -0,0 +1,97 @@ | |||
<?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 effect of the proprietary fox:widow-content-limit property. | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"> | |||
<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" widows="0" orphans="0"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block space-before="5in - (2 * 1.2em)" space-before.conditionality="retain"/> | |||
<fo:table table-layout="fixed" width="100%" border-collapse="separate" | |||
fox:widow-content-limit="3 * 1.2em"> | |||
<fo:table-column column-width="proportional-column-width(1)"/> | |||
<fo:table-column column-width="proportional-column-width(3)"/> | |||
<fo:table-body> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 1</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 2</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 3</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
<fo:table-row> | |||
<fo:table-cell> | |||
<fo:block>row 4</fo:block> | |||
</fo:table-cell> | |||
<fo:table-cell> | |||
<fo:block>Lorem ipsum dolor sit amet.</fo:block> | |||
</fo:table-cell> | |||
</fo:table-row> | |||
</fo:table-body> | |||
</fo:table> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<element-list category="breaker"> | |||
<box w="0"/> | |||
<penalty w="0" p="INF"/> | |||
<glue w="331200" y="0" z="0"/> | |||
<box w="0"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="INF"/> | |||
<box w="14400"/> | |||
<penalty w="0" p="0"/> | |||
<box w="14400"/> | |||
<skip>3</skip> | |||
</element-list> | |||
</checks> | |||
</testcase> |