aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Cumiskey <acumiskey@apache.org>2008-06-09 11:24:36 +0000
committerAdrian Cumiskey <acumiskey@apache.org>2008-06-09 11:24:36 +0000
commit7d7910f72b18167d0f5cbc441a99aeeaa97e0838 (patch)
treef694df94a60f6f5de5448238060e48fbf0364f51
parent1dbe17e5b2edc0639f92cbb7644107dae8f6ad7e (diff)
downloadxmlgraphics-fop-7d7910f72b18167d0f5cbc441a99aeeaa97e0838.tar.gz
xmlgraphics-fop-7d7910f72b18167d0f5cbc441a99aeeaa97e0838.zip
Merged revisions 662417,662807,662991,663045,663493,664347,664349-664350 via svnmerge from
https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk ........ r662417 | jeremias | 2008-06-02 13:50:55 +0100 (Mon, 02 Jun 2008) | 1 line Integer keeps inside multi-line blocks and in between block-paragraphs. ........ r662807 | jeremias | 2008-06-03 15:13:27 +0100 (Tue, 03 Jun 2008) | 3 lines Bugzilla #45115: Added a PCL-specific extension attribute on simple-page-master for controlling the simplex/duplex mode. Submitted by: Martin Edge <Martin.Edge.at.asmorphic.net.au> ........ r662991 | jeremias | 2008-06-04 07:10:37 +0100 (Wed, 04 Jun 2008) | 1 line ApacheCon EU 2008 is long over. ........ r663045 | adelmelle | 2008-06-04 10:53:15 +0100 (Wed, 04 Jun 2008) | 1 line Minor cleanup: remove spurious white-space ........ r663493 | jeremias | 2008-06-05 08:41:06 +0100 (Thu, 05 Jun 2008) | 1 line Restored lost overflow warning in static-content. ........ r664347 | adelmelle | 2008-06-07 15:49:42 +0100 (Sat, 07 Jun 2008) | 5 lines Extended behavior of preserved linefeeds to codepoints representing mandatory breaks in Unicode UAX#14: - NEXT LINE (U+0085) - LINE SEPARATOR (U+2028) - PARAGRAPH SEPARATOR (U+2029) ........ r664349 | adelmelle | 2008-06-07 15:54:13 +0100 (Sat, 07 Jun 2008) | 1 line Minor cleanup: remove unneeded constant ........ r664350 | adelmelle | 2008-06-07 16:09:42 +0100 (Sat, 07 Jun 2008) | 1 line Improve code-readability; add some clarifying comments ........ git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@664680 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/documentation/content/xdocs/trunk/output.xml25
-rw-r--r--src/documentation/skinconf.xml2
-rw-r--r--src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java6
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java31
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java31
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLGenerator.java13
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRenderer.java11
-rw-r--r--src/java/org/apache/fop/text/linebreak/LineBreakStatus.java139
-rw-r--r--src/java/org/apache/fop/util/CharUtilities.java49
-rw-r--r--status.xml4
-rw-r--r--test/layoutengine/standard-testcases/block_keep-together_integers_1.xml17
-rw-r--r--test/layoutengine/standard-testcases/block_uax14_explicit-breaks.xml64
12 files changed, 288 insertions, 104 deletions
diff --git a/src/documentation/content/xdocs/trunk/output.xml b/src/documentation/content/xdocs/trunk/output.xml
index b485cdb21..d03041f19 100644
--- a/src/documentation/content/xdocs/trunk/output.xml
+++ b/src/documentation/content/xdocs/trunk/output.xml
@@ -422,6 +422,31 @@ out = proc.getOutputStream();]]></source>
Consult the technical reference for your printer for all available values.
</p>
</section>
+ <section id="pcl-duplex-mode">
+ <title>Page Duplex Mode</title>
+ <p>
+ The duplex-mode extension attribute on fo:simple-page-master allows to
+ select the duplex mode to be used for a particular simple-page-master.
+ Example:
+ </p>
+ <source><![CDATA[
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="simple" pcl:duplex-mode="0">
+ ...
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+]]></source>
+ <p>
+ Note: the duplex is a positive integer and the value depends on
+ the target printer. Not all PCL printers support duplexing.
+ Usually,
+ "0" is simplex,
+ "1" is duplex (long-edge binding),
+ "2" is duplex (short-edge binding).
+
+ Consult the technical reference for your printer for all available values.
+ </p>
+ </section>
</section>
</section>
<section id="afp">
diff --git a/src/documentation/skinconf.xml b/src/documentation/skinconf.xml
index e87baab34..20b12808e 100644
--- a/src/documentation/skinconf.xml
+++ b/src/documentation/skinconf.xml
@@ -369,6 +369,7 @@ which will be used to configure the chosen Forrest skin.
<width>88</width>
<height>31</height>
</credit>
+ <!--
<credit box-location="alt2">
<name>ApacheCon Europe 2008</name>
<url>http://eu.apachecon.com/</url>
@@ -376,6 +377,7 @@ which will be used to configure the chosen Forrest skin.
<width>125</width>
<height>125</height>
</credit>
+ -->
<credit box-location="alt2">
<name>ApacheCon US 2008</name>
<url>http://us.apachecon.com/</url>
diff --git a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
index 42ddcc220..8065f9aad 100644
--- a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
@@ -364,6 +364,12 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager {
protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
BlockSequence originalList, BlockSequence effectiveList) {
+ if (partCount > 1) {
+ PageBreakPosition pos = (PageBreakPosition)alg.getPageBreaks().getFirst();
+ int firstPartLength = ElementListUtils.calcContentLength(effectiveList,
+ effectiveList.ignoreAtStart, pos.getLeafPos());
+ overflow += alg.totalWidth - firstPartLength;
+ }
//Rendering all parts (not just the first) at once for the case where the parts that
//overflow should be visible.
alg.removeAllPageBreaks();
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index 8c46796eb..c9f72e64f 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -46,6 +46,7 @@ import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.BreakingAlgorithm;
import org.apache.fop.layoutmgr.ElementListObserver;
import org.apache.fop.layoutmgr.InlineKnuthSequence;
+import org.apache.fop.layoutmgr.KeepUtil;
import org.apache.fop.layoutmgr.KnuthBlockBox;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
@@ -1052,11 +1053,14 @@ public class LineLayoutManager extends InlineStackingLayoutManager
LinkedList returnList = new LinkedList();
for (int p = 0; p < knuthParagraphs.size(); p++) {
- // null penalty between paragraphs
- if (p > 0 && !((BlockLevelLayoutManager) parentLM).mustKeepTogether()) {
- returnList.add(new BreakElement(
- new Position(this), 0, context));
- //returnList.add(new KnuthPenalty(0, 0, false, new Position(this), false));
+ // penalty between paragraphs
+ if (p > 0) {
+ int strength = getKeepTogetherStrength();
+ int penalty = KeepUtil.getPenaltyForKeep(strength);
+ if (penalty < KnuthElement.INFINITE) {
+ returnList.add(new BreakElement(
+ new Position(this), penalty, context));
+ }
}
LineLayoutPossibilities llPoss;
@@ -1090,14 +1094,17 @@ public class LineLayoutManager extends InlineStackingLayoutManager
for (int i = 0;
i < llPoss.getChosenLineCount();
i++) {
- if (!((BlockLevelLayoutManager) parentLM).mustKeepTogether()
+ if (returnList.size() > 0
+ && i > 0 //if i==0 break generated above already
&& i >= fobj.getOrphans()
- && i <= llPoss.getChosenLineCount() - fobj.getWidows()
- && returnList.size() > 0) {
- // null penalty allowing a page break between lines
- returnList.add(new BreakElement(
- returnPosition, 0, context));
- //returnList.add(new KnuthPenalty(0, 0, false, returnPosition, false));
+ && i <= llPoss.getChosenLineCount() - fobj.getWidows()) {
+ // penalty allowing a page break between lines
+ int strength = getKeepTogetherStrength();
+ int penalty = KeepUtil.getPenaltyForKeep(strength);
+ if (penalty < KnuthElement.INFINITE) {
+ returnList.add(new BreakElement(
+ returnPosition, penalty, context));
+ }
}
int endIndex
= ((LineBreakPosition) llPoss.getChosenPosition(i)).getLeafPos();
diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
index 6ae909cd7..903ec84ae 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
@@ -139,8 +139,6 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
*/
private final MinOptMax[] letterAdjustArray; //size = textArray.length + 1
- private static final char NEWLINE = '\n';
-
/** Font used for the space between words. */
private Font spaceFont = null;
/** Start index of next TextArea */
@@ -523,7 +521,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
|| CharUtilities.isNonBreakableSpace(ch)
|| CharUtilities.isFixedWidthSpace(ch);
}
-
+
/** {@inheritDoc} */
public LinkedList getNextKnuthElements(final LayoutContext context, final int alignment) {
this.lineStartBAP = context.getLineStartBorderAndPaddingWidth();
@@ -561,8 +559,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
TextLayoutManager.LOG.error("Unexpected breakAction: " + breakAction);
}
if (inWord) {
- if (breakOpportunity || TextLayoutManager.isSpace(ch)
- || ch == TextLayoutManager.NEWLINE) {
+ if (breakOpportunity
+ || TextLayoutManager.isSpace(ch)
+ || CharUtilities.isExplicitBreak(ch)) {
// this.textArray[lastIndex] == CharUtilities.SOFT_HYPHEN
prevAi = this.processWord(alignment, sequence, prevAi, ch,
breakOpportunity, true);
@@ -601,12 +600,13 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
(short) 0, (short) 0, ipd, false, true,
breakOpportunity, font);
this.thisStart = (short) (this.nextStart + 1);
- } else if (ch == TextLayoutManager.NEWLINE) {
- // linefeed; this can happen when linefeed-treatment="preserve"
+ } else if (CharUtilities.isExplicitBreak(ch)) {
+ //mandatory break-character: only advance index
this.thisStart = (short) (this.nextStart + 1);
}
+
inWord = !TextLayoutManager.isSpace(ch)
- && ch != TextLayoutManager.NEWLINE;
+ && !CharUtilities.isExplicitBreak(ch);
inWhitespace = ch == CharUtilities.SPACE
&& this.foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
this.nextStart++;
@@ -620,7 +620,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
} else if (ai != null) {
ai = this.processLeftoverAi(alignment, sequence, ai, ch,
ch == CharUtilities.ZERO_WIDTH_SPACE);
- } else if (ch == TextLayoutManager.NEWLINE) {
+ } else if (CharUtilities.isExplicitBreak(ch)) {
sequence = this.processLinebreak(returnList, sequence);
}
@@ -628,6 +628,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
//Remove an empty sequence because of a trailing newline
returnList.removeLast();
}
+
this.setFinished(true);
if (returnList.isEmpty()) {
return null;
@@ -1000,14 +1001,12 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
if (this.textArray[ai.startIndex] != CharUtilities.SPACE
|| this.foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) {
// a breaking space that needs to be preserved
- this
- .addElementsForBreakingSpace(baseList, alignment, ai,
+ this.addElementsForBreakingSpace(baseList, alignment, ai,
this.auxiliaryPosition, 0, mainPosition,
ai.areaIPD.opt, true);
} else {
// a (possible block) of breaking spaces
- this
- .addElementsForBreakingSpace(baseList, alignment, ai,
+ this.addElementsForBreakingSpace(baseList, alignment, ai,
mainPosition, ai.areaIPD.opt,
this.auxiliaryPosition, 0, false);
}
@@ -1048,8 +1047,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
this.auxiliaryPosition, false));
baseList.add(this.makeZeroWidthPenalty(0));
- baseList
- .add(new KnuthGlue(p2WidthOffset
+ baseList.add(new KnuthGlue(p2WidthOffset
- (this.lineStartBAP + this.lineEndBAP), -3
* LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
pos2, false));
@@ -1062,8 +1060,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
this.auxiliaryPosition, false));
baseList.add(this.makeZeroWidthPenalty(0));
- baseList
- .add(new KnuthGlue(ai.areaIPD.opt, -3
+ baseList.add(new KnuthGlue(ai.areaIPD.opt, -3
* LineLayoutManager.DEFAULT_SPACE_WIDTH, 0,
pos2, false));
}
diff --git a/src/java/org/apache/fop/render/pcl/PCLGenerator.java b/src/java/org/apache/fop/render/pcl/PCLGenerator.java
index 5ca9a8bf9..6a4425012 100644
--- a/src/java/org/apache/fop/render/pcl/PCLGenerator.java
+++ b/src/java/org/apache/fop/render/pcl/PCLGenerator.java
@@ -230,6 +230,19 @@ public class PCLGenerator {
}
/**
+ * Selects the duplexing mode for the page.
+ * The parameter is usually printer-specific.
+ * "0" means Simplex,
+ * "1" means Duplex, Long-Edge Binding,
+ * "2" means Duplex, Short-Edge Binding.
+ * @param selector the integer representing the duplexing mode of the page
+ * @throws IOException In case of an I/O error
+ */
+ public void selectDuplexMode(int selector) throws IOException {
+ writeCommand("&l" + selector + "S");
+ }
+
+ /**
* Clears the horizontal margins.
* @throws IOException In case of an I/O error
*/
diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderer.java b/src/java/org/apache/fop/render/pcl/PCLRenderer.java
index e1818c84b..11e78ea97 100644
--- a/src/java/org/apache/fop/render/pcl/PCLRenderer.java
+++ b/src/java/org/apache/fop/render/pcl/PCLRenderer.java
@@ -395,9 +395,7 @@ public class PCLRenderer extends PrintRenderer {
return MIME_TYPE;
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void renderPage(PageViewport page) throws IOException, FOPException {
saveGraphicsState();
@@ -408,6 +406,13 @@ public class PCLRenderer extends PrintRenderer {
gen.selectPaperSource(Integer.parseInt(paperSource));
}
+ // Is Page duplex?
+ String pageDuplex = page.getForeignAttributeValue(
+ new QName(PCLElementMapping.NAMESPACE, null, "duplex-mode"));
+ if (pageDuplex != null) {
+ gen.selectDuplexMode(Integer.parseInt(pageDuplex));
+ }
+
//Page size
final long pagewidth = Math.round(page.getViewArea().getWidth());
final long pageheight = Math.round(page.getViewArea().getHeight());
diff --git a/src/java/org/apache/fop/text/linebreak/LineBreakStatus.java b/src/java/org/apache/fop/text/linebreak/LineBreakStatus.java
index 2f513c59c..44b27889a 100644
--- a/src/java/org/apache/fop/text/linebreak/LineBreakStatus.java
+++ b/src/java/org/apache/fop/text/linebreak/LineBreakStatus.java
@@ -73,76 +73,99 @@ public class LineBreakStatus {
* @return the break action to be taken
*/
public byte nextChar(char c) {
+
byte currentClass = LineBreakUtils.getLineBreakProperty(c);
+
if (currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_AI
|| leftClass == LineBreakUtils.LINE_BREAK_PROPERTY_XX) {
+ //current "Ambiguous" or previous "Unknown":
+ // assume current "Alphabetic"
currentClass = LineBreakUtils.LINE_BREAK_PROPERTY_AL;
- } else if (currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_NL) {
- currentClass = LineBreakUtils.LINE_BREAK_PROPERTY_BK;
}
- if (leftClass == -1) {
- if (currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_LF) {
- leftClass = LineBreakUtils.LINE_BREAK_PROPERTY_BK;
- } else {
+
+ /** Check 1: initial character after a reset/mandatory break? */
+ switch (leftClass) {
+ case -1:
+ //first character after a reset()
leftClass = currentClass;
if (leftClass == LineBreakUtils.LINE_BREAK_PROPERTY_CM) {
leftClass = LineBreakUtils.LINE_BREAK_PROPERTY_ID;
}
- }
- // LB 2a
- return PROHIBITED_BREAK;
- } else if (!(leftClass != LineBreakUtils.LINE_BREAK_PROPERTY_BK
- && (leftClass != LineBreakUtils.LINE_BREAK_PROPERTY_CR
- || currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_LF)
- )) {
- reset();
- if (currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_LF) {
- leftClass = LineBreakUtils.LINE_BREAK_PROPERTY_BK;
- }
- return EXPLICIT_BREAK;
- } else if (currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_BK
- || currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_LF) {
- leftClass = LineBreakUtils.LINE_BREAK_PROPERTY_BK;
- return PROHIBITED_BREAK;
- } else if (currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_CR) {
- leftClass = LineBreakUtils.LINE_BREAK_PROPERTY_CR;
- return PROHIBITED_BREAK;
- } else if (currentClass == LineBreakUtils.LINE_BREAK_PROPERTY_SP) {
- hadSpace = true;
- return PROHIBITED_BREAK;
- } else {
- boolean savedHadSpace = hadSpace;
- hadSpace = false;
- switch (LineBreakUtils.getLineBreakPairProperty(leftClass, currentClass)) {
- case LineBreakUtils.PROHIBITED_BREAK :
- leftClass = currentClass;
+ // LB 2a
+ return PROHIBITED_BREAK;
+
+ case LineBreakUtils.LINE_BREAK_PROPERTY_BK:
+ case LineBreakUtils.LINE_BREAK_PROPERTY_LF:
+ case LineBreakUtils.LINE_BREAK_PROPERTY_NL:
+ //first character after mandatory break
+ reset();
+ leftClass = currentClass;
+ return EXPLICIT_BREAK;
+
+ case LineBreakUtils.LINE_BREAK_PROPERTY_CR:
+ //first character after a carriage return:
+ // explicit break if it is not a linefeed
+ if (currentClass != LineBreakUtils.LINE_BREAK_PROPERTY_LF) {
+ reset();
+ return EXPLICIT_BREAK;
+ }
+
+ default:
+ //nop
+ }
+
+ /** Check 2: current is a mandatory break or space? */
+ switch (currentClass) {
+ case LineBreakUtils.LINE_BREAK_PROPERTY_BK:
+ case LineBreakUtils.LINE_BREAK_PROPERTY_LF:
+ case LineBreakUtils.LINE_BREAK_PROPERTY_NL:
+ case LineBreakUtils.LINE_BREAK_PROPERTY_CR:
+ leftClass = currentClass;
+ return PROHIBITED_BREAK;
+
+ case LineBreakUtils.LINE_BREAK_PROPERTY_SP:
+ hadSpace = true;
+ return PROHIBITED_BREAK;
+
+ default:
+ //nop
+ }
+
+ /** Normal treatment, if the first two checks did not return */
+ boolean savedHadSpace = hadSpace;
+ hadSpace = false;
+ byte breakAction = LineBreakUtils.getLineBreakPairProperty(leftClass, currentClass);
+ switch (breakAction) {
+ case PROHIBITED_BREAK:
+ case DIRECT_BREAK:
+ leftClass = currentClass;
+ return breakAction;
+
+ case INDIRECT_BREAK:
+ leftClass = currentClass;
+ if (savedHadSpace) {
+ return INDIRECT_BREAK;
+ } else {
return PROHIBITED_BREAK;
- case LineBreakUtils.DIRECT_BREAK :
+ }
+
+ case COMBINING_INDIRECT_BREAK:
+ if (savedHadSpace) {
leftClass = currentClass;
- return DIRECT_BREAK;
- case LineBreakUtils.INDIRECT_BREAK :
+ return COMBINING_INDIRECT_BREAK;
+ } else {
+ return PROHIBITED_BREAK;
+ }
+
+ case COMBINING_PROHIBITED_BREAK:
+ if (savedHadSpace) {
leftClass = currentClass;
- if (savedHadSpace) {
- return INDIRECT_BREAK;
- } else {
- return PROHIBITED_BREAK;
- }
- case LineBreakUtils.COMBINING_INDIRECT_BREAK :
- if (savedHadSpace) {
- leftClass = currentClass;
- return COMBINING_INDIRECT_BREAK;
- } else {
- return PROHIBITED_BREAK;
- }
- case LineBreakUtils.COMBINING_PROHIBITED_BREAK :
- if (savedHadSpace) {
- leftClass = currentClass;
- }
- return COMBINING_PROHIBITED_BREAK;
- default :
- throw new RuntimeException("duh");
- }
-
+ }
+ return COMBINING_PROHIBITED_BREAK;
+
+ default:
+ assert false;
+ return breakAction;
}
}
diff --git a/src/java/org/apache/fop/util/CharUtilities.java b/src/java/org/apache/fop/util/CharUtilities.java
index 4910a371c..6baa5c0fd 100644
--- a/src/java/org/apache/fop/util/CharUtilities.java
+++ b/src/java/org/apache/fop/util/CharUtilities.java
@@ -54,10 +54,16 @@ public class CharUtilities {
public static final int XMLWHITESPACE = 4;
+ /** linefeed character */
+ public static final char LINEFEED_CHAR = '\n';
+ /** carriage return */
+ public static final char CARRIAGE_RETURN = '\r';
/** normal space */
public static final char SPACE = '\u0020';
/** non-breaking space */
public static final char NBSPACE = '\u00A0';
+ /** next line control character */
+ public static final char NEXT_LINE = '\u0085';
/** zero-width space */
public static final char ZERO_WIDTH_SPACE = '\u200B';
/** word joiner */
@@ -68,6 +74,10 @@ public class CharUtilities {
public static final char ZERO_WIDTH_NOBREAK_SPACE = '\uFEFF';
/** soft hyphen */
public static final char SOFT_HYPHEN = '\u00AD';
+ /** line-separator */
+ public static final char LINE_SEPARATOR = '\u2028';
+ /** paragraph-separator */
+ public static final char PARAGRAPH_SEPARATOR = '\u2029';
/** missing ideograph */
public static final char MISSING_IDEOGRAPH = '\u25A1';
/** Unicode value indicating the the character is "not a character". */
@@ -174,8 +184,7 @@ public class CharUtilities {
* @return True if the character represents any kind of space
*/
public static boolean isAnySpace(char c) {
- boolean ret = (isBreakableSpace(c) || isNonBreakableSpace(c));
- return ret;
+ return (isBreakableSpace(c) || isNonBreakableSpace(c));
}
/**
@@ -188,19 +197,31 @@ public class CharUtilities {
//Generated from: Other_Alphabetic + Lu + Ll + Lt + Lm + Lo + Nl
int generalCategory = Character.getType(ch);
switch (generalCategory) {
- case Character.UPPERCASE_LETTER: //Lu
- case Character.LOWERCASE_LETTER: //Ll
- case Character.TITLECASE_LETTER: //Lt
- case Character.MODIFIER_LETTER: //Lm
- case Character.OTHER_LETTER: //Lo
- case Character.LETTER_NUMBER: //Nl
- return true;
- default:
- //TODO if (ch in Other_Alphabetic) return true; (Probably need ICU4J for that)
- //Other_Alphabetic contains mostly more exotic characters
- return false;
+ case Character.UPPERCASE_LETTER: //Lu
+ case Character.LOWERCASE_LETTER: //Ll
+ case Character.TITLECASE_LETTER: //Lt
+ case Character.MODIFIER_LETTER: //Lm
+ case Character.OTHER_LETTER: //Lo
+ case Character.LETTER_NUMBER: //Nl
+ return true;
+ default:
+ //TODO if (ch in Other_Alphabetic) return true; (Probably need ICU4J for that)
+ //Other_Alphabetic contains mostly more exotic characters
+ return false;
}
}
-
+
+ /**
+ * Indicates whether the given character is an explicit break-character
+ * @param ch the character to check
+ * @return true if the character represents an explicit break
+ */
+ public static boolean isExplicitBreak(char ch) {
+ return (ch == LINEFEED_CHAR
+ || ch == CARRIAGE_RETURN
+ || ch == NEXT_LINE
+ || ch == LINE_SEPARATOR
+ || ch == PARAGRAPH_SEPARATOR);
+ }
}
diff --git a/status.xml b/status.xml
index 730edccac..665bc47dc 100644
--- a/status.xml
+++ b/status.xml
@@ -60,6 +60,10 @@
<action context="Renderers" dev="AC" importance="high" type="add">
Added de-duplication and externalization support for IOCA and GOCA data resource objects.
</action -->
+ <action context="Renderers" dev="JM" type="add" fixes-bug="45115" due-to="Martin Edge">
+ Added a PCL-specific extension attribute on simple-page-master for controlling
+ the simplex/duplex mode.
+ </action>
<action context="Code" dev="AD" type="fix" fixes-bug="45097">
Corrected white-space-treatment for situations where an inline-node is the first/last
child node of an fo:block, without preceding/following text.
diff --git a/test/layoutengine/standard-testcases/block_keep-together_integers_1.xml b/test/layoutengine/standard-testcases/block_keep-together_integers_1.xml
index f6027bf01..8ad263fcb 100644
--- a/test/layoutengine/standard-testcases/block_keep-together_integers_1.xml
+++ b/test/layoutengine/standard-testcases/block_keep-together_integers_1.xml
@@ -54,6 +54,11 @@
</fo:block>
<fo:block>block10</fo:block>
</fo:block>
+ <fo:block keep-together.within-column="5" linefeed-treatment="preserve">The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+ </fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
@@ -76,7 +81,9 @@
<box/>
<penalty w="0" p="0"/>
<box/> <!-- block 3 -->
+ <penalty w="0" p="999"/>
<box/>
+ <penalty w="0" p="999"/>
<box/>
<penalty w="0" p="0"/>
<box/> <!-- block4 -->
@@ -91,7 +98,17 @@
<penalty w="0" p="INF"/>
<box/> <!-- block9 -->
<penalty w="0" p="999"/>
+ <box/> <!-- block10 -->
+ <penalty w="0" p="0"/>
+
+ <box/>
+ <penalty w="0" p="999"/>
+ <box/>
+ <penalty w="0" p="999"/>
<box/>
+ <penalty w="0" p="999"/>
+ <box/>
+
<skip>3</skip>
</element-list>
diff --git a/test/layoutengine/standard-testcases/block_uax14_explicit-breaks.xml b/test/layoutengine/standard-testcases/block_uax14_explicit-breaks.xml
new file mode 100644
index 000000000..7636e9ae4
--- /dev/null
+++ b/test/layoutengine/standard-testcases/block_uax14_explicit-breaks.xml
@@ -0,0 +1,64 @@
+<?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 for the handling of explicit breaking characters:
+ - preserved linefeeds (U+000A)
+ - Unicode next-line (U+0085), line-separator (U+2028)
+ or paragraph-separator (U+2029)
+ Other possibilities defined in UAX#14, but not applicable for XSL-FO:
+ - carriage return (U+000D) is normalized to a space
+ - line-tabulation (U+000B) and form-feed (U+000C) are illegal XML characters
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <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" font-size="8pt">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block linefeed-treatment="preserve">This is a piece of text with preserved linefeed&#x0A;character.</fo:block>
+ <fo:block>
+ This is a piece of text with a next-line&#x85;character.
+ </fo:block>
+ <fo:block>
+ This is a piece of text with a line-separator&#x2028;character.
+ </fo:block>
+ <fo:block>
+ This is a piece of text with a paragraph-separator&#x2029;character.
+ </fo:block>
+ <fo:block>
+ There should be 2 empty lines between this one&#x2028;&#x2028;&#x2028;and this one.
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="2" xpath="count(//flow/block[1]/lineArea)"/>
+ <eval expected="2" xpath="count(//flow/block[2]/lineArea)"/>
+ <eval expected="2" xpath="count(//flow/block[3]/lineArea)"/>
+ <eval expected="2" xpath="count(//flow/block[4]/lineArea)"/>
+ <eval expected="4" xpath="count(//flow/block[5]/lineArea)"/>
+ </checks>
+</testcase>