PageRenderTime 58ms CodeModel.GetById 1ms app.highlight 51ms RepoModel.GetById 1ms app.codeStats 0ms

/src/compiler/android-ndk/jni/freetype/src/sfnt/sfdriver.c

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