1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* t1cmap.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* Type 1 character map support (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 2002 by */ 8*37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9*37da2899SCharles.Forsyth /* */ 10*37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11*37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12*37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13*37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14*37da2899SCharles.Forsyth /* understand and accept it fully. */ 15*37da2899SCharles.Forsyth /* */ 16*37da2899SCharles.Forsyth /***************************************************************************/ 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth #include "t1cmap.h" 20*37da2899SCharles.Forsyth 21*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 22*37da2899SCharles.Forsyth 23*37da2899SCharles.Forsyth 24*37da2899SCharles.Forsyth /*************************************************************************/ 25*37da2899SCharles.Forsyth /*************************************************************************/ 26*37da2899SCharles.Forsyth /***** *****/ 27*37da2899SCharles.Forsyth /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ 28*37da2899SCharles.Forsyth /***** *****/ 29*37da2899SCharles.Forsyth /*************************************************************************/ 30*37da2899SCharles.Forsyth /*************************************************************************/ 31*37da2899SCharles.Forsyth 32*37da2899SCharles.Forsyth static void t1_cmap_std_init(T1_CMapStd cmap,FT_Int is_expert)33*37da2899SCharles.Forsyth t1_cmap_std_init( T1_CMapStd cmap, 34*37da2899SCharles.Forsyth FT_Int is_expert ) 35*37da2899SCharles.Forsyth { 36*37da2899SCharles.Forsyth T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); 37*37da2899SCharles.Forsyth PSNames_Service psnames = (PSNames_Service)face->psnames; 38*37da2899SCharles.Forsyth 39*37da2899SCharles.Forsyth 40*37da2899SCharles.Forsyth cmap->num_glyphs = face->type1.num_glyphs; 41*37da2899SCharles.Forsyth cmap->glyph_names = (const char* const*)face->type1.glyph_names; 42*37da2899SCharles.Forsyth cmap->sid_to_string = psnames->adobe_std_strings; 43*37da2899SCharles.Forsyth cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding 44*37da2899SCharles.Forsyth : psnames->adobe_std_encoding; 45*37da2899SCharles.Forsyth 46*37da2899SCharles.Forsyth FT_ASSERT( cmap->code_to_sid != NULL ); 47*37da2899SCharles.Forsyth } 48*37da2899SCharles.Forsyth 49*37da2899SCharles.Forsyth 50*37da2899SCharles.Forsyth FT_CALLBACK_DEF( void ) t1_cmap_std_done(T1_CMapStd cmap)51*37da2899SCharles.Forsyth t1_cmap_std_done( T1_CMapStd cmap ) 52*37da2899SCharles.Forsyth { 53*37da2899SCharles.Forsyth cmap->num_glyphs = 0; 54*37da2899SCharles.Forsyth cmap->glyph_names = NULL; 55*37da2899SCharles.Forsyth cmap->sid_to_string = NULL; 56*37da2899SCharles.Forsyth cmap->code_to_sid = NULL; 57*37da2899SCharles.Forsyth } 58*37da2899SCharles.Forsyth 59*37da2899SCharles.Forsyth 60*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_UInt ) t1_cmap_std_char_index(T1_CMapStd cmap,FT_UInt32 char_code)61*37da2899SCharles.Forsyth t1_cmap_std_char_index( T1_CMapStd cmap, 62*37da2899SCharles.Forsyth FT_UInt32 char_code ) 63*37da2899SCharles.Forsyth { 64*37da2899SCharles.Forsyth FT_UInt result = 0; 65*37da2899SCharles.Forsyth 66*37da2899SCharles.Forsyth 67*37da2899SCharles.Forsyth if ( char_code < 256 ) 68*37da2899SCharles.Forsyth { 69*37da2899SCharles.Forsyth FT_UInt code, n; 70*37da2899SCharles.Forsyth const char* glyph_name; 71*37da2899SCharles.Forsyth 72*37da2899SCharles.Forsyth 73*37da2899SCharles.Forsyth /* convert character code to Adobe SID string */ 74*37da2899SCharles.Forsyth code = cmap->code_to_sid[char_code]; 75*37da2899SCharles.Forsyth glyph_name = cmap->sid_to_string( code ); 76*37da2899SCharles.Forsyth 77*37da2899SCharles.Forsyth /* look for the corresponding glyph name */ 78*37da2899SCharles.Forsyth for ( n = 0; n < cmap->num_glyphs; n++ ) 79*37da2899SCharles.Forsyth { 80*37da2899SCharles.Forsyth const char* gname = cmap->glyph_names[n]; 81*37da2899SCharles.Forsyth 82*37da2899SCharles.Forsyth 83*37da2899SCharles.Forsyth if ( gname && gname[0] == glyph_name[0] && 84*37da2899SCharles.Forsyth ft_strcmp( gname, glyph_name ) == 0 ) 85*37da2899SCharles.Forsyth { 86*37da2899SCharles.Forsyth result = n; 87*37da2899SCharles.Forsyth break; 88*37da2899SCharles.Forsyth } 89*37da2899SCharles.Forsyth } 90*37da2899SCharles.Forsyth } 91*37da2899SCharles.Forsyth 92*37da2899SCharles.Forsyth return result; 93*37da2899SCharles.Forsyth } 94*37da2899SCharles.Forsyth 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_UInt ) t1_cmap_std_char_next(T1_CMapStd cmap,FT_UInt32 * pchar_code)97*37da2899SCharles.Forsyth t1_cmap_std_char_next( T1_CMapStd cmap, 98*37da2899SCharles.Forsyth FT_UInt32 *pchar_code ) 99*37da2899SCharles.Forsyth { 100*37da2899SCharles.Forsyth FT_UInt result = 0; 101*37da2899SCharles.Forsyth FT_UInt32 char_code = *pchar_code + 1; 102*37da2899SCharles.Forsyth 103*37da2899SCharles.Forsyth 104*37da2899SCharles.Forsyth while ( char_code < 256 ) 105*37da2899SCharles.Forsyth { 106*37da2899SCharles.Forsyth result = t1_cmap_std_char_index( cmap, char_code ); 107*37da2899SCharles.Forsyth if ( result != 0 ) 108*37da2899SCharles.Forsyth goto Exit; 109*37da2899SCharles.Forsyth 110*37da2899SCharles.Forsyth char_code++; 111*37da2899SCharles.Forsyth } 112*37da2899SCharles.Forsyth char_code = 0; 113*37da2899SCharles.Forsyth 114*37da2899SCharles.Forsyth Exit: 115*37da2899SCharles.Forsyth *pchar_code = char_code; 116*37da2899SCharles.Forsyth return result; 117*37da2899SCharles.Forsyth } 118*37da2899SCharles.Forsyth 119*37da2899SCharles.Forsyth 120*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) t1_cmap_standard_init(T1_CMapStd cmap)121*37da2899SCharles.Forsyth t1_cmap_standard_init( T1_CMapStd cmap ) 122*37da2899SCharles.Forsyth { 123*37da2899SCharles.Forsyth t1_cmap_std_init( cmap, 0 ); 124*37da2899SCharles.Forsyth return 0; 125*37da2899SCharles.Forsyth } 126*37da2899SCharles.Forsyth 127*37da2899SCharles.Forsyth 128*37da2899SCharles.Forsyth FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec 129*37da2899SCharles.Forsyth t1_cmap_standard_class_rec = 130*37da2899SCharles.Forsyth { 131*37da2899SCharles.Forsyth sizeof ( T1_CMapStdRec ), 132*37da2899SCharles.Forsyth 133*37da2899SCharles.Forsyth (FT_CMap_InitFunc) t1_cmap_standard_init, 134*37da2899SCharles.Forsyth (FT_CMap_DoneFunc) t1_cmap_std_done, 135*37da2899SCharles.Forsyth (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, 136*37da2899SCharles.Forsyth (FT_CMap_CharNextFunc) t1_cmap_std_char_next 137*37da2899SCharles.Forsyth }; 138*37da2899SCharles.Forsyth 139*37da2899SCharles.Forsyth 140*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) t1_cmap_expert_init(T1_CMapStd cmap)141*37da2899SCharles.Forsyth t1_cmap_expert_init( T1_CMapStd cmap ) 142*37da2899SCharles.Forsyth { 143*37da2899SCharles.Forsyth t1_cmap_std_init( cmap, 1 ); 144*37da2899SCharles.Forsyth return 0; 145*37da2899SCharles.Forsyth } 146*37da2899SCharles.Forsyth 147*37da2899SCharles.Forsyth FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec 148*37da2899SCharles.Forsyth t1_cmap_expert_class_rec = 149*37da2899SCharles.Forsyth { 150*37da2899SCharles.Forsyth sizeof ( T1_CMapStdRec ), 151*37da2899SCharles.Forsyth 152*37da2899SCharles.Forsyth (FT_CMap_InitFunc) t1_cmap_expert_init, 153*37da2899SCharles.Forsyth (FT_CMap_DoneFunc) t1_cmap_std_done, 154*37da2899SCharles.Forsyth (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, 155*37da2899SCharles.Forsyth (FT_CMap_CharNextFunc) t1_cmap_std_char_next 156*37da2899SCharles.Forsyth }; 157*37da2899SCharles.Forsyth 158*37da2899SCharles.Forsyth 159*37da2899SCharles.Forsyth /*************************************************************************/ 160*37da2899SCharles.Forsyth /*************************************************************************/ 161*37da2899SCharles.Forsyth /***** *****/ 162*37da2899SCharles.Forsyth /***** TYPE1 CUSTOM ENCODING CMAP *****/ 163*37da2899SCharles.Forsyth /***** *****/ 164*37da2899SCharles.Forsyth /*************************************************************************/ 165*37da2899SCharles.Forsyth /*************************************************************************/ 166*37da2899SCharles.Forsyth 167*37da2899SCharles.Forsyth 168*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) t1_cmap_custom_init(T1_CMapCustom cmap)169*37da2899SCharles.Forsyth t1_cmap_custom_init( T1_CMapCustom cmap ) 170*37da2899SCharles.Forsyth { 171*37da2899SCharles.Forsyth T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); 172*37da2899SCharles.Forsyth T1_Encoding encoding = &face->type1.encoding; 173*37da2899SCharles.Forsyth 174*37da2899SCharles.Forsyth 175*37da2899SCharles.Forsyth cmap->first = encoding->code_first; 176*37da2899SCharles.Forsyth cmap->count = (FT_UInt)( encoding->code_last - cmap->first + 1 ); 177*37da2899SCharles.Forsyth cmap->indices = encoding->char_index; 178*37da2899SCharles.Forsyth 179*37da2899SCharles.Forsyth FT_ASSERT( cmap->indices != NULL ); 180*37da2899SCharles.Forsyth FT_ASSERT( encoding->code_first <= encoding->code_last ); 181*37da2899SCharles.Forsyth 182*37da2899SCharles.Forsyth return 0; 183*37da2899SCharles.Forsyth } 184*37da2899SCharles.Forsyth 185*37da2899SCharles.Forsyth 186*37da2899SCharles.Forsyth FT_CALLBACK_DEF( void ) t1_cmap_custom_done(T1_CMapCustom cmap)187*37da2899SCharles.Forsyth t1_cmap_custom_done( T1_CMapCustom cmap ) 188*37da2899SCharles.Forsyth { 189*37da2899SCharles.Forsyth cmap->indices = NULL; 190*37da2899SCharles.Forsyth cmap->first = 0; 191*37da2899SCharles.Forsyth cmap->count = 0; 192*37da2899SCharles.Forsyth } 193*37da2899SCharles.Forsyth 194*37da2899SCharles.Forsyth 195*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_UInt ) t1_cmap_custom_char_index(T1_CMapCustom cmap,FT_UInt32 char_code)196*37da2899SCharles.Forsyth t1_cmap_custom_char_index( T1_CMapCustom cmap, 197*37da2899SCharles.Forsyth FT_UInt32 char_code ) 198*37da2899SCharles.Forsyth { 199*37da2899SCharles.Forsyth FT_UInt result = 0; 200*37da2899SCharles.Forsyth 201*37da2899SCharles.Forsyth 202*37da2899SCharles.Forsyth if ( ( char_code >= cmap->first ) && 203*37da2899SCharles.Forsyth ( char_code < ( cmap->first + cmap->count ) ) ) 204*37da2899SCharles.Forsyth result = cmap->indices[char_code]; 205*37da2899SCharles.Forsyth 206*37da2899SCharles.Forsyth return result; 207*37da2899SCharles.Forsyth } 208*37da2899SCharles.Forsyth 209*37da2899SCharles.Forsyth 210*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_UInt ) t1_cmap_custom_char_next(T1_CMapCustom cmap,FT_UInt32 * pchar_code)211*37da2899SCharles.Forsyth t1_cmap_custom_char_next( T1_CMapCustom cmap, 212*37da2899SCharles.Forsyth FT_UInt32 *pchar_code ) 213*37da2899SCharles.Forsyth { 214*37da2899SCharles.Forsyth FT_UInt result = 0; 215*37da2899SCharles.Forsyth FT_UInt32 char_code = *pchar_code; 216*37da2899SCharles.Forsyth 217*37da2899SCharles.Forsyth 218*37da2899SCharles.Forsyth ++char_code; 219*37da2899SCharles.Forsyth 220*37da2899SCharles.Forsyth if ( char_code < cmap->first ) 221*37da2899SCharles.Forsyth char_code = cmap->first; 222*37da2899SCharles.Forsyth 223*37da2899SCharles.Forsyth for ( ; char_code < ( cmap->first + cmap->count ); char_code++ ) 224*37da2899SCharles.Forsyth { 225*37da2899SCharles.Forsyth result = cmap->indices[char_code]; 226*37da2899SCharles.Forsyth if ( result != 0 ) 227*37da2899SCharles.Forsyth goto Exit; 228*37da2899SCharles.Forsyth } 229*37da2899SCharles.Forsyth 230*37da2899SCharles.Forsyth char_code = 0; 231*37da2899SCharles.Forsyth 232*37da2899SCharles.Forsyth Exit: 233*37da2899SCharles.Forsyth *pchar_code = char_code; 234*37da2899SCharles.Forsyth return result; 235*37da2899SCharles.Forsyth } 236*37da2899SCharles.Forsyth 237*37da2899SCharles.Forsyth 238*37da2899SCharles.Forsyth FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec 239*37da2899SCharles.Forsyth t1_cmap_custom_class_rec = 240*37da2899SCharles.Forsyth { 241*37da2899SCharles.Forsyth sizeof ( T1_CMapCustomRec ), 242*37da2899SCharles.Forsyth 243*37da2899SCharles.Forsyth (FT_CMap_InitFunc) t1_cmap_custom_init, 244*37da2899SCharles.Forsyth (FT_CMap_DoneFunc) t1_cmap_custom_done, 245*37da2899SCharles.Forsyth (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, 246*37da2899SCharles.Forsyth (FT_CMap_CharNextFunc) t1_cmap_custom_char_next 247*37da2899SCharles.Forsyth }; 248*37da2899SCharles.Forsyth 249*37da2899SCharles.Forsyth 250*37da2899SCharles.Forsyth /*************************************************************************/ 251*37da2899SCharles.Forsyth /*************************************************************************/ 252*37da2899SCharles.Forsyth /***** *****/ 253*37da2899SCharles.Forsyth /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ 254*37da2899SCharles.Forsyth /***** *****/ 255*37da2899SCharles.Forsyth /*************************************************************************/ 256*37da2899SCharles.Forsyth /*************************************************************************/ 257*37da2899SCharles.Forsyth 258*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Int ) t1_cmap_uni_pair_compare(const void * pair1,const void * pair2)259*37da2899SCharles.Forsyth t1_cmap_uni_pair_compare( const void* pair1, 260*37da2899SCharles.Forsyth const void* pair2 ) 261*37da2899SCharles.Forsyth { 262*37da2899SCharles.Forsyth FT_UInt32 u1 = ((T1_CMapUniPair)pair1)->unicode; 263*37da2899SCharles.Forsyth FT_UInt32 u2 = ((T1_CMapUniPair)pair2)->unicode; 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsyth 266*37da2899SCharles.Forsyth if ( u1 < u2 ) 267*37da2899SCharles.Forsyth return -1; 268*37da2899SCharles.Forsyth 269*37da2899SCharles.Forsyth if ( u1 > u2 ) 270*37da2899SCharles.Forsyth return +1; 271*37da2899SCharles.Forsyth 272*37da2899SCharles.Forsyth return 0; 273*37da2899SCharles.Forsyth } 274*37da2899SCharles.Forsyth 275*37da2899SCharles.Forsyth 276*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) t1_cmap_unicode_init(T1_CMapUnicode cmap)277*37da2899SCharles.Forsyth t1_cmap_unicode_init( T1_CMapUnicode cmap ) 278*37da2899SCharles.Forsyth { 279*37da2899SCharles.Forsyth FT_Error error; 280*37da2899SCharles.Forsyth FT_UInt count; 281*37da2899SCharles.Forsyth T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); 282*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE_MEMORY( face ); 283*37da2899SCharles.Forsyth PSNames_Service psnames = (PSNames_Service)face->psnames; 284*37da2899SCharles.Forsyth 285*37da2899SCharles.Forsyth 286*37da2899SCharles.Forsyth cmap->num_pairs = 0; 287*37da2899SCharles.Forsyth cmap->pairs = NULL; 288*37da2899SCharles.Forsyth 289*37da2899SCharles.Forsyth count = face->type1.num_glyphs; 290*37da2899SCharles.Forsyth 291*37da2899SCharles.Forsyth if ( !FT_NEW_ARRAY( cmap->pairs, count ) ) 292*37da2899SCharles.Forsyth { 293*37da2899SCharles.Forsyth FT_UInt n, new_count; 294*37da2899SCharles.Forsyth T1_CMapUniPair pair; 295*37da2899SCharles.Forsyth FT_UInt32 uni_code; 296*37da2899SCharles.Forsyth 297*37da2899SCharles.Forsyth 298*37da2899SCharles.Forsyth pair = cmap->pairs; 299*37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 300*37da2899SCharles.Forsyth { 301*37da2899SCharles.Forsyth const char* gname = face->type1.glyph_names[n]; 302*37da2899SCharles.Forsyth 303*37da2899SCharles.Forsyth 304*37da2899SCharles.Forsyth /* build unsorted pair table by matching glyph names */ 305*37da2899SCharles.Forsyth if ( gname ) 306*37da2899SCharles.Forsyth { 307*37da2899SCharles.Forsyth uni_code = psnames->unicode_value( gname ); 308*37da2899SCharles.Forsyth 309*37da2899SCharles.Forsyth if ( uni_code != 0 ) 310*37da2899SCharles.Forsyth { 311*37da2899SCharles.Forsyth pair->unicode = uni_code; 312*37da2899SCharles.Forsyth pair->gindex = n; 313*37da2899SCharles.Forsyth pair++; 314*37da2899SCharles.Forsyth } 315*37da2899SCharles.Forsyth } 316*37da2899SCharles.Forsyth } 317*37da2899SCharles.Forsyth 318*37da2899SCharles.Forsyth new_count = (FT_UInt)( pair - cmap->pairs ); 319*37da2899SCharles.Forsyth if ( new_count == 0 ) 320*37da2899SCharles.Forsyth { 321*37da2899SCharles.Forsyth /* there are no unicode characters in here! */ 322*37da2899SCharles.Forsyth FT_FREE( cmap->pairs ); 323*37da2899SCharles.Forsyth error = FT_Err_Invalid_Argument; 324*37da2899SCharles.Forsyth } 325*37da2899SCharles.Forsyth else 326*37da2899SCharles.Forsyth { 327*37da2899SCharles.Forsyth /* re-allocate if the new array is much smaller than the original */ 328*37da2899SCharles.Forsyth /* one */ 329*37da2899SCharles.Forsyth if ( new_count != count && new_count < count / 2 ) 330*37da2899SCharles.Forsyth { 331*37da2899SCharles.Forsyth (void)FT_RENEW_ARRAY( cmap->pairs, count, new_count ); 332*37da2899SCharles.Forsyth error = 0; 333*37da2899SCharles.Forsyth } 334*37da2899SCharles.Forsyth 335*37da2899SCharles.Forsyth /* sort the pairs table to allow efficient binary searches */ 336*37da2899SCharles.Forsyth ft_qsort( cmap->pairs, 337*37da2899SCharles.Forsyth new_count, 338*37da2899SCharles.Forsyth sizeof ( T1_CMapUniPairRec ), 339*37da2899SCharles.Forsyth t1_cmap_uni_pair_compare ); 340*37da2899SCharles.Forsyth 341*37da2899SCharles.Forsyth cmap->num_pairs = new_count; 342*37da2899SCharles.Forsyth } 343*37da2899SCharles.Forsyth } 344*37da2899SCharles.Forsyth 345*37da2899SCharles.Forsyth return error; 346*37da2899SCharles.Forsyth } 347*37da2899SCharles.Forsyth 348*37da2899SCharles.Forsyth 349*37da2899SCharles.Forsyth FT_CALLBACK_DEF( void ) t1_cmap_unicode_done(T1_CMapUnicode cmap)350*37da2899SCharles.Forsyth t1_cmap_unicode_done( T1_CMapUnicode cmap ) 351*37da2899SCharles.Forsyth { 352*37da2899SCharles.Forsyth FT_Face face = FT_CMAP_FACE(cmap); 353*37da2899SCharles.Forsyth FT_Memory memory = FT_FACE_MEMORY(face); 354*37da2899SCharles.Forsyth 355*37da2899SCharles.Forsyth FT_FREE( cmap->pairs ); 356*37da2899SCharles.Forsyth cmap->num_pairs = 0; 357*37da2899SCharles.Forsyth } 358*37da2899SCharles.Forsyth 359*37da2899SCharles.Forsyth 360*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_UInt ) t1_cmap_unicode_char_index(T1_CMapUnicode cmap,FT_UInt32 char_code)361*37da2899SCharles.Forsyth t1_cmap_unicode_char_index( T1_CMapUnicode cmap, 362*37da2899SCharles.Forsyth FT_UInt32 char_code ) 363*37da2899SCharles.Forsyth { 364*37da2899SCharles.Forsyth FT_UInt min = 0; 365*37da2899SCharles.Forsyth FT_UInt max = cmap->num_pairs; 366*37da2899SCharles.Forsyth FT_UInt mid; 367*37da2899SCharles.Forsyth T1_CMapUniPair pair; 368*37da2899SCharles.Forsyth 369*37da2899SCharles.Forsyth 370*37da2899SCharles.Forsyth while ( min < max ) 371*37da2899SCharles.Forsyth { 372*37da2899SCharles.Forsyth mid = min + ( max - min ) / 2; 373*37da2899SCharles.Forsyth pair = cmap->pairs + mid; 374*37da2899SCharles.Forsyth 375*37da2899SCharles.Forsyth if ( pair->unicode == char_code ) 376*37da2899SCharles.Forsyth return pair->gindex; 377*37da2899SCharles.Forsyth 378*37da2899SCharles.Forsyth if ( pair->unicode < char_code ) 379*37da2899SCharles.Forsyth min = mid + 1; 380*37da2899SCharles.Forsyth else 381*37da2899SCharles.Forsyth max = mid; 382*37da2899SCharles.Forsyth } 383*37da2899SCharles.Forsyth return 0; 384*37da2899SCharles.Forsyth } 385*37da2899SCharles.Forsyth 386*37da2899SCharles.Forsyth 387*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_UInt ) t1_cmap_unicode_char_next(T1_CMapUnicode cmap,FT_UInt32 * pchar_code)388*37da2899SCharles.Forsyth t1_cmap_unicode_char_next( T1_CMapUnicode cmap, 389*37da2899SCharles.Forsyth FT_UInt32 *pchar_code ) 390*37da2899SCharles.Forsyth { 391*37da2899SCharles.Forsyth FT_UInt result = 0; 392*37da2899SCharles.Forsyth FT_UInt32 char_code = *pchar_code + 1; 393*37da2899SCharles.Forsyth 394*37da2899SCharles.Forsyth 395*37da2899SCharles.Forsyth Restart: 396*37da2899SCharles.Forsyth { 397*37da2899SCharles.Forsyth FT_UInt min = 0; 398*37da2899SCharles.Forsyth FT_UInt max = cmap->num_pairs; 399*37da2899SCharles.Forsyth FT_UInt mid; 400*37da2899SCharles.Forsyth T1_CMapUniPair pair; 401*37da2899SCharles.Forsyth 402*37da2899SCharles.Forsyth 403*37da2899SCharles.Forsyth while ( min < max ) 404*37da2899SCharles.Forsyth { 405*37da2899SCharles.Forsyth mid = min + ( ( max - min ) >> 1 ); 406*37da2899SCharles.Forsyth pair = cmap->pairs + mid; 407*37da2899SCharles.Forsyth 408*37da2899SCharles.Forsyth if ( pair->unicode == char_code ) 409*37da2899SCharles.Forsyth { 410*37da2899SCharles.Forsyth result = pair->gindex; 411*37da2899SCharles.Forsyth if ( result != 0 ) 412*37da2899SCharles.Forsyth goto Exit; 413*37da2899SCharles.Forsyth 414*37da2899SCharles.Forsyth char_code++; 415*37da2899SCharles.Forsyth goto Restart; 416*37da2899SCharles.Forsyth } 417*37da2899SCharles.Forsyth 418*37da2899SCharles.Forsyth if ( pair->unicode < char_code ) 419*37da2899SCharles.Forsyth min = mid+1; 420*37da2899SCharles.Forsyth else 421*37da2899SCharles.Forsyth max = mid; 422*37da2899SCharles.Forsyth } 423*37da2899SCharles.Forsyth 424*37da2899SCharles.Forsyth /* we didn't find it, but we have a pair just above it */ 425*37da2899SCharles.Forsyth char_code = 0; 426*37da2899SCharles.Forsyth 427*37da2899SCharles.Forsyth if ( min < cmap->num_pairs ) 428*37da2899SCharles.Forsyth { 429*37da2899SCharles.Forsyth pair = cmap->pairs + min; 430*37da2899SCharles.Forsyth result = pair->gindex; 431*37da2899SCharles.Forsyth if ( result != 0 ) 432*37da2899SCharles.Forsyth char_code = pair->unicode; 433*37da2899SCharles.Forsyth } 434*37da2899SCharles.Forsyth } 435*37da2899SCharles.Forsyth 436*37da2899SCharles.Forsyth Exit: 437*37da2899SCharles.Forsyth *pchar_code = char_code; 438*37da2899SCharles.Forsyth return result; 439*37da2899SCharles.Forsyth } 440*37da2899SCharles.Forsyth 441*37da2899SCharles.Forsyth 442*37da2899SCharles.Forsyth FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec 443*37da2899SCharles.Forsyth t1_cmap_unicode_class_rec = 444*37da2899SCharles.Forsyth { 445*37da2899SCharles.Forsyth sizeof ( T1_CMapUnicodeRec ), 446*37da2899SCharles.Forsyth 447*37da2899SCharles.Forsyth (FT_CMap_InitFunc) t1_cmap_unicode_init, 448*37da2899SCharles.Forsyth (FT_CMap_DoneFunc) t1_cmap_unicode_done, 449*37da2899SCharles.Forsyth (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, 450*37da2899SCharles.Forsyth (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next 451*37da2899SCharles.Forsyth }; 452*37da2899SCharles.Forsyth 453*37da2899SCharles.Forsyth 454*37da2899SCharles.Forsyth /* END */ 455