ref: 6c7c3de197be9bf8352d2a744f2ddda5d6b4403b
dir: /src/psaux/t1cmap.c/
/***************************************************************************/ /* */ /* t1cmap.c */ /* */ /* Type 1 character map support (body). */ /* */ /* Copyright 2002, 2003, 2006, 2007, 2012 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #include "t1cmap.h" #include FT_INTERNAL_DEBUG_H #include "psauxerr.h" /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ static void t1_cmap_std_init( T1_CMapStd cmap, FT_Int is_expert ) { T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; cmap->num_glyphs = face->type1.num_glyphs; cmap->glyph_names = (const char* const*)face->type1.glyph_names; cmap->sid_to_string = psnames->adobe_std_strings; cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding : psnames->adobe_std_encoding; FT_ASSERT( cmap->code_to_sid != NULL ); } FT_CALLBACK_DEF( void ) t1_cmap_std_done( T1_CMapStd cmap ) { cmap->num_glyphs = 0; cmap->glyph_names = NULL; cmap->sid_to_string = NULL; cmap->code_to_sid = NULL; } FT_CALLBACK_DEF( FT_UInt ) t1_cmap_std_char_index( T1_CMapStd cmap, FT_UInt32 char_code ) { FT_UInt result = 0; if ( char_code < 256 ) { FT_UInt code, n; const char* glyph_name; /* convert character code to Adobe SID string */ code = cmap->code_to_sid[char_code]; glyph_name = cmap->sid_to_string( code ); /* look for the corresponding glyph name */ for ( n = 0; n < cmap->num_glyphs; n++ ) { const char* gname = cmap->glyph_names[n]; if ( gname && gname[0] == glyph_name[0] && ft_strcmp( gname, glyph_name ) == 0 ) { result = n; break; } } } return result; } FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_std_char_next( T1_CMapStd cmap, FT_UInt32 *pchar_code ) { FT_UInt result = 0; FT_UInt32 char_code = *pchar_code + 1; while ( char_code < 256 ) { result = t1_cmap_std_char_index( cmap, char_code ); if ( result != 0 ) goto Exit; char_code++; } char_code = 0; Exit: *pchar_code = char_code; return result; } FT_CALLBACK_DEF( FT_Error ) t1_cmap_standard_init( T1_CMapStd cmap ) { t1_cmap_std_init( cmap, 0 ); return 0; } FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec t1_cmap_standard_class_rec = { sizeof ( T1_CMapStdRec ), (FT_CMap_InitFunc) t1_cmap_standard_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, (FT_CMap_CharNextFunc) t1_cmap_std_char_next, NULL, NULL, NULL, NULL, NULL }; FT_CALLBACK_DEF( FT_Error ) t1_cmap_expert_init( T1_CMapStd cmap ) { t1_cmap_std_init( cmap, 1 ); return 0; } FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec t1_cmap_expert_class_rec = { sizeof ( T1_CMapStdRec ), (FT_CMap_InitFunc) t1_cmap_expert_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, (FT_CMap_CharNextFunc) t1_cmap_std_char_next, NULL, NULL, NULL, NULL, NULL }; /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** TYPE1 CUSTOM ENCODING CMAP *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_CALLBACK_DEF( FT_Error ) t1_cmap_custom_init( T1_CMapCustom cmap ) { T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); T1_Encoding encoding = &face->type1.encoding; cmap->first = encoding->code_first; cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); cmap->indices = encoding->char_index; FT_ASSERT( cmap->indices != NULL ); FT_ASSERT( encoding->code_first <= encoding->code_last ); return 0; } FT_CALLBACK_DEF( void ) t1_cmap_custom_done( T1_CMapCustom cmap ) { cmap->indices = NULL; cmap->first = 0; cmap->count = 0; } FT_CALLBACK_DEF( FT_UInt ) t1_cmap_custom_char_index( T1_CMapCustom cmap, FT_UInt32 char_code ) { FT_UInt result = 0; if ( ( char_code >= cmap->first ) && ( char_code < ( cmap->first + cmap->count ) ) ) result = cmap->indices[char_code]; return result; } FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_custom_char_next( T1_CMapCustom cmap, FT_UInt32 *pchar_code ) { FT_UInt result = 0; FT_UInt32 char_code = *pchar_code; ++char_code; if ( char_code < cmap->first ) char_code = cmap->first; for ( ; char_code < ( cmap->first + cmap->count ); char_code++ ) { result = cmap->indices[char_code]; if ( result != 0 ) goto Exit; } char_code = 0; Exit: *pchar_code = char_code; return result; } FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec t1_cmap_custom_class_rec = { sizeof ( T1_CMapCustomRec ), (FT_CMap_InitFunc) t1_cmap_custom_init, (FT_CMap_DoneFunc) t1_cmap_custom_done, (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, NULL, NULL, NULL, NULL, NULL }; /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_CALLBACK_DEF( const char * ) psaux_get_glyph_name( T1_Face face, FT_UInt idx ) { return face->type1.glyph_names[idx]; } FT_CALLBACK_DEF( FT_Error ) t1_cmap_unicode_init( PS_Unicodes unicodes ) { T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); FT_Memory memory = FT_FACE_MEMORY( face ); FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; return psnames->unicodes_init( memory, unicodes, face->type1.num_glyphs, (PS_GetGlyphNameFunc)&psaux_get_glyph_name, (PS_FreeGlyphNameFunc)NULL, (FT_Pointer)face ); } FT_CALLBACK_DEF( void ) t1_cmap_unicode_done( PS_Unicodes unicodes ) { FT_Face face = FT_CMAP_FACE( unicodes ); FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( unicodes->maps ); unicodes->num_maps = 0; } FT_CALLBACK_DEF( FT_UInt ) t1_cmap_unicode_char_index( PS_Unicodes unicodes, FT_UInt32 char_code ) { T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; return psnames->unicodes_char_index( unicodes, char_code ); } FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_unicode_char_next( PS_Unicodes unicodes, FT_UInt32 *pchar_code ) { T1_Face face = (T1_Face)FT_CMAP_FACE( unicodes ); FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; return psnames->unicodes_char_next( unicodes, pchar_code ); } FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec t1_cmap_unicode_class_rec = { sizeof ( PS_UnicodesRec ), (FT_CMap_InitFunc) t1_cmap_unicode_init, (FT_CMap_DoneFunc) t1_cmap_unicode_done, (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, NULL, NULL, NULL, NULL, NULL }; /* END */