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 <psnames/psmodule.h>
31 #include <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