ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

otvgsub.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  otvgsub.c                                                              */
00004 /*                                                                         */
00005 /*    OpenType GSUB table validation (body).                               */
00006 /*                                                                         */
00007 /*  Copyright 2004, 2005, 2007 by                                          */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include "otvalid.h"
00020 #include "otvcommn.h"
00021 
00022 
00023   /*************************************************************************/
00024   /*                                                                       */
00025   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00026   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00027   /* messages during execution.                                            */
00028   /*                                                                       */
00029 #undef  FT_COMPONENT
00030 #define FT_COMPONENT  trace_otvgsub
00031 
00032 
00033   /*************************************************************************/
00034   /*************************************************************************/
00035   /*****                                                               *****/
00036   /*****                  GSUB LOOKUP TYPE 1                           *****/
00037   /*****                                                               *****/
00038   /*************************************************************************/
00039   /*************************************************************************/
00040 
00041   /* uses valid->glyph_count */
00042 
00043   static void
00044   otv_SingleSubst_validate( FT_Bytes       table,
00045                             OTV_Validator  valid )
00046   {
00047     FT_Bytes  p = table;
00048     FT_UInt   SubstFormat;
00049 
00050 
00051     OTV_NAME_ENTER( "SingleSubst" );
00052 
00053     OTV_LIMIT_CHECK( 2 );
00054     SubstFormat = FT_NEXT_USHORT( p );
00055 
00056     OTV_TRACE(( " (format %d)\n", SubstFormat ));
00057 
00058     switch ( SubstFormat )
00059     {
00060     case 1:     /* SingleSubstFormat1 */
00061       {
00062         FT_Bytes  Coverage;
00063         FT_Int    DeltaGlyphID;
00064         FT_Long   idx;
00065 
00066 
00067         OTV_LIMIT_CHECK( 4 );
00068         Coverage     = table + FT_NEXT_USHORT( p );
00069         DeltaGlyphID = FT_NEXT_SHORT( p );
00070 
00071         otv_Coverage_validate( Coverage, valid, -1 );
00072 
00073         idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID;
00074         if ( idx < 0 )
00075           FT_INVALID_DATA;
00076 
00077         idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID;
00078         if ( (FT_UInt)idx >= valid->glyph_count )
00079           FT_INVALID_DATA;
00080       }
00081       break;
00082 
00083     case 2:     /* SingleSubstFormat2 */
00084       {
00085         FT_UInt  Coverage, GlyphCount;
00086 
00087 
00088         OTV_LIMIT_CHECK( 4 );
00089         Coverage   = FT_NEXT_USHORT( p );
00090         GlyphCount = FT_NEXT_USHORT( p );
00091 
00092         OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
00093 
00094         otv_Coverage_validate( table + Coverage, valid, GlyphCount );
00095 
00096         OTV_LIMIT_CHECK( GlyphCount * 2 );
00097 
00098         /* Substitute */
00099         for ( ; GlyphCount > 0; GlyphCount-- )
00100           if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
00101             FT_INVALID_GLYPH_ID;
00102       }
00103       break;
00104 
00105     default:
00106       FT_INVALID_FORMAT;
00107     }
00108 
00109     OTV_EXIT;
00110   }
00111 
00112 
00113   /*************************************************************************/
00114   /*************************************************************************/
00115   /*****                                                               *****/
00116   /*****                  GSUB LOOKUP TYPE 2                           *****/
00117   /*****                                                               *****/
00118   /*************************************************************************/
00119   /*************************************************************************/
00120 
00121   /* sets valid->extra1 (glyph count) */
00122 
00123   static void
00124   otv_MultipleSubst_validate( FT_Bytes       table,
00125                               OTV_Validator  valid )
00126   {
00127     FT_Bytes  p = table;
00128     FT_UInt   SubstFormat;
00129 
00130 
00131     OTV_NAME_ENTER( "MultipleSubst" );
00132 
00133     OTV_LIMIT_CHECK( 2 );
00134     SubstFormat = FT_NEXT_USHORT( p );
00135 
00136     OTV_TRACE(( " (format %d)\n", SubstFormat ));
00137 
00138     switch ( SubstFormat )
00139     {
00140     case 1:
00141       valid->extra1 = valid->glyph_count;
00142       OTV_NEST2( MultipleSubstFormat1, Sequence );
00143       OTV_RUN( table, valid );
00144       break;
00145 
00146     default:
00147       FT_INVALID_FORMAT;
00148     }
00149 
00150     OTV_EXIT;
00151   }
00152 
00153 
00154   /*************************************************************************/
00155   /*************************************************************************/
00156   /*****                                                               *****/
00157   /*****                    GSUB LOOKUP TYPE 3                         *****/
00158   /*****                                                               *****/
00159   /*************************************************************************/
00160   /*************************************************************************/
00161 
00162   /* sets valid->extra1 (glyph count) */
00163 
00164   static void
00165   otv_AlternateSubst_validate( FT_Bytes       table,
00166                                OTV_Validator  valid )
00167   {
00168     FT_Bytes  p = table;
00169     FT_UInt   SubstFormat;
00170 
00171 
00172     OTV_NAME_ENTER( "AlternateSubst" );
00173 
00174     OTV_LIMIT_CHECK( 2 );
00175     SubstFormat = FT_NEXT_USHORT( p );
00176 
00177     OTV_TRACE(( " (format %d)\n", SubstFormat ));
00178 
00179     switch ( SubstFormat )
00180     {
00181     case 1:
00182       valid->extra1 = valid->glyph_count;
00183       OTV_NEST2( AlternateSubstFormat1, AlternateSet );
00184       OTV_RUN( table, valid );
00185       break;
00186 
00187     default:
00188       FT_INVALID_FORMAT;
00189     }
00190 
00191     OTV_EXIT;
00192   }
00193 
00194 
00195   /*************************************************************************/
00196   /*************************************************************************/
00197   /*****                                                               *****/
00198   /*****                    GSUB LOOKUP TYPE 4                         *****/
00199   /*****                                                               *****/
00200   /*************************************************************************/
00201   /*************************************************************************/
00202 
00203 #define LigatureFunc  otv_Ligature_validate
00204 
00205   /* uses valid->glyph_count */
00206 
00207   static void
00208   otv_Ligature_validate( FT_Bytes       table,
00209                          OTV_Validator  valid )
00210   {
00211     FT_Bytes  p = table;
00212     FT_UInt   LigatureGlyph, CompCount;
00213 
00214 
00215     OTV_ENTER;
00216 
00217     OTV_LIMIT_CHECK( 4 );
00218     LigatureGlyph = FT_NEXT_USHORT( p );
00219     if ( LigatureGlyph >= valid->glyph_count )
00220       FT_INVALID_DATA;
00221 
00222     CompCount = FT_NEXT_USHORT( p );
00223 
00224     OTV_TRACE(( " (CompCount = %d)\n", CompCount ));
00225 
00226     if ( CompCount == 0 )
00227       FT_INVALID_DATA;
00228 
00229     CompCount--;
00230 
00231     OTV_LIMIT_CHECK( CompCount * 2 );     /* Component */
00232 
00233     /* no need to check the Component glyph indices */
00234 
00235     OTV_EXIT;
00236   }
00237 
00238 
00239   static void
00240   otv_LigatureSubst_validate( FT_Bytes       table,
00241                               OTV_Validator  valid )
00242   {
00243     FT_Bytes  p = table;
00244     FT_UInt   SubstFormat;
00245 
00246 
00247     OTV_NAME_ENTER( "LigatureSubst" );
00248 
00249     OTV_LIMIT_CHECK( 2 );
00250     SubstFormat = FT_NEXT_USHORT( p );
00251 
00252     OTV_TRACE(( " (format %d)\n", SubstFormat ));
00253 
00254     switch ( SubstFormat )
00255     {
00256     case 1:
00257       OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature );
00258       OTV_RUN( table, valid );
00259       break;
00260 
00261     default:
00262       FT_INVALID_FORMAT;
00263     }
00264 
00265     OTV_EXIT;
00266   }
00267 
00268 
00269   /*************************************************************************/
00270   /*************************************************************************/
00271   /*****                                                               *****/
00272   /*****                  GSUB LOOKUP TYPE 5                           *****/
00273   /*****                                                               *****/
00274   /*************************************************************************/
00275   /*************************************************************************/
00276 
00277   /* sets valid->extra1 (lookup count) */
00278 
00279   static void
00280   otv_ContextSubst_validate( FT_Bytes       table,
00281                              OTV_Validator  valid )
00282   {
00283     FT_Bytes  p = table;
00284     FT_UInt   SubstFormat;
00285 
00286 
00287     OTV_NAME_ENTER( "ContextSubst" );
00288 
00289     OTV_LIMIT_CHECK( 2 );
00290     SubstFormat = FT_NEXT_USHORT( p );
00291 
00292     OTV_TRACE(( " (format %d)\n", SubstFormat ));
00293 
00294     switch ( SubstFormat )
00295     {
00296     case 1:
00297       /* no need to check glyph indices/classes used as input for these */
00298       /* context rules since even invalid glyph indices/classes return  */
00299       /* meaningful results                                             */
00300 
00301       valid->extra1 = valid->lookup_count;
00302       OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule );
00303       OTV_RUN( table, valid );
00304       break;
00305 
00306     case 2:
00307       /* no need to check glyph indices/classes used as input for these */
00308       /* context rules since even invalid glyph indices/classes return  */
00309       /* meaningful results                                             */
00310 
00311       OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule );
00312       OTV_RUN( table, valid );
00313       break;
00314 
00315     case 3:
00316       OTV_NEST1( ContextSubstFormat3 );
00317       OTV_RUN( table, valid );
00318       break;
00319 
00320     default:
00321       FT_INVALID_FORMAT;
00322     }
00323 
00324     OTV_EXIT;
00325   }
00326 
00327 
00328   /*************************************************************************/
00329   /*************************************************************************/
00330   /*****                                                               *****/
00331   /*****                    GSUB LOOKUP TYPE 6                         *****/
00332   /*****                                                               *****/
00333   /*************************************************************************/
00334   /*************************************************************************/
00335 
00336   /* sets valid->extra1 (lookup count)            */
00337 
00338   static void
00339   otv_ChainContextSubst_validate( FT_Bytes       table,
00340                                   OTV_Validator  valid )
00341   {
00342     FT_Bytes  p = table;
00343     FT_UInt   SubstFormat;
00344 
00345 
00346     OTV_NAME_ENTER( "ChainContextSubst" );
00347 
00348     OTV_LIMIT_CHECK( 2 );
00349     SubstFormat = FT_NEXT_USHORT( p );
00350 
00351     OTV_TRACE(( " (format %d)\n", SubstFormat ));
00352 
00353     switch ( SubstFormat )
00354     {
00355     case 1:
00356       /* no need to check glyph indices/classes used as input for these */
00357       /* context rules since even invalid glyph indices/classes return  */
00358       /* meaningful results                                             */
00359 
00360       valid->extra1 = valid->lookup_count;
00361       OTV_NEST3( ChainContextSubstFormat1,
00362                  ChainSubRuleSet, ChainSubRule );
00363       OTV_RUN( table, valid );
00364       break;
00365 
00366     case 2:
00367       /* no need to check glyph indices/classes used as input for these */
00368       /* context rules since even invalid glyph indices/classes return  */
00369       /* meaningful results                                             */
00370 
00371       OTV_NEST3( ChainContextSubstFormat2,
00372                  ChainSubClassSet, ChainSubClassRule );
00373       OTV_RUN( table, valid );
00374       break;
00375 
00376     case 3:
00377       OTV_NEST1( ChainContextSubstFormat3 );
00378       OTV_RUN( table, valid );
00379       break;
00380 
00381     default:
00382       FT_INVALID_FORMAT;
00383     }
00384 
00385     OTV_EXIT;
00386   }
00387 
00388 
00389   /*************************************************************************/
00390   /*************************************************************************/
00391   /*****                                                               *****/
00392   /*****                    GSUB LOOKUP TYPE 7                         *****/
00393   /*****                                                               *****/
00394   /*************************************************************************/
00395   /*************************************************************************/
00396 
00397   /* uses valid->type_funcs */
00398 
00399   static void
00400   otv_ExtensionSubst_validate( FT_Bytes       table,
00401                                OTV_Validator  valid )
00402   {
00403     FT_Bytes  p = table;
00404     FT_UInt   SubstFormat;
00405 
00406 
00407     OTV_NAME_ENTER( "ExtensionSubst" );
00408 
00409     OTV_LIMIT_CHECK( 2 );
00410     SubstFormat = FT_NEXT_USHORT( p );
00411 
00412     OTV_TRACE(( " (format %d)\n", SubstFormat ));
00413 
00414     switch ( SubstFormat )
00415     {
00416     case 1:     /* ExtensionSubstFormat1 */
00417       {
00418         FT_UInt            ExtensionLookupType;
00419         FT_ULong           ExtensionOffset;
00420         OTV_Validate_Func  validate;
00421 
00422 
00423         OTV_LIMIT_CHECK( 6 );
00424         ExtensionLookupType = FT_NEXT_USHORT( p );
00425         ExtensionOffset     = FT_NEXT_ULONG( p );
00426 
00427         if ( ExtensionLookupType == 0 ||
00428              ExtensionLookupType == 7 ||
00429              ExtensionLookupType > 8  )
00430           FT_INVALID_DATA;
00431 
00432         validate = valid->type_funcs[ExtensionLookupType - 1];
00433         validate( table + ExtensionOffset, valid );
00434       }
00435       break;
00436 
00437     default:
00438       FT_INVALID_FORMAT;
00439     }
00440 
00441     OTV_EXIT;
00442   }
00443 
00444 
00445   /*************************************************************************/
00446   /*************************************************************************/
00447   /*****                                                               *****/
00448   /*****                    GSUB LOOKUP TYPE 8                         *****/
00449   /*****                                                               *****/
00450   /*************************************************************************/
00451   /*************************************************************************/
00452 
00453   /* uses valid->glyph_count */
00454 
00455   static void
00456   otv_ReverseChainSingleSubst_validate( FT_Bytes       table,
00457                                         OTV_Validator  valid )
00458   {
00459     FT_Bytes  p = table, Coverage;
00460     FT_UInt   SubstFormat;
00461     FT_UInt   BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount;
00462 
00463 
00464     OTV_NAME_ENTER( "ReverseChainSingleSubst" );
00465 
00466     OTV_LIMIT_CHECK( 2 );
00467     SubstFormat = FT_NEXT_USHORT( p );
00468 
00469     OTV_TRACE(( " (format %d)\n", SubstFormat ));
00470 
00471     switch ( SubstFormat )
00472     {
00473     case 1:     /* ReverseChainSingleSubstFormat1 */
00474       OTV_LIMIT_CHECK( 4 );
00475       Coverage            = table + FT_NEXT_USHORT( p );
00476       BacktrackGlyphCount = FT_NEXT_USHORT( p );
00477 
00478       OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
00479 
00480       otv_Coverage_validate( Coverage, valid, -1 );
00481 
00482       OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
00483 
00484       for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
00485         otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
00486 
00487       LookaheadGlyphCount = FT_NEXT_USHORT( p );
00488 
00489       OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
00490 
00491       OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
00492 
00493       for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
00494         otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
00495 
00496       GlyphCount = FT_NEXT_USHORT( p );
00497 
00498       OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
00499 
00500       if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
00501         FT_INVALID_DATA;
00502 
00503       OTV_LIMIT_CHECK( GlyphCount * 2 );
00504 
00505       /* Substitute */
00506       for ( ; GlyphCount > 0; GlyphCount-- )
00507         if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
00508           FT_INVALID_DATA;
00509 
00510       break;
00511 
00512     default:
00513       FT_INVALID_FORMAT;
00514     }
00515 
00516     OTV_EXIT;
00517   }
00518 
00519 
00520   static const OTV_Validate_Func  otv_gsub_validate_funcs[8] =
00521   {
00522     otv_SingleSubst_validate,
00523     otv_MultipleSubst_validate,
00524     otv_AlternateSubst_validate,
00525     otv_LigatureSubst_validate,
00526     otv_ContextSubst_validate,
00527     otv_ChainContextSubst_validate,
00528     otv_ExtensionSubst_validate,
00529     otv_ReverseChainSingleSubst_validate
00530   };
00531 
00532 
00533   /*************************************************************************/
00534   /*************************************************************************/
00535   /*****                                                               *****/
00536   /*****                          GSUB TABLE                           *****/
00537   /*****                                                               *****/
00538   /*************************************************************************/
00539   /*************************************************************************/
00540 
00541   /* sets valid->type_count  */
00542   /* sets valid->type_funcs  */
00543   /* sets valid->glyph_count */
00544 
00545   FT_LOCAL_DEF( void )
00546   otv_GSUB_validate( FT_Bytes      table,
00547                      FT_UInt       glyph_count,
00548                      FT_Validator  ftvalid )
00549   {
00550     OTV_ValidatorRec  validrec;
00551     OTV_Validator     valid = &validrec;
00552     FT_Bytes          p     = table;
00553     FT_UInt           ScriptList, FeatureList, LookupList;
00554 
00555 
00556     valid->root = ftvalid;
00557 
00558     FT_TRACE3(( "validating GSUB table\n" ));
00559     OTV_INIT;
00560 
00561     OTV_LIMIT_CHECK( 10 );
00562 
00563     if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
00564       FT_INVALID_FORMAT;
00565 
00566     ScriptList  = FT_NEXT_USHORT( p );
00567     FeatureList = FT_NEXT_USHORT( p );
00568     LookupList  = FT_NEXT_USHORT( p );
00569 
00570     valid->type_count  = 8;
00571     valid->type_funcs  = (OTV_Validate_Func*)otv_gsub_validate_funcs;
00572     valid->glyph_count = glyph_count;
00573 
00574     otv_LookupList_validate( table + LookupList,
00575                              valid );
00576     otv_FeatureList_validate( table + FeatureList, table + LookupList,
00577                               valid );
00578     otv_ScriptList_validate( table + ScriptList, table + FeatureList,
00579                              valid );
00580 
00581     FT_TRACE4(( "\n" ));
00582   }
00583 
00584 
00585 /* END */

Generated on Fri May 25 2012 04:32:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.