gxvmorx1.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  gxvmorx1.c                                                             */
00004 /*                                                                         */
00005 /*    TrueTypeGX/AAT morx table validation                                 */
00006 /*    body for type1 (Contextual Substitution) subtable.                   */
00007 /*                                                                         */
00008 /*  Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
00009 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00010 /*                                                                         */
00011 /*  This file is part of the FreeType project, and may only be used,       */
00012 /*  modified, and distributed under the terms of the FreeType project      */
00013 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00014 /*  this file you indicate that you have read the license and              */
00015 /*  understand and accept it fully.                                        */
00016 /*                                                                         */
00017 /***************************************************************************/
00018 
00019 /***************************************************************************/
00020 /*                                                                         */
00021 /* gxvalid is derived from both gxlayout module and otvalid module.        */
00022 /* Development of gxlayout is supported by the Information-technology      */
00023 /* Promotion Agency(IPA), Japan.                                           */
00024 /*                                                                         */
00025 /***************************************************************************/
00026 
00027 
00028 #include "gxvmorx.h"
00029 
00030 
00031   /*************************************************************************/
00032   /*                                                                       */
00033   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00034   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00035   /* messages during execution.                                            */
00036   /*                                                                       */
00037 #undef  FT_COMPONENT
00038 #define FT_COMPONENT  trace_gxvmorx
00039 
00040 
00041   typedef struct  GXV_morx_subtable_type1_StateOptRec_
00042   {
00043     FT_ULong   substitutionTable;
00044     FT_ULong   substitutionTable_length;
00045     FT_UShort  substitutionTable_num_lookupTables;
00046 
00047   }  GXV_morx_subtable_type1_StateOptRec,
00048     *GXV_morx_subtable_type1_StateOptRecData;
00049 
00050 
00051 #define GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE \
00052           ( GXV_STATETABLE_HEADER_SIZE + 2 )
00053 
00054 
00055   static void
00056   gxv_morx_subtable_type1_substitutionTable_load( FT_Bytes       table,
00057                                                   FT_Bytes       limit,
00058                                                   GXV_Validator  valid )
00059   {
00060     FT_Bytes  p = table;
00061 
00062     GXV_morx_subtable_type1_StateOptRecData  optdata =
00063       (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
00064 
00065 
00066     GXV_LIMIT_CHECK( 2 );
00067     optdata->substitutionTable = FT_NEXT_USHORT( p );
00068   }
00069 
00070 
00071   static void
00072   gxv_morx_subtable_type1_subtable_setup( FT_ULong       table_size,
00073                                           FT_ULong       classTable,
00074                                           FT_ULong       stateArray,
00075                                           FT_ULong       entryTable,
00076                                           FT_ULong*      classTable_length_p,
00077                                           FT_ULong*      stateArray_length_p,
00078                                           FT_ULong*      entryTable_length_p,
00079                                           GXV_Validator  valid )
00080   {
00081     FT_ULong  o[4];
00082     FT_ULong  *l[4];
00083     FT_ULong  buff[5];
00084 
00085     GXV_morx_subtable_type1_StateOptRecData  optdata =
00086       (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
00087 
00088 
00089     o[0] = classTable;
00090     o[1] = stateArray;
00091     o[2] = entryTable;
00092     o[3] = optdata->substitutionTable;
00093     l[0] = classTable_length_p;
00094     l[1] = stateArray_length_p;
00095     l[2] = entryTable_length_p;
00096     l[3] = &(optdata->substitutionTable_length);
00097 
00098     gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid );
00099   }
00100 
00101 
00102   static void
00103   gxv_morx_subtable_type1_entry_validate(
00104     FT_UShort                       state,
00105     FT_UShort                       flags,
00106     GXV_StateTable_GlyphOffsetCPtr  glyphOffset_p,
00107     FT_Bytes                        table,
00108     FT_Bytes                        limit,
00109     GXV_Validator                   valid )
00110   {
00111     FT_UShort  setMark;
00112     FT_UShort  dontAdvance;
00113     FT_UShort  reserved;
00114     FT_Short   markIndex;
00115     FT_Short   currentIndex;
00116 
00117     GXV_morx_subtable_type1_StateOptRecData  optdata =
00118       (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
00119 
00120     FT_UNUSED( state );
00121     FT_UNUSED( table );
00122     FT_UNUSED( limit );
00123 
00124 
00125     setMark      = (FT_UShort)( ( flags >> 15 ) & 1 );
00126     dontAdvance  = (FT_UShort)( ( flags >> 14 ) & 1 );
00127 
00128     reserved = (FT_UShort)( flags & 0x3FFF );
00129 
00130     markIndex    = (FT_Short)( glyphOffset_p->ul >> 16 );
00131     currentIndex = (FT_Short)( glyphOffset_p->ul       );
00132 
00133     GXV_TRACE(( " setMark=%01d dontAdvance=%01d\n",
00134                 setMark, dontAdvance ));
00135 
00136     if ( 0 < reserved )
00137     {
00138       GXV_TRACE(( " non-zero bits found in reserved range\n" ));
00139       if ( valid->root->level >= FT_VALIDATE_PARANOID )
00140         FT_INVALID_DATA;
00141     }
00142 
00143     GXV_TRACE(( "markIndex = %d, currentIndex = %d\n",
00144                 markIndex, currentIndex ));
00145 
00146     if ( optdata->substitutionTable_num_lookupTables < markIndex + 1 )
00147       optdata->substitutionTable_num_lookupTables =
00148         (FT_Short)( markIndex + 1 );
00149 
00150     if ( optdata->substitutionTable_num_lookupTables < currentIndex + 1 )
00151       optdata->substitutionTable_num_lookupTables =
00152         (FT_Short)( currentIndex + 1 );
00153   }
00154 
00155 
00156   static void
00157   gxv_morx_subtable_type1_LookupValue_validate( FT_UShort            glyph,
00158                                                 GXV_LookupValueCPtr  value_p,
00159                                                 GXV_Validator        valid )
00160   {
00161     FT_UNUSED( glyph ); /* for the non-debugging case */
00162 
00163     GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value_p->u ));
00164 
00165     if ( value_p->u > valid->face->num_glyphs )
00166       FT_INVALID_GLYPH_ID;
00167   }
00168 
00169 
00170   static GXV_LookupValueDesc
00171   gxv_morx_subtable_type1_LookupFmt4_transit(
00172     FT_UShort            relative_gindex,
00173     GXV_LookupValueCPtr  base_value_p,
00174     FT_Bytes             lookuptbl_limit,
00175     GXV_Validator        valid )
00176   {
00177     FT_Bytes             p;
00178     FT_Bytes             limit;
00179     FT_UShort            offset;
00180     GXV_LookupValueDesc  value;
00181 
00182     /* XXX: check range? */
00183     offset = (FT_UShort)( base_value_p->u +
00184                           relative_gindex * sizeof ( FT_UShort ) );
00185 
00186     p     = valid->lookuptbl_head + offset;
00187     limit = lookuptbl_limit;
00188 
00189     GXV_LIMIT_CHECK ( 2 );
00190     value.u = FT_NEXT_USHORT( p );
00191 
00192     return value;
00193   }
00194 
00195 
00196   /*
00197    * TODO: length should be limit?
00198    **/
00199   static void
00200   gxv_morx_subtable_type1_substitutionTable_validate( FT_Bytes       table,
00201                                                       FT_Bytes       limit,
00202                                                       GXV_Validator  valid )
00203   {
00204     FT_Bytes   p = table;
00205     FT_UShort  i;
00206 
00207     GXV_morx_subtable_type1_StateOptRecData  optdata =
00208       (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
00209 
00210 
00211     /* TODO: calculate offset/length for each lookupTables */
00212     valid->lookupval_sign   = GXV_LOOKUPVALUE_UNSIGNED;
00213     valid->lookupval_func   = gxv_morx_subtable_type1_LookupValue_validate;
00214     valid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit;
00215 
00216     for ( i = 0; i < optdata->substitutionTable_num_lookupTables; i++ )
00217     {
00218       FT_ULong  offset;
00219 
00220 
00221       GXV_LIMIT_CHECK( 4 );
00222       offset = FT_NEXT_ULONG( p );
00223 
00224       gxv_LookupTable_validate( table + offset, limit, valid );
00225     }
00226 
00227     /* TODO: overlapping of lookupTables in substitutionTable */
00228   }
00229 
00230 
00231   /*
00232    * subtable for Contextual glyph substitution is a modified StateTable.
00233    * In addition to classTable, stateArray, entryTable, the field
00234    * `substitutionTable' is added.
00235    */
00236   FT_LOCAL_DEF( void )
00237   gxv_morx_subtable_type1_validate( FT_Bytes       table,
00238                                     FT_Bytes       limit,
00239                                     GXV_Validator  valid )
00240   {
00241     FT_Bytes  p = table;
00242 
00243     GXV_morx_subtable_type1_StateOptRec  st_rec;
00244 
00245 
00246     GXV_NAME_ENTER( "morx chain subtable type1 (Contextual Glyph Subst)" );
00247 
00248     GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE );
00249 
00250     st_rec.substitutionTable_num_lookupTables = 0;
00251 
00252     valid->xstatetable.optdata =
00253       &st_rec;
00254     valid->xstatetable.optdata_load_func =
00255       gxv_morx_subtable_type1_substitutionTable_load;
00256     valid->xstatetable.subtable_setup_func =
00257       gxv_morx_subtable_type1_subtable_setup;
00258     valid->xstatetable.entry_glyphoffset_fmt =
00259       GXV_GLYPHOFFSET_ULONG;
00260     valid->xstatetable.entry_validate_func =
00261       gxv_morx_subtable_type1_entry_validate;
00262 
00263     gxv_XStateTable_validate( p, limit, valid );
00264 
00265     gxv_morx_subtable_type1_substitutionTable_validate(
00266       table + st_rec.substitutionTable,
00267       table + st_rec.substitutionTable + st_rec.substitutionTable_length,
00268       valid );
00269 
00270     GXV_EXIT;
00271   }
00272 
00273 
00274 /* END */

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