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