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

gxvjust.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  gxvjust.c                                                              */
00004 /*                                                                         */
00005 /*    TrueTypeGX/AAT just table validation (body).                         */
00006 /*                                                                         */
00007 /*  Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K.,       */
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 /*                                                                         */
00020 /* gxvalid is derived from both gxlayout module and otvalid module.        */
00021 /* Development of gxlayout is supported by the Information-technology      */
00022 /* Promotion Agency(IPA), Japan.                                           */
00023 /*                                                                         */
00024 /***************************************************************************/
00025 
00026 
00027 #include "gxvalid.h"
00028 #include "gxvcommn.h"
00029 
00030 #include FT_SFNT_NAMES_H
00031 
00032 
00033   /*************************************************************************/
00034   /*                                                                       */
00035   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00036   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00037   /* messages during execution.                                            */
00038   /*                                                                       */
00039 #undef  FT_COMPONENT
00040 #define FT_COMPONENT  trace_gxvjust
00041 
00042   /*
00043    * referred `just' table format specification:
00044    * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6just.html
00045    * last updated 2000.
00046    * ----------------------------------------------
00047    * [JUST HEADER]: GXV_JUST_HEADER_SIZE
00048    * version     (fixed:  32bit) = 0x00010000
00049    * format      (uint16: 16bit) = 0 is only defined (2000)
00050    * horizOffset (uint16: 16bit)
00051    * vertOffset  (uint16: 16bit)
00052    * ----------------------------------------------
00053    */
00054 
00055   typedef struct  GXV_just_DataRec_
00056   {
00057     FT_UShort  wdc_offset_max;
00058     FT_UShort  wdc_offset_min;
00059     FT_UShort  pc_offset_max;
00060     FT_UShort  pc_offset_min;
00061 
00062   } GXV_just_DataRec, *GXV_just_Data;
00063 
00064 
00065 #define  GXV_JUST_DATA( a )  GXV_TABLE_DATA( just, a )
00066 
00067 
00068   static void
00069   gxv_just_wdp_entry_validate( FT_Bytes       table,
00070                                FT_Bytes       limit,
00071                                GXV_Validator  valid )
00072   {
00073     FT_Bytes   p = table;
00074     FT_ULong   justClass;
00075     FT_Fixed   beforeGrowLimit;
00076     FT_Fixed   beforeShrinkGrowLimit;
00077     FT_Fixed   afterGrowLimit;
00078     FT_Fixed   afterShrinkGrowLimit;
00079     FT_UShort  growFlags;
00080     FT_UShort  shrinkFlags;
00081 
00082 
00083     GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 );
00084     justClass             = FT_NEXT_ULONG( p );
00085     beforeGrowLimit       = FT_NEXT_ULONG( p );
00086     beforeShrinkGrowLimit = FT_NEXT_ULONG( p );
00087     afterGrowLimit        = FT_NEXT_ULONG( p );
00088     afterShrinkGrowLimit  = FT_NEXT_ULONG( p );
00089     growFlags             = FT_NEXT_USHORT( p );
00090     shrinkFlags           = FT_NEXT_USHORT( p );
00091 
00092     /* TODO: decode flags for human readability */
00093 
00094     valid->subtable_length = p - table;
00095   }
00096 
00097 
00098   static void
00099   gxv_just_wdc_entry_validate( FT_Bytes       table,
00100                                FT_Bytes       limit,
00101                                GXV_Validator  valid )
00102   {
00103     FT_Bytes  p = table;
00104     FT_ULong  count, i;
00105 
00106 
00107     GXV_LIMIT_CHECK( 4 );
00108     count = FT_NEXT_ULONG( p );
00109     for ( i = 0; i < count; i++ )
00110     {
00111       GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count ));
00112       gxv_just_wdp_entry_validate( p, limit, valid );
00113       p += valid->subtable_length;
00114     }
00115 
00116     valid->subtable_length = p - table;
00117   }
00118 
00119 
00120   static void
00121   gxv_just_widthDeltaClusters_validate( FT_Bytes       table,
00122                                         FT_Bytes       limit,
00123                                         GXV_Validator  valid )
00124   {
00125     FT_Bytes  p         = table ;
00126     FT_Bytes  wdc_end   = table + GXV_JUST_DATA( wdc_offset_max );
00127     FT_UInt   i;
00128 
00129 
00130     GXV_NAME_ENTER( "just justDeltaClusters" );
00131 
00132     if ( limit <= wdc_end )
00133       FT_INVALID_OFFSET;
00134 
00135     for ( i = 0; p <= wdc_end; i++ )
00136     {
00137       gxv_just_wdc_entry_validate( p, limit, valid );
00138       p += valid->subtable_length;
00139     }
00140 
00141     valid->subtable_length = p - table;
00142 
00143     GXV_EXIT;
00144   }
00145 
00146 
00147   static void
00148   gxv_just_actSubrecord_type0_validate( FT_Bytes       table,
00149                                         FT_Bytes       limit,
00150                                         GXV_Validator  valid )
00151   {
00152     FT_Bytes   p = table;
00153 
00154     FT_Fixed   lowerLimit;
00155     FT_Fixed   upperLimit;
00156 
00157     FT_UShort  order;
00158     FT_UShort  decomposedCount;
00159 
00160     FT_UInt    i;
00161 
00162 
00163     GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
00164     lowerLimit      = FT_NEXT_ULONG( p );
00165     upperLimit      = FT_NEXT_ULONG( p );
00166     order           = FT_NEXT_USHORT( p );
00167     decomposedCount = FT_NEXT_USHORT( p );
00168 
00169     for ( i = 0; i < decomposedCount; i++ )
00170     {
00171       FT_UShort glyphs;
00172 
00173 
00174       GXV_LIMIT_CHECK( 2 );
00175       glyphs = FT_NEXT_USHORT( p );
00176     }
00177 
00178     valid->subtable_length = p - table;
00179   }
00180 
00181 
00182   static void
00183   gxv_just_actSubrecord_type1_validate( FT_Bytes       table,
00184                                         FT_Bytes       limit,
00185                                         GXV_Validator  valid )
00186   {
00187     FT_Bytes   p = table;
00188     FT_UShort  addGlyph;
00189 
00190 
00191     GXV_LIMIT_CHECK( 2 );
00192     addGlyph = FT_NEXT_USHORT( p );
00193 
00194     valid->subtable_length = p - table;
00195   }
00196 
00197 
00198   static void
00199   gxv_just_actSubrecord_type2_validate( FT_Bytes       table,
00200                                         FT_Bytes       limit,
00201                                         GXV_Validator  valid )
00202   {
00203     FT_Bytes   p = table;
00204     FT_Fixed   substThreshhold; /* Apple misspelled "Threshhold" */
00205     FT_UShort  addGlyph;
00206     FT_UShort  substGlyph;
00207 
00208 
00209     GXV_LIMIT_CHECK( 4 + 2 + 2 );
00210     substThreshhold = FT_NEXT_ULONG( p );
00211     addGlyph        = FT_NEXT_USHORT( p );
00212     substGlyph      = FT_NEXT_USHORT( p );
00213 
00214     valid->subtable_length = p - table;
00215   }
00216 
00217 
00218   static void
00219   gxv_just_actSubrecord_type4_validate( FT_Bytes       table,
00220                                         FT_Bytes       limit,
00221                                         GXV_Validator  valid )
00222   {
00223     FT_Bytes  p = table;
00224     FT_ULong  variantsAxis;
00225     FT_Fixed  minimumLimit;
00226     FT_Fixed  noStretchValue;
00227     FT_Fixed  maximumLimit;
00228 
00229 
00230     GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
00231     variantsAxis   = FT_NEXT_ULONG( p );
00232     minimumLimit   = FT_NEXT_ULONG( p );
00233     noStretchValue = FT_NEXT_ULONG( p );
00234     maximumLimit   = FT_NEXT_ULONG( p );
00235 
00236     valid->subtable_length = p - table;
00237   }
00238 
00239 
00240   static void
00241   gxv_just_actSubrecord_type5_validate( FT_Bytes       table,
00242                                         FT_Bytes       limit,
00243                                         GXV_Validator  valid )
00244   {
00245     FT_Bytes   p = table;
00246     FT_UShort  flags;
00247     FT_UShort  glyph;
00248 
00249 
00250     GXV_LIMIT_CHECK( 2 + 2 );
00251     flags = FT_NEXT_USHORT( p );
00252     glyph = FT_NEXT_USHORT( p );
00253 
00254     valid->subtable_length = p - table;
00255   }
00256 
00257 
00258   /* parse single actSubrecord */
00259   static void
00260   gxv_just_actSubrecord_validate( FT_Bytes       table,
00261                                   FT_Bytes       limit,
00262                                   GXV_Validator  valid )
00263   {
00264     FT_Bytes   p = table;
00265     FT_UShort  actionClass;
00266     FT_UShort  actionType;
00267     FT_ULong   actionLength;
00268 
00269 
00270     GXV_NAME_ENTER( "just actSubrecord" );
00271 
00272     GXV_LIMIT_CHECK( 2 + 2 + 4 );
00273     actionClass  = FT_NEXT_USHORT( p );
00274     actionType   = FT_NEXT_USHORT( p );
00275     actionLength = FT_NEXT_ULONG( p );
00276 
00277     if ( actionType == 0 )
00278       gxv_just_actSubrecord_type0_validate( p, limit, valid );
00279     else if ( actionType == 1 )
00280       gxv_just_actSubrecord_type1_validate( p, limit, valid );
00281     else if ( actionType == 2 )
00282       gxv_just_actSubrecord_type2_validate( p, limit, valid );
00283     else if ( actionType == 3 )
00284       ;                         /* Stretch glyph action: no actionData */
00285     else if ( actionType == 4 )
00286       gxv_just_actSubrecord_type4_validate( p, limit, valid );
00287     else if ( actionType == 5 )
00288       gxv_just_actSubrecord_type5_validate( p, limit, valid );
00289     else
00290       FT_INVALID_DATA;
00291 
00292     valid->subtable_length = actionLength;
00293 
00294     GXV_EXIT;
00295   }
00296 
00297 
00298   static void
00299   gxv_just_pcActionRecord_validate( FT_Bytes       table,
00300                                     FT_Bytes       limit,
00301                                     GXV_Validator  valid )
00302   {
00303     FT_Bytes  p = table;
00304     FT_ULong  actionCount;
00305     FT_ULong  i;
00306 
00307 
00308     GXV_LIMIT_CHECK( 4 );
00309     actionCount = FT_NEXT_ULONG( p );
00310     GXV_TRACE(( "actionCount = %d\n", actionCount ));
00311 
00312     for ( i = 0; i < actionCount; i++ )
00313     {
00314       gxv_just_actSubrecord_validate( p, limit, valid );
00315       p += valid->subtable_length;
00316     }
00317 
00318     valid->subtable_length = p - table;
00319 
00320     GXV_EXIT;
00321   }
00322 
00323 
00324   static void
00325   gxv_just_pcTable_LookupValue_entry_validate( FT_UShort            glyph,
00326                                                GXV_LookupValueCPtr  value_p,
00327                                                GXV_Validator        valid )
00328   {
00329     FT_UNUSED( glyph );
00330 
00331     if ( value_p->u > GXV_JUST_DATA( pc_offset_max ) )
00332       GXV_JUST_DATA( pc_offset_max ) = value_p->u;
00333     if ( value_p->u < GXV_JUST_DATA( pc_offset_max ) )
00334       GXV_JUST_DATA( pc_offset_min ) = value_p->u;
00335   }
00336 
00337 
00338   static void
00339   gxv_just_pcLookupTable_validate( FT_Bytes       table,
00340                                    FT_Bytes       limit,
00341                                    GXV_Validator  valid )
00342   {
00343     FT_Bytes p = table;
00344 
00345 
00346     GXV_NAME_ENTER( "just pcLookupTable" );
00347     GXV_JUST_DATA( pc_offset_max ) = 0x0000;
00348     GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU;
00349 
00350     valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
00351     valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate;
00352 
00353     gxv_LookupTable_validate( p, limit, valid );
00354 
00355     /* subtable_length is set by gxv_LookupTable_validate() */
00356 
00357     GXV_EXIT;
00358   }
00359 
00360 
00361   static void
00362   gxv_just_postcompTable_validate( FT_Bytes       table,
00363                                    FT_Bytes       limit,
00364                                    GXV_Validator  valid )
00365   {
00366     FT_Bytes  p = table;
00367 
00368 
00369     GXV_NAME_ENTER( "just postcompTable" );
00370 
00371     gxv_just_pcLookupTable_validate( p, limit, valid );
00372     p += valid->subtable_length;
00373 
00374     gxv_just_pcActionRecord_validate( p, limit, valid );
00375     p += valid->subtable_length;
00376 
00377     valid->subtable_length = p - table;
00378 
00379     GXV_EXIT;
00380   }
00381 
00382 
00383   static void
00384   gxv_just_classTable_entry_validate(
00385     FT_Byte                         state,
00386     FT_UShort                       flags,
00387     GXV_StateTable_GlyphOffsetCPtr  glyphOffset_p,
00388     FT_Bytes                        table,
00389     FT_Bytes                        limit,
00390     GXV_Validator                   valid )
00391   {
00392     FT_UShort  setMark;
00393     FT_UShort  dontAdvance;
00394     FT_UShort  markClass;
00395     FT_UShort  currentClass;
00396 
00397     FT_UNUSED( state );
00398     FT_UNUSED( glyphOffset_p );
00399     FT_UNUSED( table );
00400     FT_UNUSED( limit );
00401     FT_UNUSED( valid );
00402 
00403 
00404     setMark      = (FT_UShort)( ( flags >> 15 ) & 1    );
00405     dontAdvance  = (FT_UShort)( ( flags >> 14 ) & 1    );
00406     markClass    = (FT_UShort)( ( flags >> 7  ) & 0x7F );
00407     currentClass = (FT_UShort)(   flags         & 0x7F );
00408 
00409     /* TODO: validate markClass & currentClass */
00410   }
00411 
00412 
00413   static void
00414   gxv_just_justClassTable_validate ( FT_Bytes       table,
00415                                      FT_Bytes       limit,
00416                                      GXV_Validator  valid )
00417   {
00418     FT_Bytes   p = table;
00419     FT_UShort  length;
00420     FT_UShort  coverage;
00421     FT_ULong   subFeatureFlags;
00422 
00423 
00424     GXV_NAME_ENTER( "just justClassTable" );
00425 
00426     GXV_LIMIT_CHECK( 2 + 2 + 4 );
00427     length          = FT_NEXT_USHORT( p );
00428     coverage        = FT_NEXT_USHORT( p );
00429     subFeatureFlags = FT_NEXT_ULONG( p );
00430 
00431     GXV_TRACE(( "  justClassTable: coverage = 0x%04x (%s)",
00432                 coverage,
00433                 ( 0x4000 & coverage ) == 0 ? "ascending" : "descending" ));
00434 
00435     valid->statetable.optdata               = NULL;
00436     valid->statetable.optdata_load_func     = NULL;
00437     valid->statetable.subtable_setup_func   = NULL;
00438     valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE;
00439     valid->statetable.entry_validate_func   =
00440       gxv_just_classTable_entry_validate;
00441 
00442     gxv_StateTable_validate( p, table + length, valid );
00443 
00444     /* subtable_length is set by gxv_LookupTable_validate() */
00445 
00446     GXV_EXIT;
00447   }
00448 
00449 
00450   static void
00451   gxv_just_wdcTable_LookupValue_validate( FT_UShort            glyph,
00452                                           GXV_LookupValueCPtr  value_p,
00453                                           GXV_Validator        valid )
00454   {
00455     FT_UNUSED( glyph );
00456 
00457     if ( value_p->u > GXV_JUST_DATA( wdc_offset_max ) )
00458       GXV_JUST_DATA( wdc_offset_max ) = value_p->u;
00459     if ( value_p->u < GXV_JUST_DATA( wdc_offset_min ) )
00460       GXV_JUST_DATA( wdc_offset_min ) = value_p->u;
00461   }
00462 
00463 
00464   static void
00465   gxv_just_justData_lookuptable_validate( FT_Bytes       table,
00466                                           FT_Bytes       limit,
00467                                           GXV_Validator  valid )
00468   {
00469     FT_Bytes  p = table;
00470 
00471 
00472     GXV_JUST_DATA( wdc_offset_max ) = 0x0000;
00473     GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU;
00474 
00475     valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
00476     valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate;
00477 
00478     gxv_LookupTable_validate( p, limit, valid );
00479 
00480     /* subtable_length is set by gxv_LookupTable_validate() */
00481 
00482     GXV_EXIT;
00483   }
00484 
00485 
00486   /*
00487    * gxv_just_justData_validate() parses and validates horizData, vertData.
00488    */
00489   static void
00490   gxv_just_justData_validate( FT_Bytes       table,
00491                               FT_Bytes       limit,
00492                               GXV_Validator  valid )
00493   {
00494     /*
00495      * following 3 offsets are measured from the start of `just'
00496      * (which table points to), not justData
00497      */
00498     FT_UShort  justClassTableOffset;
00499     FT_UShort  wdcTableOffset;
00500     FT_UShort  pcTableOffset;
00501     FT_Bytes   p = table;
00502 
00503     GXV_ODTECT( 4, odtect );
00504 
00505 
00506     GXV_NAME_ENTER( "just justData" );
00507 
00508     GXV_ODTECT_INIT( odtect );
00509     GXV_LIMIT_CHECK( 2 + 2 + 2 );
00510     justClassTableOffset = FT_NEXT_USHORT( p );
00511     wdcTableOffset       = FT_NEXT_USHORT( p );
00512     pcTableOffset        = FT_NEXT_USHORT( p );
00513 
00514     GXV_TRACE(( " (justClassTableOffset = 0x%04x)\n", justClassTableOffset ));
00515     GXV_TRACE(( " (wdcTableOffset = 0x%04x)\n", wdcTableOffset ));
00516     GXV_TRACE(( " (pcTableOffset = 0x%04x)\n", pcTableOffset ));
00517 
00518     gxv_just_justData_lookuptable_validate( p, limit, valid );
00519     gxv_odtect_add_range( p, valid->subtable_length,
00520                           "just_LookupTable", odtect );
00521 
00522     if ( wdcTableOffset )
00523     {
00524       gxv_just_widthDeltaClusters_validate(
00525         valid->root->base + wdcTableOffset, limit, valid );
00526       gxv_odtect_add_range( valid->root->base + wdcTableOffset,
00527                             valid->subtable_length, "just_wdcTable", odtect );
00528     }
00529 
00530     if ( pcTableOffset )
00531     {
00532       gxv_just_postcompTable_validate( valid->root->base + pcTableOffset,
00533                                        limit, valid );
00534       gxv_odtect_add_range( valid->root->base + pcTableOffset,
00535                             valid->subtable_length, "just_pcTable", odtect );
00536     }
00537 
00538     if ( justClassTableOffset )
00539     {
00540       gxv_just_justClassTable_validate(
00541         valid->root->base + justClassTableOffset, limit, valid );
00542       gxv_odtect_add_range( valid->root->base + justClassTableOffset,
00543                             valid->subtable_length, "just_justClassTable",
00544                             odtect );
00545     }
00546 
00547     gxv_odtect_validate( odtect, valid );
00548 
00549     GXV_EXIT;
00550   }
00551 
00552 
00553   FT_LOCAL_DEF( void )
00554   gxv_just_validate( FT_Bytes      table,
00555                      FT_Face       face,
00556                      FT_Validator  ftvalid )
00557   {
00558     FT_Bytes           p     = table;
00559     FT_Bytes           limit = 0;
00560     FT_Offset          table_size;
00561 
00562     GXV_ValidatorRec   validrec;
00563     GXV_Validator      valid = &validrec;
00564     GXV_just_DataRec   justrec;
00565     GXV_just_Data      just = &justrec;
00566 
00567     FT_ULong           version;
00568     FT_UShort          format;
00569     FT_UShort          horizOffset;
00570     FT_UShort          vertOffset;
00571 
00572     GXV_ODTECT( 3, odtect );
00573 
00574 
00575     GXV_ODTECT_INIT( odtect );
00576 
00577     valid->root       = ftvalid;
00578     valid->table_data = just;
00579     valid->face       = face;
00580 
00581     FT_TRACE3(( "validating `just' table\n" ));
00582     GXV_INIT;
00583 
00584     limit      = valid->root->limit;
00585     table_size = limit - table;
00586 
00587     GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 );
00588     version     = FT_NEXT_ULONG( p );
00589     format      = FT_NEXT_USHORT( p );
00590     horizOffset = FT_NEXT_USHORT( p );
00591     vertOffset  = FT_NEXT_USHORT( p );
00592     gxv_odtect_add_range( table, p - table, "just header", odtect );
00593 
00594 
00595     /* Version 1.0 (always:2000) */
00596     GXV_TRACE(( " (version = 0x%08x)\n", version ));
00597     if ( version != 0x00010000UL )
00598       FT_INVALID_FORMAT;
00599 
00600     /* format 0 (always:2000) */
00601     GXV_TRACE(( " (format = 0x%04x)\n", format ));
00602     if ( format != 0x0000 )
00603         FT_INVALID_FORMAT;
00604 
00605     GXV_TRACE(( " (horizOffset = %d)\n", horizOffset  ));
00606     GXV_TRACE(( " (vertOffset = %d)\n", vertOffset  ));
00607 
00608 
00609     /* validate justData */
00610     if ( 0 < horizOffset )
00611     {
00612       gxv_just_justData_validate( table + horizOffset, limit, valid );
00613       gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
00614                             "horizJustData", odtect );
00615     }
00616 
00617     if ( 0 < vertOffset )
00618     {
00619       gxv_just_justData_validate( table + vertOffset, limit, valid );
00620       gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
00621                             "vertJustData", odtect );
00622     }
00623 
00624     gxv_odtect_validate( odtect, valid );
00625 
00626     FT_TRACE4(( "\n" ));
00627   }
00628 
00629 
00630 /* END */

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