This commit was manufactured by cvs2svn to create branch 'captive'.
[reactos.git] / subsys / win32k / freetype / src / psnames / psmodule.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  psmodule.c                                                             */
4 /*                                                                         */
5 /*    PSNames module implementation (body).                                */
6 /*                                                                         */
7 /*  Copyright 1996-2000 by                                                 */
8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 /*                                                                         */
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.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17
18
19 #include <freetype/internal/psnames.h>
20 #include <freetype/internal/ftobjs.h>
21
22
23 #ifdef FT_FLAT_COMPILE
24
25 #include "psmodule.h"
26 #include "pstables.h"
27
28 #else
29
30 #include <freetype/src/psnames/psmodule.h>
31 #include <freetype/src/psnames/pstables.h>
32
33 #endif
34
35
36 #include <stdlib.h>     /* for qsort()             */
37 #include <string.h>     /* for strcmp(), strncpy() */
38
39
40 #ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
41
42
43
44
45 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
46
47
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.                        */
51   /*                                                                     */
52   static
53   FT_ULong  PS_Unicode_Value( const char*  glyph_name )
54   {
55     FT_Int  n;
56     char    first = glyph_name[0];
57     char    temp[64];
58
59
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' )
65     {
66       /* determine whether the next four characters following are */
67       /* hexadecimal.                                             */
68
69       /* XXX: Add code to deal with ligatures, i.e. glyph names like */
70       /*      `uniXXXXYYYYZZZZ'...                                   */
71
72       FT_Int       count;
73       FT_ULong     value = 0;
74       const char*  p     = glyph_name + 4;
75
76
77       for ( count = 4; count > 0; count--, p++ )
78       {
79         char           c = *p;
80         unsigned char  d;
81
82
83         d = (unsigned char)c - '0';
84         if ( d >= 10 )
85         {
86           d = (unsigned char)c - 'A';
87           if ( d >= 6 )
88             d = 16;
89           else
90             d += 10;
91         }
92
93         /* exit if a non-uppercase hexadecimal character was found */
94         if ( d >= 16 )
95           break;
96
97         value = ( value << 4 ) + d;
98
99         if ( count == 0 )
100           return value;
101       }
102     }
103
104     /* look for a non-initial dot in the glyph name in order to */
105     /* sort-out variants like `A.swash', `e.final', etc.        */
106     {
107       const char*  p;
108       int          len;
109
110
111       p = glyph_name;
112
113       while ( *p && *p != '.' )
114         p++;
115
116       len = p - glyph_name;
117
118       if ( *p && len < 64 )
119       {
120         strncpy( temp, glyph_name, len );
121         temp[len]  = 0;
122         glyph_name = temp;
123       }
124     }
125
126     /* now, look up the glyph in the Adobe Glyph List */
127     for ( n = 0; n < NUM_ADOBE_GLYPHS; n++ )
128     {
129       const char*  name = t1_standard_glyphs[n];
130
131
132       if ( first == name[0] && strcmp( glyph_name, name ) == 0 )
133         return names_to_unicode[n];
134     }
135
136     /* not found, there is probably no Unicode value for this glyph name */
137     return 0;
138   }
139
140
141   /* qsort callback to sort the unicode map */
142   static
143   int  compare_uni_maps( const void*  a,
144                          const void*  b )
145   {
146     PS_UniMap*  map1 = (PS_UniMap*)a;
147     PS_UniMap*  map2 = (PS_UniMap*)b;
148
149
150     return ( map1->unicode - map2->unicode );
151   }
152
153
154   /* Builds a table that maps Unicode values to glyph indices */
155   static
156   FT_Error  PS_Build_Unicode_Table( FT_Memory     memory,
157                                     FT_UInt       num_glyphs,
158                                     const char**  glyph_names,
159                                     PS_Unicodes*  table )
160   {
161     FT_Error  error;
162
163
164     /* we first allocate the table */
165     table->num_maps = 0;
166     table->maps     = 0;
167
168     if ( !ALLOC_ARRAY( table->maps, num_glyphs, PS_UniMap ) )
169     {
170       FT_UInt     n;
171       FT_UInt     count;
172       PS_UniMap*  map;
173       FT_ULong    uni_char;
174
175
176       map = table->maps;
177
178       for ( n = 0; n < num_glyphs; n++ )
179       {
180         const char*  gname = glyph_names[n];
181
182
183         if ( gname )
184         {
185           uni_char = PS_Unicode_Value( gname );
186
187           if ( uni_char && uni_char != 0xFFFF )
188           {
189             map->unicode     = uni_char;
190             map->glyph_index = n;
191             map++;
192           }
193         }
194       }
195
196       /* now, compress the table a bit */
197       count = map - table->maps;
198
199       if ( count > 0 && REALLOC( table->maps,
200                                  num_glyphs * sizeof ( PS_UniMap ),
201                                  count * sizeof ( PS_UniMap ) ) )
202         count = 0;
203
204       if ( count == 0 )
205       {
206         FREE( table->maps );
207         if ( !error )
208           error = FT_Err_Invalid_Argument;  /* no unicode chars here! */
209       }
210       else
211         /* sort the table in increasing order of unicode values */
212         qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps );
213
214       table->num_maps = count;
215     }
216
217     return error;
218   }
219
220
221   static
222   FT_UInt  PS_Lookup_Unicode( PS_Unicodes*  table,
223                               FT_ULong      unicode )
224   {
225     PS_UniMap  *min, *max, *mid;
226
227
228     /* perform a binary search on the table */
229
230     min = table->maps;
231     max = min + table->num_maps - 1;
232
233     while ( min <= max )
234     {
235       mid = min + ( max - min ) / 2;
236       if ( mid->unicode == unicode )
237         return mid->glyph_index;
238
239       if ( min == max )
240         break;
241
242       if ( mid->unicode < unicode )
243         min = mid + 1;
244       else
245         max = mid - 1;
246     }
247
248     return 0xFFFF;
249   }
250
251
252 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
253
254
255   static
256   const char*  PS_Macintosh_Name( FT_UInt  name_index )
257   {
258     if ( name_index >= 258 )
259       name_index = 0;
260
261     return standard_glyph_names[mac_standard_names[name_index]];
262   }
263
264
265   static
266   const char*  PS_Standard_Strings( FT_UInt  sid )
267   {
268     return ( sid < NUM_STD_GLYPHS ? t1_standard_glyphs[sid] : 0 );
269   }
270
271
272   static const PSNames_Interface  psnames_interface =
273   {
274 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
275
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,
279
280 #else
281
282     0,
283     0,
284     0,
285
286 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
287
288     (PS_Macintosh_Name_Func)   PS_Macintosh_Name,
289     (PS_Adobe_Std_Strings_Func)PS_Standard_Strings,
290
291     t1_standard_encoding,
292     t1_expert_encoding
293   };
294
295
296 #endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */
297
298
299   const FT_Module_Class  psnames_module_class =
300   {
301     0,  /* this is not a font driver, nor a renderer */
302     sizeof( FT_ModuleRec ),
303
304     "psnames",  /* driver name                         */
305     0x10000L,   /* driver version                      */
306     0x20000L,   /* driver requires FreeType 2 or above */
307
308 #ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES
309     0,
310 #else
311     (void*)&psnames_interface,   /* module specific interface */
312 #endif
313
314     (FT_Module_Constructor)0,
315     (FT_Module_Destructor) 0,
316     (FT_Module_Requester)  0
317   };
318
319
320 /* END */