]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Fix for new linebreaking in combination with hyphenation not correctly breaking when...
authorManuel Mall <manuel@apache.org>
Thu, 11 Jan 2007 10:28:57 +0000 (10:28 +0000)
committerManuel Mall <manuel@apache.org>
Thu, 11 Jan 2007 10:28:57 +0000 (10:28 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@495175 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
test/layoutengine/hyphenation-testcases/block_uax14_linebreaking_hyph.xml [new file with mode: 0755]

index 28ec13b6b4f6b723881cd32d758fbcdd234d686f..f6524718c8adf439cb0f88840cf619ff6daa109b 100644 (file)
@@ -69,8 +69,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
         private MinOptMax ipdArea;
         private boolean bHyphenated;
         private boolean isSpace;
+        private boolean breakOppAfter;
         public AreaInfo(short iSIndex, short iBIndex, short iWS, short iLS,
-                        MinOptMax ipd, boolean bHyph, boolean isSpace) {
+                        MinOptMax ipd, boolean bHyph, boolean isSpace, boolean breakOppAfter) {
             iStartIndex = iSIndex;
             iBreakIndex = iBIndex;
             iWScount = iWS;
@@ -78,6 +79,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
             ipdArea = ipd;
             bHyphenated = bHyph;
             this.isSpace = isSpace;
+            this.breakOppAfter = breakOppAfter;
         }
         
         public String toString() {
@@ -594,7 +596,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
                         }
                     }
                     int iLetterSpaces = wordLength - 1;
-                    // if the last character is '-' or '/' and the next one
+                    // if there is a break opportunity and the next one
                     // is not a space, it could be used as a line end;
                     // add one more letter space, in case other text follows
                     if (breakOpportunity && !isSpace(ch)) {
@@ -605,13 +607,13 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
                     // create the AreaInfo object
                     ai = new AreaInfo(iThisStart, iNextStart, (short) 0,
                             (short) iLetterSpaces,
-                            wordIPD, false, false);
+                            wordIPD, false, false, breakOpportunity);
                     vecAreaInfo.add(ai);
                     iTempStart = iNextStart;
 
                     // create the elements
                     sequence.addAll(createElementsForAWordFragment(alignment, ai,
-                            vecAreaInfo.size() - 1, letterSpaceIPD, breakOpportunity));
+                            vecAreaInfo.size() - 1, letterSpaceIPD));
                     ai = null;
 
                     iThisStart = iNextStart;
@@ -623,12 +625,12 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
                     ai = new AreaInfo(iThisStart, (short) (iNextStart),
                             (short) (iNextStart - iThisStart), (short) 0,
                             MinOptMax.multiply(wordSpaceIPD, iNextStart - iThisStart),
-                            false, true); 
+                            false, true, breakOpportunity); 
                     vecAreaInfo.add(ai);
 
                     // create the elements
                     sequence.addAll
-                        (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1, breakOpportunity));
+                        (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
                     ai = null;
 
                     iThisStart = iNextStart;
@@ -636,8 +638,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
             } else {
                 if (ai != null) {
                     vecAreaInfo.add(ai);
+                    ai.breakOppAfter = ch == CharUtilities.SPACE || breakOpportunity;
                     sequence.addAll
-                        (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1, ch == CharUtilities.SPACE || breakOpportunity));
+                        (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
                     ai = null;
                 }
                 if (breakAction == LineBreakStatus.EXPLICIT_BREAK) {
@@ -657,14 +660,14 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
                 // create the AreaInfo object
                 ai = new AreaInfo(iNextStart, (short) (iNextStart + 1),
                         (short) 1, (short) 0,
-                        wordSpaceIPD, false, true);
+                        wordSpaceIPD, false, true, breakOpportunity);
                 iThisStart = (short) (iNextStart + 1);
             } else if (CharUtilities.isFixedWidthSpace(ch)) {
                 // create the AreaInfo object
                 MinOptMax ipd = new MinOptMax(font.getCharWidth(ch));
                 ai = new AreaInfo(iNextStart, (short) (iNextStart + 1),
                         (short) 0, (short) 0,
-                        ipd, false, true); 
+                        ipd, false, true, breakOpportunity); 
                 iThisStart = (short) (iNextStart + 1);
             } else if (ch == NEWLINE) {
                 // linefeed; this can happen when linefeed-treatment="preserve"
@@ -705,29 +708,30 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
             // create the AreaInfo object
             ai = new AreaInfo(iThisStart, iNextStart, (short) 0,
                     (short) iLetterSpaces,
-                    wordIPD, false, false);
+                    wordIPD, false, false, false);
             vecAreaInfo.add(ai);
             iTempStart = iNextStart;
 
             // create the elements
             sequence.addAll(createElementsForAWordFragment(alignment, ai,
-                    vecAreaInfo.size() - 1, letterSpaceIPD, false));
+                    vecAreaInfo.size() - 1, letterSpaceIPD));
             ai = null;
         } else if (inWhitespace) {
             ai = new AreaInfo(iThisStart, (short) (iNextStart),
                     (short) (iNextStart - iThisStart), (short) 0,
                     MinOptMax.multiply(wordSpaceIPD, iNextStart - iThisStart),
-                    false, true); 
+                    false, true, true); 
             vecAreaInfo.add(ai);
 
             // create the elements
             sequence.addAll
