Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  sfdriver.c                                                             */
  4. /*                                                                         */
  5. /*    High-level SFNT driver interface (body).                             */
  6. /*                                                                         */
  7. /*  Copyright 1996-2007, 2009-2013 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.   /*                                                                       */
  56.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  57.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  58.   /* messages during execution.                                            */
  59.   /*                                                                       */
  60. #undef  FT_COMPONENT
  61. #define FT_COMPONENT  trace_sfdriver
  62.  
  63.  
  64.   /*
  65.    *  SFNT TABLE SERVICE
  66.    *
  67.    */
  68.  
  69.   static void*
  70.   get_sfnt_table( TT_Face      face,
  71.                   FT_Sfnt_Tag  tag )
  72.   {
  73.     void*  table;
  74.  
  75.  
  76.     switch ( tag )
  77.     {
  78.     case ft_sfnt_head:
  79.       table = &face->header;
  80.       break;
  81.  
  82.     case ft_sfnt_hhea:
  83.       table = &face->horizontal;
  84.       break;
  85.  
  86.     case ft_sfnt_vhea:
  87.       table = face->vertical_info ? &face->vertical : 0;
  88.       break;
  89.  
  90.     case ft_sfnt_os2:
  91.       table = face->os2.version == 0xFFFFU ? 0 : &face->os2;
  92.       break;
  93.  
  94.     case ft_sfnt_post:
  95.       table = &face->postscript;
  96.       break;
  97.  
  98.     case ft_sfnt_maxp:
  99.       table = &face->max_profile;
  100.       break;
  101.  
  102.     case ft_sfnt_pclt:
  103.       table = face->pclt.Version ? &face->pclt : 0;
  104.       break;
  105.  
  106.     default:
  107.       table = 0;
  108.     }
  109.  
  110.     return table;
  111.   }
  112.  
  113.  
  114.   static FT_Error
  115.   sfnt_table_info( TT_Face    face,
  116.                    FT_UInt    idx,
  117.                    FT_ULong  *tag,
  118.                    FT_ULong  *offset,
  119.                    FT_ULong  *length )
  120.   {
  121.     if ( !offset || !length )
  122.       return FT_THROW( Invalid_Argument );
  123.  
  124.     if ( !tag )
  125.       *length = face->num_tables;
  126.     else
  127.     {
  128.       if ( idx >= face->num_tables )
  129.         return FT_THROW( Table_Missing );
  130.  
  131.       *tag    = face->dir_tables[idx].Tag;
  132.       *offset = face->dir_tables[idx].Offset;
  133.       *length = face->dir_tables[idx].Length;
  134.     }
  135.  
  136.     return FT_Err_Ok;
  137.   }
  138.  
  139.  
  140.   FT_DEFINE_SERVICE_SFNT_TABLEREC(
  141.     sfnt_service_sfnt_table,
  142.     (FT_SFNT_TableLoadFunc)tt_face_load_any,
  143.     (FT_SFNT_TableGetFunc) get_sfnt_table,
  144.     (FT_SFNT_TableInfoFunc)sfnt_table_info )
  145.  
  146.  
  147. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  148.  
  149.   /*
  150.    *  GLYPH DICT SERVICE
  151.    *
  152.    */
  153.  
  154.   static FT_Error
  155.   sfnt_get_glyph_name( TT_Face     face,
  156.                        FT_UInt     glyph_index,
  157.                        FT_Pointer  buffer,
  158.                        FT_UInt     buffer_max )
  159.   {
  160.     FT_String*  gname;
  161.     FT_Error    error;
  162.  
  163.  
  164.     error = tt_face_get_ps_name( face, glyph_index, &gname );
  165.     if ( !error )
  166.       FT_STRCPYN( buffer, gname, buffer_max );
  167.  
  168.     return error;
  169.   }
  170.  
  171.  
  172.   static FT_UInt
  173.   sfnt_get_name_index( TT_Face     face,
  174.                        FT_String*  glyph_name )
  175.   {
  176.     FT_Face  root = &face->root;
  177.  
  178.     FT_UInt  i, max_gid = FT_UINT_MAX;
  179.  
  180.  
  181.     if ( root->num_glyphs < 0 )
  182.       return 0;
  183.     else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX )
  184.       max_gid = (FT_UInt)root->num_glyphs;
  185.     else
  186.       FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
  187.                   FT_UINT_MAX, root->num_glyphs ));
  188.  
  189.     for ( i = 0; i < max_gid; i++ )
  190.     {
  191.       FT_String*  gname;
  192.       FT_Error    error = tt_face_get_ps_name( face, i, &gname );
  193.  
  194.  
  195.       if ( error )
  196.         continue;
  197.  
  198.       if ( !ft_strcmp( glyph_name, gname ) )
  199.         return i;
  200.     }
  201.  
  202.     return 0;
  203.   }
  204.  
  205.  
  206.   FT_DEFINE_SERVICE_GLYPHDICTREC(
  207.     sfnt_service_glyph_dict,
  208.     (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,
  209.     (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index )
  210.  
  211.  
  212. #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
  213.  
  214.  
  215.   /*
  216.    *  POSTSCRIPT NAME SERVICE
  217.    *
  218.    */
  219.  
  220.   static const char*
  221.   sfnt_get_ps_name( TT_Face  face )
  222.   {
  223.     FT_Int       n, found_win, found_apple;
  224.     const char*  result = NULL;
  225.  
  226.  
  227.     /* shouldn't happen, but just in case to avoid memory leaks */
  228.     if ( face->postscript_name )
  229.       return face->postscript_name;
  230.  
  231.     /* scan the name table to see whether we have a Postscript name here, */
  232.     /* either in Macintosh or Windows platform encodings                  */
  233.     found_win   = -1;
  234.     found_apple = -1;
  235.  
  236.     for ( n = 0; n < face->num_names; n++ )
  237.     {
  238.       TT_NameEntryRec*  name = face->name_table.names + n;
  239.  
  240.  
  241.       if ( name->nameID == 6 && name->stringLength > 0 )
  242.       {
  243.         if ( name->platformID == 3     &&
  244.              name->encodingID == 1     &&
  245.              name->languageID == 0x409 )
  246.           found_win = n;
  247.  
  248.         if ( name->platformID == 1 &&
  249.              name->encodingID == 0 &&
  250.              name->languageID == 0 )
  251.           found_apple = n;
  252.       }
  253.     }
  254.  
  255.     if ( found_win != -1 )
  256.     {
  257.       FT_Memory         memory = face->root.memory;
  258.       TT_NameEntryRec*  name   = face->name_table.names + found_win;
  259.       FT_UInt           len    = name->stringLength / 2;
  260.       FT_Error          error  = FT_Err_Ok;
  261.  
  262.       FT_UNUSED( error );
  263.  
  264.  
  265.       if ( !FT_ALLOC( result, name->stringLength + 1 ) )
  266.       {
  267.         FT_Stream   stream = face->name_table.stream;
  268.         FT_String*  r      = (FT_String*)result;
  269.         FT_Byte*    p      = (FT_Byte*)name->string;
  270.  
  271.  
  272.         if ( FT_STREAM_SEEK( name->stringOffset ) ||
  273.              FT_FRAME_ENTER( name->stringLength ) )
  274.         {
  275.           FT_FREE( result );
  276.           name->stringLength = 0;
  277.           name->stringOffset = 0;
  278.           FT_FREE( name->string );
  279.  
  280.           goto Exit;
  281.         }
  282.  
  283.         p = (FT_Byte*)stream->cursor;
  284.  
  285.         for ( ; len > 0; len--, p += 2 )
  286.         {
  287.           if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
  288.             *r++ = p[1];
  289.         }
  290.         *r = '\0';
  291.  
  292.         FT_FRAME_EXIT();
  293.       }
  294.       goto Exit;
  295.     }
  296.  
  297.     if ( found_apple != -1 )
  298.     {
  299.       FT_Memory         memory = face->root.memory;
  300.       TT_NameEntryRec*  name   = face->name_table.names + found_apple;
  301.       FT_UInt           len    = name->stringLength;
  302.       FT_Error          error  = FT_Err_Ok;
  303.  
  304.       FT_UNUSED( error );
  305.  
  306.  
  307.       if ( !FT_ALLOC( result, len + 1 ) )
  308.       {
  309.         FT_Stream  stream = face->name_table.stream;
  310.  
  311.  
  312.         if ( FT_STREAM_SEEK( name->stringOffset ) ||
  313.              FT_STREAM_READ( result, len )        )
  314.         {
  315.           name->stringOffset = 0;
  316.           name->stringLength = 0;
  317.           FT_FREE( name->string );
  318.           FT_FREE( result );
  319.           goto Exit;
  320.         }
  321.         ((char*)result)[len] = '\0';
  322.       }
  323.     }
  324.  
  325.   Exit:
  326.     face->postscript_name = result;
  327.     return result;
  328.   }
  329.  
  330.  
  331.   FT_DEFINE_SERVICE_PSFONTNAMEREC(
  332.     sfnt_service_ps_name,
  333.     (FT_PsName_GetFunc)sfnt_get_ps_name )
  334.  
  335.  
  336.   /*
  337.    *  TT CMAP INFO
  338.    */
  339.   FT_DEFINE_SERVICE_TTCMAPSREC(
  340.     tt_service_get_cmap_info,
  341.     (TT_CMap_Info_GetFunc)tt_get_cmap_info )
  342.  
  343.  
  344. #ifdef TT_CONFIG_OPTION_BDF
  345.  
  346.   static FT_Error
  347.   sfnt_get_charset_id( TT_Face       face,
  348.                        const char*  *acharset_encoding,
  349.                        const char*  *acharset_registry )
  350.   {
  351.     BDF_PropertyRec  encoding, registry;
  352.     FT_Error         error;
  353.  
  354.  
  355.     /* XXX: I don't know whether this is correct, since
  356.      *      tt_face_find_bdf_prop only returns something correct if we have
  357.      *      previously selected a size that is listed in the BDF table.
  358.      *      Should we change the BDF table format to include single offsets
  359.      *      for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?
  360.      */
  361.     error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", &registry );
  362.     if ( !error )
  363.     {
  364.       error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
  365.       if ( !error )
  366.       {
  367.         if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
  368.              encoding.type == BDF_PROPERTY_TYPE_ATOM )
  369.         {
  370.           *acharset_encoding = encoding.u.atom;
  371.           *acharset_registry = registry.u.atom;
  372.         }
  373.         else
  374.           error = FT_THROW( Invalid_Argument );
  375.       }
  376.     }
  377.  
  378.     return error;
  379.   }
  380.  
  381.  
  382.   FT_DEFINE_SERVICE_BDFRec(
  383.     sfnt_service_bdf,
  384.     (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id,
  385.     (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop )
  386.  
  387.  
  388. #endif /* TT_CONFIG_OPTION_BDF */
  389.  
  390.  
  391.   /*
  392.    *  SERVICE LIST
  393.    */
  394.  
  395. #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
  396.   FT_DEFINE_SERVICEDESCREC5(
  397.     sfnt_services,
  398.     FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
  399.     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
  400.     FT_SERVICE_ID_GLYPH_DICT,           &SFNT_SERVICE_GLYPH_DICT_GET,
  401.     FT_SERVICE_ID_BDF,                  &SFNT_SERVICE_BDF_GET,
  402.     FT_SERVICE_ID_TT_CMAP,              &TT_SERVICE_CMAP_INFO_GET )
  403. #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  404.   FT_DEFINE_SERVICEDESCREC4(
  405.     sfnt_services,
  406.     FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
  407.     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
  408.     FT_SERVICE_ID_GLYPH_DICT,           &SFNT_SERVICE_GLYPH_DICT_GET,
  409.     FT_SERVICE_ID_TT_CMAP,              &TT_SERVICE_CMAP_INFO_GET )
  410. #elif defined TT_CONFIG_OPTION_BDF
  411.   FT_DEFINE_SERVICEDESCREC4(
  412.     sfnt_services,
  413.     FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
  414.     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
  415.     FT_SERVICE_ID_BDF,                  &SFNT_SERVICE_BDF_GET,
  416.     FT_SERVICE_ID_TT_CMAP,              &TT_SERVICE_CMAP_INFO_GET )
  417. #else
  418.   FT_DEFINE_SERVICEDESCREC3(
  419.     sfnt_services,
  420.     FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
  421.     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
  422.     FT_SERVICE_ID_TT_CMAP,              &TT_SERVICE_CMAP_INFO_GET )
  423. #endif
  424.  
  425.  
  426.   FT_CALLBACK_DEF( FT_Module_Interface )
  427.   sfnt_get_interface( FT_Module    module,
  428.                       const char*  module_interface )
  429.   {
  430.     /* SFNT_SERVICES_GET derefers `library' in PIC mode */
  431. #ifdef FT_CONFIG_OPTION_PIC
  432.     FT_Library  library;
  433.  
  434.  
  435.     if ( !module )
  436.       return NULL;
  437.     library = module->library;
  438.     if ( !library )
  439.       return NULL;
  440. #else
  441.     FT_UNUSED( module );
  442. #endif
  443.  
  444.     return ft_service_list_lookup( SFNT_SERVICES_GET, module_interface );
  445.   }
  446.  
  447.  
  448. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  449. #define PUT_EMBEDDED_BITMAPS( a )  a
  450. #else
  451. #define PUT_EMBEDDED_BITMAPS( a )  NULL
  452. #endif
  453.  
  454. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  455. #define PUT_PS_NAMES( a )  a
  456. #else
  457. #define PUT_PS_NAMES( a )  NULL
  458. #endif
  459.  
  460.   FT_DEFINE_SFNT_INTERFACE(
  461.     sfnt_interface,
  462.     tt_face_goto_table,
  463.  
  464.     sfnt_init_face,
  465.     sfnt_load_face,
  466.     sfnt_done_face,
  467.     sfnt_get_interface,
  468.  
  469.     tt_face_load_any,
  470.  
  471.     tt_face_load_head,
  472.     tt_face_load_hhea,
  473.     tt_face_load_cmap,
  474.     tt_face_load_maxp,
  475.     tt_face_load_os2,
  476.     tt_face_load_post,
  477.  
  478.     tt_face_load_name,
  479.     tt_face_free_name,
  480.  
  481.     tt_face_load_kern,
  482.     tt_face_load_gasp,
  483.     tt_face_load_pclt,
  484.  
  485.     /* see `ttload.h' */
  486.     PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ),
  487.  
  488.     PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ),
  489.  
  490.     /* see `ttpost.h' */
  491.     PUT_PS_NAMES( tt_face_get_ps_name   ),
  492.     PUT_PS_NAMES( tt_face_free_ps_names ),
  493.  
  494.     /* since version 2.1.8 */
  495.     tt_face_get_kerning,
  496.  
  497.     /* since version 2.2 */
  498.     tt_face_load_font_dir,
  499.     tt_face_load_hmtx,
  500.  
  501.     /* see `ttsbit.h' and `sfnt.h' */
  502.     PUT_EMBEDDED_BITMAPS( tt_face_load_eblc ),
  503.     PUT_EMBEDDED_BITMAPS( tt_face_free_eblc ),
  504.  
  505.     PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike     ),
  506.     PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ),
  507.  
  508.     tt_face_get_metrics
  509.   )
  510.  
  511.  
  512.   FT_DEFINE_MODULE(
  513.     sfnt_module_class,
  514.  
  515.     0,  /* not a font driver or renderer */
  516.     sizeof ( FT_ModuleRec ),
  517.  
  518.     "sfnt",     /* driver name                            */
  519.     0x10000L,   /* driver version 1.0                     */
  520.     0x20000L,   /* driver requires FreeType 2.0 or higher */
  521.  
  522.     (const void*)&SFNT_INTERFACE_GET,  /* module specific interface */
  523.  
  524.     (FT_Module_Constructor)0,
  525.     (FT_Module_Destructor) 0,
  526.     (FT_Module_Requester)  sfnt_get_interface )
  527.  
  528.  
  529. /* END */
  530.