1 /***************************************************************************/
5 /* PSNames module implementation (body). */
7 /* Copyright 1996-2000 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 /***************************************************************************/
19 #include <freetype/internal/psnames.h>
20 #include <freetype/internal/ftobjs.h>
23 #ifdef FT_FLAT_COMPILE
30 #include <freetype/src/psnames/psmodule.h>
31 #include <freetype/src/psnames/pstables.h>
36 #include <stdlib.h> /* for qsort() */
37 #include <string.h> /* for strcmp(), strncpy() */
40 #ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
45 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
48 /* return the Unicode value corresponding to a given glyph. Note that */
49 /* we do deal with glyph variants by detecting a non-initial dot in */
50 /* the name, as in `A.swash' or `e.final', etc. */
53 FT_ULong PS_Unicode_Value( const char* glyph_name )
56 char first = glyph_name[0];
60 /* if the name begins with `uni', then the glyph name may be a */
61 /* hard-coded unicode character code. */
62 if ( glyph_name[0] == 'u' &&
63 glyph_name[1] == 'n' &&
64 glyph_name[2] == 'i' )
66 /* determine whether the next four characters following are */
69 /* XXX: Add code to deal with ligatures, i.e. glyph names like */
70 /* `uniXXXXYYYYZZZZ'... */
74 const char* p = glyph_name + 4;
77 for ( count = 4; count > 0; count--, p++ )
83 d = (unsigned char)c - '0';
86 d = (unsigned char)c - 'A';
93 /* exit if a non-uppercase hexadecimal character was found */
97 value = ( value << 4 ) + d;
104 /* look for a non-initial dot in the glyph name in order to */
105 /* sort-out variants like `A.swash', `e.final', etc. */
113 while ( *p && *p != '.' )
116 len = p - glyph_name;
118 if ( *p && len < 64 )
120 strncpy( temp, glyph_name, len );
126 /* now, look up the glyph in the Adobe Glyph List */
127 for ( n = 0; n < NUM_ADOBE_GLYPHS; n++ )
129 const char* name = t1_standard_glyphs[n];
132 if ( first == name[0] && strcmp( glyph_name, name ) == 0 )
133 return names_to_unicode[n];
136 /* not found, there is probably no Unicode value for this glyph name */
141 /* qsort callback to sort the unicode map */
143 int compare_uni_maps( const void* a,
146 PS_UniMap* map1 = (PS_UniMap*)a;
147 PS_UniMap* map2 = (PS_UniMap*)b;
150 return ( map1->unicode - map2->unicode );
154 /* Builds a table that maps Unicode values to glyph indices */
156 FT_Error PS_Build_Unicode_Table( FT_Memory memory,
158 const char** glyph_names,
164 /* we first allocate the table */
168 if ( !ALLOC_ARRAY( table->maps, num_glyphs, PS_UniMap ) )
178 for ( n = 0; n < num_glyphs; n++ )
180 const char* gname = glyph_names[n];
185 uni_char = PS_Unicode_Value( gname );
187 if ( uni_char && uni_char != 0xFFFF )
189 map->unicode = uni_char;
190 map->glyph_index = n;
196 /* now, compress the table a bit */
197 count = map - table->maps;
199 if ( count > 0 && REALLOC( table->maps,
200 num_glyphs * sizeof ( PS_UniMap ),
201 count * sizeof ( PS_UniMap ) ) )
208 error = FT_Err_Invalid_Argument; /* no unicode chars here! */
211 /* sort the table in increasing order of unicode values */
212 qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps );
214 table->num_maps = count;
222 FT_UInt PS_Lookup_Unicode( PS_Unicodes* table,
225 PS_UniMap *min, *max, *mid;
228 /* perform a binary search on the table */
231 max = min + table->num_maps - 1;
235 mid = min + ( max - min ) / 2;
236 if ( mid->unicode == unicode )
237 return mid->glyph_index;
242 if ( mid->unicode < unicode )
252 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
256 const char* PS_Macintosh_Name( FT_UInt name_index )
258 if ( name_index >= 258 )
261 return standard_glyph_names[mac_standard_names[name_index]];
266 const char* PS_Standard_Strings( FT_UInt sid )
268 return ( sid < NUM_STD_GLYPHS ? t1_standard_glyphs[sid] : 0 );
272 static const PSNames_Interface psnames_interface =
274 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
276 (PS_Unicode_Value_Func) PS_Unicode_Value,
277 (PS_Build_Unicodes_Func) PS_Build_Unicode_Table,
278 (PS_Lookup_Unicode_Func) PS_Lookup_Unicode,
286 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
288 (PS_Macintosh_Name_Func) PS_Macintosh_Name,
289 (PS_Adobe_Std_Strings_Func)PS_Standard_Strings,
291 t1_standard_encoding,
296 #endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */
299 const FT_Module_Class psnames_module_class =
301 0, /* this is not a font driver, nor a renderer */
302 sizeof( FT_ModuleRec ),
304 "psnames", /* driver name */
305 0x10000L, /* driver version */
306 0x20000L, /* driver requires FreeType 2 or above */
308 #ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
311 (void*)&psnames_interface, /* module specific interface */
314 (FT_Module_Constructor)0,
315 (FT_Module_Destructor) 0,
316 (FT_Module_Requester) 0