-                (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1, true));
+                (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
             ai = null;
         } else if (ai != null) {
             vecAreaInfo.add(ai);
+            ai.breakOppAfter = ch == CharUtilities.ZERO_WIDTH_SPACE;
             sequence.addAll
-                (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1, ch == CharUtilities.ZERO_WIDTH_SPACE));
+                (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
             ai = null;
         } else if (ch == NEWLINE) {
             if (lineEndBAP != 0) {
@@ -885,7 +889,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
                                    (short) (bIsWordEnd
                                             ? (iStopIndex - iStartIndex - 1)
                                             : (iStopIndex - iStartIndex)),
-                                   newIPD, bHyphenFollows, false),
+                                   newIPD, bHyphenFollows, false, false),
                       ((LeafPosition) pos).getLeafPos()));
                 bNothingChanged = false;
             }
@@ -942,11 +946,11 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
             if (ai.iWScount == 0) {
                 // ai refers either to a word or a word fragment
                 returnList.addAll
-                (createElementsForAWordFragment(alignment, ai, iReturnedIndex, letterSpaceIPD, false));
+                (createElementsForAWordFragment(alignment, ai, iReturnedIndex, letterSpaceIPD));
             } else {
                 // ai refers to a space
                 returnList.addAll
-                (createElementsForASpace(alignment, ai, iReturnedIndex, textArray[ai.iStartIndex] == CharUtilities.SPACE));
+                (createElementsForASpace(alignment, ai, iReturnedIndex));
             }
             iReturnedIndex++;
         } // end of while
@@ -966,11 +970,11 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
     }
 
     private LinkedList createElementsForASpace(int alignment,
-            AreaInfo ai, int leafValue, boolean breakOpportunity) {
+            AreaInfo ai, int leafValue) {
         LinkedList spaceElements = new LinkedList();
         LeafPosition mainPosition = new LeafPosition(this, leafValue);
         
-        if (!breakOpportunity) {
+        if (!ai.breakOppAfter) {
             // a non-breaking space
             if (alignment == EN_JUSTIFY) {
                 // the space can stretch and shrink, and must be preserved
@@ -1204,14 +1208,14 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
     }
 
     private LinkedList createElementsForAWordFragment(int alignment,
-            AreaInfo ai, int leafValue, MinOptMax letterSpaceWidth, boolean breakOpportunity) {
+            AreaInfo ai, int leafValue, MinOptMax letterSpaceWidth) {
         LinkedList wordElements = new LinkedList();
         LeafPosition mainPosition = new LeafPosition(this, leafValue);
 
         // 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 = breakOpportunity;
+        boolean bSuppressibleLetterSpace = ai.breakOppAfter;
 
         if (letterSpaceWidth.min == letterSpaceWidth.max) {
             // constant letter spacing
diff --git a/test/layoutengine/hyphenation-testcases/block_uax14_linebreaking_hyph.xml b/test/layoutengine/hyphenation-testcases/block_uax14_linebreaking_hyph.xml
new file mode 100755 (executable)
index 0000000..e5bd584
--- /dev/null
@@ -0,0 +1,44 @@
+<?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>
+    This test checks some of the UAX#14 breaking rules under hyphenation.
+  </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="20mm" page-height="5in">
+          <fo:region-body/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="normal" language="de" hyphenate="true">
+        <fo:flow flow-name="xsl-region-body" font-size="20pt">
+          <fo:block>
+            Aggregierte Ausfallzeit IT-Komponente
+          </fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+ </fo>
+  <checks>
+      <eval expected="9" xpath="count(//flow/block/lineArea)"/>
+  </checks>
+</testcase>