source: trunk/poppler/freetype-2.1.10/src/sfnt/sfdriver.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

File size: 9.7 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  sfdriver.c                                                             */
4/*                                                                         */
5/*    High-level SFNT driver interface (body).                             */
6/*                                                                         */
7/*  Copyright 1996-2001, 2002, 2003, 2004, 2005 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 "sfobjs.h"
26
27#include "sferrors.h"
28
29#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
30#include "ttsbit.h"
31#endif
32
33#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
34#include "ttpost.h"
35#endif
36
37#include "ttcmap.h"
38#include "ttkern.h"
39
40#include FT_SERVICE_GLYPH_DICT_H
41#include FT_SERVICE_POSTSCRIPT_NAME_H
42#include FT_SERVICE_SFNT_H
43#include FT_SERVICE_TT_CMAP_H
44
45
46 /*
47  *  SFNT TABLE SERVICE
48  *
49  */
50
51  static void*
52  get_sfnt_table( TT_Face      face,
53                  FT_Sfnt_Tag  tag )
54  {
55    void*  table;
56
57
58    switch ( tag )
59    {
60    case ft_sfnt_head:
61      table = &face->header;
62      break;
63
64    case ft_sfnt_hhea:
65      table = &face->horizontal;
66      break;
67
68    case ft_sfnt_vhea:
69      table = face->vertical_info ? &face->vertical : 0;
70      break;
71
72    case ft_sfnt_os2:
73      table = face->os2.version == 0xFFFFU ? 0 : &face->os2;
74      break;
75
76    case ft_sfnt_post:
77      table = &face->postscript;
78      break;
79
80    case ft_sfnt_maxp:
81      table = &face->max_profile;
82      break;
83
84    case ft_sfnt_pclt:
85      table = face->pclt.Version ? &face->pclt : 0;
86      break;
87
88    default:
89      table = 0;
90    }
91
92    return table;
93  }
94
95
96  static FT_Error
97  sfnt_table_info( TT_Face    face,
98                   FT_UInt    idx,
99                   FT_ULong  *tag,
100                   FT_ULong  *length )
101  {
102    if ( !tag || !length )
103      return SFNT_Err_Invalid_Argument;
104
105    if ( idx >= face->num_tables )
106      return SFNT_Err_Table_Missing;
107
108    *tag    = face->dir_tables[idx].Tag;
109    *length = face->dir_tables[idx].Length;
110
111    return SFNT_Err_Ok;
112  }
113
114
115  static const FT_Service_SFNT_TableRec  sfnt_service_sfnt_table =
116  {
117    (FT_SFNT_TableLoadFunc)tt_face_load_any,
118    (FT_SFNT_TableGetFunc) get_sfnt_table,
119    (FT_SFNT_TableInfoFunc)sfnt_table_info
120  };
121
122
123#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
124
125 /*
126  *  GLYPH DICT SERVICE
127  *
128  */
129
130  static FT_Error
131  sfnt_get_glyph_name( TT_Face     face,
132                       FT_UInt     glyph_index,
133                       FT_Pointer  buffer,
134                       FT_UInt     buffer_max )
135  {
136    FT_String*  gname;
137    FT_Error    error;
138
139
140    error = tt_face_get_ps_name( face, glyph_index, &gname );
141    if ( !error && buffer_max > 0 )
142    {
143      FT_UInt  len = (FT_UInt)( ft_strlen( gname ) );
144
145
146      if ( len >= buffer_max )
147        len = buffer_max - 1;
148
149      FT_MEM_COPY( buffer, gname, len );
150      ((FT_Byte*)buffer)[len] = 0;
151    }
152
153    return error;
154  }
155
156
157  static const FT_Service_GlyphDictRec  sfnt_service_glyph_dict =
158  {
159    (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,
160    (FT_GlyphDict_NameIndexFunc)NULL
161  };
162
163#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
164
165
166 /*
167  *  POSTSCRIPT NAME SERVICE
168  *
169  */
170
171  static const char*
172  sfnt_get_ps_name( TT_Face  face )
173  {
174    FT_Int       n, found_win, found_apple;
175    const char*  result = NULL;
176
177
178    /* shouldn't happen, but just in case to avoid memory leaks */
179    if ( face->postscript_name )
180      return face->postscript_name;
181
182    /* scan the name table to see whether we have a Postscript name here, */
183    /* either in Macintosh or Windows platform encodings                  */
184    found_win   = -1;
185    found_apple = -1;
186
187    for ( n = 0; n < face->num_names; n++ )
188    {
189      TT_NameEntryRec*  name = face->name_table.names + n;
190
191
192      if ( name->nameID == 6 && name->stringLength > 0 )
193      {
194        if ( name->platformID == 3     &&
195             name->encodingID == 1     &&
196             name->languageID == 0x409 )
197          found_win = n;
198
199        if ( name->platformID == 1 &&
200             name->encodingID == 0 &&
201             name->languageID == 0 )
202          found_apple = n;
203      }
204    }
205
206    if ( found_win != -1 )
207    {
208      FT_Memory         memory = face->root.memory;
209      TT_NameEntryRec*  name   = face->name_table.names + found_win;
210      FT_UInt           len    = name->stringLength / 2;
211      FT_Error          error  = SFNT_Err_Ok;
212
213      FT_UNUSED( error );
214
215
216      if ( !FT_ALLOC( result, name->stringLength + 1 ) )
217      {
218        FT_Stream   stream = face->name_table.stream;
219        FT_String*  r      = (FT_String*)result;
220        FT_Byte*    p      = (FT_Byte*)name->string;
221
222
223        if ( FT_STREAM_SEEK( name->stringOffset ) ||
224             FT_FRAME_ENTER( name->stringLength ) )
225        {
226          FT_FREE( result );
227          name->stringLength = 0;
228          name->stringOffset = 0;
229          FT_FREE( name->string );
230
231          goto Exit;
232        }
233
234        p = (FT_Byte*)stream->cursor;
235
236        for ( ; len > 0; len--, p += 2 )
237        {
238          if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
239            *r++ = p[1];
240        }
241        *r = '\0';
242
243        FT_FRAME_EXIT();
244      }
245      goto Exit;
246    }
247
248    if ( found_apple != -1 )
249    {
250      FT_Memory         memory = face->root.memory;
251      TT_NameEntryRec*  name   = face->name_table.names + found_apple;
252      FT_UInt           len    = name->stringLength;
253      FT_Error          error  = SFNT_Err_Ok;
254
255      FT_UNUSED( error );
256
257
258      if ( !FT_ALLOC( result, len + 1 ) )
259      {
260        FT_Stream  stream = face->name_table.stream;
261
262
263        if ( FT_STREAM_SEEK( name->stringOffset ) ||
264             FT_STREAM_READ( result, len )        )
265        {
266          name->stringOffset = 0;
267          name->stringLength = 0;
268          FT_FREE( name->string );
269          FT_FREE( result );
270          goto Exit;
271        }
272        ((char*)result)[len] = '\0';
273      }
274    }
275
276  Exit:
277    face->postscript_name = result;
278    return result;
279  }
280
281  static const FT_Service_PsFontNameRec  sfnt_service_ps_name =
282  {
283    (FT_PsName_GetFunc)sfnt_get_ps_name
284  };
285
286
287 /*
288  *  TT CMAP INFO
289  *
290  */
291  static const FT_Service_TTCMapsRec  tt_service_get_cmap_info =
292  {
293    (TT_CMap_Info_GetFunc)tt_get_cmap_info
294  };
295
296
297 /*
298  *  SERVICE LIST
299  *
300  */
301
302  static const FT_ServiceDescRec  sfnt_services[] =
303  {
304    { FT_SERVICE_ID_SFNT_TABLE,           &sfnt_service_sfnt_table },
305    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name },
306#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
307    { FT_SERVICE_ID_GLYPH_DICT,           &sfnt_service_glyph_dict },
308#endif
309    { FT_SERVICE_ID_TT_CMAP,              &tt_service_get_cmap_info },
310
311    { NULL, NULL }
312  };
313
314
315  FT_CALLBACK_DEF( FT_Module_Interface )
316  sfnt_get_interface( FT_Module    module,
317                      const char*  module_interface )
318  {
319    FT_UNUSED( module );
320
321    if ( ft_strcmp( module_interface, "get_sfnt" ) == 0 )
322      return (FT_Module_Interface)get_sfnt_table;
323
324    if ( ft_strcmp( module_interface, "load_sfnt" ) == 0 )
325      return (FT_Module_Interface)tt_face_load_any;
326
327    return ft_service_list_lookup( sfnt_services, module_interface );
328  }
329
330
331  static
332  const SFNT_Interface  sfnt_interface =
333  {
334    tt_face_goto_table,
335
336    sfnt_init_face,
337    sfnt_load_face,
338    sfnt_done_face,
339    sfnt_get_interface,
340
341    tt_face_load_any,
342    tt_face_load_sfnt_header,
343    tt_face_load_directory,
344
345    tt_face_load_header,
346    tt_face_load_metrics_header,
347    tt_face_load_cmap,
348    tt_face_load_max_profile,
349    tt_face_load_os2,
350    tt_face_load_postscript,
351
352    tt_face_load_names,
353    tt_face_free_names,
354
355    tt_face_load_hdmx,
356    tt_face_free_hdmx,
357
358    tt_face_load_kern,
359    tt_face_load_gasp,
360    tt_face_load_pclt,
361
362#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
363
364    /* see `ttload.h' */
365    tt_face_load_bitmap_header,
366
367    /* see `ttsbit.h' and `sfnt.h' */
368    tt_face_set_sbit_strike,
369    tt_face_load_sbit_strikes,
370    0 /* tt_find_sbit_image */,
371    0 /* tt_load_sbit_metrics */,
372    tt_face_load_sbit_image,
373    tt_face_free_sbit_strikes,
374
375#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
376
377    0,
378    0,
379    0,
380    0,
381    0,
382    0,
383    0,
384
385#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
386
387#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
388
389    /* see `ttkern.h' */
390    tt_face_get_kerning,
391
392    /* see `ttpost.h' */
393    tt_face_get_ps_name,
394    tt_face_free_ps_names,
395
396#else /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
397
398    0,
399    0,
400
401#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
402
403  };
404
405
406  FT_CALLBACK_TABLE_DEF
407  const FT_Module_Class  sfnt_module_class =
408  {
409    0,  /* not a font driver or renderer */
410    sizeof( FT_ModuleRec ),
411
412    "sfnt",     /* driver name                            */
413    0x10000L,   /* driver version 1.0                     */
414    0x20000L,   /* driver requires FreeType 2.0 or higher */
415
416    (const void*)&sfnt_interface,  /* module specific interface */
417
418    (FT_Module_Constructor)0,
419    (FT_Module_Destructor) 0,
420    (FT_Module_Requester)  sfnt_get_interface
421  };
422
423
424/* END */
Note: See TracBrowser for help on using the repository browser.