sfdriver.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  sfdriver.c                                                             */
00004 /*                                                                         */
00005 /*    High-level SFNT driver interface (body).                             */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by       */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_DEBUG_H
00021 #include FT_INTERNAL_SFNT_H
00022 #include FT_INTERNAL_OBJECTS_H
00023 
00024 #include "sfdriver.h"
00025 #include "ttload.h"
00026 #include "sfobjs.h"
00027 #include "sfntpic.h"
00028 
00029 #include "sferrors.h"
00030 
00031 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00032 #include "ttsbit.h"
00033 #endif
00034 
00035 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
00036 #include "ttpost.h"
00037 #endif
00038 
00039 #ifdef TT_CONFIG_OPTION_BDF
00040 #include "ttbdf.h"
00041 #include FT_SERVICE_BDF_H
00042 #endif
00043 
00044 #include "ttcmap.h"
00045 #include "ttkern.h"
00046 #include "ttmtx.h"
00047 
00048 #include FT_SERVICE_GLYPH_DICT_H
00049 #include FT_SERVICE_POSTSCRIPT_NAME_H
00050 #include FT_SERVICE_SFNT_H
00051 #include FT_SERVICE_TT_CMAP_H
00052 
00053   /*************************************************************************/
00054   /*                                                                       */
00055   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00056   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00057   /* messages during execution.                                            */
00058   /*                                                                       */
00059 #undef  FT_COMPONENT
00060 #define FT_COMPONENT  trace_sfdriver
00061 
00062 
00063  /*
00064   *  SFNT TABLE SERVICE
00065   *
00066   */
00067 
00068   static void*
00069   get_sfnt_table( TT_Face      face,
00070                   FT_Sfnt_Tag  tag )
00071   {
00072     void*  table;
00073 
00074 
00075     switch ( tag )
00076     {
00077     case ft_sfnt_head:
00078       table = &face->header;
00079       break;
00080 
00081     case ft_sfnt_hhea:
00082       table = &face->horizontal;
00083       break;
00084 
00085     case ft_sfnt_vhea:
00086       table = face->vertical_info ? &face->vertical : 0;
00087       break;
00088 
00089     case ft_sfnt_os2:
00090       table = face->os2.version == 0xFFFFU ? 0 : &face->os2;
00091       break;
00092 
00093     case ft_sfnt_post:
00094       table = &face->postscript;
00095       break;
00096 
00097     case ft_sfnt_maxp:
00098       table = &face->max_profile;
00099       break;
00100 
00101     case ft_sfnt_pclt:
00102       table = face->pclt.Version ? &face->pclt : 0;
00103       break;
00104 
00105     default:
00106       table = 0;
00107     }
00108 
00109     return table;
00110   }
00111 
00112 
00113   static FT_Error
00114   sfnt_table_info( TT_Face    face,
00115                    FT_UInt    idx,
00116                    FT_ULong  *tag,
00117                    FT_ULong  *offset,
00118                    FT_ULong  *length )
00119   {
00120     if ( !tag || !offset || !length )
00121       return SFNT_Err_Invalid_Argument;
00122 
00123     if ( idx >= face->num_tables )
00124       return SFNT_Err_Table_Missing;
00125 
00126     *tag    = face->dir_tables[idx].Tag;
00127     *offset = face->dir_tables[idx].Offset;
00128     *length = face->dir_tables[idx].Length;
00129 
00130     return SFNT_Err_Ok;
00131   }
00132 
00133 
00134   FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table,
00135     (FT_SFNT_TableLoadFunc)tt_face_load_any,
00136     (FT_SFNT_TableGetFunc) get_sfnt_table,
00137     (FT_SFNT_TableInfoFunc)sfnt_table_info
00138   )
00139 
00140 
00141 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
00142 
00143  /*
00144   *  GLYPH DICT SERVICE
00145   *
00146   */
00147 
00148   static FT_Error
00149   sfnt_get_glyph_name( TT_Face     face,
00150                        FT_UInt     glyph_index,
00151                        FT_Pointer  buffer,
00152                        FT_UInt     buffer_max )
00153   {
00154     FT_String*  gname;
00155     FT_Error    error;
00156 
00157 
00158     error = tt_face_get_ps_name( face, glyph_index, &gname );
00159     if ( !error )
00160       FT_STRCPYN( buffer, gname, buffer_max );
00161 
00162     return error;
00163   }
00164 
00165 
00166   static FT_UInt
00167   sfnt_get_name_index( TT_Face     face,
00168                        FT_String*  glyph_name )
00169   {
00170     FT_Face   root = &face->root;
00171     FT_UInt   i, max_gid = FT_UINT_MAX;
00172 
00173 
00174     if ( root->num_glyphs < 0 )
00175       return 0;
00176     else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX )
00177       max_gid = ( FT_UInt ) root->num_glyphs;
00178     else
00179       FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
00180          FT_UINT_MAX, root->num_glyphs ));
00181 
00182     for ( i = 0; i < max_gid; i++ )
00183     {
00184       FT_String*  gname;
00185       FT_Error    error = tt_face_get_ps_name( face, i, &gname );
00186 
00187 
00188       if ( error )
00189         continue;
00190 
00191       if ( !ft_strcmp( glyph_name, gname ) )
00192         return i;
00193     }
00194 
00195     return 0;
00196   }
00197 
00198 
00199   FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict,
00200     (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,
00201     (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index
00202   )
00203 
00204 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
00205 
00206 
00207  /*
00208   *  POSTSCRIPT NAME SERVICE
00209   *
00210   */
00211 
00212   static const char*
00213   sfnt_get_ps_name( TT_Face  face )
00214   {
00215     FT_Int       n, found_win, found_apple;
00216     const char*  result = NULL;
00217 
00218 
00219     /* shouldn't happen, but just in case to avoid memory leaks */
00220     if ( face->postscript_name )
00221       return face->postscript_name;
00222 
00223     /* scan the name table to see whether we have a Postscript name here, */
00224     /* either in Macintosh or Windows platform encodings                  */
00225     found_win   = -1;
00226     found_apple = -1;
00227 
00228     for ( n = 0; n < face->num_names; n++ )
00229     {
00230       TT_NameEntryRec*  name = face->name_table.names + n;
00231 
00232 
00233       if ( name->nameID == 6 && name->stringLength > 0 )
00234       {
00235         if ( name->platformID == 3     &&
00236              name->encodingID == 1     &&
00237              name->languageID == 0x409 )
00238           found_win = n;
00239 
00240         if ( name->platformID == 1 &&
00241              name->encodingID == 0 &&
00242              name->languageID == 0 )
00243           found_apple = n;
00244       }
00245     }
00246 
00247     if ( found_win != -1 )
00248     {
00249       FT_Memory         memory = face->root.memory;
00250       TT_NameEntryRec*  name   = face->name_table.names + found_win;
00251       FT_UInt           len    = name->stringLength / 2;
00252       FT_Error          error  = SFNT_Err_Ok;
00253 
00254       FT_UNUSED( error );
00255 
00256 
00257       if ( !FT_ALLOC( result, name->stringLength + 1 ) )
00258       {
00259         FT_Stream   stream = face->name_table.stream;
00260         FT_String*  r      = (FT_String*)result;
00261         FT_Byte*    p      = (FT_Byte*)name->string;
00262 
00263 
00264         if ( FT_STREAM_SEEK( name->stringOffset ) ||
00265              FT_FRAME_ENTER( name->stringLength ) )
00266         {
00267           FT_FREE( result );
00268           name->stringLength = 0;
00269           name->stringOffset = 0;
00270           FT_FREE( name->string );
00271 
00272           goto Exit;
00273         }
00274 
00275         p = (FT_Byte*)stream->cursor;
00276 
00277         for ( ; len > 0; len--, p += 2 )
00278         {
00279           if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
00280             *r++ = p[1];
00281         }
00282         *r = '\0';
00283 
00284         FT_FRAME_EXIT();
00285       }
00286       goto Exit;
00287     }
00288 
00289     if ( found_apple != -1 )
00290     {
00291       FT_Memory         memory = face->root.memory;
00292       TT_NameEntryRec*  name   = face->name_table.names + found_apple;
00293       FT_UInt           len    = name->stringLength;
00294       FT_Error          error  = SFNT_Err_Ok;
00295 
00296       FT_UNUSED( error );
00297 
00298 
00299       if ( !FT_ALLOC( result, len + 1 ) )
00300       {
00301         FT_Stream  stream = face->name_table.stream;
00302 
00303 
00304         if ( FT_STREAM_SEEK( name->stringOffset ) ||
00305              FT_STREAM_READ( result, len )        )
00306         {
00307           name->stringOffset = 0;
00308           name->stringLength = 0;
00309           FT_FREE( name->string );
00310           FT_FREE( result );
00311           goto Exit;
00312         }
00313         ((char*)result)[len] = '\0';
00314       }
00315     }
00316 
00317   Exit:
00318     face->postscript_name = result;
00319     return result;
00320   }
00321 
00322   FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name,
00323     (FT_PsName_GetFunc)sfnt_get_ps_name
00324   )
00325 
00326 
00327   /*
00328    *  TT CMAP INFO
00329    */
00330   FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info,
00331     (TT_CMap_Info_GetFunc)tt_get_cmap_info
00332   )
00333 
00334 
00335 #ifdef TT_CONFIG_OPTION_BDF
00336 
00337   static FT_Error
00338   sfnt_get_charset_id( TT_Face       face,
00339                        const char*  *acharset_encoding,
00340                        const char*  *acharset_registry )
00341   {
00342     BDF_PropertyRec  encoding, registry;
00343     FT_Error         error;
00344 
00345 
00346     /* XXX: I don't know whether this is correct, since
00347      *      tt_face_find_bdf_prop only returns something correct if we have
00348      *      previously selected a size that is listed in the BDF table.
00349      *      Should we change the BDF table format to include single offsets
00350      *      for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?
00351      */
00352     error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", &registry );
00353     if ( !error )
00354     {
00355       error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
00356       if ( !error )
00357       {
00358         if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
00359              encoding.type == BDF_PROPERTY_TYPE_ATOM )
00360         {
00361           *acharset_encoding = encoding.u.atom;
00362           *acharset_registry = registry.u.atom;
00363         }
00364         else
00365           error = FT_Err_Invalid_Argument;
00366       }
00367     }
00368 
00369     return error;
00370   }
00371 
00372 
00373   FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf,
00374     (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
00375     (FT_BDF_GetPropertyFunc)  tt_face_find_bdf_prop
00376   )
00377 
00378 #endif /* TT_CONFIG_OPTION_BDF */
00379 
00380 
00381   /*
00382    *  SERVICE LIST
00383    */
00384 
00385 #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
00386   FT_DEFINE_SERVICEDESCREC5(sfnt_services,
00387     FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,
00388     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
00389     FT_SERVICE_ID_GLYPH_DICT,           &FT_SFNT_SERVICE_GLYPH_DICT_GET,
00390     FT_SERVICE_ID_BDF,                  &FT_SFNT_SERVICE_BDF_GET,
00391     FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET
00392   )
00393 #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
00394   FT_DEFINE_SERVICEDESCREC4(sfnt_services,
00395     FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,
00396     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
00397     FT_SERVICE_ID_GLYPH_DICT,           &FT_SFNT_SERVICE_GLYPH_DICT_GET,
00398     FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET
00399   )
00400 #elif defined TT_CONFIG_OPTION_BDF
00401   FT_DEFINE_SERVICEDESCREC4(sfnt_services,
00402     FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,
00403     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
00404     FT_SERVICE_ID_BDF,                  &FT_SFNT_SERVICE_BDF_GET,
00405     FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET
00406   )
00407 #else
00408   FT_DEFINE_SERVICEDESCREC3(sfnt_services,
00409     FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,
00410     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
00411     FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET
00412   )
00413 #endif
00414 
00415 
00416   FT_CALLBACK_DEF( FT_Module_Interface )
00417   sfnt_get_interface( FT_Module    module,
00418                       const char*  module_interface )
00419   {
00420     FT_UNUSED( module );
00421 
00422     return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface );
00423   }
00424 
00425 
00426 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
00427 
00428   FT_CALLBACK_DEF( FT_Error )
00429   tt_face_load_sfnt_header_stub( TT_Face      face,
00430                                  FT_Stream    stream,
00431                                  FT_Long      face_index,
00432                                  SFNT_Header  header )
00433   {
00434     FT_UNUSED( face );
00435     FT_UNUSED( stream );
00436     FT_UNUSED( face_index );
00437     FT_UNUSED( header );
00438 
00439     return FT_Err_Unimplemented_Feature;
00440   }
00441 
00442 
00443   FT_CALLBACK_DEF( FT_Error )
00444   tt_face_load_directory_stub( TT_Face      face,
00445                                FT_Stream    stream,
00446                                SFNT_Header  header )
00447   {
00448     FT_UNUSED( face );
00449     FT_UNUSED( stream );
00450     FT_UNUSED( header );
00451 
00452     return FT_Err_Unimplemented_Feature;
00453   }
00454 
00455 
00456   FT_CALLBACK_DEF( FT_Error )
00457   tt_face_load_hdmx_stub( TT_Face    face,
00458                           FT_Stream  stream )
00459   {
00460     FT_UNUSED( face );
00461     FT_UNUSED( stream );
00462 
00463     return FT_Err_Unimplemented_Feature;
00464   }
00465 
00466 
00467   FT_CALLBACK_DEF( void )
00468   tt_face_free_hdmx_stub( TT_Face  face )
00469   {
00470     FT_UNUSED( face );
00471   }
00472 
00473 
00474   FT_CALLBACK_DEF( FT_Error )
00475   tt_face_set_sbit_strike_stub( TT_Face    face,
00476                                 FT_UInt    x_ppem,
00477                                 FT_UInt    y_ppem,
00478                                 FT_ULong*  astrike_index )
00479   {
00480     /*
00481      * We simply forge a FT_Size_Request and call the real function
00482      * that does all the work.
00483      *
00484      * This stub might be called by libXfont in the X.Org Xserver,
00485      * compiled against version 2.1.8 or newer.
00486      */
00487 
00488     FT_Size_RequestRec  req;
00489 
00490 
00491     req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
00492     req.width          = (FT_F26Dot6)x_ppem;
00493     req.height         = (FT_F26Dot6)y_ppem;
00494     req.horiResolution = 0;
00495     req.vertResolution = 0;
00496 
00497     *astrike_index = 0x7FFFFFFFUL;
00498 
00499     return tt_face_set_sbit_strike( face, &req, astrike_index );
00500   }
00501 
00502 
00503   FT_CALLBACK_DEF( FT_Error )
00504   tt_face_load_sbit_stub( TT_Face    face,
00505                           FT_Stream  stream )
00506   {
00507     FT_UNUSED( face );
00508     FT_UNUSED( stream );
00509 
00510     /*
00511      *  This function was originally implemented to load the sbit table.
00512      *  However, it has been replaced by `tt_face_load_eblc', and this stub
00513      *  is only there for some rogue clients which would want to call it
00514      *  directly (which doesn't make much sense).
00515      */
00516     return FT_Err_Unimplemented_Feature;
00517   }
00518 
00519 
00520   FT_CALLBACK_DEF( void )
00521   tt_face_free_sbit_stub( TT_Face  face )
00522   {
00523     /* nothing to do in this stub */
00524     FT_UNUSED( face );
00525   }
00526 
00527 
00528   FT_CALLBACK_DEF( FT_Error )
00529   tt_face_load_charmap_stub( TT_Face    face,
00530                              void*      cmap,
00531                              FT_Stream  input )
00532   {
00533     FT_UNUSED( face );
00534     FT_UNUSED( cmap );
00535     FT_UNUSED( input );
00536 
00537     return FT_Err_Unimplemented_Feature;
00538   }
00539 
00540 
00541   FT_CALLBACK_DEF( FT_Error )
00542   tt_face_free_charmap_stub( TT_Face  face,
00543                              void*    cmap )
00544   {
00545     FT_UNUSED( face );
00546     FT_UNUSED( cmap );
00547 
00548     return 0;
00549   }
00550 
00551 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
00552 
00553 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00554 #define PUT_EMBEDDED_BITMAPS(a) a 
00555 #else
00556 #define PUT_EMBEDDED_BITMAPS(a) 0 
00557 #endif
00558 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
00559 #define PUT_PS_NAMES(a) a 
00560 #else
00561 #define PUT_PS_NAMES(a) 0 
00562 #endif
00563 
00564   FT_DEFINE_SFNT_INTERFACE(sfnt_interface,
00565     tt_face_goto_table,
00566 
00567     sfnt_init_face,
00568     sfnt_load_face,
00569     sfnt_done_face,
00570     sfnt_get_interface,
00571 
00572     tt_face_load_any,
00573 
00574     tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00575     tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00576 
00577     tt_face_load_head,
00578     tt_face_load_hhea,
00579     tt_face_load_cmap,
00580     tt_face_load_maxp,
00581     tt_face_load_os2,
00582     tt_face_load_post,
00583 
00584     tt_face_load_name,
00585     tt_face_free_name,
00586 
00587     tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00588     tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00589 
00590     tt_face_load_kern,
00591     tt_face_load_gasp,
00592     tt_face_load_pclt,
00593 
00594     /* see `ttload.h' */
00595     PUT_EMBEDDED_BITMAPS(tt_face_load_bhed),
00596 
00597     tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00598     tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00599 
00600     tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00601     tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00602 
00603     PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image),
00604 
00605     tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00606 
00607     /* see `ttpost.h' */
00608     PUT_PS_NAMES(tt_face_get_ps_name),
00609     PUT_PS_NAMES(tt_face_free_ps_names),
00610 
00611     tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00612     tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
00613 
00614     /* since version 2.1.8 */
00615 
00616     tt_face_get_kerning,
00617 
00618     /* since version 2.2 */
00619 
00620     tt_face_load_font_dir,
00621     tt_face_load_hmtx,
00622 
00623     /* see `ttsbit.h' and `sfnt.h' */
00624     PUT_EMBEDDED_BITMAPS(tt_face_load_eblc),
00625     PUT_EMBEDDED_BITMAPS(tt_face_free_eblc),
00626 
00627     PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike),
00628     PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics),
00629 
00630     tt_face_get_metrics
00631   )
00632 
00633 
00634   FT_DEFINE_MODULE(sfnt_module_class,
00635   
00636     0,  /* not a font driver or renderer */
00637     sizeof( FT_ModuleRec ),
00638 
00639     "sfnt",     /* driver name                            */
00640     0x10000L,   /* driver version 1.0                     */
00641     0x20000L,   /* driver requires FreeType 2.0 or higher */
00642 
00643     (const void*)&FT_SFNT_INTERFACE_GET,  /* module specific interface */
00644 
00645     (FT_Module_Constructor)0,
00646     (FT_Module_Destructor) 0,
00647     (FT_Module_Requester)  sfnt_get_interface
00648   )
00649 
00650 
00651 /* END */

Generated on Tue Jul 5 14:13:50 2011 for ROOT_528-00b_version by  doxygen 1.5.1