@@ -161,7 +161,8 @@ protected TextRenderer(TextRenderer other) {
161
161
public LayoutResult layout (LayoutContext layoutContext ) {
162
162
updateFontAndText ();
163
163
if (null != text ) {
164
- text = getGlyphlineWithSpacesInsteadOfTabs (text );
164
+ // if text != null => font != null
165
+ text = replaceSpecialWhitespaceGlyphs (text , font );
165
166
}
166
167
167
168
LayoutArea area = layoutContext .getArea ();
@@ -1139,7 +1140,9 @@ protected boolean resolveFonts(List<IRenderer> addTo) {
1139
1140
FontSelectorStrategy strategy = provider .getStrategy (strToBeConverted ,
1140
1141
FontFamilySplitter .splitFontFamily ((String ) font ), fc , fontSet );
1141
1142
while (!strategy .endOfText ()) {
1142
- TextRenderer textRenderer = createCopy (getGlyphlineWithSpacesInsteadOfTabs (new GlyphLine (strategy .nextGlyphs ())), strategy .getCurrentFont ());
1143
+ GlyphLine nextGlyphs = new GlyphLine (strategy .nextGlyphs ());
1144
+ PdfFont currentFont = strategy .getCurrentFont ();
1145
+ TextRenderer textRenderer = createCopy (replaceSpecialWhitespaceGlyphs (nextGlyphs , currentFont ), currentFont );
1143
1146
addTo .add (textRenderer );
1144
1147
}
1145
1148
return true ;
@@ -1296,21 +1299,42 @@ private void saveWordBreakIfNotYetSaved(Glyph wordBreak) {
1296
1299
}
1297
1300
}
1298
1301
1299
- private GlyphLine getGlyphlineWithSpacesInsteadOfTabs (GlyphLine line ) {
1302
+ private static GlyphLine replaceSpecialWhitespaceGlyphs (GlyphLine line , PdfFont font ) {
1300
1303
if (null != line ) {
1301
- Glyph space = new Glyph (resolveFirstPdfFont ().getGlyph ('\u0020' ));
1302
- space .setXAdvance ((short ) (3 * space .getWidth ()));
1304
+ Glyph space = font .getGlyph ('\u0020' );
1303
1305
Glyph glyph ;
1304
1306
for (int i = 0 ; i < line .size (); i ++) {
1305
1307
glyph = line .get (i );
1306
- if ('\t' == glyph .getUnicode ()) {
1307
- line .set (i , space );
1308
+ Integer xAdvance = getSpecialWhitespaceXAdvance (glyph , space , font .getFontProgram ().getFontMetrics ().isFixedPitch ());
1309
+ if (xAdvance != null ) {
1310
+ Glyph newGlyph = new Glyph (space , glyph .getUnicode ());
1311
+ assert xAdvance <= Short .MAX_VALUE && xAdvance >= Short .MIN_VALUE ;
1312
+ newGlyph .setXAdvance ((short ) (int )xAdvance );
1313
+ line .set (i , newGlyph );
1308
1314
}
1309
1315
}
1310
1316
}
1311
1317
return line ;
1312
1318
}
1313
1319
1320
+ private static Integer getSpecialWhitespaceXAdvance (Glyph glyph , Glyph spaceGlyph , boolean isMonospaceFont ) {
1321
+ if (glyph .getCode () > 0 ) {
1322
+ return null ;
1323
+ }
1324
+ switch (glyph .getUnicode ()) {
1325
+ case '\u2002' : // ensp
1326
+ return isMonospaceFont ? 0 : 500 - spaceGlyph .getWidth ();
1327
+ case '\u2003' : // emsp
1328
+ return isMonospaceFont ? 0 : 1000 - spaceGlyph .getWidth ();
1329
+ case '\u2009' : // thinsp
1330
+ return isMonospaceFont ? 0 : 200 - spaceGlyph .getWidth ();
1331
+ case '\t' :
1332
+ return 3 * spaceGlyph .getWidth ();
1333
+ }
1334
+
1335
+ return null ;
1336
+ }
1337
+
1314
1338
private static class ReversedCharsIterator implements Iterator <GlyphLine .GlyphLinePart > {
1315
1339
private List <Integer > outStart ;
1316
1340
private List <Integer > outEnd ;
0 commit comments