source: trunk/poppler/freetype-2.2.1/src/gxvalid/gxvmort2.c @ 150

Last change on this file since 150 was 150, checked in by Eugene Romanenko, 15 years ago

update freetype to 2.2.1

File size: 10.1 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  gxvmort2.c                                                             */
4/*                                                                         */
5/*    TrueTypeGX/AAT mort table validation                                 */
6/*    body for type2 (Ligature Substitution) subtable.                     */
7/*                                                                         */
8/*  Copyright 2005 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_type2_StateOptRec_
42  {
43    FT_UShort  ligActionTable;
44    FT_UShort  componentTable;
45    FT_UShort  ligatureTable;
46    FT_UShort  ligActionTable_length;
47    FT_UShort  componentTable_length;
48    FT_UShort  ligatureTable_length;
49
50  }  GXV_mort_subtable_type2_StateOptRec,
51    *GXV_mort_subtable_type2_StateOptRecData;
52
53#define GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE \
54          ( GXV_STATETABLE_HEADER_SIZE + 2 + 2 + 2 )
55
56
57  static void
58  gxv_mort_subtable_type2_opttable_load( FT_Bytes       table,
59                                         FT_Bytes       limit,
60                                         GXV_Validator  valid )
61  {
62    FT_Bytes p = table;
63    GXV_mort_subtable_type2_StateOptRecData  optdata =
64      (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata;
65
66
67    GXV_LIMIT_CHECK( 2 + 2 + 2 );
68    optdata->ligActionTable = FT_NEXT_USHORT( p );
69    optdata->componentTable = FT_NEXT_USHORT( p );
70    optdata->ligatureTable  = FT_NEXT_USHORT( p );
71
72    GXV_TRACE(( "offset to ligActionTable=0x%04x\n",
73                optdata->ligActionTable ));
74    GXV_TRACE(( "offset to componentTable=0x%04x\n",
75                optdata->componentTable ));
76    GXV_TRACE(( "offset to ligatureTable=0x%04x\n",
77                optdata->ligatureTable ));
78  }
79
80
81  static void
82  gxv_mort_subtable_type2_subtable_setup( FT_UShort      table_size,
83                                          FT_UShort      classTable,
84                                          FT_UShort      stateArray,
85                                          FT_UShort      entryTable,
86                                          FT_UShort      *classTable_length_p,
87                                          FT_UShort      *stateArray_length_p,
88                                          FT_UShort      *entryTable_length_p,
89                                          GXV_Validator  valid )
90  {
91    FT_UShort  o[6];
92    FT_UShort  *l[6];
93    FT_UShort  buff[7];
94
95    GXV_mort_subtable_type2_StateOptRecData  optdata =
96      (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata;
97
98
99    GXV_NAME_ENTER( "subtable boundaries setup" );
100
101    o[0] = classTable;
102    o[1] = stateArray;
103    o[2] = entryTable;
104    o[3] = optdata->ligActionTable;
105    o[4] = optdata->componentTable;
106    o[5] = optdata->ligatureTable;
107    l[0] = classTable_length_p;
108    l[1] = stateArray_length_p;
109    l[2] = entryTable_length_p;
110    l[3] = &(optdata->ligActionTable_length);
111    l[4] = &(optdata->componentTable_length);
112    l[5] = &(optdata->ligatureTable_length);
113
114    gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, valid );
115
116    GXV_TRACE(( "classTable: offset=0x%04x length=0x%04x\n",
117                classTable, *classTable_length_p ));
118    GXV_TRACE(( "stateArray: offset=0x%04x length=0x%04x\n",
119                stateArray, *stateArray_length_p ));
120    GXV_TRACE(( "entryTable: offset=0x%04x length=0x%04x\n",
121                entryTable, *entryTable_length_p ));
122    GXV_TRACE(( "ligActionTable: offset=0x%04x length=0x%04x\n",
123                optdata->ligActionTable,
124                optdata->ligActionTable_length ));
125    GXV_TRACE(( "componentTable: offset=0x%04x length=0x%04x\n",
126                optdata->componentTable,
127                optdata->componentTable_length ));
128    GXV_TRACE(( "ligatureTable:  offset=0x%04x length=0x%04x\n",
129                optdata->ligatureTable,
130                optdata->ligatureTable_length ));
131
132    GXV_EXIT;
133  }
134
135
136  static void
137  gxv_mort_subtable_type2_ligActionOffset_validate(
138    FT_Bytes       table,
139    FT_UShort      ligActionOffset,
140    GXV_Validator  valid )
141  {
142    /* access ligActionTable */
143    GXV_mort_subtable_type2_StateOptRecData  optdata =
144      (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata;
145
146    FT_Bytes lat_base  = table + optdata->ligActionTable;
147    FT_Bytes p         = table + ligActionOffset;
148    FT_Bytes lat_limit = lat_base + optdata->ligActionTable;
149
150
151    GXV_32BIT_ALIGNMENT_VALIDATE( ligActionOffset );
152    if ( p < lat_base )
153    {
154      GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%d byte rewind)\n",
155                  ligActionOffset, lat_base - p ));
156
157      /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
158      if ( valid->root->level >= FT_VALIDATE_PARANOID )
159        FT_INVALID_OFFSET;
160    }
161    else if ( lat_limit < p )
162    {
163      GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%d byte overrun)\n",
164                  ligActionOffset, p - lat_limit ));
165
166      /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
167      if ( valid->root->level >= FT_VALIDATE_PARANOID )
168        FT_INVALID_OFFSET;
169    }
170    else
171    {
172      /* validate entry in ligActionTable */
173      FT_ULong   lig_action;
174      FT_UShort  last;
175      FT_UShort  store;
176      FT_ULong   offset;
177
178
179      lig_action = FT_NEXT_ULONG( p );
180      last   = (FT_UShort)( ( lig_action >> 31 ) & 1 );
181      store  = (FT_UShort)( ( lig_action >> 30 ) & 1 );
182
183      offset = lig_action & 0x3FFFFFFFUL;
184    }
185  }
186
187
188  static void
189  gxv_mort_subtable_type2_entry_validate(
190    FT_Byte                         state,
191    FT_UShort                       flags,
192    GXV_StateTable_GlyphOffsetDesc  glyphOffset,
193    FT_Bytes                        table,
194    FT_Bytes                        limit,
195    GXV_Validator                   valid )
196  {
197    FT_UShort setComponent;
198    FT_UShort dontAdvance;
199    FT_UShort offset;
200
201    FT_UNUSED( state );
202    FT_UNUSED( glyphOffset );
203    FT_UNUSED( limit );
204
205
206    setComponent = (FT_UShort)( ( flags >> 15 ) & 1 );
207    dontAdvance  = (FT_UShort)( ( flags >> 14 ) & 1 );
208   
209    offset = (FT_UShort)( flags & 0x3FFFU );
210
211    if ( 0 < offset )
212      gxv_mort_subtable_type2_ligActionOffset_validate( table, offset,
213                                                        valid );
214  }
215
216
217  static void
218  gxv_mort_subtable_type2_ligatureTable_validate( FT_Bytes       table,
219                                                  GXV_Validator  valid )
220  {
221    GXV_mort_subtable_type2_StateOptRecData  optdata =
222      (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata;
223
224    FT_Bytes p     = table + optdata->ligatureTable;
225    FT_Bytes limit = table + optdata->ligatureTable
226                           + optdata->ligatureTable_length;
227
228
229    GXV_NAME_ENTER( "mort chain subtable type2 - substitutionTable" );
230    if ( 0 != optdata->ligatureTable )
231    {
232      /* Apple does not give specification of ligatureTable format */
233      while ( p < limit )
234      {
235        FT_UShort  lig_gid;
236
237
238        GXV_LIMIT_CHECK( 2 );
239        lig_gid = FT_NEXT_USHORT( p );
240      }
241    }
242    GXV_EXIT;
243  }
244
245
246  FT_LOCAL_DEF( void )
247  gxv_mort_subtable_type2_validate( FT_Bytes       table,
248                                    FT_Bytes       limit,
249                                    GXV_Validator  valid )
250  {
251    FT_Bytes  p = table;
252
253    GXV_mort_subtable_type2_StateOptRec  lig_rec;
254
255
256    GXV_NAME_ENTER( "mort chain subtable type2 (Ligature Substitution)" );
257
258    GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE );
259
260    valid->statetable.optdata =
261      &lig_rec;
262    valid->statetable.optdata_load_func =
263      gxv_mort_subtable_type2_opttable_load;
264    valid->statetable.subtable_setup_func =
265      gxv_mort_subtable_type2_subtable_setup;
266    valid->statetable.entry_glyphoffset_fmt =
267      GXV_GLYPHOFFSET_NONE;
268    valid->statetable.entry_validate_func =
269      gxv_mort_subtable_type2_entry_validate;
270
271    gxv_StateTable_validate( p, limit, valid );
272
273    p += valid->subtable_length;
274    gxv_mort_subtable_type2_ligatureTable_validate( table, valid );
275
276    valid->subtable_length = p - table;
277
278    GXV_EXIT;
279  }
280
281
282/* END */
Note: See TracBrowser for help on using the repository browser.