Browse Source

Fix for new linebreaking in combination with hyphenation not correctly breaking when explicit hyphen present

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@495175 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_94
Manuel Mall 17 years ago
parent
commit
edc6a56ccd

+ 25
- 21
src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java View 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

+ 44
- 0
test/layoutengine/hyphenation-testcases/block_uax14_linebreaking_hyph.xml View File

@@ -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>

Loading…
Cancel
Save