Return-Path: Delivered-To: apmail-xmlgraphics-fop-commits-archive@www.apache.org Received: (qmail 63222 invoked from network); 13 Jan 2007 09:21:54 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 13 Jan 2007 09:21:54 -0000 Received: (qmail 66777 invoked by uid 500); 13 Jan 2007 09:22:00 -0000 Delivered-To: apmail-xmlgraphics-fop-commits-archive@xmlgraphics.apache.org Received: (qmail 66742 invoked by uid 500); 13 Jan 2007 09:22:00 -0000 Mailing-List: contact fop-commits-help@xmlgraphics.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: fop-dev@xmlgraphics.apache.org Delivered-To: mailing list fop-commits@xmlgraphics.apache.org Received: (qmail 66730 invoked by uid 99); 13 Jan 2007 09:22:00 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 13 Jan 2007 01:22:00 -0800 X-ASF-Spam-Status: No, hits=-8.6 required=10.0 tests=ALL_TRUSTED,INFO_TLD,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 13 Jan 2007 01:21:52 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id 231881A981A; Sat, 13 Jan 2007 01:20:50 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r495855 - in /xmlgraphics/fop/trunk: ./ src/java/org/apache/fop/layoutmgr/inline/ test/layoutengine/ test/layoutengine/hyphenation-testcases/ test/layoutengine/standard-testcases/ Date: Sat, 13 Jan 2007 09:20:49 -0000 To: fop-commits@xmlgraphics.apache.org From: manuel@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070113092050.231881A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: manuel Date: Sat Jan 13 01:20:49 2007 New Revision: 495855 URL: http://svn.apache.org/viewvc?view=rev&rev=495855 Log: Initial support for soft hyphens Added: xmlgraphics/fop/trunk/test/layoutengine/hyphenation-testcases/block_shy_linebreaking_hyph.xml (with props) xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_shy_linebreaking.xml (with props) Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java xmlgraphics/fop/trunk/status.xml xmlgraphics/fop/trunk/test/layoutengine/disabled-testcases.xml Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java?view=diff&rev=495855&r1=495854&r2=495855 ============================================================================== --- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (original) +++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java Sat Jan 13 01:20:49 2007 @@ -319,7 +319,7 @@ return; } int textLength = ai.iBreakIndex - ai.iStartIndex; - if (ai.iLScount == textLength + if (ai.iLScount == textLength && !ai.bHyphenated && context.isLastArea()) { // the line ends at a character like "/" or "-"; // remove the letter space after the last character @@ -453,6 +453,7 @@ // set the text of the TextArea, split into words and spaces int wordStartIndex = -1; AreaInfo areaInfo; + int len = 0; for (int i = firstIndex; i <= lastIndex; i++) { areaInfo = (AreaInfo) vecAreaInfo.get(i); if (areaInfo.isSpace) { @@ -467,32 +468,45 @@ // areaInfo stores information about a word fragment if (wordStartIndex == -1) { // here starts a new word - wordStartIndex = areaInfo.iStartIndex; + wordStartIndex = i; + len = 0; } + len += areaInfo.iBreakIndex - areaInfo.iStartIndex; if (i == lastIndex || ((AreaInfo) vecAreaInfo.get(i + 1)).isSpace) { // here ends a new word // add a word to the TextArea - int len = areaInfo.iBreakIndex - wordStartIndex; - String wordChars = new String(textArray, wordStartIndex, len); if (isLastArea && i == lastIndex && areaInfo.bHyphenated) { - // add the hyphenation character - wordChars += foText.getCommonHyphenation().hyphenationCharacter; + len++; } - int[] letterAdjust = new int[wordChars.length()]; - int lsCount = areaInfo.iLScount; - for (int letter = 0; letter < len; letter++) { - MinOptMax adj = letterAdjustArray[letter + wordStartIndex]; - if (letter > 0) { - letterAdjust[letter] = (adj != null ? adj.opt : 0); - } - if (lsCount > 0) { - letterAdjust[letter] += textArea.getTextLetterSpaceAdjust(); - lsCount--; + StringBuffer wordChars = new StringBuffer(len); + int[] letterAdjust = new int[len]; + int letter = 0; + for (int j = wordStartIndex; j <= i; j++) { + AreaInfo ai = (AreaInfo) vecAreaInfo.get(j); + int lsCount = ai.iLScount; + wordChars.append(textArray, ai.iStartIndex, ai.iBreakIndex - ai.iStartIndex); + for (int k = 0; k < ai.iBreakIndex - ai.iStartIndex; k++) { + MinOptMax adj = letterAdjustArray[ai.iStartIndex + k]; + if (letter > 0) { + letterAdjust[letter] = (adj != null ? adj.opt : 0); + } + if (lsCount > 0) { + letterAdjust[letter] += textArea.getTextLetterSpaceAdjust(); + lsCount--; + } + letter++; } } - textArea.addWord(wordChars, 0, letterAdjust); + // String wordChars = new String(textArray, wordStartIndex, len); + if (isLastArea + && i == lastIndex + && areaInfo.bHyphenated) { + // add the hyphenation character + wordChars.append(foText.getCommonHyphenation().hyphenationCharacter); + } + textArea.addWord(wordChars.toString(), 0, letterAdjust); wordStartIndex = -1; } } @@ -545,6 +559,7 @@ LinkedList returnList = new LinkedList(); KnuthSequence sequence = new InlineKnuthSequence(); AreaInfo ai = null; + AreaInfo prevAi = null; returnList.add(sequence); LineBreakStatus lbs = new LineBreakStatus(); @@ -573,10 +588,14 @@ if (inWord) { if (breakOpportunity || isSpace(ch) || ch == NEWLINE) { //Word boundary found, process widths and kerning - int wordLength = iNextStart - iThisStart; + int lastIndex = iNextStart; + while (lastIndex > 0 && textArray[lastIndex - 1] == CharUtilities.SOFT_HYPHEN) { + lastIndex--; + } + int wordLength = lastIndex - iThisStart; boolean kerning = font.hasKerning(); MinOptMax wordIPD = new MinOptMax(0); - for (int i = iThisStart; i < iNextStart; i++) { + for (int i = iThisStart; i < lastIndex; i++) { char c = textArray[i]; //character width @@ -584,15 +603,26 @@ wordIPD.add(charWidth); //kerning - int kern = 0; - if (kerning && (i > iThisStart)) { - char previous = textArray[i - 1]; - kern = font.getKernValue(previous, c) * font.getFontSize() / 1000; + if (kerning) { + int kern = 0; + if (i > iThisStart) { + char previous = textArray[i - 1]; + kern = font.getKernValue(previous, c) * font.getFontSize() / 1000; + } else if (prevAi != null && !prevAi.isSpace && prevAi.iBreakIndex > 0) { + char previous = textArray[prevAi.iBreakIndex - 1]; + kern = font.getKernValue(previous, c) * font.getFontSize() / 1000; + } if (kern != 0) { //log.info("Kerning between " + previous + " and " + c + ": " + kern); addToLetterAdjust(i, kern); + wordIPD.add(kern); } - wordIPD.add(kern); + } + } + if (kerning && breakOpportunity && !isSpace(ch) && lastIndex > 0 && textArray[lastIndex] == CharUtilities.SOFT_HYPHEN) { + int kern = font.getKernValue(textArray[lastIndex - 1], ch) * font.getFontSize() / 1000; + if (kern != 0) { + addToLetterAdjust(lastIndex, kern); } } int iLetterSpaces = wordLength - 1; @@ -605,10 +635,11 @@ wordIPD.add(MinOptMax.multiply(letterSpaceIPD, iLetterSpaces)); // create the AreaInfo object - ai = new AreaInfo(iThisStart, iNextStart, (short) 0, + ai = new AreaInfo(iThisStart, (short)lastIndex, (short) 0, (short) iLetterSpaces, - wordIPD, false, false, breakOpportunity); + wordIPD, textArray[lastIndex] == CharUtilities.SOFT_HYPHEN, false, breakOpportunity); vecAreaInfo.add(ai); + prevAi = ai; iTempStart = iNextStart; // create the elements @@ -627,6 +658,7 @@ MinOptMax.multiply(wordSpaceIPD, iNextStart - iThisStart), false, true, breakOpportunity); vecAreaInfo.add(ai); + prevAi = ai; // create the elements sequence.addAll @@ -638,6 +670,7 @@ } else { if (ai != null) { vecAreaInfo.add(ai); + prevAi = ai; ai.breakOppAfter = ch == CharUtilities.SPACE || breakOpportunity; sequence.addAll (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1)); @@ -680,10 +713,14 @@ // Process any last elements if (inWord) { - int wordLength = iNextStart - iThisStart; + int lastIndex = iNextStart; + if (textArray[iNextStart - 1] == CharUtilities.SOFT_HYPHEN) { + lastIndex--; + } + int wordLength = lastIndex - iThisStart; boolean kerning = font.hasKerning(); MinOptMax wordIPD = new MinOptMax(0); - for (int i = iThisStart; i < iNextStart; i++) { + for (int i = iThisStart; i < lastIndex; i++) { char c = textArray[i]; //character width @@ -691,22 +728,27 @@ wordIPD.add(charWidth); //kerning - int kern = 0; - if (kerning && (i > iThisStart)) { - char previous = textArray[i - 1]; - kern = font.getKernValue(previous, c) * font.getFontSize() / 1000; + if (kerning) { + int kern = 0; + if (i > iThisStart) { + char previous = textArray[i - 1]; + kern = font.getKernValue(previous, c) * font.getFontSize() / 1000; + } else if (prevAi != null && !prevAi.isSpace) { + char previous = textArray[prevAi.iBreakIndex - 1]; + kern = font.getKernValue(previous, c) * font.getFontSize() / 1000; + } if (kern != 0) { //log.info("Kerning between " + previous + " and " + c + ": " + kern); addToLetterAdjust(i, kern); + wordIPD.add(kern); } - wordIPD.add(kern); } } int iLetterSpaces = wordLength - 1; wordIPD.add(MinOptMax.multiply(letterSpaceIPD, iLetterSpaces)); // create the AreaInfo object - ai = new AreaInfo(iThisStart, iNextStart, (short) 0, + ai = new AreaInfo(iThisStart, (short)lastIndex, (short) 0, (short) iLetterSpaces, wordIPD, false, false, false); vecAreaInfo.add(ai); @@ -1215,7 +1257,7 @@ // if the last character of the word fragment is '-' or '/', // the fragment could end a line; in this case, it loses one // of its letter spaces; - boolean bSuppressibleLetterSpace = ai.breakOppAfter; + boolean bSuppressibleLetterSpace = ai.breakOppAfter && !ai.bHyphenated; if (letterSpaceWidth.min == letterSpaceWidth.max) { // constant letter spacing @@ -1261,18 +1303,20 @@ // 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, widthIfNoBreakOccurs)); + wordElements.addAll(createElementsForAHyphen(alignment, hyphIPD, widthIfNoBreakOccurs, ai.breakOppAfter && ai.bHyphenated)); } else if (bSuppressibleLetterSpace) { // the word fragment ends with a character that acts as a hyphen // if a break occurs the width does not increase, // otherwise there is one more letter space - wordElements.addAll(createElementsForAHyphen(alignment, 0, letterSpaceWidth)); + wordElements.addAll(createElementsForAHyphen(alignment, 0, letterSpaceWidth, false)); } return wordElements; } + // static final int SOFT_HYPHEN_PENALTY = KnuthPenalty.FLAGGED_PENALTY / 10; + static final int SOFT_HYPHEN_PENALTY = 1; private LinkedList createElementsForAHyphen(int alignment, - int widthIfBreakOccurs, MinOptMax widthIfNoBreakOccurs) { + int widthIfBreakOccurs, MinOptMax widthIfNoBreakOccurs, boolean softHyphen) { if (widthIfNoBreakOccurs == null) { widthIfNoBreakOccurs = ZERO_MINOPTMAX; } @@ -1308,7 +1352,7 @@ new LeafPosition(this, -1), true)); hyphenElements.add (new KnuthPenalty(hyphIPD, - KnuthPenalty.FLAGGED_PENALTY, true, + softHyphen ? SOFT_HYPHEN_PENALTY : KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); hyphenElements.add (new KnuthGlue(-(lineEndBAP + lineStartBAP), @@ -1347,7 +1391,7 @@ new LeafPosition(this, -1), false)); hyphenElements.add (new KnuthPenalty(widthIfBreakOccurs, - KnuthPenalty.FLAGGED_PENALTY, true, + softHyphen ? SOFT_HYPHEN_PENALTY : KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); hyphenElements.add (new KnuthGlue(widthIfNoBreakOccurs.opt - (lineStartBAP + lineEndBAP), @@ -1368,7 +1412,7 @@ new LeafPosition(this, -1), false)); hyphenElements.add (new KnuthPenalty(widthIfBreakOccurs, - KnuthPenalty.FLAGGED_PENALTY, true, + softHyphen ? SOFT_HYPHEN_PENALTY : KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); hyphenElements.add (new KnuthGlue(widthIfNoBreakOccurs.opt, @@ -1392,7 +1436,7 @@ new LeafPosition(this, -1), false)); hyphenElements.add (new KnuthPenalty(widthIfBreakOccurs, - KnuthPenalty.FLAGGED_PENALTY, true, + softHyphen ? SOFT_HYPHEN_PENALTY : KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); // extra elements representing a letter space that is suppressed // if a break occurs @@ -1420,7 +1464,7 @@ } else { hyphenElements.add (new KnuthPenalty(widthIfBreakOccurs, - KnuthPenalty.FLAGGED_PENALTY, true, + softHyphen ? SOFT_HYPHEN_PENALTY : KnuthPenalty.FLAGGED_PENALTY, true, new LeafPosition(this, -1), false)); // extra elements representing a letter space that is suppressed // if a break occurs Modified: xmlgraphics/fop/trunk/status.xml URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?view=diff&rev=495855&r1=495854&r2=495855 ============================================================================== --- xmlgraphics/fop/trunk/status.xml (original) +++ xmlgraphics/fop/trunk/status.xml Sat Jan 13 01:20:49 2007 @@ -29,6 +29,9 @@ + Added support for the soft hyphen (SHY) character. + + Added support for line-height-shift-adjustment property. Modified: xmlgraphics/fop/trunk/test/layoutengine/disabled-testcases.xml URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/disabled-testcases.xml?view=diff&rev=495855&r1=495854&r2=495855 ============================================================================== --- xmlgraphics/fop/trunk/test/layoutengine/disabled-testcases.xml (original) +++ xmlgraphics/fop/trunk/test/layoutengine/disabled-testcases.xml Sat Jan 13 01:20:49 2007 @@ -325,4 +325,10 @@ after a block with break-after="page" http://issues.apache.org/bugzilla/show_bug.cgi?id=40230 + + Soft hyphen with normal hyphenation enabled + block_shy_linebreaking_hyph.xml + A soft hyphen should be a preferred as break compared to a + normal hyphenation point but is not. + Added: xmlgraphics/fop/trunk/test/layoutengine/hyphenation-testcases/block_shy_linebreaking_hyph.xml URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/hyphenation-testcases/block_shy_linebreaking_hyph.xml?view=auto&rev=495855 ============================================================================== --- xmlgraphics/fop/trunk/test/layoutengine/hyphenation-testcases/block_shy_linebreaking_hyph.xml (added) +++ xmlgraphics/fop/trunk/test/layoutengine/hyphenation-testcases/block_shy_linebreaking_hyph.xml Sat Jan 13 01:20:49 2007 @@ -0,0 +1,59 @@ + + + + + +

