44import org .apache .pdfbox .pdmodel .font .PDType1Font ;
55import org .fugerit .java .code .samples .pdfbox2 .SpecialCharacters ;
66import org .fugerit .java .core .lang .helpers .ClassHelper ;
7+ import org .fugerit .java .core .util .PropsIO ;
78import org .junit .jupiter .api .Assertions ;
89import org .junit .jupiter .api .Test ;
910
1011import java .io .*;
12+ import java .util .Arrays ;
13+ import java .util .HashMap ;
14+ import java .util .Map ;
15+ import java .util .Properties ;
16+ import java .util .regex .Matcher ;
17+ import java .util .regex .Pattern ;
1118
1219/*
1320 * Proof of Concept to handle special characters like U+2002 ('enspace')
@@ -34,13 +41,42 @@ class TestSpecialCharacters {
3441 "\u2212 " , // 'minus'
3542 "\u0141 " , // 'Lslash'
3643 "\u2103 " , // 'centigrade'
44+ "\u27E8 " , // '⟨',
45+ "\u27E9 " , // '⟩',
3746 };
3847
48+ private static final String HELVETICA = "Helvetica" ;
49+ private static final String DEJAVUSANS = "DejaVuSans" ;
50+ private static final String TEXGYREHEROS = "texgyreheros-regular" ;
51+ private static final String NOTOSANS = "NotoSans-Regular" ;
52+ private static final String IBMPLEXSANS = "IBMPlexSans-Regular" ;
53+
54+ private static final String [] TTF_LIST = {
55+ HELVETICA ,
56+ DEJAVUSANS ,
57+ TEXGYREHEROS ,
58+ NOTOSANS ,
59+ IBMPLEXSANS ,
60+ };
61+
62+ private static final Map <String , Integer > ERRORI ;
63+ static {
64+ ERRORI = new HashMap <>();
65+ ERRORI .put (HELVETICA , 2 );
66+ ERRORI .put (DEJAVUSANS , 0 );
67+ ERRORI .put (TEXGYREHEROS , 4 );
68+ ERRORI .put (NOTOSANS , 2 );
69+ ERRORI .put (IBMPLEXSANS , 3 );
70+ }
71+
72+ private static final Properties PATTERNS = PropsIO .loadFromClassLoaderSafe ( "font/patterns.properties" );
73+
3974 @ Test
4075 void testWithPdfBoxFontHelvetica () throws IOException {
4176 SpecialCharacters sp = new SpecialCharacters ();
42- for ( int k =0 ; k <SPECIAL_CHARACTERS .length ; k ++ ) {
43- String special = SPECIAL_CHARACTERS [k ];
77+ String [] specials = SPECIAL_CHARACTERS ;
78+ for ( int k =0 ; k <specials .length ; k ++ ) {
79+ String special = specials [k ];
4480 String line = String .format ( TEST_LINE , special );
4581 try (ByteArrayOutputStream os = new ByteArrayOutputStream ()) {
4682 log .info ( "testWithPdfBoxFontHelvetica index:{}, char:{}, line:{}" , k , special , line );
@@ -52,23 +88,34 @@ void testWithPdfBoxFontHelvetica() throws IOException {
5288 }
5389
5490 @ Test
55- void testWithExternalHelvetica () throws IOException {
56- // some characters are still not available on all font, for instance in this example :
57- // "\uFFFD", // '.notdef'
58- // "\u25AA", // 'H18543'
91+ void testWithExternalFonts () throws IOException {
5992 SpecialCharacters sp = new SpecialCharacters ();
60- for ( int k =0 ; k <SPECIAL_CHARACTERS .length ; k ++ ) {
61- String special = SPECIAL_CHARACTERS [k ];
62- String line = String .format ( TEST_LINE , special );
63- File pdfFile = new File ( String .format ( "target/test_font_external_%s.pdf" , k ) );
64- log .info ( "pdfFile: {}, delete: {}" , pdfFile , pdfFile .delete () );
65- Assertions .assertFalse ( pdfFile .exists () );
66- try (InputStream fontIS = ClassHelper .loadFromClassLoader ( "font/Helvetica.ttf" );
67- OutputStream os = new FileOutputStream ( pdfFile ) ) {
68- log .info ( "testWithExternalHelvetica index:{}, char:{}, line:{}" , k , special , line );
69- sp .generatePDF (os , fontIS , line );
93+ for ( String ttf : TTF_LIST ) {
94+ String fontPath = String .format ( "font/%s.ttf" , ttf );
95+ String [] specials = SPECIAL_CHARACTERS ;
96+ int countErrors = 0 ;
97+ StringBuilder errorList = new StringBuilder ();
98+ for ( int k =0 ; k <specials .length ; k ++ ) {
99+ String special = specials [k ];
100+ String unicode = String .format ( "u%04X" , (int )special .charAt ( 0 ) );
101+ String line = String .format ( TEST_LINE , special );
102+ File pdfFile = new File ( String .format ( "target/test_font_%s_%s.pdf" , ttf , unicode ) );
103+ log .info ( "pdfFile: {}, delete: {}" , pdfFile , pdfFile .delete () );
104+ Assertions .assertFalse ( pdfFile .exists () );
105+ try (InputStream fontIS = ClassHelper .loadFromClassLoader ( fontPath );
106+ OutputStream os = new FileOutputStream ( pdfFile ) ) {
107+ log .info ( "test '{}' index:{}, char:{}, line:{}" , ttf , k , special , line );
108+ sp .generatePDF (os , fontIS , line );
109+ } catch (Exception e ) {
110+ log .error ( "error on font : {} - {}" , ttf , e .getMessage () );
111+ pdfFile .delete ();
112+ errorList .append ( '\\' );
113+ errorList .append ( unicode );
114+ countErrors ++;
115+ }
70116 }
71- Assertions .assertTrue ( pdfFile .exists () );
117+ log .info ( "font : {}, countErrors: {}, errorList : [{}]" , ttf , countErrors , errorList );
118+ Assertions .assertEquals ( ERRORI .get ( ttf ), countErrors );
72119 }
73120 }
74121
@@ -81,4 +128,41 @@ void testWithPdfBoxFontHelveticaNormalLine() throws IOException {
81128 }
82129 }
83130
131+ private boolean check ( String regex , String input ) {
132+ Pattern pattern = Pattern .compile (regex );
133+ Matcher matcher = pattern .matcher (input );
134+ return matcher .find ();
135+ }
136+
137+ private static final String TEST_STRING_1 = "\u27E8 formula \u27E9 " ;
138+
139+ private static final String TEST_STRING_2 = "\u2002 test enscape" ;
140+
141+ @ Test
142+ void testHelvetica () {
143+ String testString1 = TEST_STRING_1 ;
144+ log .info ( "testString1 : {}" , testString1 );
145+ Assertions .assertTrue ( check ( PATTERNS .getProperty ( HELVETICA ), testString1 ) );
146+ Assertions .assertFalse ( check ( PATTERNS .getProperty ( DEJAVUSANS ), testString1 ) );
147+ String testString2 = TEST_STRING_2 ;
148+ log .info ( "testString2 : {}" , testString2 );
149+ Assertions .assertTrue ( check ( PATTERNS .getProperty ( TEXGYREHEROS ), testString2 ) );
150+ Assertions .assertFalse ( check ( PATTERNS .getProperty ( HELVETICA ), testString2 ) );
151+ }
152+
153+ private String choseFont ( String testText ) {
154+ for (String ttf : Arrays .asList ( HELVETICA , DEJAVUSANS ) ) {
155+ if ( !check ( PATTERNS .getProperty ( ttf ), testText ) ) {
156+ return ttf ;
157+ }
158+ }
159+ return null ;
160+ }
161+
162+ @ Test
163+ void testChoseFont () {
164+ Assertions .assertEquals ( DEJAVUSANS , choseFont ( TEST_STRING_1 ) );
165+ Assertions .assertEquals ( HELVETICA , choseFont ( TEST_STRING_2 ) );
166+ }
167+
84168}
0 commit comments