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,