+ This test checks Soft Hyphen breaking with hyphenation enabled. +

+
+ + + + + + + + + + + Reference block without soft Hyphen and with hyphenation enabled + + + VeryLongWordWithLotsOfSoftHyphensPutInBetweenAndAround + + + BA - Break Opportunity After (A) - Conditional Hyphen with hyphenation enabled + + + ­Very­Long­Word­With­Lots­­­Of­­­Soft­­­Hyphens­­­Put­­­In­Between­And­Around­ + + + + + + + + + + + + + + +
Propchange: xmlgraphics/fop/trunk/test/layoutengine/hyphenation-testcases/block_shy_linebreaking_hyph.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: xmlgraphics/fop/trunk/test/layoutengine/hyphenation-testcases/block_shy_linebreaking_hyph.xml ------------------------------------------------------------------------------ svn:executable = * Propchange: xmlgraphics/fop/trunk/test/layoutengine/hyphenation-testcases/block_shy_linebreaking_hyph.xml ------------------------------------------------------------------------------ svn:keywords = Id Added: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_shy_linebreaking.xml URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_shy_linebreaking.xml?view=auto&rev=495855 ============================================================================== --- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_shy_linebreaking.xml (added) +++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_shy_linebreaking.xml Sat Jan 13 01:20:49 2007 @@ -0,0 +1,63 @@ + + + + + +

+ This test checks some of the Soft Hyphen breaking rules. +

+
+ + + + + + + + + + + BA -- Break Opportunity After (A) - Conditional Hyphen + + + ­Very­Long­Word­With­Lots­­­Of­­­Soft­­­Hyphens­­­Put­­­In­Between­And­Around­ + + + BA -- Break Opportunity After (A) - Conditional Hyphen with letter spacing + + + ­Very­Long­Word­With­Lots­Of­Soft­Hyphens­Put­In­Between­And­Around­ + + + + + + + + + + + + + + + + + + +
Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_shy_linebreaking.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_shy_linebreaking.xml ------------------------------------------------------------------------------ svn:executable = * Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/block_shy_linebreaking.xml ------------------------------------------------------------------------------ svn:keywords = Id --------------------------------------------------------------------- To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org