1
/***************************************************************************/
5
/* OpenType MATH table validation (body). */
7
/* Copyright 2007, 2008 by */
8
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
10
/* Written by George Williams. */
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. */
18
/***************************************************************************/
26
/*************************************************************************/
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. */
33
#define FT_COMPONENT trace_otvmath
37
/*************************************************************************/
38
/*************************************************************************/
40
/***** MATH TYPOGRAPHIC CONSTANTS *****/
42
/*************************************************************************/
43
/*************************************************************************/
46
otv_MathConstants_validate( FT_Bytes table,
53
OTV_OPTIONAL_TABLE( DeviceTableOffset );
56
OTV_NAME_ENTER( "MathConstants" );
58
/* 56 constants, 51 have device tables */
59
OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) );
60
table_size = 2 * ( 56 + 51 );
62
p += 4 * 2; /* First 4 constants have no device tables */
63
for ( i = 0; i < 51; ++i )
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 );
76
/*************************************************************************/
77
/*************************************************************************/
79
/***** MATH ITALICS CORRECTION *****/
80
/***** MATH TOP ACCENT ATTACHMENT *****/
82
/*************************************************************************/
83
/*************************************************************************/
86
otv_MathItalicsCorrectionInfo_validate( FT_Bytes table,
91
FT_UInt i, cnt, table_size ;
93
OTV_OPTIONAL_TABLE( Coverage );
94
OTV_OPTIONAL_TABLE( DeviceTableOffset );
96
FT_UNUSED( isItalic ); /* only used if tracing is active */
99
OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
100
: "MathTopAccentAttachment" );
102
OTV_LIMIT_CHECK( 4 );
104
OTV_OPTIONAL_OFFSET( Coverage );
105
cnt = FT_NEXT_USHORT( p );
107
OTV_LIMIT_CHECK( 4 * cnt );
108
table_size = 4 + 4 * cnt;
110
OTV_SIZE_CHECK( Coverage );
111
otv_Coverage_validate( table + Coverage, valid, cnt );
113
for ( i = 0; i < cnt; ++i )
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 );
126
/*************************************************************************/
127
/*************************************************************************/
129
/***** MATH KERNING *****/
131
/*************************************************************************/
132
/*************************************************************************/
135
otv_MathKern_validate( FT_Bytes table,
136
OTV_Validator valid )
139
FT_UInt i, cnt, table_size;
141
OTV_OPTIONAL_TABLE( DeviceTableOffset );
144
/* OTV_NAME_ENTER( "MathKern" );*/
146
OTV_LIMIT_CHECK( 2 );
148
cnt = FT_NEXT_USHORT( p );
150
OTV_LIMIT_CHECK( 4 * cnt + 2 );
151
table_size = 4 + 4 * cnt;
154
for ( i = 0; i < cnt; ++i )
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 );
163
/* One more Kerning value */
164
for ( i = 0; i < cnt + 1; ++i )
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 );
178
otv_MathKernInfo_validate( FT_Bytes table,
179
OTV_Validator valid )
182
FT_UInt i, j, cnt, table_size;
184
OTV_OPTIONAL_TABLE( Coverage );
185
OTV_OPTIONAL_TABLE( MKRecordOffset );
188
OTV_NAME_ENTER( "MathKernInfo" );
190
OTV_LIMIT_CHECK( 4 );
192
OTV_OPTIONAL_OFFSET( Coverage );
193
cnt = FT_NEXT_USHORT( p );
195
OTV_LIMIT_CHECK( 8 * cnt );
196
table_size = 4 + 8 * cnt;
198
OTV_SIZE_CHECK( Coverage );
199
otv_Coverage_validate( table + Coverage, valid, cnt );
201
for ( i = 0; i < cnt; ++i )
203
for ( j = 0; j < 4; ++j )
205
OTV_OPTIONAL_OFFSET( MKRecordOffset );
206
OTV_SIZE_CHECK( MKRecordOffset );
207
if ( MKRecordOffset )
208
otv_MathKern_validate( table + MKRecordOffset, valid );
216
/*************************************************************************/
217
/*************************************************************************/
219
/***** MATH GLYPH INFO *****/
221
/*************************************************************************/
222
/*************************************************************************/
225
otv_MathGlyphInfo_validate( FT_Bytes table,
226
OTV_Validator valid )
229
FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment;
230
FT_UInt ExtendedShapeCoverage, MathKernInfo;
233
OTV_NAME_ENTER( "MathGlyphInfo" );
235
OTV_LIMIT_CHECK( 8 );
237
MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
238
MathTopAccentAttachment = FT_NEXT_USHORT( p );
239
ExtendedShapeCoverage = FT_NEXT_USHORT( p );
240
MathKernInfo = FT_NEXT_USHORT( p );
242
if ( MathItalicsCorrectionInfo )
243
otv_MathItalicsCorrectionInfo_validate(
244
table + MathItalicsCorrectionInfo, valid, TRUE );
246
/* Italic correction and Top Accent Attachment have the same format */
247
if ( MathTopAccentAttachment )
248
otv_MathItalicsCorrectionInfo_validate(
249
table + MathTopAccentAttachment, valid, FALSE );
251
if ( ExtendedShapeCoverage )
253
OTV_NAME_ENTER( "ExtendedShapeCoverage" );
254
otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
259
otv_MathKernInfo_validate( table + MathKernInfo, valid );
265
/*************************************************************************/
266
/*************************************************************************/
268
/***** MATH GLYPH CONSTRUCTION *****/
270
/*************************************************************************/
271
/*************************************************************************/
274
otv_GlyphAssembly_validate( FT_Bytes table,
275
OTV_Validator valid )
278
FT_UInt pcnt, table_size;
281
OTV_OPTIONAL_TABLE( DeviceTableOffset );
284
/* OTV_NAME_ENTER( "GlyphAssembly" ); */
286
OTV_LIMIT_CHECK( 6 );
288
p += 2; /* Skip the Italics Correction value */
289
OTV_OPTIONAL_OFFSET( DeviceTableOffset );
290
pcnt = FT_NEXT_USHORT( p );
292
OTV_LIMIT_CHECK( 8 * pcnt );
293
table_size = 6 + 8 * pcnt;
295
OTV_SIZE_CHECK( DeviceTableOffset );
296
if ( DeviceTableOffset )
297
otv_Device_validate( table + DeviceTableOffset, valid );
299
for ( i = 0; i < pcnt; ++i )
304
gid = FT_NEXT_USHORT( p );
305
if ( gid >= valid->glyph_count )
307
p += 2*4; /* skip the Start, End, Full, and Flags fields */
315
otv_MathGlyphConstruction_validate( FT_Bytes table,
316
OTV_Validator valid )
319
FT_UInt vcnt, table_size;
322
OTV_OPTIONAL_TABLE( GlyphAssembly );
325
/* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
327
OTV_LIMIT_CHECK( 4 );
329
OTV_OPTIONAL_OFFSET( GlyphAssembly );
330
vcnt = FT_NEXT_USHORT( p );
332
OTV_LIMIT_CHECK( 4 * vcnt );
333
table_size = 4 + 4 * vcnt;
335
for ( i = 0; i < vcnt; ++i )
340
gid = FT_NEXT_USHORT( p );
341
if ( gid >= valid->glyph_count )
343
p += 2; /* skip the size */
346
OTV_SIZE_CHECK( GlyphAssembly );
348
otv_GlyphAssembly_validate( table+GlyphAssembly, valid );
355
otv_MathVariants_validate( FT_Bytes table,
356
OTV_Validator valid )
359
FT_UInt vcnt, hcnt, i, table_size;
361
OTV_OPTIONAL_TABLE( VCoverage );
362
OTV_OPTIONAL_TABLE( HCoverage );
363
OTV_OPTIONAL_TABLE( Offset );
366
OTV_NAME_ENTER( "MathVariants" );
368
OTV_LIMIT_CHECK( 10 );
370
p += 2; /* Skip the MinConnectorOverlap constant */
371
OTV_OPTIONAL_OFFSET( VCoverage );
372
OTV_OPTIONAL_OFFSET( HCoverage );
373
vcnt = FT_NEXT_USHORT( p );
374
hcnt = FT_NEXT_USHORT( p );
376
OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
377
table_size = 10 + 2 * vcnt + 2 * hcnt;
379
OTV_SIZE_CHECK( VCoverage );
381
otv_Coverage_validate( table + VCoverage, valid, vcnt );
383
OTV_SIZE_CHECK( HCoverage );
385
otv_Coverage_validate( table + HCoverage, valid, hcnt );
387
for ( i = 0; i < vcnt; ++i )
389
OTV_OPTIONAL_OFFSET( Offset );
390
OTV_SIZE_CHECK( Offset );
391
otv_MathGlyphConstruction_validate( table + Offset, valid );
394
for ( i = 0; i < hcnt; ++i )
396
OTV_OPTIONAL_OFFSET( Offset );
397
OTV_SIZE_CHECK( Offset );
398
otv_MathGlyphConstruction_validate( table + Offset, valid );
405
/*************************************************************************/
406
/*************************************************************************/
408
/***** MATH TABLE *****/
410
/*************************************************************************/
411
/*************************************************************************/
413
/* sets valid->glyph_count */
416
otv_MATH_validate( FT_Bytes table,
418
FT_Validator ftvalid )
420
OTV_ValidatorRec validrec;
421
OTV_Validator valid = &validrec;
423
FT_UInt MathConstants, MathGlyphInfo, MathVariants;
426
valid->root = ftvalid;
428
FT_TRACE3(( "validating MATH table\n" ));
431
OTV_LIMIT_CHECK( 10 );
433
if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
436
MathConstants = FT_NEXT_USHORT( p );
437
MathGlyphInfo = FT_NEXT_USHORT( p );
438
MathVariants = FT_NEXT_USHORT( p );
440
valid->glyph_count = glyph_count;
442
otv_MathConstants_validate( table + MathConstants,
444
otv_MathGlyphInfo_validate( table + MathGlyphInfo,
446
otv_MathVariants_validate ( table + MathVariants,