PageRenderTime 14ms CodeModel.GetById 1ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/src/freetype/src/gxvalid/gxvmort1.c

https://bitbucket.org/cabalistic/ogredeps/
C | 259 lines | 163 code | 58 blank | 38 comment | 5 complexity | 09f0f8292d9cab813acc5c34292f28a7 MD5 | raw file
  1/***************************************************************************/
  2/*                                                                         */
  3/*  gxvmort1.c                                                             */
  4/*                                                                         */
  5/*    TrueTypeGX/AAT mort 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 "gxvmort.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_gxvmort
 39
 40
 41  typedef struct  GXV_mort_subtable_type1_StateOptRec_
 42  {
 43    FT_UShort  substitutionTable;
 44    FT_UShort  substitutionTable_length;
 45
 46  }  GXV_mort_subtable_type1_StateOptRec,
 47    *GXV_mort_subtable_type1_StateOptRecData;
 48
 49#define GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE \
 50          ( GXV_STATETABLE_HEADER_SIZE + 2 )
 51
 52
 53  static void
 54  gxv_mort_subtable_type1_substitutionTable_load( FT_Bytes       table,
 55                                                  FT_Bytes       limit,
 56                                                  GXV_Validator  valid )
 57  {
 58    FT_Bytes  p = table;
 59
 60    GXV_mort_subtable_type1_StateOptRecData  optdata =
 61      (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata;
 62
 63
 64    GXV_LIMIT_CHECK( 2 );
 65    optdata->substitutionTable = FT_NEXT_USHORT( p );
 66  }
 67
 68
 69  static void
 70  gxv_mort_subtable_type1_subtable_setup( FT_UShort      table_size,
 71                                          FT_UShort      classTable,
 72                                          FT_UShort      stateArray,
 73                                          FT_UShort      entryTable,
 74                                          FT_UShort*     classTable_length_p,
 75                                          FT_UShort*     stateArray_length_p,
 76                                          FT_UShort*     entryTable_length_p,
 77                                          GXV_Validator  valid )
 78  {
 79    FT_UShort  o[4];
 80    FT_UShort  *l[4];
 81    FT_UShort  buff[5];
 82
 83    GXV_mort_subtable_type1_StateOptRecData  optdata =
 84      (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata;
 85
 86
 87    o[0] = classTable;
 88    o[1] = stateArray;
 89    o[2] = entryTable;
 90    o[3] = optdata->substitutionTable;
 91    l[0] = classTable_length_p;
 92    l[1] = stateArray_length_p;
 93    l[2] = entryTable_length_p;
 94    l[3] = &( optdata->substitutionTable_length );
 95
 96    gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid );
 97  }
 98
 99
100  static void
101  gxv_mort_subtable_type1_offset_to_subst_validate(
102    FT_Short          wordOffset,
103    const FT_String*  tag,
104    FT_Byte           state,
105    GXV_Validator     valid )
106  {
107    FT_UShort  substTable;
108    FT_UShort  substTable_limit;
109
110    FT_UNUSED( tag );
111    FT_UNUSED( state );
112
113
114    substTable =
115      ((GXV_mort_subtable_type1_StateOptRec *)
116       (valid->statetable.optdata))->substitutionTable;
117    substTable_limit =
118      (FT_UShort)( substTable +
119                   ((GXV_mort_subtable_type1_StateOptRec *)
120                    (valid->statetable.optdata))->substitutionTable_length );
121
122    valid->min_gid = (FT_UShort)( ( substTable       - wordOffset * 2 ) / 2 );
123    valid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 );
124    valid->max_gid = (FT_UShort)( FT_MAX( valid->max_gid,
125                                          valid->face->num_glyphs ) );
126
127    /* XXX: check range? */
128
129    /* TODO: min_gid & max_gid comparison with ClassTable contents */
130  }
131
132
133  static void
134  gxv_mort_subtable_type1_entry_validate(
135    FT_Byte                         state,
136    FT_UShort                       flags,
137    GXV_StateTable_GlyphOffsetCPtr  glyphOffset_p,
138    FT_Bytes                        table,
139    FT_Bytes                        limit,
140    GXV_Validator                   valid )
141  {
142#ifdef GXV_LOAD_UNUSED_VARS
143    FT_UShort  setMark;
144    FT_UShort  dontAdvance;
145#endif
146    FT_UShort  reserved;
147    FT_Short   markOffset;
148    FT_Short   currentOffset;
149
150    FT_UNUSED( table );
151    FT_UNUSED( limit );
152
153
154#ifdef GXV_LOAD_UNUSED_VARS
155    setMark       = (FT_UShort)(   flags >> 15            );
156    dontAdvance   = (FT_UShort)( ( flags >> 14 ) & 1      );
157#endif
158    reserved      = (FT_Short)(    flags         & 0x3FFF );
159
160    markOffset    = (FT_Short)( glyphOffset_p->ul >> 16 );
161    currentOffset = (FT_Short)( glyphOffset_p->ul       );
162
163    if ( 0 < reserved )
164    {
165      GXV_TRACE(( " non-zero bits found in reserved range\n" ));
166      GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
167    }
168
169    gxv_mort_subtable_type1_offset_to_subst_validate( markOffset,
170                                                      "markOffset",
171                                                      state,
172                                                      valid );
173
174    gxv_mort_subtable_type1_offset_to_subst_validate( currentOffset,
175                                                      "currentOffset",
176                                                      state,
177                                                      valid );
178  }
179
180
181  static void
182  gxv_mort_subtable_type1_substTable_validate( FT_Bytes       table,
183                                               FT_Bytes       limit,
184                                               GXV_Validator  valid )
185  {
186    FT_Bytes   p = table;
187    FT_UShort  num_gids = (FT_UShort)(
188                 ((GXV_mort_subtable_type1_StateOptRec *)
189                  (valid->statetable.optdata))->substitutionTable_length / 2 );
190    FT_UShort  i;
191
192
193    GXV_NAME_ENTER( "validating contents of substitutionTable" );
194    for ( i = 0; i < num_gids ; i ++ )
195    {
196      FT_UShort  dst_gid;
197
198
199      GXV_LIMIT_CHECK( 2 );
200      dst_gid = FT_NEXT_USHORT( p );
201
202      if ( dst_gid >= 0xFFFFU )
203        continue;
204
205      if ( dst_gid < valid->min_gid || valid->max_gid < dst_gid )
206      {
207        GXV_TRACE(( "substTable include a strange gid[%d]=%d >"
208                    " out of define range (%d..%d)\n",
209                    i, dst_gid, valid->min_gid, valid->max_gid ));
210        GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
211      }
212    }
213
214    GXV_EXIT;
215  }
216
217
218  /*
219   * subtable for Contextual glyph substitution is a modified StateTable.
220   * In addition to classTable, stateArray, and entryTable, the field
221   * `substitutionTable' is added.
222   */
223  FT_LOCAL_DEF( void )
224  gxv_mort_subtable_type1_validate( FT_Bytes       table,
225                                    FT_Bytes       limit,
226                                    GXV_Validator  valid )
227  {
228    FT_Bytes  p = table;
229
230    GXV_mort_subtable_type1_StateOptRec  st_rec;
231
232
233    GXV_NAME_ENTER( "mort chain subtable type1 (Contextual Glyph Subst)" );
234
235    GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE );
236
237    valid->statetable.optdata =
238      &st_rec;
239    valid->statetable.optdata_load_func =
240      gxv_mort_subtable_type1_substitutionTable_load;
241    valid->statetable.subtable_setup_func =
242      gxv_mort_subtable_type1_subtable_setup;
243    valid->statetable.entry_glyphoffset_fmt =
244      GXV_GLYPHOFFSET_ULONG;
245    valid->statetable.entry_validate_func =
246
247      gxv_mort_subtable_type1_entry_validate;
248    gxv_StateTable_validate( p, limit, valid );
249
250    gxv_mort_subtable_type1_substTable_validate(
251      table + st_rec.substitutionTable,
252      table + st_rec.substitutionTable + st_rec.substitutionTable_length,
253      valid );
254
255    GXV_EXIT;
256  }
257
258
259/* END */