freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Git][freetype/freetype-demos][dev/wl/VF-info] 5 commits: [ftdump] Print


From: Werner Lemberg (@wl)
Subject: [Git][freetype/freetype-demos][dev/wl/VF-info] 5 commits: [ftdump] Print CID-keyed font properties if available.
Date: Mon, 08 May 2023 04:53:08 +0000

Werner Lemberg pushed to branch dev/wl/VF-info at FreeType / FreeType Demo Programs

Commits:

  • 7c237f33
    by suzuki toshiya at 2023-05-06T01:50:35+09:00
    [ftdump] Print CID-keyed font properties if available.
    
    * src/ftdump.c
    
    (FT_CID_MAX): New macro.
    
    (usage): Mention the CID coverage in `-c' and `-C'
    options.
    
    (Print_UInt_Range): New function to print 2 numbers
    with a separator if needed.
    
    (Print_CIDs): New function to print the implemented
    CIDs in a compressed syntax.  If a case
    `gid_N < gid_M && CID_N > CID_M' is found, ftdump
    aborts and guide the user to file the issue.
    
    (Print_ROS_From_Face): New function to print the
    Registry, Ordering, and Supplement of the CID-keyed
    fonts, if available.  If `-c' or `-C' option is
    given, Print_CIDs() is invoked.
    
    (main): Invoke Print_ROS_From_Face().
    
  • cca8c1cc
    by Werner Lemberg at 2023-05-08T04:53:01+00:00
    * src/output.c: Handle `\0` specially.
    
    Broken or intentionally invalidated fonts might contain NULL bytes at
    arbitrary places.
    
  • 2c53b921
    by Werner Lemberg at 2023-05-08T04:53:01+00:00
    [ftdump] Code cleanup.
    
    * src/ftdump.c (Print_MM_Axes): Move code to find an English name entry
    to...
    (get_english_name_entry): ... this new function.
    
  • 381fe118
    by Werner Lemberg at 2023-05-08T04:53:01+00:00
    [ftdump] Show more variation font info.
    
    * src/ftdump.c (Print_MM_Axes): Rename to...
    (Print_MM_Info): ...this.
    Show Variation Font PostScript name prefix.
    Show named instances.
    
  • c7c92e58
    by Werner Lemberg at 2023-05-08T04:53:01+00:00
    * src/ftdump.c (Print_Sfnt_Tables): Insert spaces between bytes.
    

2 changed files:

