Skip to content

Commit 523702a

Browse files
committed
Fix font selection in case diacritic font doesn't contain previous symbol
DEVSIX-8285
1 parent c02f3a1 commit 523702a

File tree

8 files changed

+58
-4
lines changed

8 files changed

+58
-4
lines changed

layout/src/main/java/com/itextpdf/layout/font/selectorstrategy/AbstractFontSelectorStrategy.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,13 @@ public List<Tuple2<GlyphLine, PdfFont>> getGlyphLines(String text) {
112112
if (i > indexDiacritic) {
113113
if (TextUtil.isDiacritic(codePoint)) {
114114
final PdfFont diacriticFont = matchFont(codePoint, fontSelector, fontProvider, additionalFonts);
115+
// Diacritic font must contain previous symbol, if not, don't
116+
// enable special logic for diacritic and process it as usual symbol
117+
boolean isPreviousMatchFont =
118+
i == 0 || diacriticFont == null || diacriticFont.containsGlyph(extractCodePoint(text, i - 1));
115119
// If diacritic font equals to the current font or null, don't
116120
// enable special logic for diacritic and process it as usual symbol
117-
if (diacriticFont != null && diacriticFont != currentFont) {
121+
if (diacriticFont != null && diacriticFont != currentFont && isPreviousMatchFont) {
118122
// If it's the first diacritic in a row, we want to break to try to find a better font for
119123
// the previous letter during the next iteration
120124
if (indexDiacritic != i - 1) {

layout/src/test/java/com/itextpdf/layout/font/selectorstrategy/BestMatchFontSelectorStrategyTest.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ This file is part of the iText (R) project.
2626
import com.itextpdf.io.font.otf.GlyphLine;
2727
import com.itextpdf.kernel.font.PdfFont;
2828
import com.itextpdf.layout.font.selectorstrategy.BestMatchFontSelectorStrategy.BestMatchFontSelectorStrategyFactory;
29-
import com.itextpdf.layout.font.selectorstrategy.FirstMatchFontSelectorStrategy.FirstMathFontSelectorStrategyFactory;
3029
import com.itextpdf.test.ExtendedITextTest;
3130
import com.itextpdf.test.annotations.type.UnitTest;
3231

@@ -66,7 +65,7 @@ public void oneDiacriticTest() {
6665

6766
@Test
6867
public void oneDiacriticWithUnsupportedFontTest() {
69-
IFontSelectorStrategy strategy = FontSelectorTestsUtil.createStrategyWithTNR(new FirstMathFontSelectorStrategyFactory());
68+
IFontSelectorStrategy strategy = FontSelectorTestsUtil.createStrategyWithTNR(new BestMatchFontSelectorStrategyFactory());
7069

7170
final List<Tuple2<GlyphLine, PdfFont>> result = strategy.getGlyphLines(
7271
"L with accent: \u004f\u0302 abc");
@@ -78,9 +77,27 @@ public void oneDiacriticWithUnsupportedFontTest() {
7877
Assert.assertEquals(result.get(0).getSecond(), result.get(1).getSecond());
7978
}
8079

80+
@Test
81+
public void diacriticFontDoesnotContainPreviousSymbolTest() {
82+
IFontSelectorStrategy strategy = FontSelectorTestsUtil.createStrategyWithNotoSans(new BestMatchFontSelectorStrategyFactory());
83+
84+
final List<Tuple2<GlyphLine, PdfFont>> result = strategy.getGlyphLines(
85+
"Ми\u0301ръ (mírə)");
86+
Assert.assertEquals(6, result.size());
87+
Assert.assertEquals("Ми", result.get(0).getFirst().toString());
88+
Assert.assertEquals("\u0301", result.get(1).getFirst().toString());
89+
Assert.assertEquals("ръ", result.get(2).getFirst().toString());
90+
Assert.assertEquals(" (mír", result.get(3).getFirst().toString());
91+
Assert.assertEquals("ə", result.get(4).getFirst().toString());
92+
Assert.assertEquals(")", result.get(5).getFirst().toString());
93+
Assert.assertEquals(result.get(0).getSecond(), result.get(2).getSecond());
94+
Assert.assertEquals(result.get(2).getSecond(), result.get(3).getSecond());
95+
}
96+
97+
8198
@Test
8299
public void oneDiacriticWithOneSupportedFontTest() {
83-
IFontSelectorStrategy strategy = FontSelectorTestsUtil.createStrategyWithFreeSans(new FirstMathFontSelectorStrategyFactory());
100+
IFontSelectorStrategy strategy = FontSelectorTestsUtil.createStrategyWithFreeSans(new BestMatchFontSelectorStrategyFactory());
84101

85102
final List<Tuple2<GlyphLine, PdfFont>> result = strategy.getGlyphLines(
86103
"L with accent: \u004f\u0302 abc");

layout/src/test/java/com/itextpdf/layout/font/selectorstrategy/FirstMatchFontSelectorStrategyTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,23 @@ public void oneDiacriticTest() {
5959
Assert.assertNotEquals(result.get(0).getSecond(), result.get(1).getSecond());
6060
}
6161

62+
@Test
63+
public void diacriticFontDoesnotContainPreviousSymbolTest() {
64+
IFontSelectorStrategy strategy = FontSelectorTestsUtil.createStrategyWithNotoSans(new FirstMathFontSelectorStrategyFactory());
65+
66+
final List<Tuple2<GlyphLine, PdfFont>> result = strategy.getGlyphLines(
67+
"Ми\u0301ръ (mírə)");
68+
Assert.assertEquals(6, result.size());
69+
Assert.assertEquals("Ми", result.get(0).getFirst().toString());
70+
Assert.assertEquals("\u0301", result.get(1).getFirst().toString());
71+
Assert.assertEquals("ръ (", result.get(2).getFirst().toString());
72+
Assert.assertEquals("mír", result.get(3).getFirst().toString());
73+
Assert.assertEquals("ə", result.get(4).getFirst().toString());
74+
Assert.assertEquals(")", result.get(5).getFirst().toString());
75+
Assert.assertEquals(result.get(0).getSecond(), result.get(2).getSecond());
76+
Assert.assertEquals(result.get(2).getSecond(), result.get(3).getSecond());
77+
}
78+
6279
@Test
6380
public void oneDiacriticWithUnsupportedFontTest() {
6481
IFontSelectorStrategy strategy = FontSelectorTestsUtil.createStrategyWithTNR(new FirstMathFontSelectorStrategyFactory());

layout/src/test/java/com/itextpdf/layout/font/selectorstrategy/FontSelectorTestsUtil.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ This file is part of the iText (R) project.
2222
*/
2323
package com.itextpdf.layout.font.selectorstrategy;
2424

25+
import com.itextpdf.io.font.constants.StandardFontFamilies;
2526
import com.itextpdf.io.font.constants.StandardFonts;
2627
import com.itextpdf.layout.font.FontCharacteristics;
2728
import com.itextpdf.layout.font.FontProvider;
@@ -45,6 +46,18 @@ public static IFontSelectorStrategy createStrategyWithFreeSansAndTNR(IFontSelect
4546
return fontProvider.createFontSelectorStrategy(fontFamilies, new FontCharacteristics(), null);
4647
}
4748

49+
public static IFontSelectorStrategy createStrategyWithNotoSans(IFontSelectorStrategyFactory factory) {
50+
FontSet fs = new FontSet();
51+
fs.addFont(FONTS_FOLDER + "NotoKufiArabic-Regular.ttf");
52+
fs.addFont(FONTS_FOLDER + "NotoSansCJKjp-Regular.otf");
53+
fs.addFont(FONTS_FOLDER + "NotoSansCherokee-Regular.ttf");
54+
final FontProvider fontProvider = new FontProvider(fs, StandardFontFamilies.TIMES);
55+
fontProvider.setFontSelectorStrategyFactory(factory);
56+
List<String> fontFamilies = new ArrayList<>();
57+
fontFamilies.add("random");
58+
return fontProvider.createFontSelectorStrategy(fontFamilies, new FontCharacteristics(), null);
59+
}
60+
4861
public static IFontSelectorStrategy createStrategyWithTNR(IFontSelectorStrategyFactory factory) {
4962
FontSet fs = new FontSet();
5063
fs.addFont(StandardFonts.TIMES_ROMAN);

layout/src/test/resources/com/itextpdf/layout/fonts/NOTICE.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ Please notice that the following fonts are used with the mentioned below license
1111
* NotoSansThai-Regular - SIL Open Font License v1.1
1212
* Puritan2 - SIL Open Font License v1.1
1313
* NotoSansOldItalic-Regular.ttf - SIL Open Font License v1.1. Based on commit 20bc5918912503bc1537a407a694738c33c048aa (07.31.2020) from "https://github.com/googlefonts/noto-fonts"
14+
* NotoSansCJKjp-Regular.otf - SIL Open Font License v1.1
15+
* NotoSansCherokee-Regular.ttf - SIL Open Font License v1.1
16+
* NotoKufiArabic-Regular.ttf - SIL Open Font License v1.1
1417

1518

1619

Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)