(root)/
freetype-2.13.2/
src/
gxvalid/
gxvmod.c
       1  /****************************************************************************
       2   *
       3   * gxvmod.c
       4   *
       5   *   FreeType's TrueTypeGX/AAT validation module implementation (body).
       6   *
       7   * Copyright (C) 2004-2023 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 <freetype/tttables.h>
      29  #include <freetype/tttags.h>
      30  #include <freetype/ftgxval.h>
      31  #include <freetype/internal/ftobjs.h>
      32  #include <freetype/internal/services/svgxval.h>
      33  
      34  #include "gxvmod.h"
      35  #include "gxvalid.h"
      36  #include "gxvcommn.h"
      37  
      38  
      39    /**************************************************************************
      40     *
      41     * The macro FT_COMPONENT is used in trace mode.  It is an implicit
      42     * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
      43     * messages during execution.
      44     */
      45  #undef  FT_COMPONENT
      46  #define FT_COMPONENT  gxvmodule
      47  
      48  
      49    static FT_Error
      50    gxv_load_table( FT_Face             face,
      51                    FT_Tag              tag,
      52                    FT_Byte* volatile*  table,
      53                    FT_ULong*           table_len )
      54    {
      55      FT_Error   error;
      56      FT_Memory  memory = FT_FACE_MEMORY( face );
      57  
      58  
      59      error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len );
      60      if ( FT_ERR_EQ( error, Table_Missing ) )
      61        return FT_Err_Ok;
      62      if ( error )
      63        goto Exit;
      64  
      65      if ( FT_QALLOC( *table, *table_len ) )
      66        goto Exit;
      67  
      68      error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len );
      69  
      70    Exit:
      71      return error;
      72    }
      73  
      74  
      75  #define GXV_TABLE_DECL( _sfnt )                     \
      76            FT_Byte* volatile  _sfnt          = NULL; \
      77            FT_ULong            len_ ## _sfnt = 0
      78  
      79  #define GXV_TABLE_LOAD( _sfnt )                                       \
      80            FT_BEGIN_STMNT                                              \
      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            FT_END_STMNT
      90  
      91  #define GXV_TABLE_VALIDATE( _sfnt )                                    \
      92            FT_BEGIN_STMNT                                               \
      93              if ( _sfnt )                                               \
      94              {                                                          \
      95                ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \
      96                                   FT_VALIDATE_DEFAULT );                \
      97                if ( ft_setjmp( valid.jump_buffer ) == 0 )               \
      98                  gxv_ ## _sfnt ## _validate( _sfnt, face, &valid );     \
      99                error = valid.error;                                     \
     100                if ( error )                                             \
     101                  goto Exit;                                             \
     102              }                                                          \
     103            FT_END_STMNT
     104  
     105  #define GXV_TABLE_SET( _sfnt )                                        \
     106            if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count )        \
     107              tables[FT_VALIDATE_ ## _sfnt ## _INDEX] = (FT_Bytes)_sfnt
     108  
     109  
     110    static FT_Error
     111    gxv_validate( FT_Face   face,
     112                  FT_UInt   gx_flags,
     113                  FT_Bytes  tables[FT_VALIDATE_GX_LENGTH],
     114                  FT_UInt   table_count )
     115    {
     116      FT_Memory volatile        memory = FT_FACE_MEMORY( face );
     117  
     118      FT_Error                  error = FT_Err_Ok;
     119      FT_ValidatorRec volatile  valid;
     120  
     121      FT_UInt  i;
     122  
     123  
     124      GXV_TABLE_DECL( feat );
     125      GXV_TABLE_DECL( bsln );
     126      GXV_TABLE_DECL( trak );
     127      GXV_TABLE_DECL( just );
     128      GXV_TABLE_DECL( mort );
     129      GXV_TABLE_DECL( morx );
     130      GXV_TABLE_DECL( kern );
     131      GXV_TABLE_DECL( opbd );
     132      GXV_TABLE_DECL( prop );
     133      GXV_TABLE_DECL( lcar );
     134  
     135      for ( i = 0; i < table_count; i++ )
     136        tables[i] = 0;
     137  
     138      /* load tables */
     139      GXV_TABLE_LOAD( feat );
     140      GXV_TABLE_LOAD( bsln );
     141      GXV_TABLE_LOAD( trak );
     142      GXV_TABLE_LOAD( just );
     143      GXV_TABLE_LOAD( mort );
     144      GXV_TABLE_LOAD( morx );
     145      GXV_TABLE_LOAD( kern );
     146      GXV_TABLE_LOAD( opbd );
     147      GXV_TABLE_LOAD( prop );
     148      GXV_TABLE_LOAD( lcar );
     149  
     150      /* validate tables */
     151      GXV_TABLE_VALIDATE( feat );
     152      GXV_TABLE_VALIDATE( bsln );
     153      GXV_TABLE_VALIDATE( trak );
     154      GXV_TABLE_VALIDATE( just );
     155      GXV_TABLE_VALIDATE( mort );
     156      GXV_TABLE_VALIDATE( morx );
     157      GXV_TABLE_VALIDATE( kern );
     158      GXV_TABLE_VALIDATE( opbd );
     159      GXV_TABLE_VALIDATE( prop );
     160      GXV_TABLE_VALIDATE( lcar );
     161  
     162      /* Set results */
     163      GXV_TABLE_SET( feat );
     164      GXV_TABLE_SET( mort );
     165      GXV_TABLE_SET( morx );
     166      GXV_TABLE_SET( bsln );
     167      GXV_TABLE_SET( just );
     168      GXV_TABLE_SET( kern );
     169      GXV_TABLE_SET( opbd );
     170      GXV_TABLE_SET( trak );
     171      GXV_TABLE_SET( prop );
     172      GXV_TABLE_SET( lcar );
     173  
     174    Exit:
     175      if ( error )
     176      {
     177        FT_FREE( feat );
     178        FT_FREE( bsln );
     179        FT_FREE( trak );
     180        FT_FREE( just );
     181        FT_FREE( mort );
     182        FT_FREE( morx );
     183        FT_FREE( kern );
     184        FT_FREE( opbd );
     185        FT_FREE( prop );
     186        FT_FREE( lcar );
     187      }
     188  
     189      return error;
     190    }
     191  
     192  
     193    static FT_Error
     194    classic_kern_validate( FT_Face    face,
     195                           FT_UInt    ckern_flags,
     196                           FT_Bytes*  ckern_table )
     197    {
     198      FT_Memory volatile        memory = FT_FACE_MEMORY( face );
     199  
     200      FT_Byte* volatile         ckern     = NULL;
     201      FT_ULong                  len_ckern = 0;
     202  
     203      /* without volatile on `error' GCC 4.1.1. emits:                         */
     204      /*  warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */
     205      /* this warning seems spurious but ---                                   */
     206      FT_Error volatile         error;
     207      FT_ValidatorRec volatile  valid;
     208  
     209  
     210      *ckern_table = NULL;
     211  
     212      error = gxv_load_table( face, TTAG_kern, &ckern, &len_ckern );
     213      if ( error )
     214        goto Exit;
     215  
     216      if ( ckern )
     217      {
     218        ft_validator_init( &valid, ckern, ckern + len_ckern,
     219                           FT_VALIDATE_DEFAULT );
     220        if ( ft_setjmp( valid.jump_buffer ) == 0 )
     221          gxv_kern_validate_classic( ckern, face,
     222                                     ckern_flags & FT_VALIDATE_CKERN, &valid );
     223        error = valid.error;
     224        if ( error )
     225          goto Exit;
     226      }
     227  
     228      *ckern_table = ckern;
     229  
     230    Exit:
     231      if ( error )
     232        FT_FREE( ckern );
     233  
     234      return error;
     235    }
     236  
     237  
     238    static
     239    const FT_Service_GXvalidateRec  gxvalid_interface =
     240    {
     241      gxv_validate              /* validate */
     242    };
     243  
     244  
     245    static
     246    const FT_Service_CKERNvalidateRec  ckernvalid_interface =
     247    {
     248      classic_kern_validate     /* validate */
     249    };
     250  
     251  
     252    static
     253    const FT_ServiceDescRec  gxvalid_services[] =
     254    {
     255      { FT_SERVICE_ID_GX_VALIDATE,          &gxvalid_interface },
     256      { FT_SERVICE_ID_CLASSICKERN_VALIDATE, &ckernvalid_interface },
     257      { NULL, NULL }
     258    };
     259  
     260  
     261    static FT_Pointer
     262    gxvalid_get_service( FT_Module    module,
     263                         const char*  service_id )
     264    {
     265      FT_UNUSED( module );
     266  
     267      return ft_service_list_lookup( gxvalid_services, service_id );
     268    }
     269  
     270  
     271    FT_CALLBACK_TABLE_DEF
     272    const FT_Module_Class  gxv_module_class =
     273    {
     274      0,
     275      sizeof ( FT_ModuleRec ),
     276      "gxvalid",
     277      0x10000L,
     278      0x20000L,
     279  
     280      NULL,              /* module-specific interface */
     281  
     282      (FT_Module_Constructor)NULL,                /* module_init   */
     283      (FT_Module_Destructor) NULL,                /* module_done   */
     284      (FT_Module_Requester)  gxvalid_get_service  /* get_interface */
     285    };
     286  
     287  
     288  /* END */