source: trunk/poppler/freetype2/src/otvalid/otvmath.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: 14.6 KB
RevLine 
[251]1/***************************************************************************/
2/*                                                                         */
3/*  otvmath.c                                                              */
4/*                                                                         */
5/*    OpenType MATH table validation (body).                               */
6/*                                                                         */
7/*  Copyright 2007 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
97    OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
98                             : "MathTopAccentAttachment" );
99
100    OTV_LIMIT_CHECK( 4 );
101
102    OTV_OPTIONAL_OFFSET( Coverage );
103    cnt = FT_NEXT_USHORT( p );
104
105    OTV_LIMIT_CHECK( 4 * cnt );
106    table_size = 4 + 4 * cnt;
107
108    OTV_SIZE_CHECK( Coverage );
109    otv_Coverage_validate( table + Coverage, valid, cnt );
110
111    for ( i = 0; i < cnt; ++i )
112    {
113      p += 2;                                            /* Skip the value */
114      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
115      OTV_SIZE_CHECK( DeviceTableOffset );
116      if ( DeviceTableOffset )
117        otv_Device_validate( table + DeviceTableOffset, valid );
118    }
119
120    OTV_EXIT;
121  }
122
123
124  /*************************************************************************/
125  /*************************************************************************/
126  /*****                                                               *****/
127  /*****                           MATH KERNING                        *****/
128  /*****                                                               *****/
129  /*************************************************************************/
130  /*************************************************************************/
131
132  static void
133  otv_MathKern_validate( FT_Bytes       table,
134                         OTV_Validator  valid )
135  {
136    FT_Bytes  p = table;
137    FT_UInt   i, cnt, table_size;
138
139    OTV_OPTIONAL_TABLE( DeviceTableOffset );
140
141
142    /* OTV_NAME_ENTER( "MathKern" );*/
143
144    OTV_LIMIT_CHECK( 2 );
145
146    cnt = FT_NEXT_USHORT( p );
147
148    OTV_LIMIT_CHECK( 4 * cnt + 2 );
149    table_size = 4 + 4 * cnt;
150
151    /* Heights */
152    for ( i = 0; i < cnt; ++i )
153    {
154      p += 2;                                            /* Skip the value */
155      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
156      OTV_SIZE_CHECK( DeviceTableOffset );
157      if ( DeviceTableOffset )
158        otv_Device_validate( table + DeviceTableOffset, valid );
159    }
160
161    /* One more Kerning value */
162    for ( i = 0; i < cnt + 1; ++i )
163    {
164      p += 2;                                            /* Skip the value */
165      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
166      OTV_SIZE_CHECK( DeviceTableOffset );
167      if ( DeviceTableOffset )
168        otv_Device_validate( table + DeviceTableOffset, valid );
169    }
170
171    OTV_EXIT;
172  }
173
174
175  static void
176  otv_MathKernInfo_validate( FT_Bytes       table,
177                             OTV_Validator  valid )
178  {
179    FT_Bytes  p = table;
180    FT_UInt   i, j, cnt, table_size;
181
182    OTV_OPTIONAL_TABLE( Coverage );
183    OTV_OPTIONAL_TABLE( MKRecordOffset );
184
185
186    OTV_NAME_ENTER( "MathKernInfo" );
187
188    OTV_LIMIT_CHECK( 4 );
189
190    OTV_OPTIONAL_OFFSET( Coverage );
191    cnt = FT_NEXT_USHORT( p );
192
193    OTV_LIMIT_CHECK( 8 * cnt );
194    table_size = 4 + 8 * cnt;
195
196    OTV_SIZE_CHECK( Coverage );
197    otv_Coverage_validate( table + Coverage, valid, cnt );
198
199    for ( i = 0; i < cnt; ++i )
200    {
201      for ( j = 0; j < 4; ++j )
202      {
203        OTV_OPTIONAL_OFFSET( MKRecordOffset );
204        OTV_SIZE_CHECK( MKRecordOffset );
205        if ( MKRecordOffset )
206          otv_MathKern_validate( table + MKRecordOffset, valid );
207      }
208    }
209
210    OTV_EXIT;
211  }
212
213
214  /*************************************************************************/
215  /*************************************************************************/
216  /*****                                                               *****/
217  /*****                         MATH GLYPH INFO                       *****/
218  /*****                                                               *****/
219  /*************************************************************************/
220  /*************************************************************************/
221
222  static void
223  otv_MathGlyphInfo_validate( FT_Bytes       table,
224                              OTV_Validator  valid )
225  {
226    FT_Bytes  p = table;
227    FT_UInt   MathItalicsCorrectionInfo, MathTopAccentAttachment;
228    FT_UInt   ExtendedShapeCoverage, MathKernInfo;
229
230
231    OTV_NAME_ENTER( "MathGlyphInfo" );
232
233    OTV_LIMIT_CHECK( 8 );
234
235    MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
236    MathTopAccentAttachment   = FT_NEXT_USHORT( p );
237    ExtendedShapeCoverage     = FT_NEXT_USHORT( p );
238    MathKernInfo              = FT_NEXT_USHORT( p );
239
240    if ( MathItalicsCorrectionInfo )
241      otv_MathItalicsCorrectionInfo_validate(
242        table + MathItalicsCorrectionInfo, valid, TRUE );
243
244    /* Italic correction and Top Accent Attachment have the same format */
245    if ( MathTopAccentAttachment )
246      otv_MathItalicsCorrectionInfo_validate(
247        table + MathTopAccentAttachment, valid, FALSE );
248
249    if ( ExtendedShapeCoverage ) {
250      OTV_NAME_ENTER( "ExtendedShapeCoverage" );
251      otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
252      OTV_EXIT;
253    }
254
255    if ( MathKernInfo )
256      otv_MathKernInfo_validate( table + MathKernInfo, valid );
257
258    OTV_EXIT;
259  }
260
261
262  /*************************************************************************/
263  /*************************************************************************/
264  /*****                                                               *****/
265  /*****                    MATH GLYPH CONSTRUCTION                    *****/
266  /*****                                                               *****/
267  /*************************************************************************/
268  /*************************************************************************/
269
270  static void
271  otv_GlyphAssembly_validate( FT_Bytes       table,
272                              OTV_Validator  valid )
273  {
274    FT_Bytes  p = table;
275    FT_UInt   pcnt, table_size;
276    FT_UInt   i;
277
278    OTV_OPTIONAL_TABLE( DeviceTableOffset );
279
280
281    /* OTV_NAME_ENTER( "GlyphAssembly" ); */
282
283    OTV_LIMIT_CHECK( 6 );
284
285    p += 2;                           /* Skip the Italics Correction value */
286    OTV_OPTIONAL_OFFSET( DeviceTableOffset );
287    pcnt = FT_NEXT_USHORT( p );
288
289    OTV_LIMIT_CHECK( 8 * pcnt );
290    table_size = 6 + 8 * pcnt;
291
292    OTV_SIZE_CHECK( DeviceTableOffset );
293    if ( DeviceTableOffset )
294      otv_Device_validate( table + DeviceTableOffset, valid );
295
296    for ( i = 0; i < pcnt; ++i )
297    {
298      FT_UInt  gid;
299
300
301      gid = FT_NEXT_USHORT( p );
302      if ( gid >= valid->glyph_count )
303        FT_INVALID_GLYPH_ID;
304      p += 2*4;             /* skip the Start, End, Full, and Flags fields */
305    }
306
307    /* OTV_EXIT; */
308  }
309
310
311  static void
312  otv_MathGlyphConstruction_validate( FT_Bytes       table,
313                                      OTV_Validator  valid )
314  {
315    FT_Bytes  p = table;
316    FT_UInt   vcnt, table_size;
317    FT_UInt   i;
318
319    OTV_OPTIONAL_TABLE( GlyphAssembly );
320
321
322    /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
323
324    OTV_LIMIT_CHECK( 4 );
325
326    OTV_OPTIONAL_OFFSET( GlyphAssembly );
327    vcnt = FT_NEXT_USHORT( p );
328
329    OTV_LIMIT_CHECK( 4 * vcnt );
330    table_size = 4 + 4 * vcnt;
331
332    for ( i = 0; i < vcnt; ++i )
333    {
334      FT_UInt  gid;
335
336
337      gid = FT_NEXT_USHORT( p );
338      if ( gid >= valid->glyph_count )
339        FT_INVALID_GLYPH_ID;
340      p += 2;                          /* skip the size */
341    }
342
343    OTV_SIZE_CHECK( GlyphAssembly );
344    if ( GlyphAssembly )
345      otv_GlyphAssembly_validate( table+GlyphAssembly, valid );
346
347    /* OTV_EXIT; */
348  }
349
350
351  static void
352  otv_MathVariants_validate( FT_Bytes       table,
353                             OTV_Validator  valid )
354  {
355    FT_Bytes  p = table;
356    FT_UInt   vcnt, hcnt, i, table_size;
357
358    OTV_OPTIONAL_TABLE( VCoverage );
359    OTV_OPTIONAL_TABLE( HCoverage );
360    OTV_OPTIONAL_TABLE( Offset );
361
362
363    OTV_NAME_ENTER( "MathVariants" );
364
365    OTV_LIMIT_CHECK( 10 );
366
367    p += 2;                       /* Skip the MinConnectorOverlap constant */
368    OTV_OPTIONAL_OFFSET( VCoverage );
369    OTV_OPTIONAL_OFFSET( HCoverage );
370    vcnt = FT_NEXT_USHORT( p );
371    hcnt = FT_NEXT_USHORT( p );
372
373    OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
374    table_size = 10 + 2 * vcnt + 2 * hcnt;
375
376    OTV_SIZE_CHECK( VCoverage );
377    if ( VCoverage )
378      otv_Coverage_validate( table + VCoverage, valid, vcnt );
379
380    OTV_SIZE_CHECK( HCoverage );
381    if ( HCoverage )
382      otv_Coverage_validate( table + HCoverage, valid, hcnt );
383
384    for ( i = 0; i < vcnt; ++i )
385    {
386      OTV_OPTIONAL_OFFSET( Offset );
387      OTV_SIZE_CHECK( Offset );
388      otv_MathGlyphConstruction_validate( table + Offset, valid );
389    }
390
391    for ( i = 0; i < hcnt; ++i )
392    {
393      OTV_OPTIONAL_OFFSET( Offset );
394      OTV_SIZE_CHECK( Offset );
395      otv_MathGlyphConstruction_validate( table + Offset, valid );
396    }
397
398    OTV_EXIT;
399  }
400
401
402  /*************************************************************************/
403  /*************************************************************************/
404  /*****                                                               *****/
405  /*****                          MATH TABLE                           *****/
406  /*****                                                               *****/
407  /*************************************************************************/
408  /*************************************************************************/
409
410  /* sets valid->glyph_count */
411
412  FT_LOCAL_DEF( void )
413  otv_MATH_validate( FT_Bytes      table,
414                     FT_UInt       glyph_count,
415                     FT_Validator  ftvalid )
416  {
417    OTV_ValidatorRec  validrec;
418    OTV_Validator     valid = &validrec;
419    FT_Bytes          p     = table;
420    FT_UInt           MathConstants, MathGlyphInfo, MathVariants;
421
422
423    valid->root = ftvalid;
424
425    FT_TRACE3(( "validating MATH table\n" ));
426    OTV_INIT;
427
428    OTV_LIMIT_CHECK( 10 );
429
430    if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
431      FT_INVALID_FORMAT;
432
433    MathConstants = FT_NEXT_USHORT( p );
434    MathGlyphInfo = FT_NEXT_USHORT( p );
435    MathVariants  = FT_NEXT_USHORT( p );
436
437    valid->glyph_count = glyph_count;
438
439    otv_MathConstants_validate( table + MathConstants,
440                                valid );
441    otv_MathGlyphInfo_validate( table + MathGlyphInfo,
442                                valid );
443    otv_MathVariants_validate ( table + MathVariants,
444                                valid );
445
446    FT_TRACE4(( "\n" ));
447  }
448
449
450/* END */
Note: See TracBrowser for help on using the repository browser.