Skip to content

Commit 794684a

Browse files
author
Joao Goncalves
committed
FOP-2880 Use soft hyphen for hyphenation
1 parent aed8a72 commit 794684a

File tree

11 files changed

+149
-9
lines changed

11 files changed

+149
-9
lines changed

fop-core/src/main/codegen/fonts/encodings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@
293293
<glyph codepoint='aa' name='ordfeminine'/>
294294
<glyph codepoint='ab' name='guillemotleft'/>
295295
<glyph codepoint='ac' name='logicalnot'/>
296-
<glyph codepoint='ad' name='hyphen'/>
296+
<glyph codepoint='ad' name='softhyphen'/>
297297
<glyph codepoint='ae' name='registered'/>
298298
<glyph codepoint='af' name='macron'/>
299299
<glyph codepoint='b0' name='degree'/>
@@ -938,6 +938,7 @@
938938
<glyph codepoint='aa' name='ordfeminine'/>
939939
<glyph codepoint='ab' name='guillemotleft'/>
940940
<glyph codepoint='ac' name='logicalnot'/>
941+
<glyph codepoint='ad' name='softhyphen'/>
941942
<glyph codepoint='ae' name='registered'/>
942943
<glyph codepoint='af' name='macron'/>
943944
<glyph codepoint='b0' name='degree'/>

fop-core/src/main/codegen/fonts/glyphlist.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@
788788
<glyph codepoint='2302' name='house'/>
789789
<glyph codepoint='02DD' name='hungarumlaut'/>
790790
<glyph codepoint='002D' name='hyphen'/>
791-
<glyph codepoint='00AD' name='hyphen'/>
791+
<glyph codepoint='00AD' name='softhyphen'/>
792792
<glyph codepoint='F6E5' name='hypheninferior'/>
793793
<glyph codepoint='F6E6' name='hyphensuperior'/>
794794
<glyph codepoint='0069' name='i'/>

fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,4 +514,8 @@ protected boolean drawSVGText(MultiByteFont multiByteFont, FontTriplet triplet,
514514
}
515515
return true;
516516
}
517+
518+
public boolean supportsSoftHyphen() {
519+
return false;
520+
}
517521
}

fop-core/src/main/java/org/apache/fop/render/intermediate/IFPainter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,10 @@ void drawLine(Point start, Point end, int width, Color color, RuleStyle style)
261261

262262
//etc. etc.
263263

264+
/**
265+
* Allows specific painters to indicate whether a soft hyphen is supported.
266+
*
267+
* @return true if the painter supports soft hyphens, false otherwise
268+
*/
269+
boolean supportsSoftHyphen();
264270
}

fop-core/src/main/java/org/apache/fop/render/intermediate/IFParser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import org.apache.fop.util.ContentHandlerFactoryRegistry;
6767
import org.apache.fop.util.DOMBuilderContentHandlerFactory;
6868
import org.apache.fop.util.LanguageTags;
69+
import org.apache.fop.util.StringUtils;
6970
import org.apache.fop.util.XMLUtil;
7071
import org.apache.fop.utils.DefaultErrorListener;
7172

@@ -683,7 +684,9 @@ public void endElement() throws IFException {
683684
documentHandler.getContext().setHyphenated(isHyphenated);
684685
}
685686
boolean nextIsSpace = Boolean.valueOf(lastAttributes.getValue("next-is-space"));
686-
painter.drawText(x, y, letterSpacing, wordSpacing, dp, content.toString(), nextIsSpace);
687+
688+
painter.drawText(x, y, letterSpacing, wordSpacing, dp,
689+
StringUtils.processSoftHyphen(content.toString(), painter), nextIsSpace);
687690
documentHandler.getContext().setHyphenated(false);
688691
resetStructureTreeElement();
689692
}

fop-core/src/main/java/org/apache/fop/render/intermediate/IFRenderer.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
import org.apache.fop.render.intermediate.extensions.URIAction;
9999
import org.apache.fop.traits.BorderProps;
100100
import org.apache.fop.traits.RuleStyle;
101+
import org.apache.fop.util.StringUtils;
101102

