(root)/
freetype-2.13.2/
src/
psaux/
t1cmap.c
       1  /****************************************************************************
       2   *
       3   * t1cmap.c
       4   *
       5   *   Type 1 character map support (body).
       6   *
       7   * Copyright (C) 2002-2023 by
       8   * David Turner, Robert Wilhelm, and Werner Lemberg.
       9   *
      10   * This file is part of the FreeType project, and may only be used,
      11   * modified, and distributed under the terms of the FreeType project
      12   * license, LICENSE.TXT.  By continuing to use, modify, or distribute
      13   * this file you indicate that you have read the license and
      14   * understand and accept it fully.
      15   *
      16   */
      17  
      18  
      19  #include "t1cmap.h"
      20  
      21  #include <freetype/internal/ftdebug.h>
      22  
      23  #include "psauxerr.h"
      24  
      25  
      26    /*************************************************************************/
      27    /*************************************************************************/
      28    /*****                                                               *****/
      29    /*****          TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS           *****/
      30    /*****                                                               *****/
      31    /*************************************************************************/
      32    /*************************************************************************/
      33  
      34    static void
      35    t1_cmap_std_init( T1_CMapStd  cmap,
      36                      FT_Int      is_expert )
      37    {
      38      T1_Face             face    = (T1_Face)FT_CMAP_FACE( cmap );
      39      FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
      40  
      41  
      42      cmap->num_glyphs    = (FT_UInt)face->type1.num_glyphs;
      43      cmap->glyph_names   = (const char* const*)face->type1.glyph_names;
      44      cmap->sid_to_string = psnames->adobe_std_strings;
      45      cmap->code_to_sid   = is_expert ? psnames->adobe_expert_encoding
      46                                      : psnames->adobe_std_encoding;
      47  
      48      FT_ASSERT( cmap->code_to_sid );
      49    }
      50  
      51  
      52    FT_CALLBACK_DEF( void )
      53    t1_cmap_std_done( FT_CMap  cmap_ )   /* T1_CMapStd */
      54    {
      55      T1_CMapStd  cmap = (T1_CMapStd)cmap_;
      56  
      57  
      58      cmap->num_glyphs    = 0;
      59      cmap->glyph_names   = NULL;
      60      cmap->sid_to_string = NULL;
      61      cmap->code_to_sid   = NULL;
      62    }
      63  
      64  
      65    FT_CALLBACK_DEF( FT_UInt )
      66    t1_cmap_std_char_index( FT_CMap    cmap,       /* T1_CMapStd */
      67                            FT_UInt32  char_code )
      68    {
      69      T1_CMapStd  t1cmap = (T1_CMapStd)cmap;
      70      FT_UInt     result = 0;
      71  
      72  
      73      if ( char_code < 256 )
      74      {
      75        FT_UInt      code, n;
      76        const char*  glyph_name;
      77  
      78  
      79        /* convert character code to Adobe SID string */
      80        code       = t1cmap->code_to_sid[char_code];
      81        glyph_name = t1cmap->sid_to_string( code );
      82  
      83        /* look for the corresponding glyph name */
      84        for ( n = 0; n < t1cmap->num_glyphs; n++ )
      85        {
      86          const char* gname = t1cmap->glyph_names[n];
      87  
      88  
      89          if ( gname && gname[0] == glyph_name[0]  &&
      90               ft_strcmp( gname, glyph_name ) == 0 )
      91          {
      92            result = n;
      93            break;
      94          }
      95        }
      96      }
      97  
      98      return result;
      99    }
     100  
     101  
     102    FT_CALLBACK_DEF( FT_UInt )
     103    t1_cmap_std_char_next( FT_CMap     cmap,
     104                           FT_UInt32  *pchar_code )
     105    {
     106      FT_UInt    result    = 0;
     107      FT_UInt32  char_code = *pchar_code + 1;
     108  
     109  
     110      while ( char_code < 256 )
     111      {
     112        result = t1_cmap_std_char_index( cmap, char_code );
     113        if ( result != 0 )
     114          goto Exit;
     115  
     116        char_code++;
     117      }
     118      char_code = 0;
     119  
     120    Exit:
     121      *pchar_code = char_code;
     122      return result;
     123    }
     124  
     125  
     126    FT_CALLBACK_DEF( FT_Error )
     127    t1_cmap_standard_init( FT_CMap     cmap,     /* T1_CMapStd */
     128                           FT_Pointer  pointer )
     129    {
     130      T1_CMapStd  t1cmap = (T1_CMapStd)cmap;
     131      FT_UNUSED( pointer );
     132  
     133  
     134      t1_cmap_std_init( t1cmap, 0 );
     135      return 0;
     136    }
     137  
     138  
     139    FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
     140    t1_cmap_standard_class_rec =
     141    {
     142      sizeof ( T1_CMapStdRec ),
     143  
     144      (FT_CMap_InitFunc)     t1_cmap_standard_init,   /* init       */
     145      (FT_CMap_DoneFunc)     t1_cmap_std_done,        /* done       */
     146      (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,  /* char_index */
     147      (FT_CMap_CharNextFunc) t1_cmap_std_char_next,   /* char_next  */
     148  
     149      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
     150      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
     151      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
     152      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
     153      (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
     154    };
     155  
     156  
     157    FT_CALLBACK_DEF( FT_Error )
     158    t1_cmap_expert_init( FT_CMap     cmap,     /* T1_CMapStd */
     159                         FT_Pointer  pointer )
     160    {
     161      T1_CMapStd  t1cmap = (T1_CMapStd)cmap;
     162      FT_UNUSED( pointer );
     163  
     164  
     165      t1_cmap_std_init( t1cmap, 1 );
     166      return 0;
     167    }
     168  
     169    FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
     170    t1_cmap_expert_class_rec =
     171    {
     172      sizeof ( T1_CMapStdRec ),
     173  
     174      (FT_CMap_InitFunc)     t1_cmap_expert_init,     /* init       */
     175      (FT_CMap_DoneFunc)     t1_cmap_std_done,        /* done       */
     176      (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,  /* char_index */
     177      (FT_CMap_CharNextFunc) t1_cmap_std_char_next,   /* char_next  */
     178  
     179      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
     180      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
     181      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
     182      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
     183      (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
     184    };
     185  
     186  
     187    /*************************************************************************/
     188    /*************************************************************************/
     189    /*****                                                               *****/
     190    /*****                    TYPE1 CUSTOM ENCODING CMAP                 *****/
     191    /*****                                                               *****/
     192    /*************************************************************************/
     193    /*************************************************************************/
     194  
     195  
     196    FT_CALLBACK_DEF( FT_Error )
     197    t1_cmap_custom_init( FT_CMap     cmap,     /* T1_CMapCustom */
     198                         FT_Pointer  pointer )
     199    {
     200      T1_CMapCustom  t1cmap   = (T1_CMapCustom)cmap;
     201      T1_Face        face     = (T1_Face)FT_CMAP_FACE( cmap );
     202      T1_Encoding    encoding = &face->type1.encoding;
     203  
     204      FT_UNUSED( pointer );
     205  
     206  
     207      t1cmap->first   = (FT_UInt)encoding->code_first;
     208      t1cmap->count   = (FT_UInt)encoding->code_last - t1cmap->first;
     209      t1cmap->indices = encoding->char_index;
     210  
     211      FT_ASSERT( t1cmap->indices );
     212      FT_ASSERT( encoding->code_first <= encoding->code_last );
     213  
     214      return 0;
     215    }
     216  
     217  
     218    FT_CALLBACK_DEF( void )
     219    t1_cmap_custom_done( FT_CMap  cmap )   /* T1_CMapCustom */
     220    {
     221      T1_CMapCustom  t1cmap = (T1_CMapCustom)cmap;
     222  
     223  
     224      t1cmap->indices = NULL;
     225      t1cmap->first   = 0;
     226      t1cmap->count   = 0;
     227    }
     228  
     229  
     230    FT_CALLBACK_DEF( FT_UInt )
     231    t1_cmap_custom_char_index( FT_CMap    cmap,       /* T1_CMapCustom */
     232                               FT_UInt32  char_code )
     233    {
     234      T1_CMapCustom  t1cmap = (T1_CMapCustom)cmap;
     235      FT_UInt        result = 0;
     236  
     237  
     238      if ( char_code >= t1cmap->first                    &&
     239           char_code < ( t1cmap->first + t1cmap->count ) )
     240        result = t1cmap->indices[char_code];
     241  
     242      return result;
     243    }
     244  
     245  
     246    FT_CALLBACK_DEF( FT_UInt )
     247    t1_cmap_custom_char_next( FT_CMap     cmap,        /* T1_CMapCustom */
     248                              FT_UInt32  *pchar_code )
     249    {
     250      T1_CMapCustom  t1cmap    = (T1_CMapCustom)cmap;
     251      FT_UInt        result    = 0;
     252      FT_UInt32      char_code = *pchar_code;
     253  
     254  
     255      char_code++;
     256  
     257      if ( char_code < t1cmap->first )
     258        char_code = t1cmap->first;
     259  
     260      for ( ; char_code < ( t1cmap->first + t1cmap->count ); char_code++ )
     261      {
     262        result = t1cmap->indices[char_code];
     263        if ( result != 0 )
     264          goto Exit;
     265      }
     266  
     267      char_code = 0;
     268  
     269    Exit:
     270      *pchar_code = char_code;
     271      return result;
     272    }
     273  
     274  
     275    FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
     276    t1_cmap_custom_class_rec =
     277    {
     278      sizeof ( T1_CMapCustomRec ),
     279  
     280      (FT_CMap_InitFunc)     t1_cmap_custom_init,        /* init       */
     281      (FT_CMap_DoneFunc)     t1_cmap_custom_done,        /* done       */
     282      (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,  /* char_index */
     283      (FT_CMap_CharNextFunc) t1_cmap_custom_char_next,   /* char_next  */
     284  
     285      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
     286      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
     287      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
     288      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
     289      (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
     290    };
     291  
     292  
     293    /*************************************************************************/
     294    /*************************************************************************/
     295    /*****                                                               *****/
     296    /*****            TYPE1 SYNTHETIC UNICODE ENCODING CMAP              *****/
     297    /*****                                                               *****/
     298    /*************************************************************************/
     299    /*************************************************************************/
     300  
     301    FT_CALLBACK_DEF( const char * )
     302    psaux_get_glyph_name( void*    face_,
     303                          FT_UInt  idx )
     304    {
     305      T1_Face  face = (T1_Face)face_;
     306  
     307  
     308      return face->type1.glyph_names[idx];
     309    }
     310  
     311  
     312    FT_CALLBACK_DEF( FT_Error )
     313    t1_cmap_unicode_init( FT_CMap     cmap,     /* PS_Unicodes */
     314                          FT_Pointer  pointer )
     315    {
     316      PS_Unicodes         unicodes = (PS_Unicodes)cmap;
     317      T1_Face             face     = (T1_Face)FT_CMAP_FACE( cmap );
     318      FT_Memory           memory   = FT_FACE_MEMORY( face );
     319      FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
     320  
     321      FT_UNUSED( pointer );
     322  
     323  
     324      if ( !psnames->unicodes_init )
     325        return FT_THROW( Unimplemented_Feature );
     326  
     327      return psnames->unicodes_init( memory,
     328                                     unicodes,
     329                                     (FT_UInt)face->type1.num_glyphs,
     330                                     &psaux_get_glyph_name,
     331                                     (PS_FreeGlyphNameFunc)NULL,
     332                                     (FT_Pointer)face );
     333    }
     334  
     335  
     336    FT_CALLBACK_DEF( void )
     337    t1_cmap_unicode_done( FT_CMap  cmap )   /* PS_Unicodes */
     338    {
     339      PS_Unicodes  unicodes = (PS_Unicodes)cmap;
     340      FT_Face      face     = FT_CMAP_FACE( cmap );
     341      FT_Memory    memory   = FT_FACE_MEMORY( face );
     342  
     343  
     344      FT_FREE( unicodes->maps );
     345      unicodes->num_maps = 0;
     346    }
     347  
     348  
     349    FT_CALLBACK_DEF( FT_UInt )
     350    t1_cmap_unicode_char_index( FT_CMap    cmap,       /* PS_Unicodes */
     351                                FT_UInt32  char_code )
     352    {
     353      PS_Unicodes         unicodes = (PS_Unicodes)cmap;
     354      T1_Face             face     = (T1_Face)FT_CMAP_FACE( cmap );
     355      FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
     356  
     357  
     358      return psnames->unicodes_char_index( unicodes, char_code );
     359    }
     360  
     361  
     362    FT_CALLBACK_DEF( FT_UInt )
     363    t1_cmap_unicode_char_next( FT_CMap     cmap,        /* PS_Unicodes */
     364                               FT_UInt32  *pchar_code )
     365    {
     366      PS_Unicodes         unicodes = (PS_Unicodes)cmap;
     367      T1_Face             face     = (T1_Face)FT_CMAP_FACE( cmap );
     368      FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
     369  
     370  
     371      return psnames->unicodes_char_next( unicodes, pchar_code );
     372    }
     373  
     374  
     375    FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
     376    t1_cmap_unicode_class_rec =
     377    {
     378      sizeof ( PS_UnicodesRec ),
     379  
     380      (FT_CMap_InitFunc)     t1_cmap_unicode_init,        /* init       */
     381      (FT_CMap_DoneFunc)     t1_cmap_unicode_done,        /* done       */
     382      (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,  /* char_index */
     383      (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next,   /* char_next  */
     384  
     385      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
     386      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
     387      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
     388      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
     389      (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
     390    };
     391  
     392  
     393  /* END */