xref: /inferno-os/libfreetype/psmodule.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
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