misc/libfreetype/src/gxvalid/gxvmorx1.c
branchwebgl
changeset 9521 8054d9d775fd
parent 9282 92af50454cf2
parent 9519 b8b5c82eb61b
child 9950 2759212a27de
equal deleted inserted replaced
9282:92af50454cf2 9521:8054d9d775fd
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  gxvmorx1.c                                                             */
       
     4 /*                                                                         */
       
     5 /*    TrueTypeGX/AAT morx table validation                                 */
       
     6 /*    body for type1 (Contextual Substitution) subtable.                   */
       
     7 /*                                                                         */
       
     8 /*  Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
       
     9 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
       
    10 /*                                                                         */
       
    11 /*  This file is part of the FreeType project, and may only be used,       */
       
    12 /*  modified, and distributed under the terms of the FreeType project      */
       
    13 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
       
    14 /*  this file you indicate that you have read the license and              */
       
    15 /*  understand and accept it fully.                                        */
       
    16 /*                                                                         */
       
    17 /***************************************************************************/
       
    18 
       
    19 /***************************************************************************/
       
    20 /*                                                                         */
       
    21 /* gxvalid is derived from both gxlayout module and otvalid module.        */
       
    22 /* Development of gxlayout is supported by the Information-technology      */
       
    23 /* Promotion Agency(IPA), Japan.                                           */
       
    24 /*                                                                         */
       
    25 /***************************************************************************/
       
    26 
       
    27 
       
    28 #include "gxvmorx.h"
       
    29 
       
    30 
       
    31   /*************************************************************************/
       
    32   /*                                                                       */
       
    33   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
       
    34   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
       
    35   /* messages during execution.                                            */
       
    36   /*                                                                       */
       
    37 #undef  FT_COMPONENT
       
    38 #define FT_COMPONENT  trace_gxvmorx
       
    39 
       
    40 
       
    41   typedef struct  GXV_morx_subtable_type1_StateOptRec_
       
    42   {
       
    43     FT_ULong   substitutionTable;
       
    44     FT_ULong   substitutionTable_length;
       
    45     FT_UShort  substitutionTable_num_lookupTables;
       
    46 
       
    47   }  GXV_morx_subtable_type1_StateOptRec,
       
    48     *GXV_morx_subtable_type1_StateOptRecData;
       
    49 
       
    50 
       
    51 #define GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE \
       
    52           ( GXV_STATETABLE_HEADER_SIZE + 2 )
       
    53 
       
    54 
       
    55   static void
       
    56   gxv_morx_subtable_type1_substitutionTable_load( FT_Bytes       table,
       
    57                                                   FT_Bytes       limit,
       
    58                                                   GXV_Validator  valid )
       
    59   {
       
    60     FT_Bytes  p = table;
       
    61 
       
    62     GXV_morx_subtable_type1_StateOptRecData  optdata =
       
    63       (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
       
    64 
       
    65 
       
    66     GXV_LIMIT_CHECK( 2 );
       
    67     optdata->substitutionTable = FT_NEXT_USHORT( p );
       
    68   }
       
    69 
       
    70 
       
    71   static void
       
    72   gxv_morx_subtable_type1_subtable_setup( FT_ULong       table_size,
       
    73                                           FT_ULong       classTable,
       
    74                                           FT_ULong       stateArray,
       
    75                                           FT_ULong       entryTable,
       
    76                                           FT_ULong*      classTable_length_p,
       
    77                                           FT_ULong*      stateArray_length_p,
       
    78                                           FT_ULong*      entryTable_length_p,
       
    79                                           GXV_Validator  valid )
       
    80   {
       
    81     FT_ULong  o[4];
       
    82     FT_ULong  *l[4];
       
    83     FT_ULong  buff[5];
       
    84 
       
    85     GXV_morx_subtable_type1_StateOptRecData  optdata =
       
    86       (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
       
    87 
       
    88 
       
    89     o[0] = classTable;
       
    90     o[1] = stateArray;
       
    91     o[2] = entryTable;
       
    92     o[3] = optdata->substitutionTable;
       
    93     l[0] = classTable_length_p;
       
    94     l[1] = stateArray_length_p;
       
    95     l[2] = entryTable_length_p;
       
    96     l[3] = &(optdata->substitutionTable_length);
       
    97 
       
    98     gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid );
       
    99   }
       
   100 
       
   101 
       
   102   static void
       
   103   gxv_morx_subtable_type1_entry_validate(
       
   104     FT_UShort                       state,
       
   105     FT_UShort                       flags,
       
   106     GXV_StateTable_GlyphOffsetCPtr  glyphOffset_p,
       
   107     FT_Bytes                        table,
       
   108     FT_Bytes                        limit,
       
   109     GXV_Validator                   valid )
       
   110   {
       
   111     FT_UShort  setMark;
       
   112     FT_UShort  dontAdvance;
       
   113     FT_UShort  reserved;
       
   114     FT_Short   markIndex;
       
   115     FT_Short   currentIndex;
       
   116 
       
   117     GXV_morx_subtable_type1_StateOptRecData  optdata =
       
   118       (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
       
   119 
       
   120     FT_UNUSED( state );
       
   121     FT_UNUSED( table );
       
   122     FT_UNUSED( limit );
       
   123 
       
   124 
       
   125     setMark      = (FT_UShort)( ( flags >> 15 ) & 1 );
       
   126     dontAdvance  = (FT_UShort)( ( flags >> 14 ) & 1 );
       
   127 
       
   128     reserved = (FT_UShort)( flags & 0x3FFF );
       
   129 
       
   130     markIndex    = (FT_Short)( glyphOffset_p->ul >> 16 );
       
   131     currentIndex = (FT_Short)( glyphOffset_p->ul       );
       
   132 
       
   133     GXV_TRACE(( " setMark=%01d dontAdvance=%01d\n",
       
   134                 setMark, dontAdvance ));
       
   135 
       
   136     if ( 0 < reserved )
       
   137     {
       
   138       GXV_TRACE(( " non-zero bits found in reserved range\n" ));
       
   139       if ( valid->root->level >= FT_VALIDATE_PARANOID )
       
   140         FT_INVALID_DATA;
       
   141     }
       
   142 
       
   143     GXV_TRACE(( "markIndex = %d, currentIndex = %d\n",
       
   144                 markIndex, currentIndex ));
       
   145 
       
   146     if ( optdata->substitutionTable_num_lookupTables < markIndex + 1 )
       
   147       optdata->substitutionTable_num_lookupTables =
       
   148         (FT_Short)( markIndex + 1 );
       
   149 
       
   150     if ( optdata->substitutionTable_num_lookupTables < currentIndex + 1 )
       
   151       optdata->substitutionTable_num_lookupTables =
       
   152         (FT_Short)( currentIndex + 1 );
       
   153   }
       
   154 
       
   155 
       
   156   static void
       
   157   gxv_morx_subtable_type1_LookupValue_validate( FT_UShort            glyph,
       
   158                                                 GXV_LookupValueCPtr  value_p,
       
   159                                                 GXV_Validator        valid )
       
   160   {
       
   161     FT_UNUSED( glyph ); /* for the non-debugging case */
       
   162 
       
   163     GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value_p->u ));
       
   164 
       
   165     if ( value_p->u > valid->face->num_glyphs )
       
   166       FT_INVALID_GLYPH_ID;
       
   167   }
       
   168 
       
   169 
       
   170   static GXV_LookupValueDesc
       
   171   gxv_morx_subtable_type1_LookupFmt4_transit(
       
   172     FT_UShort            relative_gindex,
       
   173     GXV_LookupValueCPtr  base_value_p,
       
   174     FT_Bytes             lookuptbl_limit,
       
   175     GXV_Validator        valid )
       
   176   {
       
   177     FT_Bytes             p;
       
   178     FT_Bytes             limit;
       
   179     FT_UShort            offset;
       
   180     GXV_LookupValueDesc  value;
       
   181 
       
   182     /* XXX: check range? */
       
   183     offset = (FT_UShort)( base_value_p->u +
       
   184                           relative_gindex * sizeof ( FT_UShort ) );
       
   185 
       
   186     p     = valid->lookuptbl_head + offset;
       
   187     limit = lookuptbl_limit;
       
   188 
       
   189     GXV_LIMIT_CHECK ( 2 );
       
   190     value.u = FT_NEXT_USHORT( p );
       
   191 
       
   192     return value;
       
   193   }
       
   194 
       
   195 
       
   196   /*
       
   197    * TODO: length should be limit?
       
   198    **/
       
   199   static void
       
   200   gxv_morx_subtable_type1_substitutionTable_validate( FT_Bytes       table,
       
   201                                                       FT_Bytes       limit,
       
   202                                                       GXV_Validator  valid )
       
   203   {
       
   204     FT_Bytes   p = table;
       
   205     FT_UShort  i;
       
   206 
       
   207     GXV_morx_subtable_type1_StateOptRecData  optdata =
       
   208       (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
       
   209 
       
   210 
       
   211     /* TODO: calculate offset/length for each lookupTables */
       
   212     valid->lookupval_sign   = GXV_LOOKUPVALUE_UNSIGNED;
       
   213     valid->lookupval_func   = gxv_morx_subtable_type1_LookupValue_validate;
       
   214     valid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit;
       
   215 
       
   216     for ( i = 0; i < optdata->substitutionTable_num_lookupTables; i++ )
       
   217     {
       
   218       FT_ULong  offset;
       
   219 
       
   220 
       
   221       GXV_LIMIT_CHECK( 4 );
       
   222       offset = FT_NEXT_ULONG( p );
       
   223 
       
   224       gxv_LookupTable_validate( table + offset, limit, valid );
       
   225     }
       
   226 
       
   227     /* TODO: overlapping of lookupTables in substitutionTable */
       
   228   }
       
   229 
       
   230 
       
   231   /*
       
   232    * subtable for Contextual glyph substitution is a modified StateTable.
       
   233    * In addition to classTable, stateArray, entryTable, the field
       
   234    * `substitutionTable' is added.
       
   235    */
       
   236   FT_LOCAL_DEF( void )
       
   237   gxv_morx_subtable_type1_validate( FT_Bytes       table,
       
   238                                     FT_Bytes       limit,
       
   239                                     GXV_Validator  valid )
       
   240   {
       
   241     FT_Bytes  p = table;
       
   242 
       
   243     GXV_morx_subtable_type1_StateOptRec  st_rec;
       
   244 
       
   245 
       
   246     GXV_NAME_ENTER( "morx chain subtable type1 (Contextual Glyph Subst)" );
       
   247 
       
   248     GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE );
       
   249 
       
   250     st_rec.substitutionTable_num_lookupTables = 0;
       
   251 
       
   252     valid->xstatetable.optdata =
       
   253       &st_rec;
       
   254     valid->xstatetable.optdata_load_func =
       
   255       gxv_morx_subtable_type1_substitutionTable_load;
       
   256     valid->xstatetable.subtable_setup_func =
       
   257       gxv_morx_subtable_type1_subtable_setup;
       
   258     valid->xstatetable.entry_glyphoffset_fmt =
       
   259       GXV_GLYPHOFFSET_ULONG;
       
   260     valid->xstatetable.entry_validate_func =
       
   261       gxv_morx_subtable_type1_entry_validate;
       
   262 
       
   263     gxv_XStateTable_validate( p, limit, valid );
       
   264 
       
   265     gxv_morx_subtable_type1_substitutionTable_validate(
       
   266       table + st_rec.substitutionTable,
       
   267       table + st_rec.substitutionTable + st_rec.substitutionTable_length,
       
   268       valid );
       
   269 
       
   270     GXV_EXIT;
       
   271   }
       
   272 
       
   273 
       
   274 /* END */