otvmath.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  otvmath.c                                                              */
00004 /*                                                                         */
00005 /*    OpenType MATH table validation (body).                               */
00006 /*                                                                         */
00007 /*  Copyright 2007, 2008 by                                                */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  Written by George Williams.                                            */
00011 /*                                                                         */
00012 /*  This file is part of the FreeType project, and may only be used,       */
00013 /*  modified, and distributed under the terms of the FreeType project      */
00014 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00015 /*  this file you indicate that you have read the license and              */
00016 /*  understand and accept it fully.                                        */
00017 /*                                                                         */
00018 /***************************************************************************/
00019 
00020 
00021 #include "otvalid.h"
00022 #include "otvcommn.h"
00023 #include "otvgpos.h"
00024 
00025 
00026   /*************************************************************************/
00027   /*                                                                       */
00028   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00029   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00030   /* messages during execution.                                            */
00031   /*                                                                       */
00032 #undef  FT_COMPONENT
00033 #define FT_COMPONENT  trace_otvmath
00034 
00035 
00036 
00037   /*************************************************************************/
00038   /*************************************************************************/
00039   /*****                                                               *****/
00040   /*****                  MATH TYPOGRAPHIC CONSTANTS                   *****/
00041   /*****                                                               *****/
00042   /*************************************************************************/
00043   /*************************************************************************/
00044 
00045   static void
00046   otv_MathConstants_validate( FT_Bytes       table,
00047                               OTV_Validator  valid )
00048   {
00049     FT_Bytes  p = table;
00050     FT_UInt   i;
00051     FT_UInt   table_size;
00052 
00053     OTV_OPTIONAL_TABLE( DeviceTableOffset );
00054 
00055 
00056     OTV_NAME_ENTER( "MathConstants" );
00057 
00058     /* 56 constants, 51 have device tables */
00059     OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) );
00060     table_size = 2 * ( 56 + 51 );
00061 
00062     p += 4 * 2;                 /* First 4 constants have no device tables */
00063     for ( i = 0; i < 51; ++i )
00064     {
00065       p += 2;                                            /* skip the value */
00066       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00067       OTV_SIZE_CHECK( DeviceTableOffset );
00068       if ( DeviceTableOffset )
00069         otv_Device_validate( table + DeviceTableOffset, valid );
00070     }
00071 
00072     OTV_EXIT;
00073   }
00074 
00075 
00076   /*************************************************************************/
00077   /*************************************************************************/
00078   /*****                                                               *****/
00079   /*****                   MATH ITALICS CORRECTION                     *****/
00080   /*****                 MATH TOP ACCENT ATTACHMENT                    *****/
00081   /*****                                                               *****/
00082   /*************************************************************************/
00083   /*************************************************************************/
00084 
00085   static void
00086   otv_MathItalicsCorrectionInfo_validate( FT_Bytes       table,
00087                                           OTV_Validator  valid,
00088                                           FT_Int         isItalic )
00089   {
00090     FT_Bytes  p = table;
00091     FT_UInt   i, cnt, table_size ;
00092 
00093     OTV_OPTIONAL_TABLE( Coverage );
00094     OTV_OPTIONAL_TABLE( DeviceTableOffset );
00095 
00096     FT_UNUSED( isItalic );  /* only used if tracing is active */
00097 
00098 
00099     OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
00100                              : "MathTopAccentAttachment" );
00101 
00102     OTV_LIMIT_CHECK( 4 );
00103 
00104     OTV_OPTIONAL_OFFSET( Coverage );
00105     cnt = FT_NEXT_USHORT( p );
00106 
00107     OTV_LIMIT_CHECK( 4 * cnt );
00108     table_size = 4 + 4 * cnt;
00109 
00110     OTV_SIZE_CHECK( Coverage );
00111     otv_Coverage_validate( table + Coverage, valid, cnt );
00112 
00113     for ( i = 0; i < cnt; ++i )
00114     {
00115       p += 2;                                            /* Skip the value */
00116       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00117       OTV_SIZE_CHECK( DeviceTableOffset );
00118       if ( DeviceTableOffset )
00119         otv_Device_validate( table + DeviceTableOffset, valid );
00120     }
00121 
00122     OTV_EXIT;
00123   }
00124 
00125 
00126   /*************************************************************************/
00127   /*************************************************************************/
00128   /*****                                                               *****/
00129   /*****                           MATH KERNING                        *****/
00130   /*****                                                               *****/
00131   /*************************************************************************/
00132   /*************************************************************************/
00133 
00134   static void
00135   otv_MathKern_validate( FT_Bytes       table,
00136                          OTV_Validator  valid )
00137   {
00138     FT_Bytes  p = table;
00139     FT_UInt   i, cnt, table_size;
00140 
00141     OTV_OPTIONAL_TABLE( DeviceTableOffset );
00142 
00143 
00144     /* OTV_NAME_ENTER( "MathKern" );*/
00145 
00146     OTV_LIMIT_CHECK( 2 );
00147 
00148     cnt = FT_NEXT_USHORT( p );
00149 
00150     OTV_LIMIT_CHECK( 4 * cnt + 2 );
00151     table_size = 4 + 4 * cnt;
00152 
00153     /* Heights */
00154     for ( i = 0; i < cnt; ++i )
00155     {
00156       p += 2;                                            /* Skip the value */
00157       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00158       OTV_SIZE_CHECK( DeviceTableOffset );
00159       if ( DeviceTableOffset )
00160         otv_Device_validate( table + DeviceTableOffset, valid );
00161     }
00162 
00163     /* One more Kerning value */
00164     for ( i = 0; i < cnt + 1; ++i )
00165     {
00166       p += 2;                                            /* Skip the value */
00167       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00168       OTV_SIZE_CHECK( DeviceTableOffset );
00169       if ( DeviceTableOffset )
00170         otv_Device_validate( table + DeviceTableOffset, valid );
00171     }
00172 
00173     OTV_EXIT;
00174   }
00175 
00176 
00177   static void
00178   otv_MathKernInfo_validate( FT_Bytes       table,
00179                              OTV_Validator  valid )
00180   {
00181     FT_Bytes  p = table;
00182     FT_UInt   i, j, cnt, table_size;
00183 
00184     OTV_OPTIONAL_TABLE( Coverage );
00185     OTV_OPTIONAL_TABLE( MKRecordOffset );
00186 
00187 
00188     OTV_NAME_ENTER( "MathKernInfo" );
00189 
00190     OTV_LIMIT_CHECK( 4 );
00191 
00192     OTV_OPTIONAL_OFFSET( Coverage );
00193     cnt = FT_NEXT_USHORT( p );
00194 
00195     OTV_LIMIT_CHECK( 8 * cnt );
00196     table_size = 4 + 8 * cnt;
00197 
00198     OTV_SIZE_CHECK( Coverage );
00199     otv_Coverage_validate( table + Coverage, valid, cnt );
00200 
00201     for ( i = 0; i < cnt; ++i )
00202     {
00203       for ( j = 0; j < 4; ++j )
00204       {
00205         OTV_OPTIONAL_OFFSET( MKRecordOffset );
00206         OTV_SIZE_CHECK( MKRecordOffset );
00207         if ( MKRecordOffset )
00208           otv_MathKern_validate( table + MKRecordOffset, valid );
00209       }
00210     }
00211 
00212     OTV_EXIT;
00213   }
00214 
00215 
00216   /*************************************************************************/
00217   /*************************************************************************/
00218   /*****                                                               *****/
00219   /*****                         MATH GLYPH INFO                       *****/
00220   /*****                                                               *****/
00221   /*************************************************************************/
00222   /*************************************************************************/
00223 
00224   static void
00225   otv_MathGlyphInfo_validate( FT_Bytes       table,
00226                               OTV_Validator  valid )
00227   {
00228     FT_Bytes  p = table;
00229     FT_UInt   MathItalicsCorrectionInfo, MathTopAccentAttachment;
00230     FT_UInt   ExtendedShapeCoverage, MathKernInfo;
00231 
00232 
00233     OTV_NAME_ENTER( "MathGlyphInfo" );
00234 
00235     OTV_LIMIT_CHECK( 8 );
00236 
00237     MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
00238     MathTopAccentAttachment   = FT_NEXT_USHORT( p );
00239     ExtendedShapeCoverage     = FT_NEXT_USHORT( p );
00240     MathKernInfo              = FT_NEXT_USHORT( p );
00241 
00242     if ( MathItalicsCorrectionInfo )
00243       otv_MathItalicsCorrectionInfo_validate(
00244         table + MathItalicsCorrectionInfo, valid, TRUE );
00245 
00246     /* Italic correction and Top Accent Attachment have the same format */
00247     if ( MathTopAccentAttachment )
00248       otv_MathItalicsCorrectionInfo_validate(
00249         table + MathTopAccentAttachment, valid, FALSE );
00250 
00251     if ( ExtendedShapeCoverage ) {
00252       OTV_NAME_ENTER( "ExtendedShapeCoverage" );
00253       otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
00254       OTV_EXIT;
00255     }
00256 
00257     if ( MathKernInfo )
00258       otv_MathKernInfo_validate( table + MathKernInfo, valid );
00259 
00260     OTV_EXIT;
00261   }
00262 
00263 
00264   /*************************************************************************/
00265   /*************************************************************************/
00266   /*****                                                               *****/
00267   /*****                    MATH GLYPH CONSTRUCTION                    *****/
00268   /*****                                                               *****/
00269   /*************************************************************************/
00270   /*************************************************************************/
00271 
00272   static void
00273   otv_GlyphAssembly_validate( FT_Bytes       table,
00274                               OTV_Validator  valid )
00275   {
00276     FT_Bytes  p = table;
00277     FT_UInt   pcnt, table_size;
00278     FT_UInt   i;
00279 
00280     OTV_OPTIONAL_TABLE( DeviceTableOffset );
00281 
00282 
00283     /* OTV_NAME_ENTER( "GlyphAssembly" ); */
00284 
00285     OTV_LIMIT_CHECK( 6 );
00286 
00287     p += 2;                           /* Skip the Italics Correction value */
00288     OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00289     pcnt = FT_NEXT_USHORT( p );
00290 
00291     OTV_LIMIT_CHECK( 8 * pcnt );
00292     table_size = 6 + 8 * pcnt;
00293 
00294     OTV_SIZE_CHECK( DeviceTableOffset );
00295     if ( DeviceTableOffset )
00296       otv_Device_validate( table + DeviceTableOffset, valid );
00297 
00298     for ( i = 0; i < pcnt; ++i )
00299     {
00300       FT_UInt  gid;
00301 
00302 
00303       gid = FT_NEXT_USHORT( p );
00304       if ( gid >= valid->glyph_count )
00305         FT_INVALID_GLYPH_ID;
00306       p += 2*4;             /* skip the Start, End, Full, and Flags fields */
00307     }
00308 
00309     /* OTV_EXIT; */
00310   }
00311 
00312 
00313   static void
00314   otv_MathGlyphConstruction_validate( FT_Bytes       table,
00315                                       OTV_Validator  valid )
00316   {
00317     FT_Bytes  p = table;
00318     FT_UInt   vcnt, table_size;
00319     FT_UInt   i;
00320 
00321     OTV_OPTIONAL_TABLE( GlyphAssembly );
00322 
00323 
00324     /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
00325 
00326     OTV_LIMIT_CHECK( 4 );
00327 
00328     OTV_OPTIONAL_OFFSET( GlyphAssembly );
00329     vcnt = FT_NEXT_USHORT( p );
00330 
00331     OTV_LIMIT_CHECK( 4 * vcnt );
00332     table_size = 4 + 4 * vcnt;
00333 
00334     for ( i = 0; i < vcnt; ++i )
00335     {
00336       FT_UInt  gid;
00337 
00338 
00339       gid = FT_NEXT_USHORT( p );
00340       if ( gid >= valid->glyph_count )
00341         FT_INVALID_GLYPH_ID;
00342       p += 2;                          /* skip the size */
00343     }
00344 
00345     OTV_SIZE_CHECK( GlyphAssembly );
00346     if ( GlyphAssembly )
00347       otv_GlyphAssembly_validate( table+GlyphAssembly, valid );
00348 
00349     /* OTV_EXIT; */
00350   }
00351 
00352 
00353   static void
00354   otv_MathVariants_validate( FT_Bytes       table,
00355                              OTV_Validator  valid )
00356   {
00357     FT_Bytes  p = table;
00358     FT_UInt   vcnt, hcnt, i, table_size;
00359 
00360     OTV_OPTIONAL_TABLE( VCoverage );
00361     OTV_OPTIONAL_TABLE( HCoverage );
00362     OTV_OPTIONAL_TABLE( Offset );
00363 
00364 
00365     OTV_NAME_ENTER( "MathVariants" );
00366 
00367     OTV_LIMIT_CHECK( 10 );
00368 
00369     p += 2;                       /* Skip the MinConnectorOverlap constant */
00370     OTV_OPTIONAL_OFFSET( VCoverage );
00371     OTV_OPTIONAL_OFFSET( HCoverage );
00372     vcnt = FT_NEXT_USHORT( p );
00373     hcnt = FT_NEXT_USHORT( p );
00374 
00375     OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
00376     table_size = 10 + 2 * vcnt + 2 * hcnt;
00377 
00378     OTV_SIZE_CHECK( VCoverage );
00379     if ( VCoverage )
00380       otv_Coverage_validate( table + VCoverage, valid, vcnt );
00381 
00382     OTV_SIZE_CHECK( HCoverage );
00383     if ( HCoverage )
00384       otv_Coverage_validate( table + HCoverage, valid, hcnt );
00385 
00386     for ( i = 0; i < vcnt; ++i )
00387     {
00388       OTV_OPTIONAL_OFFSET( Offset );
00389       OTV_SIZE_CHECK( Offset );
00390       otv_MathGlyphConstruction_validate( table + Offset, valid );
00391     }
00392 
00393     for ( i = 0; i < hcnt; ++i )
00394     {
00395       OTV_OPTIONAL_OFFSET( Offset );
00396       OTV_SIZE_CHECK( Offset );
00397       otv_MathGlyphConstruction_validate( table + Offset, valid );
00398     }
00399 
00400     OTV_EXIT;
00401   }
00402 
00403 
00404   /*************************************************************************/
00405   /*************************************************************************/
00406   /*****                                                               *****/
00407   /*****                          MATH TABLE                           *****/
00408   /*****                                                               *****/
00409   /*************************************************************************/
00410   /*************************************************************************/
00411 
00412   /* sets valid->glyph_count */
00413 
00414   FT_LOCAL_DEF( void )
00415   otv_MATH_validate( FT_Bytes      table,
00416                      FT_UInt       glyph_count,
00417                      FT_Validator  ftvalid )
00418   {
00419     OTV_ValidatorRec  validrec;
00420     OTV_Validator     valid = &validrec;
00421     FT_Bytes          p     = table;
00422     FT_UInt           MathConstants, MathGlyphInfo, MathVariants;
00423 
00424 
00425     valid->root = ftvalid;
00426 
00427     FT_TRACE3(( "validating MATH table\n" ));
00428     OTV_INIT;
00429 
00430     OTV_LIMIT_CHECK( 10 );
00431 
00432     if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
00433       FT_INVALID_FORMAT;
00434 
00435     MathConstants = FT_NEXT_USHORT( p );
00436     MathGlyphInfo = FT_NEXT_USHORT( p );
00437     MathVariants  = FT_NEXT_USHORT( p );
00438 
00439     valid->glyph_count = glyph_count;
00440 
00441     otv_MathConstants_validate( table + MathConstants,
00442                                 valid );
00443     otv_MathGlyphInfo_validate( table + MathGlyphInfo,
00444                                 valid );
00445     otv_MathVariants_validate ( table + MathVariants,
00446                                 valid );
00447 
00448     FT_TRACE4(( "\n" ));
00449   }
00450 
00451 
00452 /* END */

Generated on Tue Jul 5 14:13:48 2011 for ROOT_528-00b_version by  doxygen 1.5.1