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

Last change on this file since 269 was 269, checked in by Eugene Romanenko, 13 years ago

PDF plugin: freetype library updated to version 2.3.9

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