Home | History | Annotate | Download | only in psaux
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  t1cmap.c                                                               */
      4 /*                                                                         */
      5 /*    Type 1 character map support (body).                                 */
      6 /*                                                                         */
      7 /*  Copyright 2002, 2003, 2006, 2007, 2012 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    = 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 != NULL );
     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   {
    125     t1_cmap_std_init( cmap, 0 );
    126     return 0;
    127   }
    128 
    129 
    130   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
    131   t1_cmap_standard_class_rec =
    132   {
    133     sizeof ( T1_CMapStdRec ),
    134 
    135     (FT_CMap_InitFunc)     t1_cmap_standard_init,
    136     (FT_CMap_DoneFunc)     t1_cmap_std_done,
    137     (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
    138     (FT_CMap_CharNextFunc) t1_cmap_std_char_next,
    139 
    140     NULL, NULL, NULL, NULL, NULL
    141   };
    142 
    143 
    144   FT_CALLBACK_DEF( FT_Error )
    145   t1_cmap_expert_init( T1_CMapStd  cmap )
    146   {
    147     t1_cmap_std_init( cmap, 1 );
    148     return 0;
    149   }
    150 
    151   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
    152   t1_cmap_expert_class_rec =
    153   {
    154     sizeof ( T1_CMapStdRec ),
    155 
    156     (FT_CMap_InitFunc)     t1_cmap_expert_init,
    157     (FT_CMap_DoneFunc)     t1_cmap_std_done,
    158     (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
    159     (FT_CMap_CharNextFunc) t1_cmap_std_char_next,
    160 
    161     NULL, NULL, NULL, NULL, NULL
    162   };
    163 
    164 
    165   /*************************************************************************/
    166   /*************************************************************************/
    167   /*****                                                               *****/
    168   /*****                    TYPE1 CUSTOM ENCODING CMAP                 *****/
    169   /*****                                                               *****/
    170   /*************************************************************************/
    171   /*************************************************************************/
    172 
    173 
    174   FT_CALLBACK_DEF( FT_Error )
    175   t1_cmap_custom_init( T1_CMapCustom  cmap )
    176   {
    177     T1_Face      face     = (T1_Face)FT_CMAP_FACE( cmap );
    178     T1_Encoding  encoding = &face->type1.encoding;
    179 
    180 
    181     cmap->first   = encoding->code_first;
    182     cmap->count   = (FT_UInt)( encoding->code_last - cmap->first );
    183     cmap->indices = encoding->char_index;
    184 
    185     FT_ASSERT( cmap->indices != NULL );
    186     FT_ASSERT( encoding->code_first <= encoding->code_last );
    187 
    188     return 0;
    189   }
    190 
    191 
    192   FT_CALLBACK_DEF( void )
    193   t1_cmap_custom_done( T1_CMapCustom  cmap )
    194   {
    195     cmap->indices = NULL;
    196     cmap->first   = 0;
    197     cmap->count   = 0;
    198   }
    199 
    200 
    201   FT_CALLBACK_DEF( FT_UInt )
    202   t1_cmap_custom_char_index( T1_CMapCustom  cmap,
    203                              FT_UInt32      char_code )
    204   {
    205     FT_UInt    result = 0;
    206 
    207 
    208     if ( ( char_code >= cmap->first )                  &&
    209          ( char_code < ( cmap->first + cmap->count ) ) )
    210       result = cmap->indices[char_code];
    211 
    212     return result;
    213   }
    214 
    215 
    216   FT_CALLBACK_DEF( FT_UInt32 )
    217   t1_cmap_custom_char_next( T1_CMapCustom  cmap,
    218                             FT_UInt32     *pchar_code )
    219   {
    220     FT_UInt    result = 0;
    221     FT_UInt32  char_code = *pchar_code;
    222 
    223 
    224     ++char_code;
    225 
    226     if ( char_code < cmap->first )
    227       char_code = cmap->first;
    228 
    229     for ( ; char_code < ( cmap->first + cmap->count ); char_code++ )
    230     {
    231       result = cmap->indices[char_code];
    232       if ( result != 0 )
    233         goto Exit;
    234     }
    235 
    236     char_code = 0;
    237 
    238   Exit:
    239     *pchar_code = char_code;
    240     return result;
    241   }
    242 
    243 
    244   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
    245   t1_cmap_custom_class_rec =
    246   {
    247     sizeof ( T1_CMapCustomRec ),
    248 
    249     (FT_CMap_InitFunc)     t1_cmap_custom_init,
    250     (FT_CMap_DoneFunc)     t1_cmap_custom_done,
    251     (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,
    252     (FT_CMap_CharNextFunc) t1_cmap_custom_char_next,
    253 
    254     NULL, NULL, NULL, NULL, NULL
    255   };
    256 
    257 
    258   /*************************************************************************/
    259   /*************************************************************************/
    260   /*****                                                               *****/
    261   /*****            TYPE1 SYNTHETIC UNICODE ENCODING CMAP              *****/
    262   /*****                                                               *****/
    263   /*************************************************************************/
    264   /*************************************************************************/
    265 
    266   FT_CALLBACK_DEF( const char * )
    267   psaux_get_glyph_name( T1_Face  face,
    268                         FT_UInt  idx )
    269   {
    270     return face->type1.glyph_names[idx];
    271   }
    272 
    273 
    274   FT_CALLBACK_DEF( FT_Error )
    275   t1_cmap_unicode_init( PS_Unicodes  unicodes )
    276   {
    277     T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
    278     FT_Memory           memory  = FT_FACE_MEMORY( face );
    279     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
    280 
    281 
    282     return psnames->unicodes_init( memory,
    283                                    unicodes,
    284                                    face->type1.num_glyphs,
    285                                    (PS_GetGlyphNameFunc)&psaux_get_glyph_name,
    286                                    (PS_FreeGlyphNameFunc)NULL,
    287                                    (FT_Pointer)face );
    288   }
    289 
    290 
    291   FT_CALLBACK_DEF( void )
    292   t1_cmap_unicode_done( PS_Unicodes  unicodes )
    293   {
    294     FT_Face    face   = FT_CMAP_FACE( unicodes );
    295     FT_Memory  memory = FT_FACE_MEMORY( face );
    296 
    297 
    298     FT_FREE( unicodes->maps );
    299     unicodes->num_maps = 0;
    300   }
    301 
    302 
    303   FT_CALLBACK_DEF( FT_UInt )
    304   t1_cmap_unicode_char_index( PS_Unicodes  unicodes,
    305                               FT_UInt32    char_code )
    306   {
    307     T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
    308     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
    309 
    310 
    311     return psnames->unicodes_char_index( unicodes, char_code );
    312   }
    313 
    314 
    315   FT_CALLBACK_DEF( FT_UInt32 )
    316   t1_cmap_unicode_char_next( PS_Unicodes  unicodes,
    317                              FT_UInt32   *pchar_code )
    318   {
    319     T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
    320     FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
    321 
    322 
    323     return psnames->unicodes_char_next( unicodes, pchar_code );
    324   }
    325 
    326 
    327   FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
    328   t1_cmap_unicode_class_rec =
    329   {
    330     sizeof ( PS_UnicodesRec ),
    331 
    332     (FT_CMap_InitFunc)     t1_cmap_unicode_init,
    333     (FT_CMap_DoneFunc)     t1_cmap_unicode_done,
    334     (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,
    335     (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next,
    336 
    337     NULL, NULL, NULL, NULL, NULL
    338   };
    339 
    340 
    341 /* END */
    342