Home | History | Annotate | Download | only in otvalid
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  otvgdef.c                                                              */
      4 /*                                                                         */
      5 /*    OpenType GDEF table validation (body).                               */
      6 /*                                                                         */
      7 /*  Copyright 2004-2015 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 "otvalid.h"
     20 #include "otvcommn.h"
     21 
     22 
     23   /*************************************************************************/
     24   /*                                                                       */
     25   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     26   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     27   /* messages during execution.                                            */
     28   /*                                                                       */
     29 #undef  FT_COMPONENT
     30 #define FT_COMPONENT  trace_otvgdef
     31 
     32 
     33   /*************************************************************************/
     34   /*************************************************************************/
     35   /*****                                                               *****/
     36   /*****                      UTILITY FUNCTIONS                        *****/
     37   /*****                                                               *****/
     38   /*************************************************************************/
     39   /*************************************************************************/
     40 
     41 #define AttachListFunc    otv_O_x_Ox
     42 #define LigCaretListFunc  otv_O_x_Ox
     43 
     44   /* sets valid->extra1 (0)           */
     45 
     46   static void
     47   otv_O_x_Ox( FT_Bytes       table,
     48               OTV_Validator  otvalid )
     49   {
     50     FT_Bytes           p = table;
     51     FT_Bytes           Coverage;
     52     FT_UInt            GlyphCount;
     53     OTV_Validate_Func  func;
     54 
     55 
     56     OTV_ENTER;
     57 
     58     OTV_LIMIT_CHECK( 4 );
     59     Coverage   = table + FT_NEXT_USHORT( p );
     60     GlyphCount = FT_NEXT_USHORT( p );
     61 
     62     OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
     63 
     64     otv_Coverage_validate( Coverage, otvalid, (FT_Int)GlyphCount );
     65     if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
     66       FT_INVALID_DATA;
     67 
     68     OTV_LIMIT_CHECK( GlyphCount * 2 );
     69 
     70     otvalid->nesting_level++;
     71     func          = otvalid->func[otvalid->nesting_level];
     72     otvalid->extra1 = 0;
     73 
     74     for ( ; GlyphCount > 0; GlyphCount-- )
     75       func( table + FT_NEXT_USHORT( p ), otvalid );
     76 
     77     otvalid->nesting_level--;
     78 
     79     OTV_EXIT;
     80   }
     81 
     82 
     83   /*************************************************************************/
     84   /*************************************************************************/
     85   /*****                                                               *****/
     86   /*****                       LIGATURE CARETS                         *****/
     87   /*****                                                               *****/
     88   /*************************************************************************/
     89   /*************************************************************************/
     90 
     91 #define CaretValueFunc  otv_CaretValue_validate
     92 
     93   static void
     94   otv_CaretValue_validate( FT_Bytes       table,
     95                            OTV_Validator  otvalid )
     96   {
     97     FT_Bytes  p = table;
     98     FT_UInt   CaretValueFormat;
     99 
    100 
    101     OTV_ENTER;
    102 
    103     OTV_LIMIT_CHECK( 4 );
    104 
    105     CaretValueFormat = FT_NEXT_USHORT( p );
    106 
    107     OTV_TRACE(( " (format = %d)\n", CaretValueFormat ));
    108 
    109     switch ( CaretValueFormat )
    110     {
    111     case 1:     /* CaretValueFormat1 */
    112       /* skip Coordinate, no test */
    113       break;
    114 
    115     case 2:     /* CaretValueFormat2 */
    116       /* skip CaretValuePoint, no test */
    117       break;
    118 
    119     case 3:     /* CaretValueFormat3 */
    120       p += 2;   /* skip Coordinate */
    121 
    122       OTV_LIMIT_CHECK( 2 );
    123 
    124       /* DeviceTable */
    125       otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid );
    126       break;
    127 
    128     default:
    129       FT_INVALID_FORMAT;
    130     }
    131 
    132     OTV_EXIT;
    133   }
    134 
    135 
    136   /*************************************************************************/
    137   /*************************************************************************/
    138   /*****                                                               *****/
    139   /*****                         GDEF TABLE                            *****/
    140   /*****                                                               *****/
    141   /*************************************************************************/
    142   /*************************************************************************/
    143 
    144   /* sets otvalid->glyph_count */
    145 
    146   FT_LOCAL_DEF( void )
    147   otv_GDEF_validate( FT_Bytes      table,
    148                      FT_Bytes      gsub,
    149                      FT_Bytes      gpos,
    150                      FT_UInt       glyph_count,
    151                      FT_Validator  ftvalid )
    152   {
    153     OTV_ValidatorRec  otvalidrec;
    154     OTV_Validator     otvalid = &otvalidrec;
    155     FT_Bytes          p     = table;
    156     FT_UInt           table_size;
    157     FT_Bool           need_MarkAttachClassDef;
    158 
    159     OTV_OPTIONAL_TABLE( GlyphClassDef );
    160     OTV_OPTIONAL_TABLE( AttachListOffset );
    161     OTV_OPTIONAL_TABLE( LigCaretListOffset );
    162     OTV_OPTIONAL_TABLE( MarkAttachClassDef );
    163 
    164 
    165     otvalid->root = ftvalid;
    166 
    167     FT_TRACE3(( "validating GDEF table\n" ));
    168     OTV_INIT;
    169 
    170     OTV_LIMIT_CHECK( 12 );
    171 
    172     if ( FT_NEXT_ULONG( p ) != 0x10000UL )          /* Version */
    173       FT_INVALID_FORMAT;
    174 
    175     /* MarkAttachClassDef has been added to the OpenType */
    176     /* specification without increasing GDEF's version,  */
    177     /* so we use this ugly hack to find out whether the  */
    178     /* table is needed actually.                         */
    179 
    180     need_MarkAttachClassDef = FT_BOOL(
    181       otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) ||
    182       otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) );
    183 
    184     if ( need_MarkAttachClassDef )
    185       table_size = 12;              /* OpenType >= 1.2 */
    186     else
    187       table_size = 10;              /* OpenType < 1.2  */
    188 
    189     otvalid->glyph_count = glyph_count;
    190 
    191     OTV_OPTIONAL_OFFSET( GlyphClassDef );
    192     OTV_SIZE_CHECK( GlyphClassDef );
    193     if ( GlyphClassDef )
    194       otv_ClassDef_validate( table + GlyphClassDef, otvalid );
    195 
    196     OTV_OPTIONAL_OFFSET( AttachListOffset );
    197     OTV_SIZE_CHECK( AttachListOffset );
    198     if ( AttachListOffset )
    199     {
    200       OTV_NEST2( AttachList, AttachPoint );
    201       OTV_RUN( table + AttachListOffset, otvalid );
    202     }
    203 
    204     OTV_OPTIONAL_OFFSET( LigCaretListOffset );
    205     OTV_SIZE_CHECK( LigCaretListOffset );
    206     if ( LigCaretListOffset )
    207     {
    208       OTV_NEST3( LigCaretList, LigGlyph, CaretValue );
    209       OTV_RUN( table + LigCaretListOffset, otvalid );
    210     }
    211 
    212     if ( need_MarkAttachClassDef )
    213     {
    214       OTV_OPTIONAL_OFFSET( MarkAttachClassDef );
    215       OTV_SIZE_CHECK( MarkAttachClassDef );
    216       if ( MarkAttachClassDef )
    217         otv_ClassDef_validate( table + MarkAttachClassDef, otvalid );
    218     }
    219 
    220     FT_TRACE4(( "\n" ));
    221   }
    222 
    223 
    224 /* END */
    225