(root)/
freetype-2.13.2/
src/
otvalid/
otvmod.c
       1  /****************************************************************************
       2   *
       3   * otvmod.c
       4   *
       5   *   FreeType's OpenType validation module implementation (body).
       6   *
       7   * Copyright (C) 2004-2023 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 <freetype/tttables.h>
      20  #include <freetype/tttags.h>
      21  #include <freetype/ftotval.h>
      22  #include <freetype/internal/ftobjs.h>
      23  #include <freetype/internal/services/svotval.h>
      24  
      25  #include "otvmod.h"
      26  #include "otvalid.h"
      27  #include "otvcommn.h"
      28  
      29  
      30    /**************************************************************************
      31     *
      32     * The macro FT_COMPONENT is used in trace mode.  It is an implicit
      33     * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
      34     * messages during execution.
      35     */
      36  #undef  FT_COMPONENT
      37  #define FT_COMPONENT  otvmodule
      38  
      39  
      40    static FT_Error
      41    otv_load_table( FT_Face             face,
      42                    FT_Tag              tag,
      43                    FT_Byte* volatile*  table,
      44                    FT_ULong*           table_len )
      45    {
      46      FT_Error   error;
      47      FT_Memory  memory = FT_FACE_MEMORY( face );
      48  
      49  
      50      error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len );
      51      if ( FT_ERR_EQ( error, Table_Missing ) )
      52        return FT_Err_Ok;
      53      if ( error )
      54        goto Exit;
      55  
      56      if ( FT_QALLOC( *table, *table_len ) )
      57        goto Exit;
      58  
      59      error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len );
      60  
      61    Exit:
      62      return error;
      63    }
      64  
      65  
      66    static FT_Error
      67    otv_validate( FT_Face volatile   face,
      68                  FT_UInt            ot_flags,
      69                  FT_Bytes          *ot_base,
      70                  FT_Bytes          *ot_gdef,
      71                  FT_Bytes          *ot_gpos,
      72                  FT_Bytes          *ot_gsub,
      73                  FT_Bytes          *ot_jstf )
      74    {
      75      FT_Error                  error = FT_Err_Ok;
      76      FT_Byte* volatile         base;
      77      FT_Byte* volatile         gdef;
      78      FT_Byte* volatile         gpos;
      79      FT_Byte* volatile         gsub;
      80      FT_Byte* volatile         jstf;
      81      FT_Byte* volatile         math;
      82      FT_ULong                  len_base, len_gdef, len_gpos, len_gsub, len_jstf;
      83      FT_ULong                  len_math;
      84      FT_UInt                   num_glyphs = (FT_UInt)face->num_glyphs;
      85      FT_ValidatorRec volatile  valid;
      86  
      87  
      88      base     = gdef     = gpos     = gsub     = jstf     = math     = NULL;
      89      len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0;
      90  
      91      /*
      92       * XXX: OpenType tables cannot handle 32-bit glyph index,
      93       *      although broken TrueType can have 32-bit glyph index.
      94       */
      95      if ( face->num_glyphs > 0xFFFFL )
      96      {
      97        FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08lx) ",
      98                    face->num_glyphs ));
      99        FT_TRACE1(( "are not handled by OpenType tables\n" ));
     100        num_glyphs = 0xFFFF;
     101      }
     102  
     103      /* load tables */
     104  
     105      if ( ot_flags & FT_VALIDATE_BASE )
     106      {
     107        error = otv_load_table( face, TTAG_BASE, &base, &len_base );
     108        if ( error )
     109          goto Exit;
     110      }
     111  
     112      if ( ot_flags & FT_VALIDATE_GDEF )
     113      {
     114        error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef );
     115        if ( error )
     116          goto Exit;
     117      }
     118  
     119      if ( ot_flags & FT_VALIDATE_GPOS )
     120      {
     121        error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos );
     122        if ( error )
     123          goto Exit;
     124      }
     125  
     126      if ( ot_flags & FT_VALIDATE_GSUB )
     127      {
     128        error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub );
     129        if ( error )
     130          goto Exit;
     131      }
     132  
     133      if ( ot_flags & FT_VALIDATE_JSTF )
     134      {
     135        error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf );
     136        if ( error )
     137          goto Exit;
     138      }
     139  
     140      if ( ot_flags & FT_VALIDATE_MATH )
     141      {
     142        error = otv_load_table( face, TTAG_MATH, &math, &len_math );
     143        if ( error )
     144          goto Exit;
     145      }
     146  
     147      /* validate tables */
     148  
     149      if ( base )
     150      {
     151        ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT );
     152        if ( ft_setjmp( valid.jump_buffer ) == 0 )
     153          otv_BASE_validate( base, &valid );
     154        error = valid.error;
     155        if ( error )
     156          goto Exit;
     157      }
     158  
     159      if ( gpos )
     160      {
     161        ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT );
     162        if ( ft_setjmp( valid.jump_buffer ) == 0 )
     163          otv_GPOS_validate( gpos, num_glyphs, &valid );
     164        error = valid.error;
     165        if ( error )
     166          goto Exit;
     167      }
     168  
     169      if ( gsub )
     170      {
     171        ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT );
     172        if ( ft_setjmp( valid.jump_buffer ) == 0 )
     173          otv_GSUB_validate( gsub, num_glyphs, &valid );
     174        error = valid.error;
     175        if ( error )
     176          goto Exit;
     177      }
     178  
     179      if ( gdef )
     180      {
     181        ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT );
     182        if ( ft_setjmp( valid.jump_buffer ) == 0 )
     183          otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid );
     184        error = valid.error;
     185        if ( error )
     186          goto Exit;
     187      }
     188  
     189      if ( jstf )
     190      {
     191        ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT );
     192        if ( ft_setjmp( valid.jump_buffer ) == 0 )
     193          otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid );
     194        error = valid.error;
     195        if ( error )
     196          goto Exit;
     197      }
     198  
     199      if ( math )
     200      {
     201        ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT );
     202        if ( ft_setjmp( valid.jump_buffer ) == 0 )
     203          otv_MATH_validate( math, num_glyphs, &valid );
     204        error = valid.error;
     205        if ( error )
     206          goto Exit;
     207      }
     208  
     209      *ot_base = (FT_Bytes)base;
     210      *ot_gdef = (FT_Bytes)gdef;
     211      *ot_gpos = (FT_Bytes)gpos;
     212      *ot_gsub = (FT_Bytes)gsub;
     213      *ot_jstf = (FT_Bytes)jstf;
     214  
     215    Exit:
     216      if ( error )
     217      {
     218        FT_Memory  memory = FT_FACE_MEMORY( face );
     219  
     220  
     221        FT_FREE( base );
     222        FT_FREE( gdef );
     223        FT_FREE( gpos );
     224        FT_FREE( gsub );
     225        FT_FREE( jstf );
     226      }
     227  
     228      {
     229        FT_Memory  memory = FT_FACE_MEMORY( face );
     230  
     231  
     232        FT_FREE( math );                 /* Can't return this as API is frozen */
     233      }
     234  
     235      return error;
     236    }
     237  
     238  
     239    static
     240    const FT_Service_OTvalidateRec  otvalid_interface =
     241    {
     242      otv_validate        /* validate */
     243    };
     244  
     245  
     246    static
     247    const FT_ServiceDescRec  otvalid_services[] =
     248    {
     249      { FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface },
     250      { NULL, NULL }
     251    };
     252  
     253  
     254    static FT_Pointer
     255    otvalid_get_service( FT_Module    module,
     256                         const char*  service_id )
     257    {
     258      FT_UNUSED( module );
     259  
     260      return ft_service_list_lookup( otvalid_services, service_id );
     261    }
     262  
     263  
     264    FT_CALLBACK_TABLE_DEF
     265    const FT_Module_Class  otv_module_class =
     266    {
     267      0,
     268      sizeof ( FT_ModuleRec ),
     269      "otvalid",
     270      0x10000L,
     271      0x20000L,
     272  
     273      NULL,              /* module-specific interface */
     274  
     275      (FT_Module_Constructor)NULL,                /* module_init   */
     276      (FT_Module_Destructor) NULL,                /* module_done   */
     277      (FT_Module_Requester)  otvalid_get_service  /* get_interface */
     278    };
     279  
     280  
     281  /* END */