diff options
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java | 7 | ||||
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java | 11 | ||||
-rw-r--r-- | src/java/org/apache/fop/util/CharUtilities.java | 20 | ||||
-rw-r--r-- | status.xml | 4 | ||||
-rw-r--r-- | test/layoutengine/standard-testcases/block_white-space_4.xml | 22 |
5 files changed, 41 insertions, 23 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java index 26dc8c3b4..3d1291480 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java @@ -75,11 +75,14 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { } private org.apache.fop.area.inline.TextArea getCharacterInlineArea(Character node) { - org.apache.fop.area.inline.TextArea text + org.apache.fop.area.inline.TextArea text = new org.apache.fop.area.inline.TextArea(); char ch = node.getCharacter(); if (CharUtilities.isAnySpace(ch)) { - text.addSpace(ch, 0, CharUtilities.isAdjustableSpace(ch)); + // add space unless it's zero-width: + if (!CharUtilities.isZeroWidthSpace(ch)) { + text.addSpace(ch, 0, CharUtilities.isAdjustableSpace(ch)); + } } else { text.addWord(String.valueOf(ch), 0); } diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java index 7e14f49da..8d6c13670 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.List; import java.util.LinkedList; import java.util.ListIterator; -import java.util.NoSuchElementException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -378,7 +377,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { iTotalAdjust += (iWordSpaceDim - wordSpaceIPD.opt) * iWScount; if (iTotalAdjust != iDifference) { // the applied adjustment is greater or smaller than the needed one - log.trace("TextLM.addAreas: error in word / letter space adjustment = " + log.trace("TextLM.addAreas: error in word / letter space adjustment = " + (iTotalAdjust - iDifference)); // set iTotalAdjust = iDifference, so that the width of the TextArea // will counterbalance the error and the other inline areas will be @@ -458,11 +457,13 @@ public class TextLayoutManager extends LeafNodeLayoutManager { areaInfo = (AreaInfo) vecAreaInfo.get(i); if (areaInfo.isSpace) { // areaInfo stores information about spaces - // add the spaces to the TextArea + // add the spaces - except zero-width spaces - to the TextArea for (int j = areaInfo.iStartIndex; j < areaInfo.iBreakIndex; j++) { char spaceChar = textArray[j]; - textArea.addSpace(spaceChar, 0, - CharUtilities.isAdjustableSpace(spaceChar)); + if (!CharUtilities.isZeroWidthSpace(spaceChar)) { + textArea.addSpace(spaceChar, 0, + CharUtilities.isAdjustableSpace(spaceChar)); + } } } else { // areaInfo stores information about a word fragment diff --git a/src/java/org/apache/fop/util/CharUtilities.java b/src/java/org/apache/fop/util/CharUtilities.java index dc2d987f3..1aad75ad7 100644 --- a/src/java/org/apache/fop/util/CharUtilities.java +++ b/src/java/org/apache/fop/util/CharUtilities.java @@ -64,8 +64,8 @@ public class CharUtilities { public static final char ZERO_WIDTH_NOBREAK_SPACE = '\uFEFF'; /** soft hyphen */ public static final char SOFT_HYPHEN = '\u00AD'; - - + + /** * Utility class: Constructor prevents instantiating when subclassed. */ @@ -98,7 +98,17 @@ public class CharUtilities { public static boolean isBreakableSpace(char c) { return (c == SPACE || isFixedWidthSpace(c)); } - + + /** + * Method to determine if the character is a zero-width space. + * @param c the character to check + * @return true if the character is a zero-width space + */ + public static boolean isZeroWidthSpace(char c) { + return c == ZERO_WIDTH_SPACE // 200Bh + || c == ZERO_WIDTH_NOBREAK_SPACE; // FEFFh (also used as BOM) + } + /** * Method to determine if the character is a (breakable) fixed-width space. * @param c the character to check @@ -111,7 +121,7 @@ public class CharUtilities { // c == '\u2002' // en space // c == '\u2003' // em space // c == '\u2004' // three-per-em space -// c == '\u2005' // four--per-em space +// c == '\u2005' // four-per-em space // c == '\u2006' // six-per-em space // c == '\u2007' // figure space // c == '\u2008' // punctuation space @@ -120,7 +130,7 @@ public class CharUtilities { // c == '\u200B' // zero width space // c == '\u3000' // ideographic space } - + /** * Method to determine if the character is a nonbreaking * space. diff --git a/status.xml b/status.xml index 7078fab7c..2eee9a5e6 100644 --- a/status.xml +++ b/status.xml @@ -28,6 +28,10 @@ <changes> <release version="FOP Trunk"> + <action context="Code" dev="JM" type="fix" fixes-bug="42109" due-to="Paul Vinkenoog"> + Fixed the rendering of zero-width spaces for certain fonts by not generating them into + the area tree. + </action> <action context="Code" dev="LF" type="fix"> Fixed a problem with disappearing footnotes inside hyphenated inlines (and footnotes with hyphenated inline child). </action> diff --git a/test/layoutengine/standard-testcases/block_white-space_4.xml b/test/layoutengine/standard-testcases/block_white-space_4.xml index b587f6b8a..1fa72b1cd 100644 --- a/test/layoutengine/standard-testcases/block_white-space_4.xml +++ b/test/layoutengine/standard-testcases/block_white-space_4.xml @@ -164,8 +164,8 @@ <true xpath="//block[@prod-id='l-hair-space']/lineArea/text/*[6]/@adj = 'false'"/> <eval expected="55368" xpath="//block[@prod-id='l-zwsp']/lineArea/text/@ipd"/> - <true xpath="//block[@prod-id='l-zwsp']/lineArea/text/*[2]/@adj = 'false'"/> - <true xpath="//block[@prod-id='l-zwsp']/lineArea/text/*[6]/@adj = 'false'"/> + <!-- zwsp is not rendered to the area tree --> + <eval expected="1" xpath="count(//block[@prod-id='l-zwsp']/lineArea/text/space)"/> <eval expected="55368" xpath="//block[@prod-id='l-nosp']/lineArea/text/@ipd"/> @@ -232,9 +232,9 @@ <true xpath="//block[@prod-id='c-hair-space']/lineArea/text/*[6]/@adj = 'false'"/> <eval expected="55368" xpath="//block[@prod-id='c-zwsp']/lineArea/text/@ipd"/> - <true xpath="//block[@prod-id='c-zwsp']/lineArea/text/*[2]/@adj = 'false'"/> - <true xpath="//block[@prod-id='c-zwsp']/lineArea/text/*[6]/@adj = 'false'"/> - + <!-- zwsp is not rendered to the area tree --> + <eval expected="1" xpath="count(//block[@prod-id='c-zwsp']/lineArea/text/space)"/> + <eval expected="55368" xpath="//block[@prod-id='c-nosp']/lineArea/text/@ipd"/> <eval expected="190804" xpath="//block[@prod-id='j-sp']/lineArea/text/@ipd"/> @@ -313,9 +313,9 @@ <eval expected="84280" xpath="//block[@prod-id='j-zwsp']/lineArea/text/@ipd"/> <eval expected="28912" xpath="//block[@prod-id='j-zwsp']/lineArea/text/@twsadjust"/> - <true xpath="//block[@prod-id='j-zwsp']/lineArea/text/*[2]/@adj = 'false'"/> - <true xpath="//block[@prod-id='j-zwsp']/lineArea/text/*[6]/@adj = 'false'"/> - + <!-- zwsp is not rendered to the area tree --> + <eval expected="1" xpath="count(//block[@prod-id='j-zwsp']/lineArea/text/space)"/> + <eval expected="134904" xpath="//block[@prod-id='j-nosp']/lineArea/text/@ipd"/> <eval expected="79536" xpath="//block[@prod-id='j-nosp']/lineArea/text/@twsadjust"/> @@ -408,9 +408,9 @@ <eval expected="85480" xpath="//block[@prod-id='lsj-zwsp']/lineArea/text/@ipd"/> <eval expected="14112" xpath="//block[@prod-id='lsj-zwsp']/lineArea/text/@twsadjust"/> <eval expected="2000" xpath="//block[@prod-id='lsj-zwsp']/lineArea/text/@tlsadjust"/> - <true xpath="//block[@prod-id='lsj-zwsp']/lineArea/text/*[2]/@adj = 'false'"/> - <true xpath="//block[@prod-id='lsj-zwsp']/lineArea/text/*[6]/@adj = 'false'"/> - + <!-- zwsp is not rendered to the area tree --> + <eval expected="1" xpath="count(//block[@prod-id='lsj-zwsp']/lineArea/text/space)"/> + <eval expected="140237" xpath="//block[@prod-id='lsj-nosp']/lineArea/text/@ipd"/> <eval expected="64869" xpath="//block[@prod-id='lsj-nosp']/lineArea/text/@twsadjust"/> <eval expected="2000" xpath="//block[@prod-id='lsj-nosp']/lineArea/text/@tlsadjust"/> |