1 /***************************************************************************/
5 /* PSNames module implementation (body). */
7 /* Copyright 1996-2001, 2002 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_POSTSCRIPT_NAMES_H
21 #include FT_INTERNAL_OBJECTS_H
29 #ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
32 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
35 /* return the Unicode value corresponding to a given glyph. Note that */
36 /* we do deal with glyph variants by detecting a non-initial dot in */
37 /* the name, as in `A.swash' or `e.final', etc. */
40 ps_unicode_value( const char* glyph_name )
43 char first = glyph_name[0];
47 /* if the name begins with `uni', then the glyph name may be a */
48 /* hard-coded unicode character code. */
49 if ( glyph_name[0] == 'u' &&
50 glyph_name[1] == 'n' &&
51 glyph_name[2] == 'i' )
53 /* determine whether the next four characters following are */
56 /* XXX: Add code to deal with ligatures, i.e. glyph names like */
57 /* `uniXXXXYYYYZZZZ'... */
61 const char* p = glyph_name + 3;
64 for ( count = 4; count > 0; count--, p++ )
70 d = (unsigned char)c - '0';
73 d = (unsigned char)c - 'A';
80 /* exit if a non-uppercase hexadecimal character was found */
84 value = ( value << 4 ) + d;
90 /* look for a non-initial dot in the glyph name in order to */
91 /* sort-out variants like `A.swash', `e.final', etc. */
99 while ( *p && *p != '.' )
102 len = (int)( p - glyph_name );
104 if ( *p && len < 64 )
106 ft_strncpy( temp, glyph_name, len );
112 /* now, look up the glyph in the Adobe Glyph List */
113 for ( n = 0; n < NUM_ADOBE_GLYPHS; n++ )
115 const char* name = sid_standard_names[n];
118 if ( first == name[0] && ft_strcmp( glyph_name, name ) == 0 )
119 return ps_names_to_unicode[n];
122 /* not found, there is probably no Unicode value for this glyph name */
127 /* ft_qsort callback to sort the unicode map */
128 FT_CALLBACK_DEF( int )
129 compare_uni_maps( const void* a,
132 PS_UniMap* map1 = (PS_UniMap*)a;
133 PS_UniMap* map2 = (PS_UniMap*)b;
136 return ( map1->unicode - map2->unicode );
140 /* Builds a table that maps Unicode values to glyph indices */
142 ps_build_unicode_table( FT_Memory memory,
144 const char** glyph_names,
150 /* we first allocate the table */
154 if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) )
164 for ( n = 0; n < num_glyphs; n++ )
166 const char* gname = glyph_names[n];
171 uni_char = ps_unicode_value( gname );
173 if ( uni_char != 0 && uni_char != 0xFFFF )
175 map->unicode = uni_char;
176 map->glyph_index = n;
182 /* now, compress the table a bit */
183 count = (FT_UInt)( map - table->maps );
185 if ( count > 0 && FT_REALLOC( table->maps,
186 num_glyphs * sizeof ( PS_UniMap ),
187 count * sizeof ( PS_UniMap ) ) )
192 FT_FREE( table->maps );
194 error = PSnames_Err_Invalid_Argument; /* no unicode chars here! */
197 /* sort the table in increasing order of unicode values */
198 ft_qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps );
200 table->num_maps = count;
208 ps_lookup_unicode( PS_Unicodes* table,
211 PS_UniMap *min, *max, *mid;
214 /* perform a binary search on the table */
217 max = min + table->num_maps - 1;
221 mid = min + ( max - min ) / 2;
222 if ( mid->unicode == unicode )
223 return mid->glyph_index;
228 if ( mid->unicode < unicode )
239 ps_next_unicode( PS_Unicodes* table,
242 PS_UniMap *min, *max, *mid;
246 /* perform a binary search on the table */
249 max = min + table->num_maps - 1;
253 mid = min + ( max - min ) / 2;
254 if ( mid->unicode == unicode )
260 if ( mid->unicode < unicode )
266 if ( max < table->maps )
269 while ( max < table->maps + table->num_maps )
271 if ( unicode < max->unicode )
280 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
284 ps_get_macintosh_name( FT_UInt name_index )
286 if ( name_index >= 258 )
289 return ps_glyph_names[mac_standard_names[name_index]];
294 ps_get_standard_strings( FT_UInt sid )
296 return ( sid < NUM_SID_GLYPHS ? sid_standard_names[sid] : 0 );
301 const PSNames_Interface psnames_interface =
303 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
305 (PS_Unicode_Value_Func) ps_unicode_value,
306 (PS_Build_Unicodes_Func) ps_build_unicode_table,
307 (PS_Lookup_Unicode_Func) ps_lookup_unicode,
315 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
317 (PS_Macintosh_Name_Func) ps_get_macintosh_name,
318 (PS_Adobe_Std_Strings_Func) ps_get_standard_strings,
320 t1_standard_encoding,
323 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
324 (PS_Next_Unicode_Func) ps_next_unicode
327 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
332 #endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */
335 FT_CALLBACK_TABLE_DEF
336 const FT_Module_Class psnames_module_class =
338 0, /* this is not a font driver, nor a renderer */
339 sizeof ( FT_ModuleRec ),
341 "psnames", /* driver name */
342 0x10000L, /* driver version */
343 0x20000L, /* driver requires FreeType 2 or above */
345 #ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
348 (void*)&psnames_interface, /* module specific interface */
351 (FT_Module_Constructor)0,
352 (FT_Module_Destructor) 0,
353 (FT_Module_Requester) 0