Changes:

  • src/ftdump.c
    ... ... @@ -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
       {
    
    ... ... @@ -560,7 +687,7 @@
    560 687
           else
    
    561 688
             continue;
    
    562 689
     
    
    563
    -      printf( "  %2lu: %c%c%c%c %02X%02X%02X%02X...\n", i,
    
    690
    +      printf( "  %2lu: %c%c%c%c   %02X %02X %02X %02X ...\n", i,
    
    564 691
                                        (FT_Char)( tag >> 24 ),
    
    565 692
                                        (FT_Char)( tag >> 16 ),
    
    566 693
                                        (FT_Char)( tag >>  8 ),
    
    ... ... @@ -711,19 +838,53 @@
    711 838
     
    
    712 839
     
    
    713 840
       static void
    
    714
    -  Print_MM_Axes( FT_Face  face )
    
    841
    +  get_english_name_entry( FT_Face       face,
    
    842
    +                          FT_UInt       strid,
    
    843
    +                          FT_SfntName*  entry )
    
    844
    +  {
    
    845
    +    FT_UInt  num_names = FT_Get_Sfnt_Name_Count( face );
    
    846
    +    FT_UInt  i;
    
    847
    +
    
    848
    +    FT_SfntName  name;
    
    849
    +
    
    850
    +
    
    851
    +    for ( i = 0; i < num_names; i++ )
    
    852
    +    {
    
    853
    +      error = FT_Get_Sfnt_Name( face, i, &name );
    
    854
    +      if ( error )
    
    855
    +        continue;
    
    856
    +
    
    857
    +      if ( name.name_id == strid )
    
    858
    +      {
    
    859
    +        /* XXX we don't have support for Apple's new `ltag' table yet, */
    
    860
    +        /* thus we ignore TT_PLATFORM_APPLE_UNICODE                    */
    
    861
    +        if ( ( name.platform_id == TT_PLATFORM_MACINTOSH &&
    
    862
    +               name.language_id == TT_MAC_LANGID_ENGLISH )        ||
    
    863
    +             ( name.platform_id == TT_PLATFORM_MICROSOFT        &&
    
    864
    +               ( name.language_id & 0xFF )
    
    865
    +                                == TT_MS_LANGID_ENGLISH_GENERAL ) )
    
    866
    +          break;
    
    867
    +      }
    
    868
    +    }
    
    869
    +
    
    870
    +    if ( i < num_names )
    
    871
    +      *entry = name;
    
    872
    +  }
    
    873
    +
    
    874
    +
    
    875
    +  static void
    
    876
    +  Print_MM_Info( FT_Face  face )
    
    715 877
       {
    
    716 878
         FT_MM_Var*       mm;
    
    717 879
         FT_Multi_Master  dummy;
    
    718
    -    FT_UInt          is_GX, i, num_names;
    
    880
    +    FT_SfntName      name;
    
    881
    +    FT_UInt          is_GX, i;
    
    719 882
     
    
    720 883
     
    
    721 884
         /* MM or GX axes */
    
    722 885
         error = FT_Get_Multi_Master( face, &dummy );
    
    723 886
         is_GX = error ? 1 : 0;
    
    724 887
     
    
    725
    -    printf( "%s axes\n", is_GX ? "GX" : "MM" );
    
    726
    -
    
    727 888
         error = FT_Get_MM_Var( face, &mm );
    
    728 889
         if ( error )
    
    729 890
         {
    
    ... ... @@ -731,60 +892,134 @@
    731 892
           return;
    
    732 893
         }
    
    733 894
     
    
    734
    -    num_names = FT_Get_Sfnt_Name_Count( face );
    
    895
    +    printf( "%s info\n", is_GX ? "GX" : "MM" );
    
    896
    +
    
    897
    +    printf( "  axes (%u)\n", mm->num_axis );
    
    735 898
     
    
    736 899
         for ( i = 0; i < mm->num_axis; i++ )
    
    737 900
         {
    
    738
    -      FT_SfntName  name;
    
    739
    -
    
    740
    -
    
    741 901
           name.string = NULL;
    
    742 902
     
    
    743 903
           if ( is_GX )
    
    744
    -      {
    
    745
    -        FT_UInt  strid = mm->axis[i].strid;
    
    746
    -        FT_UInt  j;
    
    747
    -
    
    748
    -
    
    749
    -        /* iterate over all name entries        */
    
    750
    -        /* to find an English entry for `strid' */
    
    751
    -
    
    752
    -        for ( j = 0; j < num_names; j++ )
    
    753
    -        {
    
    754
    -          error = FT_Get_Sfnt_Name( face, j, &name );
    
    755
    -          if ( error )
    
    756
    -            continue;
    
    757
    -
    
    758
    -          if ( name.name_id == strid )
    
    759
    -          {
    
    760
    -            /* XXX we don't have support for Apple's new `ltag' table yet, */
    
    761
    -            /* thus we ignore TT_PLATFORM_APPLE_UNICODE                    */
    
    762
    -            if ( ( name.platform_id == TT_PLATFORM_MACINTOSH &&
    
    763
    -                   name.language_id == TT_MAC_LANGID_ENGLISH )        ||
    
    764
    -                 ( name.platform_id == TT_PLATFORM_MICROSOFT        &&
    
    765
    -                   ( name.language_id & 0xFF )
    
    766
    -                                    == TT_MS_LANGID_ENGLISH_GENERAL ) )
    
    767
    -              break;
    
    768
    -          }
    
    769
    -        }
    
    770
    -      }
    
    904
    +        get_english_name_entry( face, mm->axis[i].strid, &name );
    
    771 905
     
    
    906
    +      printf( "    %u: ", i );
    
    772 907
           if ( name.string )
    
    773 908
           {
    
    774 909
             if ( name.platform_id == TT_PLATFORM_MACINTOSH )
    
    775
    -          put_ascii( name.string, name.string_len, 3 );
    
    910
    +          put_ascii( name.string, name.string_len, 0 );
    
    776 911
             else
    
    777
    -          put_unicode_be16( name.string, name.string_len, 3, utf8 );
    
    912
    +          put_unicode_be16( name.string, name.string_len, 0, utf8 );
    
    778 913
           }
    
    779 914
           else
    
    780
    -        printf( "   %s", mm->axis[i].name );
    
    915
    +        printf( "%s", mm->axis[i].name );
    
    781 916
     
    
    782
    -      printf( ": [%g;%g], default %g\n",
    
    917
    +      printf( ", [%g;%g], default %g\n",
    
    783 918
                   mm->axis[i].minimum / 65536.0,
    
    784 919
                   mm->axis[i].maximum / 65536.0,
    
    785 920
                   mm->axis[i].def / 65536.0 );
    
    786 921
         }
    
    787 922
     
    
    923
    +    if ( is_GX )
    
    924
    +    {
    
    925
    +      FT_Fixed*    coords;
    
    926
    +      const char*  ps_name;
    
    927
    +
    
    928
    +      FT_Long              instance_count;
    
    929
    +      FT_UInt              default_named_instance;
    
    930
    +      FT_Var_Named_Style*  named_styles;
    
    931
    +
    
    932
    +
    
    933
    +      /* Show Variation PostScript Name Prefix. */
    
    934
    +
    
    935
    +      coords = (FT_Fixed*)malloc( mm->num_axis * sizeof ( FT_Fixed ) );
    
    936
    +      if ( coords == NULL )
    
    937
    +        return;
    
    938
    +
    
    939
    +      /* We temporarily activate variation font handling.  Because we */
    
    940
    +      /* use the default axes, the now retrieved PS name is identical */
    
    941
    +      /* to the PS name prefix.                                       */
    
    942
    +      FT_Get_Var_Design_Coordinates( face, mm->num_axis, coords );
    
    943
    +      FT_Set_Var_Design_Coordinates( face, mm->num_axis, coords );
    
    944
    +
    
    945
    +      ps_name = FT_Get_Postscript_Name( face );
    
    946
    +      if ( ps_name == NULL )
    
    947
    +        ps_name = "UNAVAILABLE";
    
    948
    +
    
    949
    +      printf( "\n"
    
    950
    +              "  VF PS name prefix: %s\n", ps_name );
    
    951
    +
    
    952
    +      /* Switch off variation font handling. */
    
    953
    +      FT_Set_Var_Design_Coordinates( face, 0, NULL );
    
    954
    +
    
    955
    +      free( coords );
    
    956
    +
    
    957
    +
    
    958
    +      /* Show named instances. */
    
    959
    +
    
    960
    +      instance_count = face->style_flags >> 16;
    
    961
    +      named_styles   = mm->namedstyle;
    
    962
    +
    
    963
    +      FT_Get_Default_Named_Instance( face, &default_named_instance );
    
    964
    +      default_named_instance--;   /* `named_styles` is a zero-based array */
    
    965
    +
    
    966
    +      printf( "\n" );
    
    967
    +      printf( "  named instances (%lu)\n", instance_count );
    
    968
    +
    
    969
    +      for ( i = 0; i < instance_count; i++ )
    
    970
    +      {
    
    971
    +        int        pos;
    
    972
    +        FT_UInt    j;
    
    973
    +        FT_Bool    semicolon;
    
    974
    +        FT_Fixed*  c;
    
    975
    +
    
    976
    +
    
    977
    +        /* Since FreeType starts the instance numbering with value 1 */
    
    978
    +        /* in `face_index` we report the same here for consistency.  */
    
    979
    +        pos = printf( "    %u: ", i + 1);
    
    980
    +
    
    981
    +        name.string = NULL;
    
    982
    +        get_english_name_entry( face, named_styles[i].strid, &name );
    
    983
    +        if ( name.string )
    
    984
    +        {
    
    985
    +          if ( name.platform_id == TT_PLATFORM_MACINTOSH )
    
    986
    +            put_ascii( name.string, name.string_len, 0 );
    
    987
    +          else
    
    988
    +            put_unicode_be16( name.string, name.string_len, 0, utf8 );
    
    989
    +        }
    
    990
    +        else
    
    991
    +          printf( "UNAVAILABLE" );
    
    992
    +        printf( "%s\n", i == default_named_instance ? " (default)" : "" );
    
    993
    +
    
    994
    +        name.string = NULL;
    
    995
    +        get_english_name_entry( face, named_styles[i].psid, &name );
    
    996
    +        printf( "%*s   PS: ", pos, "" );
    
    997
    +        if ( name.string )
    
    998
    +        {
    
    999
    +          if ( name.platform_id == TT_PLATFORM_MACINTOSH )
    
    1000
    +            put_ascii( name.string, name.string_len, 0 );
    
    1001
    +          else
    
    1002
    +            put_unicode_be16( name.string, name.string_len, 0, utf8 );
    
    1003
    +        }
    
    1004
    +        else
    
    1005
    +          printf( "UNAVAILABLE" );
    
    1006
    +        printf( "\n" );
    
    1007
    +
    
    1008
    +        semicolon = 0;
    
    1009
    +        c         = named_styles[i].coords;
    
    1010
    +
    
    1011
    +        printf( "%*scoord: (", pos, "" );
    
    1012
    +        for ( j = 0; j < mm->num_axis; j++ )
    
    1013
    +        {
    
    1014
    +          printf( "%s%g", semicolon ? ";" : "", c[j] / 65536.0);
    
    1015
    +          semicolon = 1;
    
    1016
    +        }
    
    1017
    +        printf( ")\n" );
    
    1018
    +      }
    
    1019
    +
    
    1020
    +      printf( "\n" );
    
    1021
    +    }
    
    1022
    +
    
    788 1023
         FT_Done_MM_Var( face->glyph->library, mm );
    
    789 1024
       }
    
    790 1025
     
    
    ... ... @@ -1350,10 +1585,15 @@
    1350 1585
             Print_Charmaps( face );
    
    1351 1586
           }
    
    1352 1587
     
    
    1588
    +      /* FT_IS_CID_KEYED() does not catch an OpenType/CFF,
    
    1589
    +       * let Print_ROS_From_Face() catch various cases.
    
    1590
    +       */
    
    1591
    +      Print_ROS_From_Face( face );
    
    1592
    +
    
    1353 1593
           if ( FT_HAS_MULTIPLE_MASTERS( face ) )
    
    1354 1594
           {
    
    1355 1595
             printf( "\n" );
    
    1356
    -        Print_MM_Axes( face );
    
    1596
    +        Print_MM_Info( face );
    
    1357 1597
           }
    
    1358 1598
     
    
    1359 1599
           FT_Done_Face( face );
    

  • src/output.c
    ... ... @@ -37,6 +37,11 @@
    37 37
         {
    
    38 38
           switch ( string[i] )
    
    39 39
           {
    
    40
    +      case '\0':
    
    41
    +        *out++ = '\\';
    
    42
    +        *out++ = '0';
    
    43
    +        break;
    
    44
    +
    
    40 45
           case '\n':
    
    41 46
             *out++ = '\\';
    
    42 47
             *out++ = 'n';
    
    ... ... @@ -125,6 +130,7 @@
    125 130
             }
    
    126 131
             break;
    
    127 132
     
    
    133
    +      case '\0':
    
    128 134
           case '\r':
    
    129 135
           case '\t':
    
    130 136
           case '\\':
    
    ... ... @@ -196,6 +202,11 @@
    196 202
     
    
    197 203
           switch ( ch )
    
    198 204
           {
    
    205
    +      case '\0':
    
    206
    +        *out++ = '\\';
    
    207
    +        *out++ = '0';
    
    208
    +        continue;
    
    209
    +
    
    199 210
           case '\n':
    
    200 211
             *out++ = '\\';
    
    201 212
             *out++ = 'n';
    
    ... ... @@ -350,6 +361,7 @@
    350 361
             }
    
    351 362
             continue;
    
    352 363
     
    
    364
    +      case '\0':
    
    353 365
           case '\r':
    
    354 366
           case '\t':
    
    355 367
           case '\\':
    


  • reply via email to

    [Prev in Thread] Current Thread [Next in Thread]