misc/libfreetype/src/otvalid/otvmath.c
changeset 5172 88f2e05288ba
equal deleted inserted replaced
5171:f9283dc4860d 5172:88f2e05288ba
       
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  otvmath.c                                                              */
       
     4 /*                                                                         */
       
     5 /*    OpenType MATH table validation (body).                               */
       
     6 /*                                                                         */
       
     7 /*  Copyright 2007, 2008 by                                                */
       
     8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
       
     9 /*                                                                         */
       
    10 /*  Written by George Williams.                                            */
       
    11 /*                                                                         */
       
    12 /*  This file is part of the FreeType project, and may only be used,       */
       
    13 /*  modified, and distributed under the terms of the FreeType project      */
       
    14 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
       
    15 /*  this file you indicate that you have read the license and              */
       
    16 /*  understand and accept it fully.                                        */
       
    17 /*                                                                         */
       
    18 /***************************************************************************/
       
    19 
       
    20 
       
    21 #include "otvalid.h"
       
    22 #include "otvcommn.h"
       
    23 #include "otvgpos.h"
       
    24 
       
    25 
       
    26   /*************************************************************************/
       
    27   /*                                                                       */
       
    28   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
       
    29   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
       
    30   /* messages during execution.                                            */
       
    31   /*                                                                       */
       
    32 #undef  FT_COMPONENT
       
    33 #define FT_COMPONENT  trace_otvmath
       
    34 
       
    35 
       
    36 
       
    37   /*************************************************************************/
       
    38   /*************************************************************************/
       
    39   /*****                                                               *****/
       
    40   /*****                  MATH TYPOGRAPHIC CONSTANTS                   *****/
       
    41   /*****                                                               *****/
       
    42   /*************************************************************************/
       
    43   /*************************************************************************/
       
    44 
       
    45   static void
       
    46   otv_MathConstants_validate( FT_Bytes       table,
       
    47                               OTV_Validator  valid )
       
    48   {
       
    49     FT_Bytes  p = table;
       
    50     FT_UInt   i;
       
    51     FT_UInt   table_size;
       
    52 
       
    53     OTV_OPTIONAL_TABLE( DeviceTableOffset );
       
    54 
       
    55 
       
    56     OTV_NAME_ENTER( "MathConstants" );
       
    57 
       
    58     /* 56 constants, 51 have device tables */
       
    59     OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) );
       
    60     table_size = 2 * ( 56 + 51 );
       
    61 
       
    62     p += 4 * 2;                 /* First 4 constants have no device tables */
       
    63     for ( i = 0; i < 51; ++i )
       
    64     {
       
    65       p += 2;                                            /* skip the value */
       
    66       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
       
    67       OTV_SIZE_CHECK( DeviceTableOffset );
       
    68       if ( DeviceTableOffset )
       
    69         otv_Device_validate( table + DeviceTableOffset, valid );
       
    70     }
       
    71 
       
    72     OTV_EXIT;
       
    73   }
       
    74 
       
    75 
       
    76   /*************************************************************************/
       
    77   /*************************************************************************/
       
    78   /*****                                                               *****/
       
    79   /*****                   MATH ITALICS CORRECTION                     *****/
       
    80   /*****                 MATH TOP ACCENT ATTACHMENT                    *****/
       
    81   /*****                                                               *****/
       
    82   /*************************************************************************/
       
    83   /*************************************************************************/
       
    84 
       
    85   static void
       
    86   otv_MathItalicsCorrectionInfo_validate( FT_Bytes       table,
       
    87                                           OTV_Validator  valid,
       
    88                                           FT_Int         isItalic )
       
    89   {
       
    90     FT_Bytes  p = table;
       
    91     FT_UInt   i, cnt, table_size ;
       
    92 
       
    93     OTV_OPTIONAL_TABLE( Coverage );
       
    94     OTV_OPTIONAL_TABLE( DeviceTableOffset );
       
    95 
       
    96     FT_UNUSED( isItalic );  /* only used if tracing is active */
       
    97 
       
    98 
       
    99     OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
       
   100                              : "MathTopAccentAttachment" );
       
   101 
       
   102     OTV_LIMIT_CHECK( 4 );
       
   103 
       
   104     OTV_OPTIONAL_OFFSET( Coverage );
       
   105     cnt = FT_NEXT_USHORT( p );
       
   106 
       
   107     OTV_LIMIT_CHECK( 4 * cnt );
       
   108     table_size = 4 + 4 * cnt;
       
   109 
       
   110     OTV_SIZE_CHECK( Coverage );
       
   111     otv_Coverage_validate( table + Coverage, valid, cnt );
       
   112 
       
   113     for ( i = 0; i < cnt; ++i )
       
   114     {
       
   115       p += 2;                                            /* Skip the value */
       
   116       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
       
   117       OTV_SIZE_CHECK( DeviceTableOffset );
       
   118       if ( DeviceTableOffset )
       
   119         otv_Device_validate( table + DeviceTableOffset, valid );
       
   120     }
       
   121 
       
   122     OTV_EXIT;
       
   123   }
       
   124 
       
   125 
       
   126   /*************************************************************************/
       
   127   /*************************************************************************/
       
   128   /*****                                                               *****/
       
   129   /*****                           MATH KERNING                        *****/
       
   130   /*****                                                               *****/
       
   131   /*************************************************************************/
       
   132   /*************************************************************************/
       
   133 
       
   134   static void
       
   135   otv_MathKern_validate( FT_Bytes       table,
       
   136                          OTV_Validator  valid )
       
   137   {
       
   138     FT_Bytes  p = table;
       
   139     FT_UInt   i, cnt, table_size;
       
   140 
       
   141     OTV_OPTIONAL_TABLE( DeviceTableOffset );
       
   142 
       
   143 
       
   144     /* OTV_NAME_ENTER( "MathKern" );*/
       
   145 
       
   146     OTV_LIMIT_CHECK( 2 );
       
   147 
       
   148     cnt = FT_NEXT_USHORT( p );
       
   149 
       
   150     OTV_LIMIT_CHECK( 4 * cnt + 2 );
       
   151     table_size = 4 + 4 * cnt;
       
   152 
       
   153     /* Heights */
       
   154     for ( i = 0; i < cnt; ++i )
       
   155     {
       
   156       p += 2;                                            /* Skip the value */
       
   157       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
       
   158       OTV_SIZE_CHECK( DeviceTableOffset );
       
   159       if ( DeviceTableOffset )
       
   160         otv_Device_validate( table + DeviceTableOffset, valid );
       
   161     }
       
   162 
       
   163     /* One more Kerning value */
       
   164     for ( i = 0; i < cnt + 1; ++i )
       
   165     {
       
   166       p += 2;                                            /* Skip the value */
       
   167       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
       
   168       OTV_SIZE_CHECK( DeviceTableOffset );
       
   169       if ( DeviceTableOffset )
       
   170         otv_Device_validate( table + DeviceTableOffset, valid );
       
   171     }
       
   172 
       
   173     OTV_EXIT;
       
   174   }
       
   175 
       
   176 
       
   177   static void
       
   178   otv_MathKernInfo_validate( FT_Bytes       table,
       
   179                              OTV_Validator  valid )
       
   180   {
       
   181     FT_Bytes  p = table;
       
   182     FT_UInt   i, j, cnt, table_size;
       
   183 
       
   184     OTV_OPTIONAL_TABLE( Coverage );
       
   185     OTV_OPTIONAL_TABLE( MKRecordOffset );
       
   186 
       
   187 
       
   188     OTV_NAME_ENTER( "MathKernInfo" );
       
   189 
       
   190     OTV_LIMIT_CHECK( 4 );
       
   191 
       
   192     OTV_OPTIONAL_OFFSET( Coverage );
       
   193     cnt = FT_NEXT_USHORT( p );
       
   194 
       
   195     OTV_LIMIT_CHECK( 8 * cnt );
       
   196     table_size = 4 + 8 * cnt;
       
   197 
       
   198     OTV_SIZE_CHECK( Coverage );
       
   199     otv_Coverage_validate( table + Coverage, valid, cnt );
       
   200 
       
   201     for ( i = 0; i < cnt; ++i )
       
   202     {
       
   203       for ( j = 0; j < 4; ++j )
       
   204       {
       
   205         OTV_OPTIONAL_OFFSET( MKRecordOffset );
       
   206         OTV_SIZE_CHECK( MKRecordOffset );
       
   207         if ( MKRecordOffset )
       
   208           otv_MathKern_validate( table + MKRecordOffset, valid );
       
   209       }
       
   210     }
       
   211 
       
   212     OTV_EXIT;
       
   213   }
       
   214 
       
   215 
       
   216   /*************************************************************************/
       
   217   /*************************************************************************/
       
   218   /*****                                                               *****/
       
   219   /*****                         MATH GLYPH INFO                       *****/
       
   220   /*****                                                               *****/
       
   221   /*************************************************************************/
       
   222   /*************************************************************************/
       
   223 
       
   224   static void
       
   225   otv_MathGlyphInfo_validate( FT_Bytes       table,
       
   226                               OTV_Validator  valid )
       
   227   {
       
   228     FT_Bytes  p = table;
       
   229     FT_UInt   MathItalicsCorrectionInfo, MathTopAccentAttachment;
       
   230     FT_UInt   ExtendedShapeCoverage, MathKernInfo;
       
   231 
       
   232 
       
   233     OTV_NAME_ENTER( "MathGlyphInfo" );
       
   234 
       
   235     OTV_LIMIT_CHECK( 8 );
       
   236 
       
   237     MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
       
   238     MathTopAccentAttachment   = FT_NEXT_USHORT( p );
       
   239     ExtendedShapeCoverage     = FT_NEXT_USHORT( p );
       
   240     MathKernInfo              = FT_NEXT_USHORT( p );
       
   241 
       
   242     if ( MathItalicsCorrectionInfo )
       
   243       otv_MathItalicsCorrectionInfo_validate(
       
   244         table + MathItalicsCorrectionInfo, valid, TRUE );
       
   245 
       
   246     /* Italic correction and Top Accent Attachment have the same format */
       
   247     if ( MathTopAccentAttachment )
       
   248       otv_MathItalicsCorrectionInfo_validate(
       
   249         table + MathTopAccentAttachment, valid, FALSE );
       
   250 
       
   251     if ( ExtendedShapeCoverage )
       
   252     {
       
   253       OTV_NAME_ENTER( "ExtendedShapeCoverage" );
       
   254       otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
       
   255       OTV_EXIT;
       
   256     }
       
   257 
       
   258     if ( MathKernInfo )
       
   259       otv_MathKernInfo_validate( table + MathKernInfo, valid );
       
   260 
       
   261     OTV_EXIT;
       
   262   }
       
   263 
       
   264 
       
   265   /*************************************************************************/
       
   266   /*************************************************************************/
       
   267   /*****                                                               *****/
       
   268   /*****                    MATH GLYPH CONSTRUCTION                    *****/
       
   269   /*****                                                               *****/
       
   270   /*************************************************************************/
       
   271   /*************************************************************************/
       
   272 
       
   273   static void
       
   274   otv_GlyphAssembly_validate( FT_Bytes       table,
       
   275                               OTV_Validator  valid )
       
   276   {
       
   277     FT_Bytes  p = table;
       
   278     FT_UInt   pcnt, table_size;
       
   279     FT_UInt   i;
       
   280 
       
   281     OTV_OPTIONAL_TABLE( DeviceTableOffset );
       
   282 
       
   283 
       
   284     /* OTV_NAME_ENTER( "GlyphAssembly" ); */
       
   285 
       
   286     OTV_LIMIT_CHECK( 6 );
       
   287 
       
   288     p += 2;                           /* Skip the Italics Correction value */
       
   289     OTV_OPTIONAL_OFFSET( DeviceTableOffset );
       
   290     pcnt = FT_NEXT_USHORT( p );
       
   291 
       
   292     OTV_LIMIT_CHECK( 8 * pcnt );
       
   293     table_size = 6 + 8 * pcnt;
       
   294 
       
   295     OTV_SIZE_CHECK( DeviceTableOffset );
       
   296     if ( DeviceTableOffset )
       
   297       otv_Device_validate( table + DeviceTableOffset, valid );
       
   298 
       
   299     for ( i = 0; i < pcnt; ++i )
       
   300     {
       
   301       FT_UInt  gid;
       
   302 
       
   303 
       
   304       gid = FT_NEXT_USHORT( p );
       
   305       if ( gid >= valid->glyph_count )
       
   306         FT_INVALID_GLYPH_ID;
       
   307       p += 2*4;             /* skip the Start, End, Full, and Flags fields */
       
   308     }
       
   309 
       
   310     /* OTV_EXIT; */
       
   311   }
       
   312 
       
   313 
       
   314   static void
       
   315   otv_MathGlyphConstruction_validate( FT_Bytes       table,
       
   316                                       OTV_Validator  valid )
       
   317   {
       
   318     FT_Bytes  p = table;
       
   319     FT_UInt   vcnt, table_size;
       
   320     FT_UInt   i;
       
   321 
       
   322     OTV_OPTIONAL_TABLE( GlyphAssembly );
       
   323 
       
   324 
       
   325     /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
       
   326 
       
   327     OTV_LIMIT_CHECK( 4 );
       
   328 
       
   329     OTV_OPTIONAL_OFFSET( GlyphAssembly );
       
   330     vcnt = FT_NEXT_USHORT( p );
       
   331 
       
   332     OTV_LIMIT_CHECK( 4 * vcnt );
       
   333     table_size = 4 + 4 * vcnt;
       
   334 
       
   335     for ( i = 0; i < vcnt; ++i )
       
   336     {
       
   337       FT_UInt  gid;
       
   338 
       
   339 
       
   340       gid = FT_NEXT_USHORT( p );
       
   341       if ( gid >= valid->glyph_count )
       
   342         FT_INVALID_GLYPH_ID;
       
   343       p += 2;                          /* skip the size */
       
   344     }
       
   345 
       
   346     OTV_SIZE_CHECK( GlyphAssembly );
       
   347     if ( GlyphAssembly )
       
   348       otv_GlyphAssembly_validate( table+GlyphAssembly, valid );
       
   349 
       
   350     /* OTV_EXIT; */
       
   351   }
       
   352 
       
   353 
       
   354   static void
       
   355   otv_MathVariants_validate( FT_Bytes       table,
       
   356                              OTV_Validator  valid )
       
   357   {
       
   358     FT_Bytes  p = table;
       
   359     FT_UInt   vcnt, hcnt, i, table_size;
       
   360 
       
   361     OTV_OPTIONAL_TABLE( VCoverage );
       
   362     OTV_OPTIONAL_TABLE( HCoverage );
       
   363     OTV_OPTIONAL_TABLE( Offset );
       
   364 
       
   365 
       
   366     OTV_NAME_ENTER( "MathVariants" );
       
   367 
       
   368     OTV_LIMIT_CHECK( 10 );
       
   369 
       
   370     p += 2;                       /* Skip the MinConnectorOverlap constant */
       
   371     OTV_OPTIONAL_OFFSET( VCoverage );
       
   372     OTV_OPTIONAL_OFFSET( HCoverage );
       
   373     vcnt = FT_NEXT_USHORT( p );
       
   374     hcnt = FT_NEXT_USHORT( p );
       
   375 
       
   376     OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
       
   377     table_size = 10 + 2 * vcnt + 2 * hcnt;
       
   378 
       
   379     OTV_SIZE_CHECK( VCoverage );
       
   380     if ( VCoverage )
       
   381       otv_Coverage_validate( table + VCoverage, valid, vcnt );
       
   382 
       
   383     OTV_SIZE_CHECK( HCoverage );
       
   384     if ( HCoverage )
       
   385       otv_Coverage_validate( table + HCoverage, valid, hcnt );
       
   386 
       
   387     for ( i = 0; i < vcnt; ++i )
       
   388     {
       
   389       OTV_OPTIONAL_OFFSET( Offset );
       
   390       OTV_SIZE_CHECK( Offset );
       
   391       otv_MathGlyphConstruction_validate( table + Offset, valid );
       
   392     }
       
   393 
       
   394     for ( i = 0; i < hcnt; ++i )
       
   395     {
       
   396       OTV_OPTIONAL_OFFSET( Offset );
       
   397       OTV_SIZE_CHECK( Offset );
       
   398       otv_MathGlyphConstruction_validate( table + Offset, valid );
       
   399     }
       
   400 
       
   401     OTV_EXIT;
       
   402   }
       
   403 
       
   404 
       
   405   /*************************************************************************/
       
   406   /*************************************************************************/
       
   407   /*****                                                               *****/
       
   408   /*****                          MATH TABLE                           *****/
       
   409   /*****                                                               *****/
       
   410   /*************************************************************************/
       
   411   /*************************************************************************/
       
   412 
       
   413   /* sets valid->glyph_count */
       
   414 
       
   415   FT_LOCAL_DEF( void )
       
   416   otv_MATH_validate( FT_Bytes      table,
       
   417                      FT_UInt       glyph_count,
       
   418                      FT_Validator  ftvalid )
       
   419   {
       
   420     OTV_ValidatorRec  validrec;
       
   421     OTV_Validator     valid = &validrec;
       
   422     FT_Bytes          p     = table;
       
   423     FT_UInt           MathConstants, MathGlyphInfo, MathVariants;
       
   424 
       
   425 
       
   426     valid->root = ftvalid;
       
   427 
       
   428     FT_TRACE3(( "validating MATH table\n" ));
       
   429     OTV_INIT;
       
   430 
       
   431     OTV_LIMIT_CHECK( 10 );
       
   432 
       
   433     if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
       
   434       FT_INVALID_FORMAT;
       
   435 
       
   436     MathConstants = FT_NEXT_USHORT( p );
       
   437     MathGlyphInfo = FT_NEXT_USHORT( p );
       
   438     MathVariants  = FT_NEXT_USHORT( p );
       
   439 
       
   440     valid->glyph_count = glyph_count;
       
   441 
       
   442     otv_MathConstants_validate( table + MathConstants,
       
   443                                 valid );
       
   444     otv_MathGlyphInfo_validate( table + MathGlyphInfo,
       
   445                                 valid );
       
   446     otv_MathVariants_validate ( table + MathVariants,
       
   447                                 valid );
       
   448 
       
   449     FT_TRACE4(( "\n" ));
       
   450   }
       
   451 
       
   452 
       
   453 /* END */