102103
/**
103104
* This renderer implementation is an adapter to the {@link IFPainter} interface. It is used
@@ -1240,8 +1241,8 @@ void flush() {
12401241
painter.drawText(startx, starty, 0, 0,
12411242
trimAdjustments(dp, text.length()), text.toString());
12421243
} else { */
1243-
painter.drawText(startx, starty, tls, tws,
1244-
trimAdjustments(dp, text.length()), text.toString(), nextIsSpace);
1244+
painter.drawText(startx, starty, tls, tws, trimAdjustments(dp, text.length()),
1245+
StringUtils.processSoftHyphen(text.toString(), painter), nextIsSpace);
12451246
/* } */
12461247
} catch (IFException e) {
12471248
handleIFException(e);
@@ -1252,7 +1253,7 @@ void flush() {
12521253

12531254
void drawText(int x, int y, int letterSpacing, int wordSpacing, int[][] dx, String text, boolean nextIsSpace)
12541255
throws IFException {
1255-
painter.drawText(startx, starty, tls, tws, dx, text, nextIsSpace);
1256+
painter.drawText(startx, starty, tls, tws, dx, StringUtils.processSoftHyphen(text, painter), nextIsSpace);
12561257
}
12571258

12581259
/**

fop-core/src/main/java/org/apache/fop/render/intermediate/IFSerializer.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,11 @@ public void drawImage(Document doc, Rectangle rect) throws IFException {
523523
}
524524
}
525525

526+
@Override
527+
public boolean supportsSoftHyphen() {
528+
return false;
529+
}
530+
526531
private static String toString(Paint paint) {
527532
if (paint instanceof Color) {
528533
return ColorUtil.colorToString((Color)paint);

fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,4 +649,9 @@ private int selectAndMapSingleByteFont(Typeface tf, String fontName, float fontS
649649
return ch;
650650
}
651651

652+
@Override
653+
public boolean supportsSoftHyphen() {
654+
return true;
655+
}
656+
652657
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/* $Id$ */
19+
20+
package org.apache.fop.util;
21+
22+
import org.apache.fop.render.intermediate.IFPainter;
23+
24+
public final class StringUtils {
25+
26+
private StringUtils() {
27+
}
28+
29+
public static String processSoftHyphen(String text, IFPainter painter) {
30+
if (!painter.supportsSoftHyphen()) {
31+
return text.replace(CharUtilities.SOFT_HYPHEN, '-');
32+
}
33+
return text;
34+
}
35+
36+
}

fop-core/src/test/java/org/apache/fop/render/intermediate/IFRendererTestCase.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,18 @@
3333
import javax.xml.transform.sax.SAXResult;
3434
import javax.xml.transform.stream.StreamSource;
3535

36-
import org.junit.Assert;
3736
import org.junit.Test;
3837

38+
import static org.junit.Assert.assertFalse;
39+
import static org.junit.Assert.assertTrue;
40+
3941
import org.apache.fop.apps.FOPException;
4042
import org.apache.fop.apps.FOUserAgent;
4143
import org.apache.fop.apps.Fop;
4244
import org.apache.fop.apps.FopFactory;
4345
import org.apache.fop.apps.FopFactoryBuilder;
4446
import org.apache.fop.area.inline.WordArea;
47+
import org.apache.fop.util.CharUtilities;
4548

4649
public class IFRendererTestCase {
4750
private List<WordArea> wordAreas = new ArrayList<WordArea>();
@@ -80,7 +83,46 @@ public void testWordSpace() throws FOPException, TransformerException {
8083
+ " </fo:page-sequence>\n"
8184
+ "</fo:root>";
8285
foToOutput(new ByteArrayInputStream(fo.getBytes()));
83-
Assert.assertTrue(wordAreas.get(0).isNextIsSpace());
84-
Assert.assertFalse(wordAreas.get(1).isNextIsSpace());
86+
assertTrue(wordAreas.get(0).isNextIsSpace());
87+
assertFalse(wordAreas.get(1).isNextIsSpace());
88+
}
89+
90+
@Test
91+
public void testSoftHyphen() throws FOPException, TransformerException {
92+
String fo = getSoftHyphenTestFO("&#x00AD;");
93+
foToOutput(new ByteArrayInputStream(fo.getBytes()));
94+
assertTrue("PDF files are able to handle the soft hyphen, so must not replace with normal hyphen",
95+
wordAreas.get(1).getWord().endsWith(String.valueOf(CharUtilities.SOFT_HYPHEN)));
96+
97+
98+
wordAreas = new ArrayList<>();
99+
fo = getSoftHyphenTestFO("-");
100+
foToOutput(new ByteArrayInputStream(fo.getBytes()));
101+
assertTrue("Must not replace the hyphenation character", wordAreas.get(1).getWord().endsWith("-"));
102+
103+
wordAreas = new ArrayList<>();
104+
fo = getSoftHyphenTestFO("/");
105+
foToOutput(new ByteArrayInputStream(fo.getBytes()));
106+
assertTrue("Must not replace the hyphenation character", wordAreas.get(1).getWord().endsWith("/"));
107+
}
108+
109+
private String getSoftHyphenTestFO(String hyphenationCharacter) {
110+
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
111+
+ "<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\" "
112+
+ "xmlns:fox=\"http://xmlgraphics.apache.org/fop/extensions\">\n"
113+
+ "\t<fo:layout-master-set>\n"
114+
+ "\t\t<fo:simple-page-master master-name=\"mainPage\" page-width=\"90pt\">\n"
115+
+ "\t\t\t<fo:region-body/>\n"
116+
+ "\t\t</fo:simple-page-master>\n"
117+
+ "\t</fo:layout-master-set>\n"
118+
+ "\t<fo:page-sequence master-reference=\"mainPage\">\n"
119+
+ "\t\t<fo:flow flow-name=\"xsl-region-body\">\n"
120+
+ "\t\t\t<fo:block language=\"en\" country=\"GB\" hyphenate=\"true\" page-break-inside=\"auto\" "
121+
+ "hyphenation-character=\"" + hyphenationCharacter + "\">\n"
122+
+ "\t\t\t\tcomputer computer computer computer computer computer computer computer\n"
123+
+ "\t\t\t</fo:block>\n"
124+
+ "\t\t</fo:flow>\n"
125+
+ "\t</fo:page-sequence>\n"
126+
+ "</fo:root>";
85127
}
86128
}

0 commit comments

Comments
 (0)