source: trunk/poppler/freetype2/src/sfnt/sfdriver.c @ 182

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

freetype update to version 2.3.0

File size: 15.0 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  sfdriver.c                                                             */
4/*                                                                         */
5/*    High-level SFNT driver interface (body).                             */
6/*                                                                         */
7/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 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#ifdef TT_CONFIG_OPTION_BDF
38#include "ttbdf.h"
39#include FT_SERVICE_BDF_H
40#endif
41
42#include "ttcmap.h"
43#include "ttkern.h"
44#include "ttmtx.h"
45
46#include FT_SERVICE_GLYPH_DICT_H
47#include FT_SERVICE_POSTSCRIPT_NAME_H
48#include FT_SERVICE_SFNT_H
49#include FT_SERVICE_TT_CMAP_H
50
51
52 /*
53  *  SFNT TABLE SERVICE
54  *
55  */
56
57  static void*
58  get_sfnt_table( TT_Face      face,
59                  FT_Sfnt_Tag  tag )
60  {
61    void*  table;
62
63
64    switch ( tag )
65    {
66    case ft_sfnt_head:
67      table = &face->header;
68      break;
69
70    case ft_sfnt_hhea:
71      table = &face->horizontal;
72      break;
73
74    case ft_sfnt_vhea:
75      table = face->vertical_info ? &face->vertical : 0;
76      break;
77
78    case ft_sfnt_os2:
79      table = face->os2.version == 0xFFFFU ? 0 : &face->os2;
80      break;
81
82    case ft_sfnt_post:
83      table = &face->postscript;
84      break;
85
86    case ft_sfnt_maxp:
87      table = &face->max_profile;
88      break;
89
90    case ft_sfnt_pclt:
91      table = face->pclt.Version ? &face->pclt : 0;
92      break;
93
94    default:
95      table = 0;
96    }
97
98    return table;
99  }
100
101
102  static FT_Error
103  sfnt_table_info( TT_Face    face,
104                   FT_UInt    idx,
105                   FT_ULong  *tag,
106                   FT_ULong  *length )
107  {
108    if ( !tag || !length )
109      return SFNT_Err_Invalid_Argument;
110
111    if ( idx >= face->num_tables )
112      return SFNT_Err_Table_Missing;
113
114    *tag    = face->dir_tables[idx].Tag;
115    *length = face->dir_tables[idx].Length;
116
117    return SFNT_Err_Ok;
118  }
119
120
121  static const FT_Service_SFNT_TableRec  sfnt_service_sfnt_table =
122  {
123    (FT_SFNT_TableLoadFunc)tt_face_load_any,
124    (FT_SFNT_TableGetFunc) get_sfnt_table,
125    (FT_SFNT_TableInfoFunc)sfnt_table_info
126  };
127
128
129#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
130
131 /*
132  *  GLYPH DICT SERVICE
133  *
134  */
135
136  static FT_Error
137  sfnt_get_glyph_name( TT_Face     face,
138                       FT_UInt     glyph_index,
139                       FT_Pointer  buffer,
140                       FT_UInt     buffer_max )
141  {
142    FT_String*  gname;
143    FT_Error    error;
144
145
146    error = tt_face_get_ps_name( face, glyph_index, &gname );
147    if ( !error && buffer_max > 0 )
148    {
149      FT_UInt  len = (FT_UInt)( ft_strlen( gname ) );
150
151
152      if ( len >= buffer_max )
153        len = buffer_max - 1;
154
155      FT_MEM_COPY( buffer, gname, len );
156      ((FT_Byte*)buffer)[len] = 0;
157    }
158
159    return error;
160  }
161
162
163  static const FT_Service_GlyphDictRec  sfnt_service_glyph_dict =
164  {
165    (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,
166    (FT_GlyphDict_NameIndexFunc)NULL
167  };
168
169#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
170
171
172 /*
173  *  POSTSCRIPT NAME SERVICE
174  *
175  */
176
177  static const char*
178  sfnt_get_ps_name( TT_Face  face )
179  {
180    FT_Int       n, found_win, found_apple;
181    const char*  result = NULL;
182
183
184    /* shouldn't happen, but just in case to avoid memory leaks */
185    if ( face->postscript_name )
186      return face->postscript_name;
187
188    /* scan the name table to see whether we have a Postscript name here, */
189    /* either in Macintosh or Windows platform encodings                  */
190    found_win   = -1;
191    found_apple = -1;
192
193    for ( n = 0; n < face->num_names; n++ )
194    {
195      TT_NameEntryRec*  name = face->name_table.names + n;
196
197
198      if ( name->nameID == 6 && name->stringLength > 0 )
199      {
200        if ( name->platformID == 3     &&
201             name->encodingID == 1     &&
202             name->languageID == 0x409 )
203          found_win = n;
204
205        if ( name->platformID == 1 &&
206             name->encodingID == 0 &&
207             name->languageID == 0 )
208          found_apple = n;
209      }
210    }
211
212    if ( found_win != -1 )
213    {
214      FT_Memory         memory = face->root.memory;
215      TT_NameEntryRec*  name   = face->name_table.names + found_win;
216      FT_UInt           len    = name->stringLength / 2;
217      FT_Error          error  = SFNT_Err_Ok;
218
219      FT_UNUSED( error );
220
221
222      if ( !FT_ALLOC( result, name->stringLength + 1 ) )
223      {
224        FT_Stream   stream = face->name_table.stream;
225        FT_String*  r      = (FT_String*)result;
226        FT_Byte*    p      = (FT_Byte*)name->string;
227
228
229        if ( FT_STREAM_SEEK( name->stringOffset ) ||
230             FT_FRAME_ENTER( name->stringLength ) )
231        {
232          FT_FREE( result );
233          name->stringLength = 0;
234          name->stringOffset = 0;
235          FT_FREE( name->string );
236
237          goto Exit;
238        }
239
240        p = (FT_Byte*)stream->cursor;
241
242        for ( ; len > 0; len--, p += 2 )
243        {
244          if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
245            *r++ = p[1];
246        }
247        *r = '\0';
248
249        FT_FRAME_EXIT();
250      }
251      goto Exit;
252    }
253
254    if ( found_apple != -1 )
255    {
256      FT_Memory         memory = face->root.memory;
257      TT_NameEntryRec*  name   = face->name_table.names + found_apple;
258      FT_UInt           len    = name->stringLength;
259      FT_Error          error  = SFNT_Err_Ok;
260
261      FT_UNUSED( error );
262
263
264      if ( !FT_ALLOC( result, len + 1 ) )
265      {
266        FT_Stream  stream = face->name_table.stream;
267
268
269        if ( FT_STREAM_SEEK( name->stringOffset ) ||
270             FT_STREAM_READ( result, len )        )
271        {
272          name->stringOffset = 0;
273          name->stringLength = 0;
274          FT_FREE( name->string );
275          FT_FREE( result );
276          goto Exit;
277        }
278        ((char*)result)[len] = '\0';
279      }
280    }
281
282  Exit:
283    face->postscript_name = result;
284    return result;
285  }
286
287  static const FT_Service_PsFontNameRec  sfnt_service_ps_name =
288  {
289    (FT_PsName_GetFunc)sfnt_get_ps_name
290  };
291
292
293  /*
294   *  TT CMAP INFO
295   */
296  static const FT_Service_TTCMapsRec  tt_service_get_cmap_info =
297  {
298    (TT_CMap_Info_GetFunc)tt_get_cmap_info
299  };
300
301
302#ifdef TT_CONFIG_OPTION_BDF
303
304  static FT_Error
305  sfnt_get_charset_id( TT_Face       face,
306                       const char*  *acharset_encoding,
307                       const char*  *acharset_registry )
308  {
309    BDF_PropertyRec  encoding, registry;
310    FT_Error         error;
311
312
313    /* XXX: I don't know whether this is correct, since
314     *      tt_face_find_bdf_prop only returns something correct if we have
315     *      previously selected a size that is listed in the BDF table.
316     *      Should we change the BDF table format to include single offsets
317     *      for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?
318     */
319    error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", &registry );
320    if ( !error )
321    {
322      error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
323      if ( !error )
324      {
325        if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
326             encoding.type == BDF_PROPERTY_TYPE_ATOM )
327        {
328          *acharset_encoding = encoding.u.atom;
329          *acharset_registry = registry.u.atom;
330        }
331        else
332          error = FT_Err_Invalid_Argument;
333      }
334    }
335
336    return error;
337  }
338
339
340  static const FT_Service_BDFRec  sfnt_service_bdf =
341  {
342    (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
343    (FT_BDF_GetPropertyFunc)  tt_face_find_bdf_prop,
344  };
345
346#endif /* TT_CONFIG_OPTION_BDF */
347
348
349  /*
350   *  SERVICE LIST
351   */
352
353  static const FT_ServiceDescRec  sfnt_services[] =
354  {
355    { FT_SERVICE_ID_SFNT_TABLE,           &sfnt_service_sfnt_table },
356    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name },
357#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
358    { FT_SERVICE_ID_GLYPH_DICT,           &sfnt_service_glyph_dict },
359#endif
360#ifdef TT_CONFIG_OPTION_BDF
361    { FT_SERVICE_ID_BDF,                  &sfnt_service_bdf },
362#endif
363    { FT_SERVICE_ID_TT_CMAP,              &tt_service_get_cmap_info },
364
365    { NULL, NULL }
366  };
367
368
369  FT_CALLBACK_DEF( FT_Module_Interface )
370  sfnt_get_interface( FT_Module    module,
371                      const char*  module_interface )
372  {
373    FT_UNUSED( module );
374
375    return ft_service_list_lookup( sfnt_services, module_interface );
376  }
377
378
379#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
380
381  FT_CALLBACK_DEF( FT_Error )
382  tt_face_load_sfnt_header_stub( TT_Face      face,
383                                 FT_Stream    stream,
384                                 FT_Long      face_index,
385                                 SFNT_Header  header )
386  {
387    FT_UNUSED( face );
388    FT_UNUSED( stream );
389    FT_UNUSED( face_index );
390    FT_UNUSED( header );
391
392    return FT_Err_Unimplemented_Feature;
393  }
394
395
396  FT_CALLBACK_DEF( FT_Error )
397  tt_face_load_directory_stub( TT_Face      face,
398                               FT_Stream    stream,
399                               SFNT_Header  header )
400  {
401    FT_UNUSED( face );
402    FT_UNUSED( stream );
403    FT_UNUSED( header );
404
405    return FT_Err_Unimplemented_Feature;
406  }
407
408
409  FT_CALLBACK_DEF( FT_Error )
410  tt_face_load_hdmx_stub( TT_Face    face,
411                          FT_Stream  stream )
412  {
413    FT_UNUSED( face );
414    FT_UNUSED( stream );
415
416    return FT_Err_Unimplemented_Feature;
417  }
418
419
420  FT_CALLBACK_DEF( void )
421  tt_face_free_hdmx_stub( TT_Face  face )
422  {
423    FT_UNUSED( face );
424  }
425
426
427  FT_CALLBACK_DEF( FT_Error )
428  tt_face_set_sbit_strike_stub( TT_Face    face,
429                                FT_UInt    x_ppem,
430                                FT_UInt    y_ppem,
431                                FT_ULong*  astrike_index )
432  {
433    /*
434     * We simply forge a FT_Size_Request and call the real function
435     * that does all the work.
436     *
437     * This stub might be called by libXfont in the X.Org Xserver,
438     * compiled against version 2.1.8 or newer.
439     */
440
441    FT_Size_RequestRec  req;
442
443
444    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
445    req.width          = (FT_F26Dot6)x_ppem;
446    req.height         = (FT_F26Dot6)y_ppem;
447    req.horiResolution = 0;
448    req.vertResolution = 0;
449
450    *astrike_index = 0x7FFFFFFFUL;
451
452    return tt_face_set_sbit_strike( face, &req, astrike_index );
453  }
454
455
456  FT_CALLBACK_DEF( FT_Error )
457  tt_face_load_sbit_stub( TT_Face    face,
458                          FT_Stream  stream )
459  {
460    FT_UNUSED( face );
461    FT_UNUSED( stream );
462
463    /*
464     *  This function was originally implemented to load the sbit table.
465     *  However, it has been replaced by `tt_face_load_eblc', and this stub
466     *  is only there for some rogue clients which would want to call it
467     *  directly (which doesn't make much sense).
468     */
469    return FT_Err_Unimplemented_Feature;
470  }
471
472
473  FT_CALLBACK_DEF( void )
474  tt_face_free_sbit_stub( TT_Face  face )
475  {
476    /* nothing to do in this stub */
477    FT_UNUSED( face );
478  }
479
480
481  FT_CALLBACK_DEF( FT_Error )
482  tt_face_load_charmap_stub( TT_Face    face,
483                             void*      cmap,
484                             FT_Stream  input )
485  {
486    FT_UNUSED( face );
487    FT_UNUSED( cmap );
488    FT_UNUSED( input );
489
490    return FT_Err_Unimplemented_Feature;
491  }
492
493
494  FT_CALLBACK_DEF( FT_Error )
495  tt_face_free_charmap_stub( TT_Face  face,
496                             void*    cmap )
497  {
498    FT_UNUSED( face );
499    FT_UNUSED( cmap );
500
501    return 0;
502  }
503
504#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
505
506
507  static
508  const SFNT_Interface  sfnt_interface =
509  {
510    tt_face_goto_table,
511
512    sfnt_init_face,
513    sfnt_load_face,
514    sfnt_done_face,
515    sfnt_get_interface,
516
517    tt_face_load_any,
518
519#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
520    tt_face_load_sfnt_header_stub,
521    tt_face_load_directory_stub,
522#endif
523
524    tt_face_load_head,
525    tt_face_load_hhea,
526    tt_face_load_cmap,
527    tt_face_load_maxp,
528    tt_face_load_os2,
529    tt_face_load_post,
530
531    tt_face_load_name,
532    tt_face_free_name,
533
534#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
535    tt_face_load_hdmx_stub,
536    tt_face_free_hdmx_stub,
537#endif
538
539    tt_face_load_kern,
540    tt_face_load_gasp,
541    tt_face_load_pclt,
542
543#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
544    /* see `ttload.h' */
545    tt_face_load_bhed,
546#else
547    0,
548#endif
549
550#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
551    tt_face_set_sbit_strike_stub,
552    tt_face_load_sbit_stub,
553
554    tt_find_sbit_image,
555    tt_load_sbit_metrics,
556#endif
557
558#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
559    tt_face_load_sbit_image,
560#else
561    0,
562#endif
563
564#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
565    tt_face_free_sbit_stub,
566#endif
567
568#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
569    /* see `ttpost.h' */
570    tt_face_get_ps_name,
571    tt_face_free_ps_names,
572#else
573    0,
574    0,
575#endif
576
577#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
578    tt_face_load_charmap_stub,
579    tt_face_free_charmap_stub,
580#endif
581
582    /* since version 2.1.8 */
583
584    tt_face_get_kerning,
585
586    /* since version 2.2 */
587
588    tt_face_load_font_dir,
589    tt_face_load_hmtx,
590
591#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
592    /* see `ttsbit.h' and `sfnt.h' */
593    tt_face_load_eblc,
594    tt_face_free_eblc,
595
596    tt_face_set_sbit_strike,
597    tt_face_load_strike_metrics,
598#else
599    0,
600    0,
601    0,
602    0,
603#endif
604
605    tt_face_get_metrics
606  };
607
608
609  FT_CALLBACK_TABLE_DEF
610  const FT_Module_Class  sfnt_module_class =
611  {
612    0,  /* not a font driver or renderer */
613    sizeof( FT_ModuleRec ),
614
615    "sfnt",     /* driver name                            */
616    0x10000L,   /* driver version 1.0                     */
617    0x20000L,   /* driver requires FreeType 2.0 or higher */
618
619    (const void*)&sfnt_interface,  /* module specific interface */
620
621    (FT_Module_Constructor)0,
622    (FT_Module_Destructor) 0,
623    (FT_Module_Requester)  sfnt_get_interface
624  };
625
626
627/* END */
Note: See TracBrowser for help on using the repository browser.