From 5db46401762875432068ec08a6558213b80d540f Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Fri, 19 May 2006 11:51:40 +0000 Subject: [PATCH] Bugfix: The combination of hyphenation and kerning resulted in slightly ragged right ends for right-aligned and justified text. The kerning values were not correctly placed and summed up for hyphenation and no-hyphenation conditions. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@407774 13f79535-47bb-0310-9956-ffa450edef68 --- .../layoutmgr/inline/TextLayoutManager.java | 52 ++++++++++++---- status.xml | 16 +++++ .../block_hyphenation_kerning.xml | 60 +++++++++++++++++++ 3 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 test/layoutengine/hyphenation-testcases/block_hyphenation_kerning.xml diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java index 1582ea30d..159ece158 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java @@ -106,12 +106,17 @@ public class TextLayoutManager extends LeafNodeLayoutManager { /** Non-space characters on which we can end a line. */ private static final String BREAK_CHARS = "-/"; + /** Used to reduce instantiation of MinOptMax with zero length. Do not modify! */ + private static final MinOptMax ZERO_MINOPTMAX = new MinOptMax(0); + private FOText foText; private char[] textArray; - /** Contains an array of widths to adjust for kerning and letter spacing */ + /** + * Contains an array of widths to adjust for kerning. The first entry can + * be used to influence the start position of the first letter. The entry i+1 defines the + * cursor advancement after the character i. A null entry means no special advancement. + */ private MinOptMax[] letterAdjustArray; //size = textArray.length + 1 - /** The sum of all entries in the letterAdjustArray */ - private MinOptMax totalLetterAdjust = new MinOptMax(0); private static final char NEWLINE = '\n'; @@ -310,8 +315,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { iLScount--; } - for (int i = ai.iStartIndex + 1; i < ai.iBreakIndex + 1; i++) { - MinOptMax ladj = letterAdjustArray[i]; + for (int i = ai.iStartIndex; i < ai.iBreakIndex; i++) { + MinOptMax ladj = letterAdjustArray[i + 1]; if (ladj != null && ladj.isElastic()) { iLScount++; } @@ -466,8 +471,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager { int[] letterAdjust = new int[wordChars.length()]; int lsCount = areaInfo.iLScount; for (int letter = 0; letter < len; letter++) { - MinOptMax adj = letterAdjustArray[letter + wordStartIndex + 1]; - letterAdjust[letter] = (adj != null ? adj.opt : 0); + MinOptMax adj = letterAdjustArray[letter + wordStartIndex]; + if (letter > 0) { + letterAdjust[letter] = (adj != null ? adj.opt : 0); + } if (lsCount > 0) { letterAdjust[letter] += textArea.getTextLetterSpaceAdjust(); lsCount--; @@ -492,7 +499,6 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } else { letterAdjustArray[index].add(width); } - totalLetterAdjust.add(width); } private void addToLetterAdjust(int index, MinOptMax width) { @@ -501,7 +507,6 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } else { letterAdjustArray[index].add(width); } - totalLetterAdjust.add(width); } /** @@ -625,7 +630,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { char previous = textArray[i - 1]; kern = font.getKernValue(previous, c) * font.getFontSize() / 1000; if (kern != 0) { - addToLetterAdjust(i + 1, kern); + //log.info("Kerning between " + previous + " and " + c + ": " + kern); + addToLetterAdjust(i, kern); } wordIPD.add(kern); } @@ -761,9 +767,22 @@ public class TextLayoutManager extends LeafNodeLayoutManager { hc.updateOffset(iStopIndex - iStartIndex); + //log.info("Word: " + new String(textArray, iStartIndex, iStopIndex - iStartIndex)); for (int i = iStartIndex; i < iStopIndex; i++) { char c = textArray[i]; newIPD.add(new MinOptMax(font.getCharWidth(c))); + //if (i > iStartIndex) { + if (i < iStopIndex) { + MinOptMax la = this.letterAdjustArray[i + 1]; + if ((i == iStopIndex - 1) && bHyphenFollows) { + //the letter adjust here needs to be handled further down during + //element generation because it depends on hyph/no-hyph condition + la = null; + } + if (la != null) { + newIPD.add(la); + } + } } // add letter spaces boolean bIsWordEnd @@ -854,6 +873,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { iReturnedIndex++; } // end of while setFinished(true); + //ElementListObserver.observe(returnList, "text-changed", null); return returnList; } @@ -1152,10 +1172,17 @@ public class TextLayoutManager extends LeafNodeLayoutManager { // extra-elements if the word fragment is the end of a syllable, // or it ends with a character that can be used as a line break if (ai.bHyphenated) { + MinOptMax widthIfNoBreakOccurs = null; + if (ai.iBreakIndex < textArray.length) { + //Add in kerning in no-break condition + widthIfNoBreakOccurs = letterAdjustArray[ai.iBreakIndex]; + } + //if (ai.iBreakIndex) + // the word fragment ends at the end of a syllable: // if a break occurs the content width increases, // otherwise nothing happens - wordElements.addAll(createElementsForAHyphen(alignment, hyphIPD, new MinOptMax(0))); + wordElements.addAll(createElementsForAHyphen(alignment, hyphIPD, widthIfNoBreakOccurs)); } else if (bSuppressibleLetterSpace) { // the word fragment ends with a character that acts as a hyphen // if a break occurs the width does not increase, @@ -1167,6 +1194,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager { private LinkedList createElementsForAHyphen(int alignment, int widthIfBreakOccurs, MinOptMax widthIfNoBreakOccurs) { + if (widthIfNoBreakOccurs == null) { + widthIfNoBreakOccurs = ZERO_MINOPTMAX; + } LinkedList hyphenElements = new LinkedList(); switch (alignment) { diff --git a/status.xml b/status.xml index 7848f22f5..765a0fcc4 100644 --- a/status.xml +++ b/status.xml @@ -27,6 +27,22 @@ + + Bugfix: The combination of hyphenation and kerning resulted in slightly ragged + right ends for right-aligned and justified text. + + + Bugfix: NullPointerException in AreaAdditionUtil in a table-cell spanning + multiple pages and with a marker. + + + Bugfix: NullPointerException in RTF output when a table does not contain + table-columns. + + + Bugfix: NullPointerException in RTF library when there are no borders on + the parent table. + Automatic support for all fonts available to the Java2D subsystem for all Java2D-descendant renderers (TIFF, PNG, print, AWT). diff --git a/test/layoutengine/hyphenation-testcases/block_hyphenation_kerning.xml b/test/layoutengine/hyphenation-testcases/block_hyphenation_kerning.xml new file mode 100644 index 000000000..5ee6c9b68 --- /dev/null +++ b/test/layoutengine/hyphenation-testcases/block_hyphenation_kerning.xml @@ -0,0 +1,60 @@ + + + + + +

+ Checks hyphenation in combination with kerning. +

+
+ + true + + + + + + + + + + + + hyphenation regression advantage foundation vandalism AVAVAVA vandavanda + hyphenation regression advantage foundation vandalism AVAVAVA vandavanda + hyphenation regression + + + + + + + + + + + + + + + + + + + + +
-- 2.39.5