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