1 /****************************************************************************
   2  *
   3  * t1cmap.c
   4  *
   5  *   Type 1 character map support (body).
   6  *
   7  * Copyright (C) 2002-2019 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 FT_INTERNAL_DEBUG_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( T1_CMapStd  cmap )
  54   {
  55     cmap->num_glyphs    = 0;
  56     cmap->glyph_names   = NULL;
  57     cmap->sid_to_string = NULL;
  58     cmap->code_to_sid   = NULL;
  59   }
  60 
  61 
  62   FT_CALLBACK_DEF( FT_UInt )
  63   t1_cmap_std_char_index( T1_CMapStd  cmap,
  64                           FT_UInt32   char_code )
  65   {
  66     FT_UInt  result = 0;
  67 
  68 
  69     if ( char_code < 256 )
  70     {
  71       FT_UInt      code, n;
  72       const char*  glyph_name;
  73 
  74 
  75       /* convert character code to Adobe SID string */
  76       code       = cmap->code_to_sid[char_code];
  77       glyph_name = cmap->sid_to_string( code );
  78 
  79       /* look for the corresponding glyph name */
  80       for ( n = 0; n < cmap->num_glyphs; n++ )
  81       {
  82         const char* gname = cmap->glyph_names[n];
  83 
  84 
  85         if ( gname && gname[0] == glyph_name[0]  &&
  86              ft_strcmp( gname, glyph_name ) == 0 )
  87         {
  88           result = n;
  89           break;
  90         }
  91       }
  92     }
  93 
  94     return result;
  95   }
  96 
  97 
  98   FT_CALLBACK_DEF( FT_UInt32 )
  99   t1_cmap_std_char_next( T1_CMapStd   cmap,
 100                          FT_UInt32   *pchar_code )
 101   {
 102     FT_UInt    result    = 0;
 103     FT_UInt32  char_code = *pchar_code + 1;
 104 
 105 
 106     while ( char_code < 256 )
 107     {
 108       result = t1_cmap_std_char_index( cmap, char_code );
 109       if ( result != 0 )
 110         goto Exit;
 111 
 112       char_code++;
 113     }
 114     char_code = 0;
 115 
 116   Exit:
 117     *pchar_code = char_code;
 118     return result;
 119   }
 120 
 121 
 122   FT_CALLBACK_DEF( FT_Error )
 123   t1_cmap_standard_init( T1_CMapStd  cmap,
 124                          FT_Pointer  pointer )
 125   {
 126     FT_UNUSED( pointer );
 127 
 128 
 129     t1_cmap_std_init( cmap, 0 );
 130     return 0;
 131   }
 132 
 133 
 134   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
 135   t1_cmap_standard_class_rec =
 136   {
 137     sizeof ( T1_CMapStdRec ),
 138 
 139     (FT_CMap_InitFunc)     t1_cmap_standard_init,   /* init       */
 140     (FT_CMap_DoneFunc)     t1_cmap_std_done,        /* done       */
 141     (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,  /* char_index */
 142     (FT_CMap_CharNextFunc) t1_cmap_std_char_next,   /* char_next  */
 143 
 144     (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
 145     (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
 146     (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
 147     (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
 148     (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
 149   };
 150 
 151 
 152   FT_CALLBACK_DEF( FT_Error )
 153   t1_cmap_expert_init( T1_CMapStd  cmap,
 154                        FT_Pointer  pointer )
 155   {
 156     FT_UNUSED( pointer );
 157 
 158 
 159     t1_cmap_std_init( cmap, 1 );
 160     return 0;
 161   }
 162 
 163   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
 164   t1_cmap_expert_class_rec =
 165   {
 166     sizeof ( T1_CMapStdRec ),
 167 
 168     (FT_CMap_InitFunc)     t1_cmap_expert_init,     /* init       */
 169     (FT_CMap_DoneFunc)     t1_cmap_std_done,        /* done       */
 170     (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,  /* char_index */
 171     (FT_CMap_CharNextFunc) t1_cmap_std_char_next,   /* char_next  */
 172 
 173     (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
 174     (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
 175     (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
 176     (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
 177     (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
 178   };
 179 
 180 
 181   /*************************************************************************/
 182   /*************************************************************************/
 183   /*****                                                               *****/
 184   /*****                    TYPE1 CUSTOM ENCODING CMAP                 *****/
 185   /*****                                                               *****/
 186   /*************************************************************************/
 187   /*************************************************************************/
 188 
 189 
 190   FT_CALLBACK_DEF( FT_Error )
 191   t1_cmap_custom_init( T1_CMapCustom  cmap,
 192                        FT_Pointer     pointer )
 193   {
 194     T1_Face      face     = (T1_Face)FT_CMAP_FACE( cmap );
 195     T1_Encoding  encoding = &face->type1.encoding;
 196 
 197     FT_UNUSED( pointer );
 198 
 199 
 200     cmap->first   = (FT_UInt)encoding->code_first;
 201     cmap->count   = (FT_UInt)encoding->code_last - cmap->first;
 202     cmap->indices = encoding->char_index;
 203 
 204     FT_ASSERT( cmap->indices );
 205     FT_ASSERT( encoding->code_first <= encoding->code_last );
 206 
 207     return 0;
 208   }
 209 
 210 
 211   FT_CALLBACK_DEF( void )
 212   t1_cmap_custom_done( T1_CMapCustom  cmap )
 213   {
 214     cmap->indices = NULL;
 215     cmap->first   = 0;
 216     cmap->count   = 0;
 217   }
 218 
 219 
 220   FT_CALLBACK_DEF( FT_UInt )
 221   t1_cmap_custom_char_index( T1_CMapCustom  cmap,
 222                              FT_UInt32      char_code )
 223   {
 224     FT_UInt    result = 0;
 225 
 226 
 227     if ( ( char_code >= cmap->first )                  &&
 228          ( char_code < ( cmap->first + cmap->count ) ) )
 229       result = cmap->indices[char_code];
 230 
 231     return result;
 232   }
 233 
 234 
 235   FT_CALLBACK_DEF( FT_UInt32 )
 236   t1_cmap_custom_char_next( T1_CMapCustom  cmap,
 237                             FT_UInt32     *pchar_code )
 238   {
 239     FT_UInt    result = 0;
 240     FT_UInt32  char_code = *pchar_code;
 241 
 242 
 243     char_code++;
 244 
 245     if ( char_code < cmap->first )
 246       char_code = cmap->first;
 247 
 248     for ( ; char_code < ( cmap->first + cmap->count ); char_code++ )
 249     {
 250       result = cmap->indices[char_code];
 251       if ( result != 0 )
 252         goto Exit;
 253     }
 254 
 255     char_code = 0;
 256 
 257   Exit:
 258     *pchar_code = char_code;
 259     return result;
 260   }
 261 
 262 
 263   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
 264   t1_cmap_custom_class_rec =
 265   {
 266     sizeof ( T1_CMapCustomRec ),
 267 
 268     (FT_CMap_InitFunc)     t1_cmap_custom_init,        /* init       */
 269     (FT_CMap_DoneFunc)     t1_cmap_custom_done,        /* done       */
 270     (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,  /* char_index */
 271     (FT_CMap_CharNextFunc) t1_cmap_custom_char_next,   /* char_next  */
 272 
 273     (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
 274     (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
 275     (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
 276     (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
 277     (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
 278   };
 279 
 280 
 281   /*************************************************************************/
 282   /*************************************************************************/
 283   /*****                                                               *****/
 284   /*****            TYPE1 SYNTHETIC UNICODE ENCODING CMAP              *****/
 285   /*****                                                               *****/
 286   /*************************************************************************/
 287   /*************************************************************************/
 288 
 289   FT_CALLBACK_DEF( const char * )
 290   psaux_get_glyph_name( T1_Face  face,
 291                         FT_UInt  idx )
 292   {
 293     return face->type1.glyph_names[idx];
 294   }
 295 
 296 
 297   FT_CALLBACK_DEF( FT_Error )
 298   t1_cmap_unicode_init( PS_Unicodes  unicodes,
 299                         FT_Pointer   pointer )
 300   {
 301     T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
 302     FT_Memory           memory  = FT_FACE_MEMORY( face );
 303     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
 304 
 305     FT_UNUSED( pointer );
 306 
 307 
 308     if ( !psnames->unicodes_init )
 309       return FT_THROW( Unimplemented_Feature );
 310 
 311     return psnames->unicodes_init( memory,
 312                                    unicodes,
 313                                    (FT_UInt)face->type1.num_glyphs,
 314                                    (PS_GetGlyphNameFunc)&psaux_get_glyph_name,
 315                                    (PS_FreeGlyphNameFunc)NULL,
 316                                    (FT_Pointer)face );
 317   }
 318 
 319 
 320   FT_CALLBACK_DEF( void )
 321   t1_cmap_unicode_done( PS_Unicodes  unicodes )
 322   {
 323     FT_Face    face   = FT_CMAP_FACE( unicodes );
 324     FT_Memory  memory = FT_FACE_MEMORY( face );
 325 
 326 
 327     FT_FREE( unicodes->maps );
 328     unicodes->num_maps = 0;
 329   }
 330 
 331 
 332   FT_CALLBACK_DEF( FT_UInt )
 333   t1_cmap_unicode_char_index( PS_Unicodes  unicodes,
 334                               FT_UInt32    char_code )
 335   {
 336     T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
 337     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
 338 
 339 
 340     return psnames->unicodes_char_index( unicodes, char_code );
 341   }
 342 
 343 
 344   FT_CALLBACK_DEF( FT_UInt32 )
 345   t1_cmap_unicode_char_next( PS_Unicodes  unicodes,
 346                              FT_UInt32   *pchar_code )
 347   {
 348     T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
 349     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
 350 
 351 
 352     return psnames->unicodes_char_next( unicodes, pchar_code );
 353   }
 354 
 355 
 356   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
 357   t1_cmap_unicode_class_rec =
 358   {
 359     sizeof ( PS_UnicodesRec ),
 360 
 361     (FT_CMap_InitFunc)     t1_cmap_unicode_init,        /* init       */
 362     (FT_CMap_DoneFunc)     t1_cmap_unicode_done,        /* done       */
 363     (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,  /* char_index */
 364     (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next,   /* char_next  */
 365 
 366     (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
 367     (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
 368     (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
 369     (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
 370     (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
 371   };
 372 
 373 
 374 /* END */