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

otvgpos.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  otvgpos.c                                                              */
00004 /*                                                                         */
00005 /*    OpenType GPOS table validation (body).                               */
00006 /*                                                                         */
00007 /*  Copyright 2002, 2004, 2005, 2006, 2007, 2008 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 #include "otvgpos.h"
00022 
00023 
00024   /*************************************************************************/
00025   /*                                                                       */
00026   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00027   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00028   /* messages during execution.                                            */
00029   /*                                                                       */
00030 #undef  FT_COMPONENT
00031 #define FT_COMPONENT  trace_otvgpos
00032 
00033 
00034   static void
00035   otv_Anchor_validate( FT_Bytes       table,
00036                        OTV_Validator  valid );
00037 
00038   static void
00039   otv_MarkArray_validate( FT_Bytes       table,
00040                           OTV_Validator  valid );
00041 
00042 
00043   /*************************************************************************/
00044   /*************************************************************************/
00045   /*****                                                               *****/
00046   /*****                      UTILITY FUNCTIONS                        *****/
00047   /*****                                                               *****/
00048   /*************************************************************************/
00049   /*************************************************************************/
00050 
00051 #define BaseArrayFunc       otv_x_sxy
00052 #define LigatureAttachFunc  otv_x_sxy
00053 #define Mark2ArrayFunc      otv_x_sxy
00054 
00055   /* uses valid->extra1 (counter)                             */
00056   /* uses valid->extra2 (boolean to handle NULL anchor field) */
00057 
00058   static void
00059   otv_x_sxy( FT_Bytes       table,
00060              OTV_Validator  valid )
00061   {
00062     FT_Bytes  p = table;
00063     FT_UInt   Count, count1, table_size;
00064 
00065 
00066     OTV_ENTER;
00067 
00068     OTV_LIMIT_CHECK( 2 );
00069 
00070     Count = FT_NEXT_USHORT( p );
00071 
00072     OTV_TRACE(( " (Count = %d)\n", Count ));
00073 
00074     OTV_LIMIT_CHECK( Count * valid->extra1 * 2 );
00075 
00076     table_size = Count * valid->extra1 * 2 + 2;
00077 
00078     for ( ; Count > 0; Count-- )
00079       for ( count1 = valid->extra1; count1 > 0; count1-- )
00080       {
00081         OTV_OPTIONAL_TABLE( anchor_offset );
00082 
00083 
00084         OTV_OPTIONAL_OFFSET( anchor_offset );
00085 
00086         if ( valid->extra2 )
00087         {
00088           OTV_SIZE_CHECK( anchor_offset );
00089           if ( anchor_offset )
00090             otv_Anchor_validate( table + anchor_offset, valid );
00091         }
00092         else
00093           otv_Anchor_validate( table + anchor_offset, valid );
00094       }
00095 
00096     OTV_EXIT;
00097   }
00098 
00099 
00100 #define MarkBasePosFormat1Func  otv_u_O_O_u_O_O
00101 #define MarkLigPosFormat1Func   otv_u_O_O_u_O_O
00102 #define MarkMarkPosFormat1Func  otv_u_O_O_u_O_O
00103 
00104   /* sets valid->extra1 (class count) */
00105 
00106   static void
00107   otv_u_O_O_u_O_O( FT_Bytes       table,
00108                    OTV_Validator  valid )
00109   {
00110     FT_Bytes           p = table;
00111     FT_UInt            Coverage1, Coverage2, ClassCount;
00112     FT_UInt            Array1, Array2;
00113     OTV_Validate_Func  func;
00114 
00115 
00116     OTV_ENTER;
00117 
00118     p += 2;     /* skip PosFormat */
00119 
00120     OTV_LIMIT_CHECK( 10 );
00121     Coverage1  = FT_NEXT_USHORT( p );
00122     Coverage2  = FT_NEXT_USHORT( p );
00123     ClassCount = FT_NEXT_USHORT( p );
00124     Array1     = FT_NEXT_USHORT( p );
00125     Array2     = FT_NEXT_USHORT( p );
00126 
00127     otv_Coverage_validate( table + Coverage1, valid, -1 );
00128     otv_Coverage_validate( table + Coverage2, valid, -1 );
00129 
00130     otv_MarkArray_validate( table + Array1, valid );
00131 
00132     valid->nesting_level++;
00133     func          = valid->func[valid->nesting_level];
00134     valid->extra1 = ClassCount;
00135 
00136     func( table + Array2, valid );
00137 
00138     valid->nesting_level--;
00139 
00140     OTV_EXIT;
00141   }
00142 
00143 
00144   /*************************************************************************/
00145   /*************************************************************************/
00146   /*****                                                               *****/
00147   /*****                        VALUE RECORDS                          *****/
00148   /*****                                                               *****/
00149   /*************************************************************************/
00150   /*************************************************************************/
00151 
00152   static FT_UInt
00153   otv_value_length( FT_UInt  format )
00154   {
00155     FT_UInt  count;
00156 
00157 
00158     count = ( ( format & 0xAA ) >> 1 ) + ( format & 0x55 );
00159     count = ( ( count  & 0xCC ) >> 2 ) + ( count  & 0x33 );
00160     count = ( ( count  & 0xF0 ) >> 4 ) + ( count  & 0x0F );
00161 
00162     return count * 2;
00163   }
00164 
00165 
00166   /* uses valid->extra3 (pointer to base table) */
00167 
00168   static void
00169   otv_ValueRecord_validate( FT_Bytes       table,
00170                             FT_UInt        format,
00171                             OTV_Validator  valid )
00172   {
00173     FT_Bytes  p = table;
00174     FT_UInt   count;
00175 
00176 #ifdef FT_DEBUG_LEVEL_TRACE
00177     FT_Int    loop;
00178     FT_ULong  res = 0;
00179 
00180 
00181     OTV_NAME_ENTER( "ValueRecord" );
00182 
00183     /* display `format' in dual representation */
00184     for ( loop = 7; loop >= 0; loop-- )
00185     {
00186       res <<= 4;
00187       res  += ( format >> loop ) & 1;
00188     }
00189 
00190     OTV_TRACE(( " (format 0b%08lx)\n", res ));
00191 #endif
00192 
00193     if ( format >= 0x100 )
00194       FT_INVALID_FORMAT;
00195 
00196     for ( count = 4; count > 0; count-- )
00197     {
00198       if ( format & 1 )
00199       {
00200         /* XPlacement, YPlacement, XAdvance, YAdvance */
00201         OTV_LIMIT_CHECK( 2 );
00202         p += 2;
00203       }
00204 
00205       format >>= 1;
00206     }
00207 
00208     for ( count = 4; count > 0; count-- )
00209     {
00210       if ( format & 1 )
00211       {
00212         FT_PtrDist  table_size;
00213 
00214         OTV_OPTIONAL_TABLE( device );
00215 
00216 
00217         /* XPlaDevice, YPlaDevice, XAdvDevice, YAdvDevice */
00218         OTV_LIMIT_CHECK( 2 );
00219         OTV_OPTIONAL_OFFSET( device );
00220 
00221         /* XXX: this value is usually too small, especially if the current */
00222         /* ValueRecord is part of an array -- getting the correct table    */
00223         /* size is probably not worth the trouble                          */
00224 
00225         table_size = p - valid->extra3;
00226 
00227         OTV_SIZE_CHECK( device );
00228         if ( device )
00229           otv_Device_validate( valid->extra3 + device, valid );
00230       }
00231       format >>= 1;
00232     }
00233 
00234     OTV_EXIT;
00235   }
00236 
00237 
00238   /*************************************************************************/
00239   /*************************************************************************/
00240   /*****                                                               *****/
00241   /*****                           ANCHORS                             *****/
00242   /*****                                                               *****/
00243   /*************************************************************************/
00244   /*************************************************************************/
00245 
00246   static void
00247   otv_Anchor_validate( FT_Bytes       table,
00248                        OTV_Validator  valid )
00249   {
00250     FT_Bytes  p = table;
00251     FT_UInt   AnchorFormat;
00252 
00253 
00254     OTV_NAME_ENTER( "Anchor");
00255 
00256     OTV_LIMIT_CHECK( 6 );
00257     AnchorFormat = FT_NEXT_USHORT( p );
00258 
00259     OTV_TRACE(( " (format %d)\n", AnchorFormat ));
00260 
00261     p += 4;     /* skip XCoordinate and YCoordinate */
00262 
00263     switch ( AnchorFormat )
00264     {
00265     case 1:
00266       break;
00267 
00268     case 2:
00269       OTV_LIMIT_CHECK( 2 );  /* AnchorPoint */
00270       break;
00271 
00272     case 3:
00273       {
00274         FT_UInt   table_size;
00275 
00276         OTV_OPTIONAL_TABLE( XDeviceTable );
00277         OTV_OPTIONAL_TABLE( YDeviceTable );
00278 
00279 
00280         OTV_LIMIT_CHECK( 4 );
00281         OTV_OPTIONAL_OFFSET( XDeviceTable );
00282         OTV_OPTIONAL_OFFSET( YDeviceTable );
00283 
00284         table_size = 6 + 4;
00285 
00286         OTV_SIZE_CHECK( XDeviceTable );
00287         if ( XDeviceTable )
00288           otv_Device_validate( table + XDeviceTable, valid );
00289 
00290         OTV_SIZE_CHECK( YDeviceTable );
00291         if ( YDeviceTable )
00292           otv_Device_validate( table + YDeviceTable, valid );
00293       }
00294       break;
00295 
00296     default:
00297       FT_INVALID_FORMAT;
00298     }
00299 
00300     OTV_EXIT;
00301   }
00302 
00303 
00304   /*************************************************************************/
00305   /*************************************************************************/
00306   /*****                                                               *****/
00307   /*****                         MARK ARRAYS                           *****/
00308   /*****                                                               *****/
00309   /*************************************************************************/
00310   /*************************************************************************/
00311 
00312   static void
00313   otv_MarkArray_validate( FT_Bytes       table,
00314                           OTV_Validator  valid )
00315   {
00316     FT_Bytes  p = table;
00317     FT_UInt   MarkCount;
00318 
00319 
00320     OTV_NAME_ENTER( "MarkArray" );
00321 
00322     OTV_LIMIT_CHECK( 2 );
00323     MarkCount = FT_NEXT_USHORT( p );
00324 
00325     OTV_TRACE(( " (MarkCount = %d)\n", MarkCount ));
00326 
00327     OTV_LIMIT_CHECK( MarkCount * 4 );
00328 
00329     /* MarkRecord */
00330     for ( ; MarkCount > 0; MarkCount-- )
00331     {
00332       p += 2;   /* skip Class */
00333       /* MarkAnchor */
00334       otv_Anchor_validate( table + FT_NEXT_USHORT( p ), valid );
00335     }
00336 
00337     OTV_EXIT;
00338   }
00339 
00340 
00341   /*************************************************************************/
00342   /*************************************************************************/
00343   /*****                                                               *****/
00344   /*****                     GPOS LOOKUP TYPE 1                        *****/
00345   /*****                                                               *****/
00346   /*************************************************************************/
00347   /*************************************************************************/
00348 
00349   /* sets valid->extra3 (pointer to base table) */
00350 
00351   static void
00352   otv_SinglePos_validate( FT_Bytes       table,
00353                           OTV_Validator  valid )
00354   {
00355     FT_Bytes  p = table;
00356     FT_UInt   PosFormat;
00357 
00358 
00359     OTV_NAME_ENTER( "SinglePos" );
00360 
00361     OTV_LIMIT_CHECK( 2 );
00362     PosFormat = FT_NEXT_USHORT( p );
00363 
00364     OTV_TRACE(( " (format %d)\n", PosFormat ));
00365 
00366     valid->extra3 = table;
00367 
00368     switch ( PosFormat )
00369     {
00370     case 1:     /* SinglePosFormat1 */
00371       {
00372         FT_UInt  Coverage, ValueFormat;
00373 
00374 
00375         OTV_LIMIT_CHECK( 4 );
00376         Coverage    = FT_NEXT_USHORT( p );
00377         ValueFormat = FT_NEXT_USHORT( p );
00378 
00379         otv_Coverage_validate( table + Coverage, valid, -1 );
00380         otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */
00381       }
00382       break;
00383 
00384     case 2:     /* SinglePosFormat2 */
00385       {
00386         FT_UInt  Coverage, ValueFormat, ValueCount, len_value;
00387 
00388 
00389         OTV_LIMIT_CHECK( 6 );
00390         Coverage    = FT_NEXT_USHORT( p );
00391         ValueFormat = FT_NEXT_USHORT( p );
00392         ValueCount  = FT_NEXT_USHORT( p );
00393 
00394         OTV_TRACE(( " (ValueCount = %d)\n", ValueCount ));
00395 
00396         len_value = otv_value_length( ValueFormat );
00397 
00398         otv_Coverage_validate( table + Coverage, valid, ValueCount );
00399 
00400         OTV_LIMIT_CHECK( ValueCount * len_value );
00401 
00402         /* Value */
00403         for ( ; ValueCount > 0; ValueCount-- )
00404         {
00405           otv_ValueRecord_validate( p, ValueFormat, valid );
00406           p += len_value;
00407         }
00408       }
00409       break;
00410 
00411     default:
00412       FT_INVALID_FORMAT;
00413     }
00414 
00415     OTV_EXIT;
00416   }
00417 
00418 
00419   /*************************************************************************/
00420   /*************************************************************************/
00421   /*****                                                               *****/
00422   /*****                     GPOS LOOKUP TYPE 2                        *****/
00423   /*****                                                               *****/
00424   /*************************************************************************/
00425   /*************************************************************************/
00426 
00427   static void
00428   otv_PairSet_validate( FT_Bytes       table,
00429                         FT_UInt        format1,
00430                         FT_UInt        format2,
00431                         OTV_Validator  valid )
00432   {
00433     FT_Bytes  p = table;
00434     FT_UInt   value_len1, value_len2, PairValueCount;
00435 
00436 
00437     OTV_NAME_ENTER( "PairSet" );
00438 
00439     OTV_LIMIT_CHECK( 2 );
00440     PairValueCount = FT_NEXT_USHORT( p );
00441 
00442     OTV_TRACE(( " (PairValueCount = %d)\n", PairValueCount ));
00443 
00444     value_len1 = otv_value_length( format1 );
00445     value_len2 = otv_value_length( format2 );
00446 
00447     OTV_LIMIT_CHECK( PairValueCount * ( value_len1 + value_len2 + 2 ) );
00448 
00449     /* PairValueRecord */
00450     for ( ; PairValueCount > 0; PairValueCount-- )
00451     {
00452       p += 2;       /* skip SecondGlyph */
00453 
00454       if ( format1 )
00455         otv_ValueRecord_validate( p, format1, valid ); /* Value1 */
00456       p += value_len1;
00457 
00458       if ( format2 )
00459         otv_ValueRecord_validate( p, format2, valid ); /* Value2 */
00460       p += value_len2;
00461     }
00462 
00463     OTV_EXIT;
00464   }
00465 
00466 
00467   /* sets valid->extra3 (pointer to base table) */
00468 
00469   static void
00470   otv_PairPos_validate( FT_Bytes       table,
00471                         OTV_Validator  valid )
00472   {
00473     FT_Bytes  p = table;
00474     FT_UInt   PosFormat;
00475 
00476 
00477     OTV_NAME_ENTER( "PairPos" );
00478 
00479     OTV_LIMIT_CHECK( 2 );
00480     PosFormat = FT_NEXT_USHORT( p );
00481 
00482     OTV_TRACE(( " (format %d)\n", PosFormat ));
00483 
00484     valid->extra3 = table;
00485 
00486     switch ( PosFormat )
00487     {
00488     case 1:     /* PairPosFormat1 */
00489       {
00490         FT_UInt  Coverage, ValueFormat1, ValueFormat2, PairSetCount;
00491 
00492 
00493         OTV_LIMIT_CHECK( 8 );
00494         Coverage     = FT_NEXT_USHORT( p );
00495         ValueFormat1 = FT_NEXT_USHORT( p );
00496         ValueFormat2 = FT_NEXT_USHORT( p );
00497         PairSetCount = FT_NEXT_USHORT( p );
00498 
00499         OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount ));
00500 
00501         otv_Coverage_validate( table + Coverage, valid, -1 );
00502 
00503         OTV_LIMIT_CHECK( PairSetCount * 2 );
00504 
00505         /* PairSetOffset */
00506         for ( ; PairSetCount > 0; PairSetCount-- )
00507           otv_PairSet_validate( table + FT_NEXT_USHORT( p ),
00508                                 ValueFormat1, ValueFormat2, valid );
00509       }
00510       break;
00511 
00512     case 2:     /* PairPosFormat2 */
00513       {
00514         FT_UInt  Coverage, ValueFormat1, ValueFormat2, ClassDef1, ClassDef2;
00515         FT_UInt  ClassCount1, ClassCount2, len_value1, len_value2, count;
00516 
00517 
00518         OTV_LIMIT_CHECK( 14 );
00519         Coverage     = FT_NEXT_USHORT( p );
00520         ValueFormat1 = FT_NEXT_USHORT( p );
00521         ValueFormat2 = FT_NEXT_USHORT( p );
00522         ClassDef1    = FT_NEXT_USHORT( p );
00523         ClassDef2    = FT_NEXT_USHORT( p );
00524         ClassCount1  = FT_NEXT_USHORT( p );
00525         ClassCount2  = FT_NEXT_USHORT( p );
00526 
00527         OTV_TRACE(( " (ClassCount1 = %d)\n", ClassCount1 ));
00528         OTV_TRACE(( " (ClassCount2 = %d)\n", ClassCount2 ));
00529 
00530         len_value1 = otv_value_length( ValueFormat1 );
00531         len_value2 = otv_value_length( ValueFormat2 );
00532 
00533         otv_Coverage_validate( table + Coverage, valid, -1 );
00534         otv_ClassDef_validate( table + ClassDef1, valid );
00535         otv_ClassDef_validate( table + ClassDef2, valid );
00536 
00537         OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 *
00538                      ( len_value1 + len_value2 ) );
00539 
00540         /* Class1Record */
00541         for ( ; ClassCount1 > 0; ClassCount1-- )
00542         {
00543           /* Class2Record */
00544           for ( count = ClassCount2; count > 0; count-- )
00545           {
00546             if ( ValueFormat1 )
00547               /* Value1 */
00548               otv_ValueRecord_validate( p, ValueFormat1, valid );
00549             p += len_value1;
00550 
00551             if ( ValueFormat2 )
00552               /* Value2 */
00553               otv_ValueRecord_validate( p, ValueFormat2, valid );
00554             p += len_value2;
00555           }
00556         }
00557       }
00558       break;
00559 
00560     default:
00561       FT_INVALID_FORMAT;
00562     }
00563 
00564     OTV_EXIT;
00565   }
00566 
00567 
00568   /*************************************************************************/
00569   /*************************************************************************/
00570   /*****                                                               *****/
00571   /*****                     GPOS LOOKUP TYPE 3                        *****/
00572   /*****                                                               *****/
00573   /*************************************************************************/
00574   /*************************************************************************/
00575 
00576   static void
00577   otv_CursivePos_validate( FT_Bytes       table,
00578                            OTV_Validator  valid )
00579   {
00580     FT_Bytes  p = table;
00581     FT_UInt   PosFormat;
00582 
00583 
00584     OTV_NAME_ENTER( "CursivePos" );
00585 
00586     OTV_LIMIT_CHECK( 2 );
00587     PosFormat = FT_NEXT_USHORT( p );
00588 
00589     OTV_TRACE(( " (format %d)\n", PosFormat ));
00590 
00591     switch ( PosFormat )
00592     {
00593     case 1:     /* CursivePosFormat1 */
00594       {
00595         FT_UInt   table_size;
00596         FT_UInt   Coverage, EntryExitCount;
00597 
00598         OTV_OPTIONAL_TABLE( EntryAnchor );
00599         OTV_OPTIONAL_TABLE( ExitAnchor  );
00600 
00601 
00602         OTV_LIMIT_CHECK( 4 );
00603         Coverage       = FT_NEXT_USHORT( p );
00604         EntryExitCount = FT_NEXT_USHORT( p );
00605 
00606         OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount ));
00607 
00608         otv_Coverage_validate( table + Coverage, valid, EntryExitCount );
00609 
00610         OTV_LIMIT_CHECK( EntryExitCount * 4 );
00611 
00612         table_size = EntryExitCount * 4 + 4;
00613 
00614         /* EntryExitRecord */
00615         for ( ; EntryExitCount > 0; EntryExitCount-- )
00616         {
00617           OTV_OPTIONAL_OFFSET( EntryAnchor );
00618           OTV_OPTIONAL_OFFSET( ExitAnchor  );
00619 
00620           OTV_SIZE_CHECK( EntryAnchor );
00621           if ( EntryAnchor )
00622             otv_Anchor_validate( table + EntryAnchor, valid );
00623 
00624           OTV_SIZE_CHECK( ExitAnchor );
00625           if ( ExitAnchor )
00626             otv_Anchor_validate( table + ExitAnchor, valid );
00627         }
00628       }
00629       break;
00630 
00631     default:
00632       FT_INVALID_FORMAT;
00633     }
00634 
00635     OTV_EXIT;
00636   }
00637 
00638 
00639   /*************************************************************************/
00640   /*************************************************************************/
00641   /*****                                                               *****/
00642   /*****                     GPOS LOOKUP TYPE 4                        *****/
00643   /*****                                                               *****/
00644   /*************************************************************************/
00645   /*************************************************************************/
00646 
00647   /* UNDOCUMENTED (in OpenType 1.5):              */
00648   /* BaseRecord tables can contain NULL pointers. */
00649 
00650   /* sets valid->extra2 (1) */
00651 
00652   static void
00653   otv_MarkBasePos_validate( FT_Bytes       table,
00654                             OTV_Validator  valid )
00655   {
00656     FT_Bytes  p = table;
00657     FT_UInt   PosFormat;
00658 
00659 
00660     OTV_NAME_ENTER( "MarkBasePos" );
00661 
00662     OTV_LIMIT_CHECK( 2 );
00663     PosFormat = FT_NEXT_USHORT( p );
00664 
00665     OTV_TRACE(( " (format %d)\n", PosFormat ));
00666 
00667     switch ( PosFormat )
00668     {
00669     case 1:
00670       valid->extra2 = 1;
00671       OTV_NEST2( MarkBasePosFormat1, BaseArray );
00672       OTV_RUN( table, valid );
00673       break;
00674 
00675     default:
00676       FT_INVALID_FORMAT;
00677     }
00678 
00679     OTV_EXIT;
00680   }
00681 
00682 
00683   /*************************************************************************/
00684   /*************************************************************************/
00685   /*****                                                               *****/
00686   /*****                     GPOS LOOKUP TYPE 5                        *****/
00687   /*****                                                               *****/
00688   /*************************************************************************/
00689   /*************************************************************************/
00690 
00691   /* sets valid->extra2 (1) */
00692 
00693   static void
00694   otv_MarkLigPos_validate( FT_Bytes       table,
00695                            OTV_Validator  valid )
00696   {
00697     FT_Bytes  p = table;
00698     FT_UInt   PosFormat;
00699 
00700 
00701     OTV_NAME_ENTER( "MarkLigPos" );
00702 
00703     OTV_LIMIT_CHECK( 2 );
00704     PosFormat = FT_NEXT_USHORT( p );
00705 
00706     OTV_TRACE(( " (format %d)\n", PosFormat ));
00707 
00708     switch ( PosFormat )
00709     {
00710     case 1:
00711       valid->extra2 = 1;
00712       OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach );
00713       OTV_RUN( table, valid );
00714       break;
00715 
00716     default:
00717       FT_INVALID_FORMAT;
00718     }
00719 
00720     OTV_EXIT;
00721   }
00722 
00723 
00724   /*************************************************************************/
00725   /*************************************************************************/
00726   /*****                                                               *****/
00727   /*****                     GPOS LOOKUP TYPE 6                        *****/
00728   /*****                                                               *****/
00729   /*************************************************************************/
00730   /*************************************************************************/
00731 
00732   /* sets valid->extra2 (0) */
00733 
00734   static void
00735   otv_MarkMarkPos_validate( FT_Bytes       table,
00736                             OTV_Validator  valid )
00737   {
00738     FT_Bytes  p = table;
00739     FT_UInt   PosFormat;
00740 
00741 
00742     OTV_NAME_ENTER( "MarkMarkPos" );
00743 
00744     OTV_LIMIT_CHECK( 2 );
00745     PosFormat = FT_NEXT_USHORT( p );
00746 
00747     OTV_TRACE(( " (format %d)\n", PosFormat ));
00748 
00749     switch ( PosFormat )
00750     {
00751     case 1:
00752       valid->extra2 = 0;
00753       OTV_NEST2( MarkMarkPosFormat1, Mark2Array );
00754       OTV_RUN( table, valid );
00755       break;
00756 
00757     default:
00758       FT_INVALID_FORMAT;
00759     }
00760 
00761     OTV_EXIT;
00762   }
00763 
00764 
00765   /*************************************************************************/
00766   /*************************************************************************/
00767   /*****                                                               *****/
00768   /*****                     GPOS LOOKUP TYPE 7                        *****/
00769   /*****                                                               *****/
00770   /*************************************************************************/
00771   /*************************************************************************/
00772 
00773   /* sets valid->extra1 (lookup count) */
00774 
00775   static void
00776   otv_ContextPos_validate( FT_Bytes       table,
00777                            OTV_Validator  valid )
00778   {
00779     FT_Bytes  p = table;
00780     FT_UInt   PosFormat;
00781 
00782 
00783     OTV_NAME_ENTER( "ContextPos" );
00784 
00785     OTV_LIMIT_CHECK( 2 );
00786     PosFormat = FT_NEXT_USHORT( p );
00787 
00788     OTV_TRACE(( " (format %d)\n", PosFormat ));
00789 
00790     switch ( PosFormat )
00791     {
00792     case 1:
00793       /* no need to check glyph indices/classes used as input for these */
00794       /* context rules since even invalid glyph indices/classes return  */
00795       /* meaningful results                                             */
00796 
00797       valid->extra1 = valid->lookup_count;
00798       OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule );
00799       OTV_RUN( table, valid );
00800       break;
00801 
00802     case 2:
00803       /* no need to check glyph indices/classes used as input for these */
00804       /* context rules since even invalid glyph indices/classes return  */
00805       /* meaningful results                                             */
00806 
00807       OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule );
00808       OTV_RUN( table, valid );
00809       break;
00810 
00811     case 3:
00812       OTV_NEST1( ContextPosFormat3 );
00813       OTV_RUN( table, valid );
00814       break;
00815 
00816     default:
00817       FT_INVALID_FORMAT;
00818     }
00819 
00820     OTV_EXIT;
00821   }
00822 
00823 
00824   /*************************************************************************/
00825   /*************************************************************************/
00826   /*****                                                               *****/
00827   /*****                     GPOS LOOKUP TYPE 8                        *****/
00828   /*****                                                               *****/
00829   /*************************************************************************/
00830   /*************************************************************************/
00831 
00832   /* sets valid->extra1 (lookup count) */
00833 
00834   static void
00835   otv_ChainContextPos_validate( FT_Bytes       table,
00836                                 OTV_Validator  valid )
00837   {
00838     FT_Bytes  p = table;
00839     FT_UInt   PosFormat;
00840 
00841 
00842     OTV_NAME_ENTER( "ChainContextPos" );
00843 
00844     OTV_LIMIT_CHECK( 2 );
00845     PosFormat = FT_NEXT_USHORT( p );
00846 
00847     OTV_TRACE(( " (format %d)\n", PosFormat ));
00848 
00849     switch ( PosFormat )
00850     {
00851     case 1:
00852       /* no need to check glyph indices/classes used as input for these */
00853       /* context rules since even invalid glyph indices/classes return  */
00854       /* meaningful results                                             */
00855 
00856       valid->extra1 = valid->lookup_count;
00857       OTV_NEST3( ChainContextPosFormat1,
00858                  ChainPosRuleSet, ChainPosRule );
00859       OTV_RUN( table, valid );
00860       break;
00861 
00862     case 2:
00863       /* no need to check glyph indices/classes used as input for these */
00864       /* context rules since even invalid glyph indices/classes return  */
00865       /* meaningful results                                             */
00866 
00867       OTV_NEST3( ChainContextPosFormat2,
00868                  ChainPosClassSet, ChainPosClassRule );
00869       OTV_RUN( table, valid );
00870       break;
00871 
00872     case 3:
00873       OTV_NEST1( ChainContextPosFormat3 );
00874       OTV_RUN( table, valid );
00875       break;
00876 
00877     default:
00878       FT_INVALID_FORMAT;
00879     }
00880 
00881     OTV_EXIT;
00882   }
00883 
00884 
00885   /*************************************************************************/
00886   /*************************************************************************/
00887   /*****                                                               *****/
00888   /*****                     GPOS LOOKUP TYPE 9                        *****/
00889   /*****                                                               *****/
00890   /*************************************************************************/
00891   /*************************************************************************/
00892 
00893   /* uses valid->type_funcs */
00894 
00895   static void
00896   otv_ExtensionPos_validate( FT_Bytes       table,
00897                              OTV_Validator  valid )
00898   {
00899     FT_Bytes  p = table;
00900     FT_UInt   PosFormat;
00901 
00902 
00903     OTV_NAME_ENTER( "ExtensionPos" );
00904 
00905     OTV_LIMIT_CHECK( 2 );
00906     PosFormat = FT_NEXT_USHORT( p );
00907 
00908     OTV_TRACE(( " (format %d)\n", PosFormat ));
00909 
00910     switch ( PosFormat )
00911     {
00912     case 1:     /* ExtensionPosFormat1 */
00913       {
00914         FT_UInt            ExtensionLookupType;
00915         FT_ULong           ExtensionOffset;
00916         OTV_Validate_Func  validate;
00917 
00918 
00919         OTV_LIMIT_CHECK( 6 );
00920         ExtensionLookupType = FT_NEXT_USHORT( p );
00921         ExtensionOffset     = FT_NEXT_ULONG( p );
00922 
00923         if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 )
00924           FT_INVALID_DATA;
00925 
00926         validate = valid->type_funcs[ExtensionLookupType - 1];
00927         validate( table + ExtensionOffset, valid );
00928       }
00929       break;
00930 
00931     default:
00932       FT_INVALID_FORMAT;
00933     }
00934 
00935     OTV_EXIT;
00936   }
00937 
00938 
00939   static const OTV_Validate_Func  otv_gpos_validate_funcs[9] =
00940   {
00941     otv_SinglePos_validate,
00942     otv_PairPos_validate,
00943     otv_CursivePos_validate,
00944     otv_MarkBasePos_validate,
00945     otv_MarkLigPos_validate,
00946     otv_MarkMarkPos_validate,
00947     otv_ContextPos_validate,
00948     otv_ChainContextPos_validate,
00949     otv_ExtensionPos_validate
00950   };
00951 
00952 
00953   /* sets valid->type_count */
00954   /* sets valid->type_funcs */
00955 
00956   FT_LOCAL_DEF( void )
00957   otv_GPOS_subtable_validate( FT_Bytes       table,
00958                               OTV_Validator  valid )
00959   {
00960     valid->type_count = 9;
00961     valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs;
00962 
00963     otv_Lookup_validate( table, valid );
00964   }
00965 
00966 
00967   /*************************************************************************/
00968   /*************************************************************************/
00969   /*****                                                               *****/
00970   /*****                          GPOS TABLE                           *****/
00971   /*****                                                               *****/
00972   /*************************************************************************/
00973   /*************************************************************************/
00974 
00975   /* sets valid->glyph_count */
00976 
00977   FT_LOCAL_DEF( void )
00978   otv_GPOS_validate( FT_Bytes      table,
00979                      FT_UInt       glyph_count,
00980                      FT_Validator  ftvalid )
00981   {
00982     OTV_ValidatorRec  validrec;
00983     OTV_Validator     valid = &validrec;
00984     FT_Bytes          p     = table;
00985     FT_UInt           ScriptList, FeatureList, LookupList;
00986 
00987 
00988     valid->root = ftvalid;
00989 
00990     FT_TRACE3(( "validating GPOS table\n" ));
00991     OTV_INIT;
00992 
00993     OTV_LIMIT_CHECK( 10 );
00994 
00995     if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
00996       FT_INVALID_FORMAT;
00997 
00998     ScriptList  = FT_NEXT_USHORT( p );
00999     FeatureList = FT_NEXT_USHORT( p );
01000     LookupList  = FT_NEXT_USHORT( p );
01001 
01002     valid->type_count  = 9;
01003     valid->type_funcs  = (OTV_Validate_Func*)otv_gpos_validate_funcs;
01004     valid->glyph_count = glyph_count;
01005 
01006     otv_LookupList_validate( table + LookupList,
01007                              valid );
01008     otv_FeatureList_validate( table + FeatureList, table + LookupList,
01009                               valid );
01010     otv_ScriptList_validate( table + ScriptList, table + FeatureList,
01011                              valid );
01012 
01013     FT_TRACE4(( "\n" ));
01014   }
01015 
01016 
01017 /* END */

Generated on Sat May 26 2012 04:32:45 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.