xref: /inferno-os/libfreetype/sfdriver.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 /***************************************************************************/
2 /*                                                                         */
3 /*  sfdriver.c                                                             */
4 /*                                                                         */
5 /*    High-level SFNT driver interface (body).                             */
6 /*                                                                         */
7 /*  Copyright 1996-2001, 2002 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 <ft2build.h>
20 #include FT_INTERNAL_SFNT_H
21 #include FT_INTERNAL_OBJECTS_H
22 
23 #include "sfdriver.h"
24 #include "ttload.h"
25 #include "ttcmap.h"
26 #include "sfobjs.h"
27 
28 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
29 #include "ttsbit.h"
30 #endif
31 
32 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
33 #include "ttpost.h"
34 #endif
35 
36 
37   static void*
get_sfnt_table(TT_Face face,FT_Sfnt_Tag tag)38   get_sfnt_table( TT_Face      face,
39                   FT_Sfnt_Tag  tag )
40   {
41     void*  table;
42 
43 
44     switch ( tag )
45     {
46     case ft_sfnt_head:
47       table = &face->header;
48       break;
49 
50     case ft_sfnt_hhea:
51       table = &face->horizontal;
52       break;
53 
54     case ft_sfnt_vhea:
55       table = face->vertical_info ? &face->vertical : 0;
56       break;
57 
58     case ft_sfnt_os2:
59       table = face->os2.version == 0xFFFFU ? 0 : &face->os2;
60       break;
61 
62     case ft_sfnt_post:
63       table = &face->postscript;
64       break;
65 
66     case ft_sfnt_maxp:
67       table = &face->max_profile;
68       break;
69 
70     case ft_sfnt_pclt:
71       table = face->pclt.Version ? &face->pclt : 0;
72       break;
73 
74     default:
75       table = 0;
76     }
77 
78     return table;
79   }
80 
81 
82 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
83 
84 
85   static FT_Error
get_sfnt_glyph_name(TT_Face face,FT_UInt glyph_index,FT_Pointer buffer,FT_UInt buffer_max)86   get_sfnt_glyph_name( TT_Face     face,
87                        FT_UInt     glyph_index,
88                        FT_Pointer  buffer,
89                        FT_UInt     buffer_max )
90   {
91     FT_String*  gname;
92     FT_Error    error;
93 
94 
95     error = tt_face_get_ps_name( face, glyph_index, &gname );
96     if ( !error && buffer_max > 0 )
97     {
98       FT_UInt  len = (FT_UInt)( ft_strlen( gname ) );
99 
100 
101       if ( len >= buffer_max )
102         len = buffer_max - 1;
103 
104       FT_MEM_COPY( buffer, gname, len );
105       ((FT_Byte*)buffer)[len] = 0;
106     }
107 
108     return error;
109   }
110 
111 
112   static const char*
get_sfnt_postscript_name(TT_Face face)113   get_sfnt_postscript_name( TT_Face  face )
114   {
115     FT_Int       n, found_win, found_apple;
116     const char*  result = NULL;
117 
118 
119     /* shouldn't happen, but just in case to avoid memory leaks */
120     if ( face->root.internal->postscript_name )
121       return face->root.internal->postscript_name;
122 
123     /* scan the name table to see whether we have a Postscript name here, */
124     /* either in Macintosh or Windows platform encodings                  */
125     found_win   = -1;
126     found_apple = -1;
127 
128     for ( n = 0; n < face->num_names; n++ )
129     {
130       TT_NameEntryRec*  name = face->name_table.names + n;
131 
132 
133       if ( name->nameID == 6 && name->stringLength > 0 )
134       {
135         if ( name->platformID == 3     &&
136              name->encodingID == 1     &&
137              name->languageID == 0x409 )
138           found_win = n;
139 
140         if ( name->platformID == 1 &&
141              name->encodingID == 0 &&
142              name->languageID == 0 )
143           found_apple = n;
144       }
145     }
146 
147     if ( found_win != -1 )
148     {
149       FT_Memory         memory = face->root.memory;
150       TT_NameEntryRec*  name   = face->name_table.names + found_win;
151       FT_UInt           len    = name->stringLength / 2;
152       FT_Error          error;
153 
154 
155       if ( !FT_ALLOC( result, name->stringLength + 1 ) )
156       {
157         FT_Stream   stream = face->name_table.stream;
158         FT_String*  r      = (FT_String*)result;
159         FT_Byte*    p      = (FT_Byte*)name->string;
160 
161 
162         if ( FT_STREAM_SEEK( name->stringOffset ) ||
163              FT_FRAME_ENTER( name->stringLength ) )
164         {
165           FT_FREE( result );
166           name->stringLength = 0;
167           name->stringOffset = 0;
168           FT_FREE( name->string );
169 
170           goto Exit;
171         }
172 
173         p = (FT_Byte*)stream->cursor;
174 
175         for ( ; len > 0; len--, p += 2 )
176         {
177           if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
178             *r++ = p[1];
179         }
180         *r = '\0';
181 
182         FT_FRAME_EXIT();
183       }
184       goto Exit;
185     }
186 
187     if ( found_apple != -1 )
188     {
189       FT_Memory         memory = face->root.memory;
190       TT_NameEntryRec*  name   = face->name_table.names + found_apple;
191       FT_UInt           len    = name->stringLength;
192       FT_Error          error;
193 
194 
195       if ( !FT_ALLOC( result, len + 1 ) )
196       {
197         FT_Stream  stream = face->name_table.stream;
198 
199 
200         if ( FT_STREAM_SEEK( name->stringOffset ) ||
201              FT_STREAM_READ( result, len )        )
202         {
203           name->stringOffset = 0;
204           name->stringLength = 0;
205           FT_FREE( name->string );
206           FT_FREE( result );
207           goto Exit;
208         }
209         ((char*)result)[len] = '\0';
210       }
211     }
212 
213   Exit:
214     face->root.internal->postscript_name = result;
215     return result;
216   }
217 
218 
219 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
220 
221 
222   FT_CALLBACK_DEF( FT_Module_Interface )
sfnt_get_interface(FT_Module module,const char * module_interface)223   sfnt_get_interface( FT_Module    module,
224                       const char*  module_interface )
225   {
226     FT_UNUSED( module );
227 
228     if ( ft_strcmp( module_interface, "get_sfnt" ) == 0 )
229       return (FT_Module_Interface)get_sfnt_table;
230 
231 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
232     if ( ft_strcmp( module_interface, "glyph_name" ) == 0 )
233       return (FT_Module_Interface)get_sfnt_glyph_name;
234 #endif
235 
236     if ( ft_strcmp( module_interface, "postscript_name" ) == 0 )
237       return (FT_Module_Interface)get_sfnt_postscript_name;
238 
239     return 0;
240   }
241 
242 
243   static
244   const SFNT_Interface  sfnt_interface =
245   {
246     tt_face_goto_table,
247 
248     sfnt_init_face,
249     sfnt_load_face,
250     sfnt_done_face,
251     sfnt_get_interface,
252 
253     tt_face_load_any,
254     tt_face_load_sfnt_header,
255     tt_face_load_directory,
256 
257     tt_face_load_header,
258     tt_face_load_metrics_header,
259     tt_face_load_cmap,
260     tt_face_load_max_profile,
261     tt_face_load_os2,
262     tt_face_load_postscript,
263 
264     tt_face_load_names,
265     tt_face_free_names,
266 
267     tt_face_load_hdmx,
268     tt_face_free_hdmx,
269 
270     tt_face_load_kern,
271     tt_face_load_gasp,
272     tt_face_load_pclt,
273 
274 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
275 
276     /* see `ttload.h' */
277     tt_face_load_bitmap_header,
278 
279     /* see `ttsbit.h' */
280     tt_face_set_sbit_strike,
281     tt_face_load_sbit_strikes,
282     tt_face_load_sbit_image,
283     tt_face_free_sbit_strikes,
284 
285 #else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
286 
287     0,
288     0,
289     0,
290     0,
291     0,
292 
293 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
294 
295 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
296 
297     /* see `ttpost.h' */
298     tt_face_get_ps_name,
299     tt_face_free_ps_names,
300 
301 #else /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
302 
303     0,
304     0,
305 
306 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
307 
308     /* see `ttcmap.h' */
309     tt_face_load_charmap,
310     tt_face_free_charmap,
311   };
312 
313 
314   FT_CALLBACK_TABLE_DEF
315   const FT_Module_Class  sfnt_module_class =
316   {
317     0,  /* not a font driver or renderer */
318     sizeof( FT_ModuleRec ),
319 
320     "sfnt",     /* driver name                            */
321     0x10000L,   /* driver version 1.0                     */
322     0x20000L,   /* driver requires FreeType 2.0 or higher */
323 
324     (const void*)&sfnt_interface,  /* module specific interface */
325 
326     (FT_Module_Constructor)0,
327     (FT_Module_Destructor) 0,
328     (FT_Module_Requester)  sfnt_get_interface
329   };
330 
331 
332 /* END */
333