Fixed the rendering of zero-width spaces for certain fonts by not generating them into the area tree. Submitted by: Paul Vinkenoog <paul.at.vinkenoog.nl> git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@540049 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_94
@@ -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); | |||
} |
@@ -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 |
@@ -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. |
@@ -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> |
@@ -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"/> |