source: trunk/poppler/freetype2/src/gxvalid/gxvmort1.c @ 251

Last change on this file since 251 was 251, checked in by Eugene Romanenko, 13 years ago

PDF plugin: freetype library updated to version 2.3.5

File size: 9.2 KB
Line 
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    FT_UShort  min_gid;
110    FT_UShort  max_gid;
111
112    FT_UNUSED( tag );
113    FT_UNUSED( state );
114
115
116    substTable =
117      ((GXV_mort_subtable_type1_StateOptRec *)
118       (valid->statetable.optdata))->substitutionTable;
119    substTable_limit =
120      (FT_UShort)( substTable +
121                   ((GXV_mort_subtable_type1_StateOptRec *)
122                    (valid->statetable.optdata))->substitutionTable_length );
123
124    min_gid = (FT_UShort)( ( substTable       - wordOffset * 2 ) / 2 );
125    max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 );
126    max_gid = (FT_UShort)( FT_MAX( max_gid, valid->face->num_glyphs ) );
127
128    /* XXX: check range? */
129
130    /* TODO: min_gid & max_gid comparison with ClassTable contents */
131  }
132
133
134  static void
135  gxv_mort_subtable_type1_entry_validate(
136    FT_Byte                         state,
137    FT_UShort                       flags,
138    GXV_StateTable_GlyphOffsetDesc  glyphOffset,
139    FT_Bytes                        table,
140    FT_Bytes                        limit,
141    GXV_Validator                   valid )
142  {
143    FT_UShort  setMark;
144    FT_UShort  dontAdvance;
145    FT_UShort  reserved;
146    FT_Short   markOffset;
147    FT_Short   currentOffset;
148
149    FT_UNUSED( table );
150    FT_UNUSED( limit );
151
152
153    setMark       = (FT_UShort)(   flags >> 15            );
154    dontAdvance   = (FT_UShort)( ( flags >> 14 ) & 1      );
155    reserved      = (FT_Short)(    flags         & 0x3FFF );
156
157    markOffset    = (FT_Short)( glyphOffset.ul >> 16 );
158    currentOffset = (FT_Short)( glyphOffset.ul       );
159
160    if ( 0 < reserved )
161    {
162      GXV_TRACE(( " non-zero bits found in reserved range\n" ));
163      if ( valid->root->level >= FT_VALIDATE_PARANOID )
164        FT_INVALID_DATA;
165    }
166
167    gxv_mort_subtable_type1_offset_to_subst_validate( markOffset,
168                                                      "markOffset",
169                                                      state,
170                                                      valid );
171
172    gxv_mort_subtable_type1_offset_to_subst_validate( currentOffset,
173                                                      "currentOffset",
174                                                      state,
175                                                      valid );
176  }
177
178
179  static void
180  gxv_mort_subtable_type1_substTable_validate( FT_Bytes       table,
181                                               FT_Bytes       limit,
182                                               GXV_Validator  valid )
183  {
184    FT_Bytes   p = table;
185    FT_UShort  num_gids = (FT_UShort)(
186                 ((GXV_mort_subtable_type1_StateOptRec *)
187                  (valid->statetable.optdata))->substitutionTable_length / 2 );
188    FT_UShort  i;
189
190
191    GXV_NAME_ENTER( "validating contents of substitutionTable" );
192    for ( i = 0; i < num_gids ; i ++ )
193    {
194      FT_UShort  dst_gid;
195
196
197      GXV_LIMIT_CHECK( 2 );
198      dst_gid = FT_NEXT_USHORT( p );
199
200      if ( dst_gid >= 0xFFFFU )
201        continue;
202
203      if ( dst_gid > valid->face->num_glyphs )
204      {
205        GXV_TRACE(( "substTable include too large gid[%d]=%d >"
206                    " max defined gid #%d\n",
207                    i, dst_gid, valid->face->num_glyphs ));
208        if ( valid->root->level >= FT_VALIDATE_PARANOID )
209          FT_INVALID_GLYPH_ID;
210      }
211    }
212
213    GXV_EXIT;
214  }
215
216
217  /*
218   * subtable for Contextual glyph substitution is a modified StateTable.
219   * In addition to classTable, stateArray, and entryTable, the field
220   * `substitutionTable' is added.
221   */
222  FT_LOCAL_DEF( void )
223  gxv_mort_subtable_type1_validate( FT_Bytes       table,
224                                    FT_Bytes       limit,
225                                    GXV_Validator  valid )
226  {
227    FT_Bytes  p = table;
228
229    GXV_mort_subtable_type1_StateOptRec  st_rec;
230
231
232    GXV_NAME_ENTER( "mort chain subtable type1 (Contextual Glyph Subst)" );
233
234    GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE );
235
236    valid->statetable.optdata =
237      &st_rec;
238    valid->statetable.optdata_load_func =
239      gxv_mort_subtable_type1_substitutionTable_load;
240    valid->statetable.subtable_setup_func =
241      gxv_mort_subtable_type1_subtable_setup;
242    valid->statetable.entry_glyphoffset_fmt =
243      GXV_GLYPHOFFSET_ULONG;
244    valid->statetable.entry_validate_func =
245
246      gxv_mort_subtable_type1_entry_validate;
247    gxv_StateTable_validate( p, limit, valid );
248
249    gxv_mort_subtable_type1_substTable_validate(
250      table + st_rec.substitutionTable,
251      table + st_rec.substitutionTable + st_rec.substitutionTable_length,
252      valid );
253
254    GXV_EXIT;
255  }
256
257
258/* END */
Note: See TracBrowser for help on using the repository browser.