... |
... |
@@ -24,6 +24,7 @@ |
24
|
24
|
#include <freetype/tttags.h>
|
25
|
25
|
#include <freetype/t1tables.h>
|
26
|
26
|
|
|
27
|
+#include <freetype/ftcid.h>
|
27
|
28
|
|
28
|
29
|
/* error messages */
|
29
|
30
|
#undef FTERRORS_H_
|
... |
... |
@@ -114,7 +115,7 @@ |
114
|
115
|
execname );
|
115
|
116
|
|
116
|
117
|
fprintf( stderr,
|
117
|
|
- " -c, -C Print charmap coverage.\n"
|
|
118
|
+ " -c, -C Print charmap coverage and/or CID coverage.\n"
|
118
|
119
|
" -n Print SFNT 'name' table or Type1 font info.\n"
|
119
|
120
|
" -p Print TrueType programs.\n"
|
120
|
121
|
" -t Print SFNT table list.\n"
|
... |
... |
@@ -480,6 +481,132 @@ |
480
|
481
|
}
|
481
|
482
|
|
482
|
483
|
|
|
484
|
+ /*
|
|
485
|
+ * FreeType 2 API supports 32-bit gid, but
|
|
486
|
+ * the CIDFont does not support 32-bit CID,
|
|
487
|
+ * because of the 64k limit of the array
|
|
488
|
+ * and dictionary objects in PostScript.
|
|
489
|
+ */
|
|
490
|
+#ifndef FT_CID_MAX
|
|
491
|
+#define FT_CID_MAX 0xFFFFU
|
|
492
|
+#endif
|
|
493
|
+ /*
|
|
494
|
+ * Print a range specified by 2 integers.
|
|
495
|
+ */
|
|
496
|
+ static void
|
|
497
|
+ Print_UInt_Range( FT_UInt from,
|
|
498
|
+ FT_UInt to,
|
|
499
|
+ char* is_first )
|
|
500
|
+ {
|
|
501
|
+ if (!(*is_first))
|
|
502
|
+ printf(",");
|
|
503
|
+
|
|
504
|
+ if ( from == to )
|
|
505
|
+ printf( "%d", from );
|
|
506
|
+ else if ( from < to )
|
|
507
|
+ printf( "%d-%d", from, to );
|
|
508
|
+
|
|
509
|
+ *is_first = 0;
|
|
510
|
+ }
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+ /*
|
|
514
|
+ * Print implemented CIDs by calling
|
|
515
|
+ * FT_Get_CID_From_Glyph_Index() for all GIDs.
|
|
516
|
+ *
|
|
517
|
+ */
|
|
518
|
+ static void
|
|
519
|
+ Print_CIDs( FT_Face face )
|
|
520
|
+ {
|
|
521
|
+ FT_UInt gid = 0, max_gid = FT_UINT_MAX;
|
|
522
|
+ FT_UInt cid = 0, rng_from = 0, rng_to = 0;
|
|
523
|
+ char is_first_rng = 1;
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+ if ( face->num_glyphs < 1 )
|
|
527
|
+ return;
|
|
528
|
+
|
|
529
|
+ printf( "\n" );
|
|
530
|
+ printf( "CID coverage\n" );
|
|
531
|
+ printf( " " );
|
|
532
|
+
|
|
533
|
+ if ( (FT_ULong)face->num_glyphs < FT_UINT_MAX )
|
|
534
|
+ max_gid = (FT_UInt)face->num_glyphs;
|
|
535
|
+
|
|
536
|
+ for ( gid = 0; gid <= max_gid; gid ++ )
|
|
537
|
+ {
|
|
538
|
+ if ( FT_Get_CID_From_Glyph_Index( face, gid, &cid ) )
|
|
539
|
+ continue;
|
|
540
|
+
|
|
541
|
+ if ( FT_CID_MAX < cid )
|
|
542
|
+ {
|
|
543
|
+ fprintf( stderr, "gid=%d resulted too large CID=%d, ignore it\n", gid, cid );
|
|
544
|
+ break;
|
|
545
|
+ }
|
|
546
|
+
|
|
547
|
+ if ( rng_to == cid )
|
|
548
|
+ continue;
|
|
549
|
+ else if ( cid < rng_to )
|
|
550
|
+ {
|
|
551
|
+ fprintf( stderr, "Unordered GID-CID map is found, please file your issue on "
|
|
552
|
+ "https://gitlab.freedesktop.org/groups/freetype/-/issues\n" );
|
|
553
|
+ exit( 1 );
|
|
554
|
+ }
|
|
555
|
+ else if ( rng_to + 1 == cid )
|
|
556
|
+ {
|
|
557
|
+ rng_to = cid;
|
|
558
|
+ continue;
|
|
559
|
+ }
|
|
560
|
+
|
|
561
|
+ /* Found a gap (rng_to + 1 < cid), print the last range */
|
|
562
|
+ Print_UInt_Range( rng_from, rng_to, &is_first_rng );
|
|
563
|
+ rng_to = rng_from = cid;
|
|
564
|
+ }
|
|
565
|
+
|
|
566
|
+ Print_UInt_Range( rng_from, rng_to, &is_first_rng );
|
|
567
|
+
|
|
568
|
+ printf( "\n" );
|
|
569
|
+ }
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+ /*
|
|
573
|
+ * Print_CIDFontInfo_Dictionary() might be conventional,
|
|
574
|
+ * but other tables, like gcid, can have ROS info too.
|
|
575
|
+ */
|
|
576
|
+ static void
|
|
577
|
+ Print_ROS_From_Face( FT_Face face )
|
|
578
|
+ {
|
|
579
|
+ FT_Bool is_cid = 0;
|
|
580
|
+ const char* r = NULL;
|
|
581
|
+ const char* o = NULL;
|
|
582
|
+ FT_Int s = -1;
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+ if ( FT_Get_CID_Is_Internally_CID_Keyed( face, &is_cid ) )
|
|
586
|
+ return;
|
|
587
|
+
|
|
588
|
+ if ( !is_cid )
|
|
589
|
+ return;
|
|
590
|
+
|
|
591
|
+ if ( FT_Get_CID_Registry_Ordering_Supplement( face, &r, &o, &s ) )
|
|
592
|
+ return;
|
|
593
|
+
|
|
594
|
+ printf( "\n" );
|
|
595
|
+ printf( "/CIDSystemInfo dictionary\n" );
|
|
596
|
+
|
|
597
|
+ if ( r )
|
|
598
|
+ printf( "%s%s\n", Name_Field( "Registry" ), r );
|
|
599
|
+
|
|
600
|
+ if ( o )
|
|
601
|
+ printf( "%s%s\n", Name_Field( "Ordering" ), o );
|
|
602
|
+
|
|
603
|
+ printf( "%s%d\n", Name_Field( "Supplement" ), s );
|
|
604
|
+
|
|
605
|
+ if ( coverage > 0 )
|
|
606
|
+ Print_CIDs( face );
|
|
607
|
+ }
|
|
608
|
+
|
|
609
|
+
|
483
|
610
|
static void
|
484
|
611
|
Print_FontPrivate_Dictionary( PS_Private fp )
|
485
|
612
|
{
|
... |
... |
@@ -1350,6 +1477,11 @@ |
1350
|
1477
|
Print_Charmaps( face );
|
1351
|
1478
|
}
|
1352
|
1479
|
|
|
1480
|
+ /* FT_IS_CID_KEYED() does not catch an OpenType/CFF,
|
|
1481
|
+ * let Print_ROS_From_Face() catch various cases.
|
|
1482
|
+ */
|
|
1483
|
+ Print_ROS_From_Face( face );
|
|
1484
|
+
|
1353
|
1485
|
if ( FT_HAS_MULTIPLE_MASTERS( face ) )
|
1354
|
1486
|
{
|
1355
|
1487
|
printf( "\n" );
|