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 t1_cmap_std_init(T1_CMapStd cmap,FT_Int is_expert)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 ) t1_cmap_std_done(T1_CMapStd cmap)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 ) t1_cmap_std_char_index(T1_CMapStd cmap,FT_UInt32 char_code)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 ) t1_cmap_std_char_next(T1_CMapStd cmap,FT_UInt32 * pchar_code)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 ) t1_cmap_standard_init(T1_CMapStd cmap)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 ) t1_cmap_expert_init(T1_CMapStd cmap)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 ) t1_cmap_custom_init(T1_CMapCustom cmap)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 ) t1_cmap_custom_done(T1_CMapCustom cmap)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 ) t1_cmap_custom_char_index(T1_CMapCustom cmap,FT_UInt32 char_code)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 ) t1_cmap_custom_char_next(T1_CMapCustom cmap,FT_UInt32 * pchar_code)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 * ) psaux_get_glyph_name(T1_Face face,FT_UInt idx)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 ) t1_cmap_unicode_init(PS_Unicodes unicodes)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 ) t1_cmap_unicode_done(PS_Unicodes unicodes)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 ) t1_cmap_unicode_char_index(PS_Unicodes unicodes,FT_UInt32 char_code)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 ) t1_cmap_unicode_char_next(PS_Unicodes unicodes,FT_UInt32 * pchar_code)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