1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* psmodule.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* PSNames module implementation (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 1996-2001, 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 <ft2build.h> 20*37da2899SCharles.Forsyth #include FT_INTERNAL_POSTSCRIPT_NAMES_H 21*37da2899SCharles.Forsyth #include FT_INTERNAL_OBJECTS_H 22*37da2899SCharles.Forsyth 23*37da2899SCharles.Forsyth #include "psmodule.h" 24*37da2899SCharles.Forsyth #include "pstables.h" 25*37da2899SCharles.Forsyth 26*37da2899SCharles.Forsyth #include "psnamerr.h" 27*37da2899SCharles.Forsyth 28*37da2899SCharles.Forsyth 29*37da2899SCharles.Forsyth #ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES 30*37da2899SCharles.Forsyth 31*37da2899SCharles.Forsyth 32*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST 33*37da2899SCharles.Forsyth 34*37da2899SCharles.Forsyth 35*37da2899SCharles.Forsyth /* return the Unicode value corresponding to a given glyph. Note that */ 36*37da2899SCharles.Forsyth /* we do deal with glyph variants by detecting a non-initial dot in */ 37*37da2899SCharles.Forsyth /* the name, as in `A.swash' or `e.final', etc. */ 38*37da2899SCharles.Forsyth /* */ 39*37da2899SCharles.Forsyth static FT_UInt32 ps_unicode_value(const char * glyph_name)40*37da2899SCharles.Forsyth ps_unicode_value( const char* glyph_name ) 41*37da2899SCharles.Forsyth { 42*37da2899SCharles.Forsyth FT_Int n; 43*37da2899SCharles.Forsyth char first = glyph_name[0]; 44*37da2899SCharles.Forsyth char temp[64]; 45*37da2899SCharles.Forsyth 46*37da2899SCharles.Forsyth 47*37da2899SCharles.Forsyth /* if the name begins with `uni', then the glyph name may be a */ 48*37da2899SCharles.Forsyth /* hard-coded unicode character code. */ 49*37da2899SCharles.Forsyth if ( glyph_name[0] == 'u' && 50*37da2899SCharles.Forsyth glyph_name[1] == 'n' && 51*37da2899SCharles.Forsyth glyph_name[2] == 'i' ) 52*37da2899SCharles.Forsyth { 53*37da2899SCharles.Forsyth /* determine whether the next four characters following are */ 54*37da2899SCharles.Forsyth /* hexadecimal. */ 55*37da2899SCharles.Forsyth 56*37da2899SCharles.Forsyth /* XXX: Add code to deal with ligatures, i.e. glyph names like */ 57*37da2899SCharles.Forsyth /* `uniXXXXYYYYZZZZ'... */ 58*37da2899SCharles.Forsyth 59*37da2899SCharles.Forsyth FT_Int count; 60*37da2899SCharles.Forsyth FT_ULong value = 0; 61*37da2899SCharles.Forsyth const char* p = glyph_name + 3; 62*37da2899SCharles.Forsyth 63*37da2899SCharles.Forsyth 64*37da2899SCharles.Forsyth for ( count = 4; count > 0; count--, p++ ) 65*37da2899SCharles.Forsyth { 66*37da2899SCharles.Forsyth char c = *p; 67*37da2899SCharles.Forsyth unsigned int d; 68*37da2899SCharles.Forsyth 69*37da2899SCharles.Forsyth 70*37da2899SCharles.Forsyth d = (unsigned char)c - '0'; 71*37da2899SCharles.Forsyth if ( d >= 10 ) 72*37da2899SCharles.Forsyth { 73*37da2899SCharles.Forsyth d = (unsigned char)c - 'A'; 74*37da2899SCharles.Forsyth if ( d >= 6 ) 75*37da2899SCharles.Forsyth d = 16; 76*37da2899SCharles.Forsyth else 77*37da2899SCharles.Forsyth d += 10; 78*37da2899SCharles.Forsyth } 79*37da2899SCharles.Forsyth 80*37da2899SCharles.Forsyth /* exit if a non-uppercase hexadecimal character was found */ 81*37da2899SCharles.Forsyth if ( d >= 16 ) 82*37da2899SCharles.Forsyth break; 83*37da2899SCharles.Forsyth 84*37da2899SCharles.Forsyth value = ( value << 4 ) + d; 85*37da2899SCharles.Forsyth } 86*37da2899SCharles.Forsyth if ( count == 0 ) 87*37da2899SCharles.Forsyth return value; 88*37da2899SCharles.Forsyth } 89*37da2899SCharles.Forsyth 90*37da2899SCharles.Forsyth /* look for a non-initial dot in the glyph name in order to */ 91*37da2899SCharles.Forsyth /* sort-out variants like `A.swash', `e.final', etc. */ 92*37da2899SCharles.Forsyth { 93*37da2899SCharles.Forsyth const char* p; 94*37da2899SCharles.Forsyth int len; 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth 97*37da2899SCharles.Forsyth p = glyph_name; 98*37da2899SCharles.Forsyth 99*37da2899SCharles.Forsyth while ( *p && *p != '.' ) 100*37da2899SCharles.Forsyth p++; 101*37da2899SCharles.Forsyth 102*37da2899SCharles.Forsyth len = (int)( p - glyph_name ); 103*37da2899SCharles.Forsyth 104*37da2899SCharles.Forsyth if ( *p && len < 64 ) 105*37da2899SCharles.Forsyth { 106*37da2899SCharles.Forsyth ft_strncpy( temp, glyph_name, len ); 107*37da2899SCharles.Forsyth temp[len] = 0; 108*37da2899SCharles.Forsyth glyph_name = temp; 109*37da2899SCharles.Forsyth } 110*37da2899SCharles.Forsyth } 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsyth /* now, look up the glyph in the Adobe Glyph List */ 113*37da2899SCharles.Forsyth for ( n = 0; n < NUM_ADOBE_GLYPHS; n++ ) 114*37da2899SCharles.Forsyth { 115*37da2899SCharles.Forsyth const char* name = sid_standard_names[n]; 116*37da2899SCharles.Forsyth 117*37da2899SCharles.Forsyth 118*37da2899SCharles.Forsyth if ( first == name[0] && ft_strcmp( glyph_name, name ) == 0 ) 119*37da2899SCharles.Forsyth return ps_names_to_unicode[n]; 120*37da2899SCharles.Forsyth } 121*37da2899SCharles.Forsyth 122*37da2899SCharles.Forsyth /* not found, there is probably no Unicode value for this glyph name */ 123*37da2899SCharles.Forsyth return 0; 124*37da2899SCharles.Forsyth } 125*37da2899SCharles.Forsyth 126*37da2899SCharles.Forsyth 127*37da2899SCharles.Forsyth /* ft_qsort callback to sort the unicode map */ 128*37da2899SCharles.Forsyth FT_CALLBACK_DEF( int ) compare_uni_maps(const void * a,const void * b)129*37da2899SCharles.Forsyth compare_uni_maps( const void* a, 130*37da2899SCharles.Forsyth const void* b ) 131*37da2899SCharles.Forsyth { 132*37da2899SCharles.Forsyth PS_UniMap* map1 = (PS_UniMap*)a; 133*37da2899SCharles.Forsyth PS_UniMap* map2 = (PS_UniMap*)b; 134*37da2899SCharles.Forsyth 135*37da2899SCharles.Forsyth 136*37da2899SCharles.Forsyth return ( map1->unicode - map2->unicode ); 137*37da2899SCharles.Forsyth } 138*37da2899SCharles.Forsyth 139*37da2899SCharles.Forsyth 140*37da2899SCharles.Forsyth /* Builds a table that maps Unicode values to glyph indices */ 141*37da2899SCharles.Forsyth static FT_Error ps_build_unicode_table(FT_Memory memory,FT_UInt num_glyphs,const char ** glyph_names,PS_Unicodes * table)142*37da2899SCharles.Forsyth ps_build_unicode_table( FT_Memory memory, 143*37da2899SCharles.Forsyth FT_UInt num_glyphs, 144*37da2899SCharles.Forsyth const char** glyph_names, 145*37da2899SCharles.Forsyth PS_Unicodes* table ) 146*37da2899SCharles.Forsyth { 147*37da2899SCharles.Forsyth FT_Error error; 148*37da2899SCharles.Forsyth 149*37da2899SCharles.Forsyth 150*37da2899SCharles.Forsyth /* we first allocate the table */ 151*37da2899SCharles.Forsyth table->num_maps = 0; 152*37da2899SCharles.Forsyth table->maps = 0; 153*37da2899SCharles.Forsyth 154*37da2899SCharles.Forsyth if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) ) 155*37da2899SCharles.Forsyth { 156*37da2899SCharles.Forsyth FT_UInt n; 157*37da2899SCharles.Forsyth FT_UInt count; 158*37da2899SCharles.Forsyth PS_UniMap* map; 159*37da2899SCharles.Forsyth FT_UInt32 uni_char; 160*37da2899SCharles.Forsyth 161*37da2899SCharles.Forsyth 162*37da2899SCharles.Forsyth map = table->maps; 163*37da2899SCharles.Forsyth 164*37da2899SCharles.Forsyth for ( n = 0; n < num_glyphs; n++ ) 165*37da2899SCharles.Forsyth { 166*37da2899SCharles.Forsyth const char* gname = glyph_names[n]; 167*37da2899SCharles.Forsyth 168*37da2899SCharles.Forsyth 169*37da2899SCharles.Forsyth if ( gname ) 170*37da2899SCharles.Forsyth { 171*37da2899SCharles.Forsyth uni_char = ps_unicode_value( gname ); 172*37da2899SCharles.Forsyth 173*37da2899SCharles.Forsyth if ( uni_char != 0 && uni_char != 0xFFFF ) 174*37da2899SCharles.Forsyth { 175*37da2899SCharles.Forsyth map->unicode = uni_char; 176*37da2899SCharles.Forsyth map->glyph_index = n; 177*37da2899SCharles.Forsyth map++; 178*37da2899SCharles.Forsyth } 179*37da2899SCharles.Forsyth } 180*37da2899SCharles.Forsyth } 181*37da2899SCharles.Forsyth 182*37da2899SCharles.Forsyth /* now, compress the table a bit */ 183*37da2899SCharles.Forsyth count = (FT_UInt)( map - table->maps ); 184*37da2899SCharles.Forsyth 185*37da2899SCharles.Forsyth if ( count > 0 && FT_REALLOC( table->maps, 186*37da2899SCharles.Forsyth num_glyphs * sizeof ( PS_UniMap ), 187*37da2899SCharles.Forsyth count * sizeof ( PS_UniMap ) ) ) 188*37da2899SCharles.Forsyth count = 0; 189*37da2899SCharles.Forsyth 190*37da2899SCharles.Forsyth if ( count == 0 ) 191*37da2899SCharles.Forsyth { 192*37da2899SCharles.Forsyth FT_FREE( table->maps ); 193*37da2899SCharles.Forsyth if ( !error ) 194*37da2899SCharles.Forsyth error = PSnames_Err_Invalid_Argument; /* no unicode chars here! */ 195*37da2899SCharles.Forsyth } 196*37da2899SCharles.Forsyth else 197*37da2899SCharles.Forsyth /* sort the table in increasing order of unicode values */ 198*37da2899SCharles.Forsyth ft_qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps ); 199*37da2899SCharles.Forsyth 200*37da2899SCharles.Forsyth table->num_maps = count; 201*37da2899SCharles.Forsyth } 202*37da2899SCharles.Forsyth 203*37da2899SCharles.Forsyth return error; 204*37da2899SCharles.Forsyth } 205*37da2899SCharles.Forsyth 206*37da2899SCharles.Forsyth 207*37da2899SCharles.Forsyth static FT_UInt ps_lookup_unicode(PS_Unicodes * table,FT_ULong unicode)208*37da2899SCharles.Forsyth ps_lookup_unicode( PS_Unicodes* table, 209*37da2899SCharles.Forsyth FT_ULong unicode ) 210*37da2899SCharles.Forsyth { 211*37da2899SCharles.Forsyth PS_UniMap *min, *max, *mid; 212*37da2899SCharles.Forsyth 213*37da2899SCharles.Forsyth 214*37da2899SCharles.Forsyth /* perform a binary search on the table */ 215*37da2899SCharles.Forsyth 216*37da2899SCharles.Forsyth min = table->maps; 217*37da2899SCharles.Forsyth max = min + table->num_maps - 1; 218*37da2899SCharles.Forsyth 219*37da2899SCharles.Forsyth while ( min <= max ) 220*37da2899SCharles.Forsyth { 221*37da2899SCharles.Forsyth mid = min + ( max - min ) / 2; 222*37da2899SCharles.Forsyth if ( mid->unicode == unicode ) 223*37da2899SCharles.Forsyth return mid->glyph_index; 224*37da2899SCharles.Forsyth 225*37da2899SCharles.Forsyth if ( min == max ) 226*37da2899SCharles.Forsyth break; 227*37da2899SCharles.Forsyth 228*37da2899SCharles.Forsyth if ( mid->unicode < unicode ) 229*37da2899SCharles.Forsyth min = mid + 1; 230*37da2899SCharles.Forsyth else 231*37da2899SCharles.Forsyth max = mid - 1; 232*37da2899SCharles.Forsyth } 233*37da2899SCharles.Forsyth 234*37da2899SCharles.Forsyth return 0xFFFF; 235*37da2899SCharles.Forsyth } 236*37da2899SCharles.Forsyth 237*37da2899SCharles.Forsyth 238*37da2899SCharles.Forsyth static FT_ULong ps_next_unicode(PS_Unicodes * table,FT_ULong unicode)239*37da2899SCharles.Forsyth ps_next_unicode( PS_Unicodes* table, 240*37da2899SCharles.Forsyth FT_ULong unicode ) 241*37da2899SCharles.Forsyth { 242*37da2899SCharles.Forsyth PS_UniMap *min, *max, *mid; 243*37da2899SCharles.Forsyth 244*37da2899SCharles.Forsyth 245*37da2899SCharles.Forsyth unicode++; 246*37da2899SCharles.Forsyth /* perform a binary search on the table */ 247*37da2899SCharles.Forsyth 248*37da2899SCharles.Forsyth min = table->maps; 249*37da2899SCharles.Forsyth max = min + table->num_maps - 1; 250*37da2899SCharles.Forsyth 251*37da2899SCharles.Forsyth while ( min <= max ) 252*37da2899SCharles.Forsyth { 253*37da2899SCharles.Forsyth mid = min + ( max - min ) / 2; 254*37da2899SCharles.Forsyth if ( mid->unicode == unicode ) 255*37da2899SCharles.Forsyth return unicode; 256*37da2899SCharles.Forsyth 257*37da2899SCharles.Forsyth if ( min == max ) 258*37da2899SCharles.Forsyth break; 259*37da2899SCharles.Forsyth 260*37da2899SCharles.Forsyth if ( mid->unicode < unicode ) 261*37da2899SCharles.Forsyth min = mid + 1; 262*37da2899SCharles.Forsyth else 263*37da2899SCharles.Forsyth max = mid - 1; 264*37da2899SCharles.Forsyth } 265*37da2899SCharles.Forsyth 266*37da2899SCharles.Forsyth if ( max < table->maps ) 267*37da2899SCharles.Forsyth max = table->maps; 268*37da2899SCharles.Forsyth 269*37da2899SCharles.Forsyth while ( max < table->maps + table->num_maps ) 270*37da2899SCharles.Forsyth { 271*37da2899SCharles.Forsyth if ( unicode < max->unicode ) 272*37da2899SCharles.Forsyth return max->unicode; 273*37da2899SCharles.Forsyth max++; 274*37da2899SCharles.Forsyth } 275*37da2899SCharles.Forsyth 276*37da2899SCharles.Forsyth return 0; 277*37da2899SCharles.Forsyth } 278*37da2899SCharles.Forsyth 279*37da2899SCharles.Forsyth 280*37da2899SCharles.Forsyth #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ 281*37da2899SCharles.Forsyth 282*37da2899SCharles.Forsyth 283*37da2899SCharles.Forsyth static const char* ps_get_macintosh_name(FT_UInt name_index)284*37da2899SCharles.Forsyth ps_get_macintosh_name( FT_UInt name_index ) 285*37da2899SCharles.Forsyth { 286*37da2899SCharles.Forsyth if ( name_index >= 258 ) 287*37da2899SCharles.Forsyth name_index = 0; 288*37da2899SCharles.Forsyth 289*37da2899SCharles.Forsyth return ps_glyph_names[mac_standard_names[name_index]]; 290*37da2899SCharles.Forsyth } 291*37da2899SCharles.Forsyth 292*37da2899SCharles.Forsyth 293*37da2899SCharles.Forsyth static const char* ps_get_standard_strings(FT_UInt sid)294*37da2899SCharles.Forsyth ps_get_standard_strings( FT_UInt sid ) 295*37da2899SCharles.Forsyth { 296*37da2899SCharles.Forsyth return ( sid < NUM_SID_GLYPHS ? sid_standard_names[sid] : 0 ); 297*37da2899SCharles.Forsyth } 298*37da2899SCharles.Forsyth 299*37da2899SCharles.Forsyth 300*37da2899SCharles.Forsyth static 301*37da2899SCharles.Forsyth const PSNames_Interface psnames_interface = 302*37da2899SCharles.Forsyth { 303*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST 304*37da2899SCharles.Forsyth 305*37da2899SCharles.Forsyth (PS_Unicode_Value_Func) ps_unicode_value, 306*37da2899SCharles.Forsyth (PS_Build_Unicodes_Func) ps_build_unicode_table, 307*37da2899SCharles.Forsyth (PS_Lookup_Unicode_Func) ps_lookup_unicode, 308*37da2899SCharles.Forsyth 309*37da2899SCharles.Forsyth #else 310*37da2899SCharles.Forsyth 311*37da2899SCharles.Forsyth 0, 312*37da2899SCharles.Forsyth 0, 313*37da2899SCharles.Forsyth 0, 314*37da2899SCharles.Forsyth 315*37da2899SCharles.Forsyth #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ 316*37da2899SCharles.Forsyth 317*37da2899SCharles.Forsyth (PS_Macintosh_Name_Func) ps_get_macintosh_name, 318*37da2899SCharles.Forsyth (PS_Adobe_Std_Strings_Func) ps_get_standard_strings, 319*37da2899SCharles.Forsyth 320*37da2899SCharles.Forsyth t1_standard_encoding, 321*37da2899SCharles.Forsyth t1_expert_encoding, 322*37da2899SCharles.Forsyth 323*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST 324*37da2899SCharles.Forsyth (PS_Next_Unicode_Func) ps_next_unicode 325*37da2899SCharles.Forsyth #else 326*37da2899SCharles.Forsyth 0 327*37da2899SCharles.Forsyth #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ 328*37da2899SCharles.Forsyth 329*37da2899SCharles.Forsyth }; 330*37da2899SCharles.Forsyth 331*37da2899SCharles.Forsyth 332*37da2899SCharles.Forsyth #endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */ 333*37da2899SCharles.Forsyth 334*37da2899SCharles.Forsyth 335*37da2899SCharles.Forsyth FT_CALLBACK_TABLE_DEF 336*37da2899SCharles.Forsyth const FT_Module_Class psnames_module_class = 337*37da2899SCharles.Forsyth { 338*37da2899SCharles.Forsyth 0, /* this is not a font driver, nor a renderer */ 339*37da2899SCharles.Forsyth sizeof ( FT_ModuleRec ), 340*37da2899SCharles.Forsyth 341*37da2899SCharles.Forsyth "psnames", /* driver name */ 342*37da2899SCharles.Forsyth 0x10000L, /* driver version */ 343*37da2899SCharles.Forsyth 0x20000L, /* driver requires FreeType 2 or above */ 344*37da2899SCharles.Forsyth 345*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES 346*37da2899SCharles.Forsyth 0, 347*37da2899SCharles.Forsyth #else 348*37da2899SCharles.Forsyth (void*)&psnames_interface, /* module specific interface */ 349*37da2899SCharles.Forsyth #endif 350*37da2899SCharles.Forsyth 351*37da2899SCharles.Forsyth (FT_Module_Constructor)0, 352*37da2899SCharles.Forsyth (FT_Module_Destructor) 0, 353*37da2899SCharles.Forsyth (FT_Module_Requester) 0 354*37da2899SCharles.Forsyth }; 355*37da2899SCharles.Forsyth 356*37da2899SCharles.Forsyth 357*37da2899SCharles.Forsyth /* END */ 358