source: trunk/poppler/freetype2/src/otvalid/otvmath.c @ 262

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

PDF plugin: freetype library updated to version 2.3.8

File size: 14.7 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  otvmath.c                                                              */
4/*                                                                         */
5/*    OpenType MATH table validation (body).                               */
6/*                                                                         */
7/*  Copyright 2007, 2008 by                                                */
8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9/*                                                                         */
10/*  Written by George Williams.                                            */
11/*                                                                         */
12/*  This file is part of the FreeType project, and may only be used,       */
13/*  modified, and distributed under the terms of the FreeType project      */
14/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
15/*  this file you indicate that you have read the license and              */
16/*  understand and accept it fully.                                        */
17/*                                                                         */
18/***************************************************************************/
19
20
21#include "otvalid.h"
22#include "otvcommn.h"
23#include "otvgpos.h"
24
25
26  /*************************************************************************/
27  /*                                                                       */
28  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
29  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
30  /* messages during execution.                                            */
31  /*                                                                       */
32#undef  FT_COMPONENT
33#define FT_COMPONENT  trace_otvmath
34
35
36
37  /*************************************************************************/
38  /*************************************************************************/
39  /*****                                                               *****/
40  /*****                  MATH TYPOGRAPHIC CONSTANTS                   *****/
41  /*****                                                               *****/
42  /*************************************************************************/
43  /*************************************************************************/
44
45  static void
46  otv_MathConstants_validate( FT_Bytes       table,
47                              OTV_Validator  valid )
48  {
49    FT_Bytes  p = table;
50    FT_UInt   i;
51    FT_UInt   table_size;
52
53    OTV_OPTIONAL_TABLE( DeviceTableOffset );
54
55
56    OTV_NAME_ENTER( "MathConstants" );
57
58    /* 56 constants, 51 have device tables */
59    OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) );
60    table_size = 2 * ( 56 + 51 );
61
62    p += 4 * 2;                 /* First 4 constants have no device tables */
63    for ( i = 0; i < 51; ++i )
64    {
65      p += 2;                                            /* skip the value */
66      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
67      OTV_SIZE_CHECK( DeviceTableOffset );
68      if ( DeviceTableOffset )
69        otv_Device_validate( table + DeviceTableOffset, valid );
70    }
71
72    OTV_EXIT;
73  }
74
75
76  /*************************************************************************/
77  /*************************************************************************/
78  /*****                                                               *****/
79  /*****                   MATH ITALICS CORRECTION                     *****/
80  /*****                 MATH TOP ACCENT ATTACHMENT                    *****/
81  /*****                                                               *****/
82  /*************************************************************************/
83  /*************************************************************************/
84
85  static void
86  otv_MathItalicsCorrectionInfo_validate( FT_Bytes       table,
87                                          OTV_Validator  valid,
88                                          FT_Int         isItalic )
89  {
90    FT_Bytes  p = table;
91    FT_UInt   i, cnt, table_size ;
92
93    OTV_OPTIONAL_TABLE( Coverage );
94    OTV_OPTIONAL_TABLE( DeviceTableOffset );
95
96    FT_UNUSED( isItalic );  /* only used if tracing is active */
97
98
99    OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
100                             : "MathTopAccentAttachment" );
101
102    OTV_LIMIT_CHECK( 4 );
103
104    OTV_OPTIONAL_OFFSET( Coverage );
105    cnt = FT_NEXT_USHORT( p );
106
107    OTV_LIMIT_CHECK( 4 * cnt );
108    table_size = 4 + 4 * cnt;
109
110    OTV_SIZE_CHECK( Coverage );
111    otv_Coverage_validate( table + Coverage, valid, cnt );
112
113    for ( i = 0; i < cnt; ++i )
114    {
115      p += 2;                                            /* Skip the value */
116      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
117      OTV_SIZE_CHECK( DeviceTableOffset );
118      if ( DeviceTableOffset )
119        otv_Device_validate( table + DeviceTableOffset, valid );
120    }
121
122    OTV_EXIT;
123  }
124
125
126  /*************************************************************************/
127  /*************************************************************************/
128  /*****                                                               *****/
129  /*****                           MATH KERNING                        *****/
130  /*****                                                               *****/
131  /*************************************************************************/
132  /*************************************************************************/
133
134  static void
135  otv_MathKern_validate( FT_Bytes       table,
136                         OTV_Validator  valid )
137  {
138    FT_Bytes  p = table;
139    FT_UInt   i, cnt, table_size;
140
141    OTV_OPTIONAL_TABLE( DeviceTableOffset );
142
143
144    /* OTV_NAME_ENTER( "MathKern" );*/
145
146    OTV_LIMIT_CHECK( 2 );
147
148    cnt = FT_NEXT_USHORT( p );
149
150    OTV_LIMIT_CHECK( 4 * cnt + 2 );
151    table_size = 4 + 4 * cnt;
152
153    /* Heights */
154    for ( i = 0; i < cnt; ++i )
155    {
156      p += 2;                                            /* Skip the value */
157      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
158      OTV_SIZE_CHECK( DeviceTableOffset );
159      if ( DeviceTableOffset )
160        otv_Device_validate( table + DeviceTableOffset, valid );
161    }
162
163    /* One more Kerning value */
164    for ( i = 0; i < cnt + 1; ++i )
165    {
166      p += 2;                                            /* Skip the value */
167      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
168      OTV_SIZE_CHECK( DeviceTableOffset );
169      if ( DeviceTableOffset )
170        otv_Device_validate( table + DeviceTableOffset, valid );
171    }
172
173    OTV_EXIT;
174  }
175
176
177  static void
178  otv_MathKernInfo_validate( FT_Bytes       table,
179                             OTV_Validator  valid )
180  {
181    FT_Bytes  p = table;
182    FT_UInt   i, j, cnt, table_size;
183
184    OTV_OPTIONAL_TABLE( Coverage );
185    OTV_OPTIONAL_TABLE( MKRecordOffset );
186
187
188    OTV_NAME_ENTER( "MathKernInfo" );
189
190    OTV_LIMIT_CHECK( 4 );
191
192    OTV_OPTIONAL_OFFSET( Coverage );
193    cnt = FT_NEXT_USHORT( p );
194
195    OTV_LIMIT_CHECK( 8 * cnt );
196    table_size = 4 + 8 * cnt;
197
198    OTV_SIZE_CHECK( Coverage );
199    otv_Coverage_validate( table + Coverage, valid, cnt );
200
201    for ( i = 0; i < cnt; ++i )
202    {
203      for ( j = 0; j < 4; ++j )
204      {
205        OTV_OPTIONAL_OFFSET( MKRecordOffset );
206        OTV_SIZE_CHECK( MKRecordOffset );
207        if ( MKRecordOffset )
208          otv_MathKern_validate( table + MKRecordOffset, valid );
209      }
210    }
211
212    OTV_EXIT;
213  }
214
215
216  /*************************************************************************/
217  /*************************************************************************/
218  /*****                                                               *****/
219  /*****                         MATH GLYPH INFO                       *****/
220  /*****                                                               *****/
221  /*************************************************************************/
222  /*************************************************************************/
223
224  static void
225  otv_MathGlyphInfo_validate( FT_Bytes       table,
226                              OTV_Validator  valid )
227  {
228    FT_Bytes  p = table;
229    FT_UInt   MathItalicsCorrectionInfo, MathTopAccentAttachment;
230    FT_UInt   ExtendedShapeCoverage, MathKernInfo;
231
232
233    OTV_NAME_ENTER( "MathGlyphInfo" );
234
235    OTV_LIMIT_CHECK( 8 );
236
237    MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
238    MathTopAccentAttachment   = FT_NEXT_USHORT( p );
239    ExtendedShapeCoverage     = FT_NEXT_USHORT( p );
240    MathKernInfo              = FT_NEXT_USHORT( p );
241
242    if ( MathItalicsCorrectionInfo )
243      otv_MathItalicsCorrectionInfo_validate(
244        table + MathItalicsCorrectionInfo, valid, TRUE );
245
246    /* Italic correction and Top Accent Attachment have the same format */
247    if ( MathTopAccentAttachment )
248      otv_MathItalicsCorrectionInfo_validate(
249        table + MathTopAccentAttachment, valid, FALSE );
250
251    if ( ExtendedShapeCoverage ) {
252      OTV_NAME_ENTER( "ExtendedShapeCoverage" );
253      otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
254      OTV_EXIT;
255    }
256
257    if ( MathKernInfo )
258      otv_MathKernInfo_validate( table + MathKernInfo, valid );
259
260    OTV_EXIT;
261  }
262
263
264  /*************************************************************************/
265  /*************************************************************************/
266  /*****                                                               *****/
267  /*****                    MATH GLYPH CONSTRUCTION                    *****/
268  /*****                                                               *****/
269  /*************************************************************************/
270  /*************************************************************************/
271
272  static void
273  otv_GlyphAssembly_validate( FT_Bytes       table,
274                              OTV_Validator  valid )
275  {
276    FT_Bytes  p = table;
277    FT_UInt   pcnt, table_size;
278    FT_UInt   i;
279
280    OTV_OPTIONAL_TABLE( DeviceTableOffset );
281
282
283    /* OTV_NAME_ENTER( "GlyphAssembly" ); */
284
285    OTV_LIMIT_CHECK( 6 );
286
287    p += 2;                           /* Skip the Italics Correction value */
288    OTV_OPTIONAL_OFFSET( DeviceTableOffset );
289    pcnt = FT_NEXT_USHORT( p );
290
291    OTV_LIMIT_CHECK( 8 * pcnt );
292    table_size = 6 + 8 * pcnt;
293
294    OTV_SIZE_CHECK( DeviceTableOffset );
295    if ( DeviceTableOffset )
296      otv_Device_validate( table + DeviceTableOffset, valid );
297
298    for ( i = 0; i < pcnt; ++i )
299    {
300      FT_UInt  gid;
301
302
303      gid = FT_NEXT_USHORT( p );
304      if ( gid >= valid->glyph_count )
305        FT_INVALID_GLYPH_ID;
306      p += 2*4;             /* skip the Start, End, Full, and Flags fields */
307    }
308
309    /* OTV_EXIT; */
310  }
311
312
313  static void
314  otv_MathGlyphConstruction_validate( FT_Bytes       table,
315                                      OTV_Validator  valid )
316  {
317    FT_Bytes  p = table;
318    FT_UInt   vcnt, table_size;
319    FT_UInt   i;
320
321    OTV_OPTIONAL_TABLE( GlyphAssembly );
322
323
324    /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
325
326    OTV_LIMIT_CHECK( 4 );
327
328    OTV_OPTIONAL_OFFSET( GlyphAssembly );
329    vcnt = FT_NEXT_USHORT( p );
330
331    OTV_LIMIT_CHECK( 4 * vcnt );
332    table_size = 4 + 4 * vcnt;
333
334    for ( i = 0; i < vcnt; ++i )
335    {
336      FT_UInt  gid;
337
338
339      gid = FT_NEXT_USHORT( p );
340      if ( gid >= valid->glyph_count )
341        FT_INVALID_GLYPH_ID;
342      p += 2;                          /* skip the size */
343    }
344
345    OTV_SIZE_CHECK( GlyphAssembly );
346    if ( GlyphAssembly )
347      otv_GlyphAssembly_validate( table+GlyphAssembly, valid );
348
349    /* OTV_EXIT; */
350  }
351
352
353  static void
354  otv_MathVariants_validate( FT_Bytes       table,
355                             OTV_Validator  valid )
356  {
357    FT_Bytes  p = table;
358    FT_UInt   vcnt, hcnt, i, table_size;
359
360    OTV_OPTIONAL_TABLE( VCoverage );
361    OTV_OPTIONAL_TABLE( HCoverage );
362    OTV_OPTIONAL_TABLE( Offset );
363
364
365    OTV_NAME_ENTER( "MathVariants" );
366
367    OTV_LIMIT_CHECK( 10 );
368
369    p += 2;                       /* Skip the MinConnectorOverlap constant */
370    OTV_OPTIONAL_OFFSET( VCoverage );
371    OTV_OPTIONAL_OFFSET( HCoverage );
372    vcnt = FT_NEXT_USHORT( p );
373    hcnt = FT_NEXT_USHORT( p );
374
375    OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
376    table_size = 10 + 2 * vcnt + 2 * hcnt;
377
378    OTV_SIZE_CHECK( VCoverage );
379    if ( VCoverage )
380      otv_Coverage_validate( table + VCoverage, valid, vcnt );
381
382    OTV_SIZE_CHECK( HCoverage );
383    if ( HCoverage )
384      otv_Coverage_validate( table + HCoverage, valid, hcnt );
385
386    for ( i = 0; i < vcnt; ++i )
387    {
388      OTV_OPTIONAL_OFFSET( Offset );
389      OTV_SIZE_CHECK( Offset );
390      otv_MathGlyphConstruction_validate( table + Offset, valid );
391    }
392
393    for ( i = 0; i < hcnt; ++i )
394    {
395      OTV_OPTIONAL_OFFSET( Offset );
396      OTV_SIZE_CHECK( Offset );
397      otv_MathGlyphConstruction_validate( table + Offset, valid );
398    }
399
400    OTV_EXIT;
401  }
402
403
404  /*************************************************************************/
405  /*************************************************************************/
406  /*****                                                               *****/
407  /*****                          MATH TABLE                           *****/
408  /*****                                                               *****/
409  /*************************************************************************/
410  /*************************************************************************/
411
412  /* sets valid->glyph_count */
413
414  FT_LOCAL_DEF( void )
415  otv_MATH_validate( FT_Bytes      table,
416                     FT_UInt       glyph_count,
417                     FT_Validator  ftvalid )
418  {
419    OTV_ValidatorRec  validrec;
420    OTV_Validator     valid = &validrec;
421    FT_Bytes          p     = table;
422    FT_UInt           MathConstants, MathGlyphInfo, MathVariants;
423
424
425    valid->root = ftvalid;
426
427    FT_TRACE3(( "validating MATH table\n" ));
428    OTV_INIT;
429
430    OTV_LIMIT_CHECK( 10 );
431
432    if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
433      FT_INVALID_FORMAT;
434
435    MathConstants = FT_NEXT_USHORT( p );
436    MathGlyphInfo = FT_NEXT_USHORT( p );
437    MathVariants  = FT_NEXT_USHORT( p );
438
439    valid->glyph_count = glyph_count;
440
441    otv_MathConstants_validate( table + MathConstants,
442                                valid );
443    otv_MathGlyphInfo_validate( table + MathGlyphInfo,
444                                valid );
445    otv_MathVariants_validate ( table + MathVariants,
446                                valid );
447
448    FT_TRACE4(( "\n" ));
449  }
450
451
452/* END */
Note: See TracBrowser for help on using the repository browser.