Skip to content

Commit 5b3aa94

Browse files
committed
Fix offset issue. Consider word bounds while word splitting. Add new hyphenation tests.
DEVSIX-1812
1 parent d14d440 commit 5b3aa94

File tree

5 files changed

+185
-4
lines changed

5 files changed

+185
-4
lines changed

layout/src/main/java/com/itextpdf/layout/hyphenation/HyphenationTree.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ public Hyphenation hyphenate(char[] w, int offset, int len,
528528
for (i = 0; i < len; i++) {
529529
if (((il[i + 1] & 1) == 1) && i >= remainCharCount
530530
&& i <= (len - pushCharCount)) {
531-
result[k++] = i + iIgnoreAtBeginning;
531+
result[k++] = i;
532532
}
533533
}
534534
}
@@ -538,7 +538,7 @@ public Hyphenation hyphenate(char[] w, int offset, int len,
538538
// trim result array
539539
int[] res = new int[k];
540540
System.arraycopy(result, 0, res, 0, k);
541-
return new Hyphenation(new String(w, offset, len), res);
541+
return new Hyphenation(new String(w, iIgnoreAtBeginning, len), res);
542542
} else {
543543
return null;
544544
}

layout/src/main/java/com/itextpdf/layout/renderer/TextRenderer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
385385
if (line.start == -1) {
386386
line.start = currentTextPos;
387387
}
388-
line.end = Math.max(line.end, currentTextPos + pre.length());
388+
line.end = Math.max(line.end, wordBounds[0] + pre.length());
389389
GlyphLine lineCopy = line.copy(line.start, line.end);
390390
lineCopy.add(font.getGlyph(hyphenationConfig.getHyphenSymbol()));
391391
lineCopy.end++;
@@ -400,7 +400,7 @@ public LayoutResult layout(LayoutContext layoutContext) {
400400
widthHandler.updateMinChildWidth(currentHyphenationChoicePreTextWidth + italicSkewAddition + boldSimulationAddition);
401401
widthHandler.updateMaxChildWidth(currentHyphenationChoicePreTextWidth + italicSkewAddition + boldSimulationAddition);
402402

403-
currentTextPos += pre.length();
403+
currentTextPos = wordBounds[0] + pre.length();
404404

405405
break;
406406
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2018 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
package com.itextpdf.layout;
44+
45+
import com.itextpdf.kernel.geom.PageSize;
46+
import com.itextpdf.kernel.pdf.PdfDocument;
47+
import com.itextpdf.kernel.pdf.PdfWriter;
48+
import com.itextpdf.kernel.utils.CompareTool;
49+
import com.itextpdf.layout.element.Paragraph;
50+
import com.itextpdf.layout.hyphenation.HyphenationConfig;
51+
import com.itextpdf.layout.hyphenation.Hyphenator;
52+
import com.itextpdf.test.ExtendedITextTest;
53+
import com.itextpdf.test.annotations.type.IntegrationTest;
54+
import org.junit.Assert;
55+
import org.junit.BeforeClass;
56+
import org.junit.Test;
57+
import org.junit.experimental.categories.Category;
58+
59+
@Category(IntegrationTest.class)
60+
public class HyphenateLayoutTest extends ExtendedITextTest {
61+
62+
public static final String sourceFolder = "./src/test/resources/com/itextpdf/layout/HyphenateLayoutTest/";
63+
public static final String destinationFolder = "./target/test/com/itextpdf/layout/HyphenateLayoutTest/";
64+
65+
@BeforeClass
66+
public static void beforeClass() {
67+
createDestinationFolder(destinationFolder);
68+
}
69+
70+
@Test
71+
public void parenthesisTest01() throws Exception {
72+
String outFileName = destinationFolder + "parenthesisTest01.pdf";
73+
String cmpFileName = sourceFolder + "cmp_parenthesisTest01.pdf";
74+
75+
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
76+
Document document = new Document(pdfDoc, new PageSize(300, 500));
77+
78+
Hyphenator hyphenator = new Hyphenator("de", "de", 3, 3);
79+
HyphenationConfig hyphenationConfig = new HyphenationConfig(hyphenator);
80+
document.setHyphenation(hyphenationConfig);
81+
82+
document.add(new Paragraph("1 (((\"|Annuitätendarlehen|\")))"));
83+
document.add(new Paragraph("2 ((\"|Annuitätendarlehen|\"))"));
84+
document.add(new Paragraph("3 (\"|Annuitätendarlehen|\")"));
85+
document.add(new Paragraph("4 \"|Annuitätendarlehen|\""));
86+
document.add(new Paragraph("5 \"Annuitätendarlehen\""));
87+
document.add(new Paragraph("6 Annuitätendarlehen"));
88+
89+
document.close();
90+
91+
Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
92+
}
93+
94+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2018 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
package com.itextpdf.layout;
44+
45+
import com.itextpdf.layout.hyphenation.Hyphenation;
46+
import com.itextpdf.layout.hyphenation.HyphenationConfig;
47+
import com.itextpdf.test.ExtendedITextTest;
48+
import com.itextpdf.test.annotations.type.UnitTest;
49+
import org.junit.Assert;
50+
import org.junit.Test;
51+
import org.junit.experimental.categories.Category;
52+
53+
@Category(UnitTest.class)
54+
public class HyphenateResultTest extends ExtendedITextTest {
55+
56+
@Test
57+
public void parenthesisTest01() {
58+
//Annuitätendarlehen
59+
testHyphenateResult("de", "((:::(\"|;Annuitätendarlehen|\")))", new int[]{5, 7, 10, 13, 15});
60+
}
61+
62+
@Test
63+
public void spacesTest01() {
64+
//Annuitätendarlehen
65+
testHyphenateResult("de", " Annuitätendarlehen", new int[]{5, 7, 10, 13, 15});
66+
}
67+
68+
@Test
69+
public void softHyphenTest01() {
70+
//Ann\u00ADuit\u00ADätendarl\u00ADehen
71+
testHyphenateResult("de", "Ann\u00ADuit\u00ADätendarl\u00ADehen", new int[]{3, 7, 16});
72+
}
73+
74+
75+
private void testHyphenateResult(String lang, String testWorld, int[] expectedHyphenatePoints) {
76+
String[] parts = lang.split("_");
77+
lang = parts[0];
78+
String country = (parts.length == 2) ? parts[1] : null;
79+
HyphenationConfig config = new HyphenationConfig(lang, country, 3, 3);
80+
Hyphenation result = config.hyphenate(testWorld);
81+
if (result != null) {
82+
Assert.assertArrayEquals(expectedHyphenatePoints, result.getHyphenationPoints());
83+
} else {
84+
Assert.assertNull(expectedHyphenatePoints);
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)