Home | History | Annotate | Download | only in gxvalid
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  gxvmod.c                                                               */
      4 /*                                                                         */
      5 /*    FreeType's TrueTypeGX/AAT validation module implementation (body).   */
      6 /*                                                                         */
      7 /*  Copyright 2004-2018 by                                                 */
      8 /*  suzuki toshiya, Masatake YAMATO, Red Hat K.K.,                         */
      9 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
     10 /*                                                                         */
     11 /*  This file is part of the FreeType project, and may only be used,       */
     12 /*  modified, and distributed under the terms of the FreeType project      */
     13 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     14 /*  this file you indicate that you have read the license and              */
     15 /*  understand and accept it fully.                                        */
     16 /*                                                                         */
     17 /***************************************************************************/
     18 
     19 /***************************************************************************/
     20 /*                                                                         */
     21 /* gxvalid is derived from both gxlayout module and otvalid module.        */
     22 /* Development of gxlayout is supported by the Information-technology      */
     23 /* Promotion Agency(IPA), Japan.                                           */
     24 /*                                                                         */
     25 /***************************************************************************/
     26 
     27 
     28 #include <ft2build.h>
     29 #include FT_TRUETYPE_TABLES_H
     30 #include FT_TRUETYPE_TAGS_H
     31 #include FT_GX_VALIDATE_H
     32 #include FT_INTERNAL_OBJECTS_H
     33 #include FT_SERVICE_GX_VALIDATE_H
     34 
     35 #include "gxvmod.h"
     36 #include "gxvalid.h"
     37 #include "gxvcommn.h"
     38 
     39 
     40   /*************************************************************************/
     41   /*                                                                       */
     42   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     43   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     44   /* messages during execution.                                            */
     45   /*                                                                       */
     46 #undef  FT_COMPONENT
     47 #define FT_COMPONENT  trace_gxvmodule
     48 
     49 
     50   static FT_Error
     51   gxv_load_table( FT_Face             face,
     52                   FT_Tag              tag,
     53                   FT_Byte* volatile*  table,
     54                   FT_ULong*           table_len )
     55   {
     56     FT_Error   error;
     57     FT_Memory  memory = FT_FACE_MEMORY( face );
     58 
     59 
     60     error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len );
     61     if ( FT_ERR_EQ( error, Table_Missing ) )
     62       return FT_Err_Ok;
     63     if ( error )
     64       goto Exit;
     65 
     66     if ( FT_ALLOC( *table, *table_len ) )
     67       goto Exit;
     68 
     69     error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len );
     70 
     71   Exit:
     72     return error;
     73   }
     74 
     75 
     76 #define GXV_TABLE_DECL( _sfnt )                     \
     77           FT_Byte* volatile  _sfnt          = NULL; \
     78           FT_ULong            len_ ## _sfnt = 0
     79 
     80 #define GXV_TABLE_LOAD( _sfnt )                                     \
     81           if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \
     82                ( gx_flags & FT_VALIDATE_ ## _sfnt )            )    \
     83           {                                                         \
     84             error = gxv_load_table( face, TTAG_ ## _sfnt,           \
     85                                     &_sfnt, &len_ ## _sfnt );       \
     86             if ( error )                                            \
     87               goto Exit;                                            \
     88           }
     89 
     90 #define GXV_TABLE_VALIDATE( _sfnt )                                  \
     91           if ( _sfnt )                                               \
     92           {                                                          \
     93             ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \
     94                                FT_VALIDATE_DEFAULT );                \
     95             if ( ft_setjmp( valid.jump_buffer ) == 0 )               \
     96               gxv_ ## _sfnt ## _validate( _sfnt, face, &valid );     \
     97             error = valid.error;                                     \
     98             if ( error )                                             \
     99               goto Exit;                                             \
    100           }
    101 
    102 #define GXV_TABLE_SET( _sfnt )                                        \
    103           if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count )        \
    104             tables[FT_VALIDATE_ ## _sfnt ## _INDEX] = (FT_Bytes)_sfnt
    105 
    106 
    107   static FT_Error
    108   gxv_validate( FT_Face   face,
    109                 FT_UInt   gx_flags,
    110                 FT_Bytes  tables[FT_VALIDATE_GX_LENGTH],
    111                 FT_UInt   table_count )
    112   {
    113     FT_Memory volatile        memory = FT_FACE_MEMORY( face );
    114 
    115     FT_Error                  error = FT_Err_Ok;
    116     FT_ValidatorRec volatile  valid;
    117 
    118     FT_UInt  i;
    119 
    120 
    121     GXV_TABLE_DECL( feat );
    122     GXV_TABLE_DECL( bsln );
    123     GXV_TABLE_DECL( trak );
    124     GXV_TABLE_DECL( just );
    125     GXV_TABLE_DECL( mort );
    126     GXV_TABLE_DECL( morx );
    127     GXV_TABLE_DECL( kern );
    128     GXV_TABLE_DECL( opbd );
    129     GXV_TABLE_DECL( prop );
    130     GXV_TABLE_DECL( lcar );
    131 
    132     for ( i = 0; i < table_count; i++ )
    133       tables[i] = 0;
    134 
    135     /* load tables */
    136     GXV_TABLE_LOAD( feat );
    137     GXV_TABLE_LOAD( bsln );
    138     GXV_TABLE_LOAD( trak );
    139     GXV_TABLE_LOAD( just );
    140     GXV_TABLE_LOAD( mort );
    141     GXV_TABLE_LOAD( morx );
    142     GXV_TABLE_LOAD( kern );
    143     GXV_TABLE_LOAD( opbd );
    144     GXV_TABLE_LOAD( prop );
    145     GXV_TABLE_LOAD( lcar );
    146 
    147     /* validate tables */
    148     GXV_TABLE_VALIDATE( feat );
    149     GXV_TABLE_VALIDATE( bsln );
    150     GXV_TABLE_VALIDATE( trak );
    151     GXV_TABLE_VALIDATE( just );
    152     GXV_TABLE_VALIDATE( mort );
    153     GXV_TABLE_VALIDATE( morx );
    154     GXV_TABLE_VALIDATE( kern );
    155     GXV_TABLE_VALIDATE( opbd );
    156     GXV_TABLE_VALIDATE( prop );
    157     GXV_TABLE_VALIDATE( lcar );
    158 
    159     /* Set results */
    160     GXV_TABLE_SET( feat );
    161     GXV_TABLE_SET( mort );
    162     GXV_TABLE_SET( morx );
    163     GXV_TABLE_SET( bsln );
    164     GXV_TABLE_SET( just );
    165     GXV_TABLE_SET( kern );
    166     GXV_TABLE_SET( opbd );
    167     GXV_TABLE_SET( trak );
    168     GXV_TABLE_SET( prop );
    169     GXV_TABLE_SET( lcar );
    170 
    171   Exit:
    172     if ( error )
    173     {
    174       FT_FREE( feat );
    175       FT_FREE( bsln );
    176       FT_FREE( trak );
    177       FT_FREE( just );
    178       FT_FREE( mort );
    179       FT_FREE( morx );
    180       FT_FREE( kern );
    181       FT_FREE( opbd );
    182       FT_FREE( prop );
    183       FT_FREE( lcar );
    184     }
    185 
    186     return error;
    187   }
    188 
    189 
    190   static FT_Error
    191   classic_kern_validate( FT_Face    face,
    192                          FT_UInt    ckern_flags,
    193                          FT_Bytes*  ckern_table )
    194   {
    195     FT_Memory volatile        memory = FT_FACE_MEMORY( face );
    196 
    197     FT_Byte* volatile         ckern     = NULL;
    198     FT_ULong                  len_ckern = 0;
    199 
    200     /* without volatile on `error' GCC 4.1.1. emits:                         */
    201     /*  warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */
    202     /* this warning seems spurious but ---                                   */
    203     FT_Error volatile         error;
    204     FT_ValidatorRec volatile  valid;
    205 
    206 
    207     *ckern_table = NULL;
    208 
    209     error = gxv_load_table( face, TTAG_kern, &ckern, &len_ckern );
    210     if ( error )
    211       goto Exit;
    212 
    213     if ( ckern )
    214     {
    215       ft_validator_init( &valid, ckern, ckern + len_ckern,
    216                          FT_VALIDATE_DEFAULT );
    217       if ( ft_setjmp( valid.jump_buffer ) == 0 )
    218         gxv_kern_validate_classic( ckern, face,
    219                                    ckern_flags & FT_VALIDATE_CKERN, &valid );
    220       error = valid.error;
    221       if ( error )
    222         goto Exit;
    223     }
    224 
    225     *ckern_table = ckern;
    226 
    227   Exit:
    228     if ( error )
    229       FT_FREE( ckern );
    230 
    231     return error;
    232   }
    233 
    234 
    235   static
    236   const FT_Service_GXvalidateRec  gxvalid_interface =
    237   {
    238     gxv_validate              /* validate */
    239   };
    240 
    241 
    242   static
    243   const FT_Service_CKERNvalidateRec  ckernvalid_interface =
    244   {
    245     classic_kern_validate     /* validate */
    246   };
    247 
    248 
    249   static
    250   const FT_ServiceDescRec  gxvalid_services[] =
    251   {
    252     { FT_SERVICE_ID_GX_VALIDATE,          &gxvalid_interface },
    253     { FT_SERVICE_ID_CLASSICKERN_VALIDATE, &ckernvalid_interface },
    254     { NULL, NULL }
    255   };
    256 
    257 
    258   static FT_Pointer
    259   gxvalid_get_service( FT_Module    module,
    260                        const char*  service_id )
    261   {
    262     FT_UNUSED( module );
    263 
    264     return ft_service_list_lookup( gxvalid_services, service_id );
    265   }
    266 
    267 
    268   FT_CALLBACK_TABLE_DEF
    269   const FT_Module_Class  gxv_module_class =
    270   {
    271     0,
    272     sizeof ( FT_ModuleRec ),
    273     "gxvalid",
    274     0x10000L,
    275     0x20000L,
    276 
    277     NULL,              /* module-specific interface */
    278 
    279     (FT_Module_Constructor)NULL,                /* module_init   */
    280     (FT_Module_Destructor) NULL,                /* module_done   */
    281     (FT_Module_Requester)  gxvalid_get_service  /* get_interface */
    282   };
    283 
    284 
    285 /* END */
    286