@@ -55,10 +55,14 @@ This file is part of the iText (R) project.
55
55
import org .slf4j .LoggerFactory ;
56
56
57
57
import com .itextpdf .io .util .MessageFormatUtil ;
58
+
59
+ import java .util .ArrayList ;
58
60
import java .util .LinkedHashMap ;
61
+ import java .util .List ;
59
62
import java .util .Map ;
60
63
import java .util .Objects ;
61
64
import java .util .Set ;
65
+ import java .util .SortedSet ;
62
66
63
67
public class TrueTypeFont extends FontProgram {
64
68
@@ -85,32 +89,30 @@ public class TrueTypeFont extends FontProgram {
85
89
86
90
private byte [] fontStreamBytes ;
87
91
92
+ private TrueTypeFont (OpenTypeParser fontParser ) throws java .io .IOException {
93
+ this .fontParser = fontParser ;
94
+ this .fontParser .loadTables (true );
95
+ initializeFontProperties ();
96
+ }
97
+
88
98
protected TrueTypeFont () {
89
99
fontNames = new FontNames ();
90
100
}
91
101
92
102
public TrueTypeFont (String path ) throws java .io .IOException {
93
- fontParser = new OpenTypeParser (path );
94
- fontParser .loadTables (true );
95
- initializeFontProperties ();
103
+ this (new OpenTypeParser (path ));
96
104
}
97
105
98
106
public TrueTypeFont (byte [] ttf ) throws java .io .IOException {
99
- fontParser = new OpenTypeParser (ttf );
100
- fontParser .loadTables (true );
101
- initializeFontProperties ();
107
+ this (new OpenTypeParser (ttf ));
102
108
}
103
109
104
110
TrueTypeFont (String ttcPath , int ttcIndex ) throws java .io .IOException {
105
- fontParser = new OpenTypeParser (ttcPath , ttcIndex );
106
- fontParser .loadTables (true );
107
- initializeFontProperties ();
111
+ this (new OpenTypeParser (ttcPath , ttcIndex ));
108
112
}
109
113
110
114
TrueTypeFont (byte [] ttc , int ttcIndex ) throws java .io .IOException {
111
- fontParser = new OpenTypeParser (ttc , ttcIndex );
112
- fontParser .loadTables (true );
113
- initializeFontProperties ();
115
+ this (new OpenTypeParser (ttc , ttcIndex ));
114
116
}
115
117
116
118
@ Override
@@ -370,4 +372,61 @@ public void close() throws java.io.IOException {
370
372
}
371
373
fontParser = null ;
372
374
}
375
+
376
+ /**
377
+ * The method will update usedGlyphs with additional range or with all glyphs if there is no subset.
378
+ * usedGlyphs can be used for width array and ToUnicode CMAP.
379
+ *
380
+ * @param usedGlyphs used glyphs that will be updated if needed.
381
+ * @param subset subset status
382
+ * @param subsetRanges additional subset ranges
383
+ */
384
+ public void updateUsedGlyphs (SortedSet <Integer > usedGlyphs , boolean subset , List <int []> subsetRanges ) {
385
+ int [] compactRange ;
386
+ if (subsetRanges != null ) {
387
+ compactRange = toCompactRange (subsetRanges );
388
+ } else if (!subset ) {
389
+ compactRange = new int [] {0 , 0xFFFF };
390
+ } else {
391
+ compactRange = new int [] {};
392
+ }
393
+
394
+ for (int k = 0 ; k < compactRange .length ; k += 2 ) {
395
+ int from = compactRange [k ];
396
+ int to = compactRange [k + 1 ];
397
+ for (int glyphId = from ; glyphId <= to ; glyphId ++) {
398
+ if (getGlyphByCode (glyphId ) != null ) {
399
+ usedGlyphs .add (glyphId );
400
+ }
401
+ }
402
+ }
403
+ }
404
+
405
+ private static int [] toCompactRange (List <int []> ranges ) {
406
+ List <int []> simp = new ArrayList <>();
407
+ for (int [] range : ranges ) {
408
+ for (int j = 0 ; j < range .length ; j += 2 ) {
409
+ simp .add (new int []{Math .max (0 , Math .min (range [j ], range [j + 1 ])), Math .min (0xffff , Math .max (range [j ], range [j + 1 ]))});
410
+ }
411
+ }
412
+ for (int k1 = 0 ; k1 < simp .size () - 1 ; ++k1 ) {
413
+ for (int k2 = k1 + 1 ; k2 < simp .size (); ++k2 ) {
414
+ int [] r1 = simp .get (k1 );
415
+ int [] r2 = simp .get (k2 );
416
+ if (r1 [0 ] >= r2 [0 ] && r1 [0 ] <= r2 [1 ] || r1 [1 ] >= r2 [0 ] && r1 [0 ] <= r2 [1 ]) {
417
+ r1 [0 ] = Math .min (r1 [0 ], r2 [0 ]);
418
+ r1 [1 ] = Math .max (r1 [1 ], r2 [1 ]);
419
+ simp .remove (k2 );
420
+ --k2 ;
421
+ }
422
+ }
423
+ }
424
+ int [] s = new int [simp .size () * 2 ];
425
+ for (int k = 0 ; k < simp .size (); ++k ) {
426
+ int [] r = simp .get (k );
427
+ s [k * 2 ] = r [0 ];
428
+ s [k * 2 + 1 ] = r [1 ];
429
+ }
430
+ return s ;
431
+ }
373
432
}
0 commit comments