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
<code>http://xml.apache.org/fop/extensions</code> to the root element: | <code>http://xml.apache.org/fop/extensions</code> to the root element: | ||||
</p> | </p> | ||||
<source><![CDATA[<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" | <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> | ||||
<section id="bookmarks"> | <section id="bookmarks"> | ||||
<title>PDF Bookmarks</title> | <title>PDF Bookmarks</title> | ||||
</fo:table-row> | </fo:table-row> | ||||
</fo:table-header>]]></source--> | </fo:table-header>]]></source--> | ||||
</section> | </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> | </section> | ||||
</body> | </body> | ||||
</document> | </document> |
int PR_INDEX_CLASS = 249; | int PR_INDEX_CLASS = 249; | ||||
/** Property constant - XSL 1.1 */ | /** Property constant - XSL 1.1 */ | ||||
int PR_INDEX_KEY = 250; | 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; | 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 */ | /** Number of property constants defined */ | ||||
int PROPERTY_COUNT = 251; | |||||
int PROPERTY_COUNT = 253; | |||||
// compound property constants | // compound property constants | ||||
import javax.xml.parsers.DocumentBuilderFactory; | import javax.xml.parsers.DocumentBuilderFactory; | ||||
import javax.xml.parsers.ParserConfigurationException; | import javax.xml.parsers.ParserConfigurationException; | ||||
import org.apache.fop.util.QName; | |||||
import org.w3c.dom.DOMImplementation; | import org.w3c.dom.DOMImplementation; | ||||
/** | /** | ||||
"Cannot return default DOM implementation: " + e.getMessage()); | "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 | * Initializes the set of maker objects associated with this ElementMapping |
} | } | ||||
} | } | ||||
/** | |||||
* 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. | * Indicates whether a namespace is known to FOP. | ||||
* @param namespaceURI the namespace URI | * @param namespaceURI the namespace URI |
// Java | // Java | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import org.apache.fop.util.QName; | |||||
/** | /** | ||||
* Element mapping class for all XSL-FO elements. | * Element mapping class for all XSL-FO elements. | ||||
*/ | */ | ||||
} | } | ||||
} | } | ||||
/** @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 { | static class RootMaker extends ElementMapping.Maker { | ||||
public FONode make(FONode parent) { | public FONode make(FONode parent) { | ||||
return new org.apache.fop.fo.pagination.Root(parent); | return new org.apache.fop.fo.pagination.Root(parent); |
l.setDefault("auto"); | l.setDefault("auto"); | ||||
addPropertyMaker("width", l); | 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() { | private void createBlockAndLineProperties() { | ||||
m.setInherited(true); | m.setInherited(true); | ||||
m.setDefault("2"); | m.setDefault("2"); | ||||
addPropertyMaker("widows", m); | 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() { | private void createLayoutProperties() { |
/** | /** | ||||
* Adds a foreign attribute to this FObj. | * 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 | * @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 | /* TODO: Handle this over FOP's property mechanism so we can use | ||||
* inheritance. | * 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) { | if (foreignAttributes == null) { | ||||
foreignAttributes = new java.util.HashMap(); | 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 */ | /** @return the map of foreign attributes */ |
import org.apache.fop.fo.properties.CommonTextDecoration; | import org.apache.fop.fo.properties.CommonTextDecoration; | ||||
import org.apache.fop.fo.properties.Property; | import org.apache.fop.fo.properties.Property; | ||||
import org.apache.fop.fo.properties.PropertyMaker; | import org.apache.fop.fo.properties.PropertyMaker; | ||||
import org.apache.fop.util.QName; | |||||
/** | /** | ||||
* Class containing the collection of properties for a given FObj. | * Class containing the collection of properties for a given FObj. | ||||
if (attributeNS == null || attributeNS.length() == 0) { | if (attributeNS == null || attributeNS.length() == 0) { | ||||
convertAttributeToProperty(attributes, attributeName, attributeValue); | convertAttributeToProperty(attributes, attributeName, attributeValue); | ||||
} else if (!factory.isNamespaceIgnored(attributeNS)) { | } 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 { | } else { | ||||
handleInvalidProperty( | handleInvalidProperty( | ||||
"Error processing foreign attribute: " | "Error processing foreign attribute: " |
import org.apache.fop.fo.ElementMapping; | import org.apache.fop.fo.ElementMapping; | ||||
import org.apache.fop.fo.UnknownXMLObj; | import org.apache.fop.fo.UnknownXMLObj; | ||||
import org.apache.fop.util.QName; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Set; | |||||
/** | /** | ||||
* Element mapping for FOP's proprietary extension to XSL-FO. | * Element mapping for FOP's proprietary extension to XSL-FO. | ||||
/** The FOP extension namespace URI */ | /** The FOP extension namespace URI */ | ||||
public static final String URI = "http://xmlgraphics.apache.org/fop/extensions"; | 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. | * Constructor. | ||||
*/ | */ | ||||
foObjs.put("label", new UnknownXMLObj.Maker(URI)); | 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()); | |||||
} | |||||
} | } |
} | } | ||||
} | } | ||||
/** @see org.apache.fop.fo.ElementMapping#getStandardPrefix() */ | |||||
public String getStandardPrefix() { | |||||
return "svg"; | |||||
} | |||||
static class SVGMaker extends ElementMapping.Maker { | static class SVGMaker extends ElementMapping.Maker { | ||||
public FONode make(FONode parent) { | public FONode make(FONode parent) { | ||||
return new SVGObj(parent); | return new SVGObj(parent); |
private Length provisionalLabelSeparation; | private Length provisionalLabelSeparation; | ||||
// End of property values | // End of property values | ||||
/** extension properties */ | |||||
private Length widowContentLimit; | |||||
private Length orphanContentLimit; | |||||
// used for child node validation | // used for child node validation | ||||
private boolean hasListItem = false; | private boolean hasListItem = false; | ||||
PR_PROVISIONAL_DISTANCE_BETWEEN_STARTS).getLength(); | PR_PROVISIONAL_DISTANCE_BETWEEN_STARTS).getLength(); | ||||
provisionalLabelSeparation = pList.get( | provisionalLabelSeparation = pList.get( | ||||
PR_PROVISIONAL_LABEL_SEPARATION).getLength(); | 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(); | |||||
} | } | ||||
/** | /** | ||||
return keepTogether; | 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() { | public String getId() { | ||||
return id; | return id; | ||||
} | } | ||||
return "list-block"; | return "list-block"; | ||||
} | } | ||||
/** | |||||
* @see org.apache.fop.fo.FObj#getNameId() | |||||
*/ | |||||
/** @see org.apache.fop.fo.FObj#getNameId() */ | |||||
public int getNameId() { | public int getNameId() { | ||||
return FO_LIST_BLOCK; | return FO_LIST_BLOCK; | ||||
} | } |
private int tableOmitFooterAtBreak; | private int tableOmitFooterAtBreak; | ||||
private int tableOmitHeaderAtBreak; | private int tableOmitHeaderAtBreak; | ||||
private int writingMode; | private int writingMode; | ||||
/** extension properties */ | |||||
private Length widowContentLimit; | |||||
private Length orphanContentLimit; | |||||
private static final int MINCOLWIDTH = 10000; // 10pt | private static final int MINCOLWIDTH = 10000; // 10pt | ||||
tableOmitHeaderAtBreak = pList.get(PR_TABLE_OMIT_HEADER_AT_BREAK).getEnum(); | tableOmitHeaderAtBreak = pList.get(PR_TABLE_OMIT_HEADER_AT_BREAK).getEnum(); | ||||
writingMode = pList.get(PR_WRITING_MODE).getEnum(); | writingMode = pList.get(PR_WRITING_MODE).getEnum(); | ||||
super.bind(pList); | 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) { | if (borderCollapse != EN_SEPARATE) { | ||||
//TODO Remove once the collapsing border is at least marginally working. | //TODO Remove once the collapsing border is at least marginally working. | ||||
public LengthPairProperty getBorderSeparation() { | public LengthPairProperty getBorderSeparation() { | ||||
return borderSeparation; | 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() { | public String getId() { | ||||
return id; | return id; | ||||
} | } | ||||
return "table"; | return "table"; | ||||
} | } | ||||
/** | |||||
* @see org.apache.fop.fo.FObj#getNameId() | |||||
*/ | |||||
/** @see org.apache.fop.fo.FObj#getNameId() */ | |||||
public int getNameId() { | public int getNameId() { | ||||
return FO_TABLE; | return FO_TABLE; | ||||
} | } |
//Convert all penalties no break inhibitors | //Convert all penalties no break inhibitors | ||||
if (breakPoss.getPenaltyValue() < KnuthPenalty.INFINITE) { | if (breakPoss.getPenaltyValue() < KnuthPenalty.INFINITE) { | ||||
breakPoss.setPenaltyValue(KnuthPenalty.INFINITE); | breakPoss.setPenaltyValue(KnuthPenalty.INFINITE); | ||||
/* | |||||
i.set(new KnuthPenalty(penalty.getW(), KnuthPenalty.INFINITE, | |||||
penalty.isFlagged(), penalty.getPosition(), penalty.isAuxiliary())); | |||||
*/ | |||||
} | } | ||||
} else if (el.isGlue()) { | } else if (el.isGlue()) { | ||||
i.previous(); | i.previous(); | ||||
if (el.isBox()) { | if (el.isBox()) { | ||||
i.next(); | i.next(); | ||||
i.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, false, | 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 | * range in which the breaks are removed. Legal breaks occuring before at least | ||||
* constraint.opt space is filled will be removed. | * constraint.opt space is filled will be removed. | ||||
* @param elements the element list | * @param elements the element list | ||||
* @return true if the opt constraint is bigger than the list contents | * @return true if the opt constraint is bigger than the list contents | ||||
*/ | */ | ||||
public static boolean removeLegalBreaks(LinkedList elements, MinOptMax constraint) { | 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; | 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()) { | if (el.isPenalty()) { | ||||
KnuthPenalty penalty = (KnuthPenalty)el; | 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) { | if (penalty.getP() < KnuthPenalty.INFINITE) { | ||||
i.set(new KnuthPenalty(penalty.getW(), KnuthPenalty.INFINITE, | i.set(new KnuthPenalty(penalty.getW(), KnuthPenalty.INFINITE, | ||||
penalty.isFlagged(), penalty.getPosition(), penalty.isAuxiliary())); | penalty.isFlagged(), penalty.getPosition(), penalty.isAuxiliary())); | ||||
} | } | ||||
} else if (el.isGlue()) { | } 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()) { | if (el.isBox()) { | ||||
i.next(); | |||||
i.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, false, | 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 { | } else { | ||||
len += el.getW(); | |||||
KnuthElement kel = (KnuthElement)el; | |||||
len += kel.getW(); | |||||
} | } | ||||
if (len > constraint.opt) { | |||||
if (len >= constraint) { | |||||
return false; | return false; | ||||
} | } | ||||
} | } |
import org.apache.fop.layoutmgr.BlockLevelLayoutManager; | import org.apache.fop.layoutmgr.BlockLevelLayoutManager; | ||||
import org.apache.fop.layoutmgr.BlockStackingLayoutManager; | import org.apache.fop.layoutmgr.BlockStackingLayoutManager; | ||||
import org.apache.fop.layoutmgr.ConditionalElementListener; | import org.apache.fop.layoutmgr.ConditionalElementListener; | ||||
import org.apache.fop.layoutmgr.ElementListUtils; | |||||
import org.apache.fop.layoutmgr.LayoutManager; | import org.apache.fop.layoutmgr.LayoutManager; | ||||
import org.apache.fop.layoutmgr.LayoutContext; | import org.apache.fop.layoutmgr.LayoutContext; | ||||
import org.apache.fop.layoutmgr.PositionIterator; | import org.apache.fop.layoutmgr.PositionIterator; | ||||
} | } | ||||
} | } | ||||
/* | |||||
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. | * Create a new list block layout manager. | ||||
* @param node list-block to create the layout manager for | * @param node list-block to create the layout manager for | ||||
/** @see org.apache.fop.layoutmgr.BlockStackingLayoutManager */ | /** @see org.apache.fop.layoutmgr.BlockStackingLayoutManager */ | ||||
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { | public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { | ||||
resetSpaces(); | 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) */ | /** @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(java.util.List, int) */ |
} | } | ||||
} else { | } else { | ||||
if (!firstBreakBeforeServed) { | if (!firstBreakBeforeServed) { | ||||
//returnList.add(new KnuthPenalty(0, -KnuthPenalty.INFINITE, | |||||
// false, rowFO.getBreakBefore(), new Position(getTableLM()), true)); | |||||
returnList.add(new BreakElement(new Position(getTableLM()), | returnList.add(new BreakElement(new Position(getTableLM()), | ||||
0, -KnuthPenalty.INFINITE, rowFO.getBreakBefore(), context)); | 0, -KnuthPenalty.INFINITE, rowFO.getBreakBefore(), context)); | ||||
iter.backToPreviousRow(); | iter.backToPreviousRow(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
//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; | return returnList; | ||||
} | } | ||||
<changes> | <changes> | ||||
<release version="FOP Trunk"> | <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"> | <action context="Code" dev="JM" type="add"> | ||||
Configuration option in the Java2D-based renderers that allows to disable the default | Configuration option in the Java2D-based renderers that allows to disable the default | ||||
white background in order to produce bitmap output with transparency. | white background in order to produce bitmap output with transparency. |
/* | |||||
* 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()); | |||||
} | |||||
} |
<?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> |
<?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> |
<?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> |
<?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> |
<?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> |