1 /**************************************************************************** 2 * 3 * t1cmap.c 4 * 5 * Type 1 character map support (body). 6 * 7 * Copyright (C) 2002-2020 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 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 = (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 ) 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,FT_Pointer pointer)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 ) t1_cmap_expert_init(T1_CMapStd cmap,FT_Pointer pointer)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 ) t1_cmap_custom_init(T1_CMapCustom cmap,FT_Pointer pointer)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 ) t1_cmap_custom_done(T1_CMapCustom cmap)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 ) t1_cmap_custom_char_index(T1_CMapCustom cmap,FT_UInt32 char_code)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 ) t1_cmap_custom_char_next(T1_CMapCustom cmap,FT_UInt32 * pchar_code)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 * ) psaux_get_glyph_name(T1_Face face,FT_UInt idx)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 ) t1_cmap_unicode_init(PS_Unicodes unicodes,FT_Pointer pointer)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 ) t1_cmap_unicode_done(PS_Unicodes unicodes)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 ) t1_cmap_unicode_char_index(PS_Unicodes unicodes,FT_UInt32 char_code)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 ) t1_cmap_unicode_char_next(PS_Unicodes unicodes,FT_UInt32 * pchar_code)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 */ 375