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
) {
252 OTV_NAME_ENTER( "ExtendedShapeCoverage" );
253 otv_Coverage_validate( table
+ ExtendedShapeCoverage
, valid
, -1 );
258 otv_MathKernInfo_validate( table
+ MathKernInfo
, valid
);
264 /*************************************************************************/
265 /*************************************************************************/
267 /***** MATH GLYPH CONSTRUCTION *****/
269 /*************************************************************************/
270 /*************************************************************************/
273 otv_GlyphAssembly_validate( FT_Bytes table
,
274 OTV_Validator valid
)
277 FT_UInt pcnt
, table_size
;
280 OTV_OPTIONAL_TABLE( DeviceTableOffset
);
283 /* OTV_NAME_ENTER( "GlyphAssembly" ); */
285 OTV_LIMIT_CHECK( 6 );
287 p
+= 2; /* Skip the Italics Correction value */
288 OTV_OPTIONAL_OFFSET( DeviceTableOffset
);
289 pcnt
= FT_NEXT_USHORT( p
);
291 OTV_LIMIT_CHECK( 8 * pcnt
);
292 table_size
= 6 + 8 * pcnt
;
294 OTV_SIZE_CHECK( DeviceTableOffset
);
295 if ( DeviceTableOffset
)
296 otv_Device_validate( table
+ DeviceTableOffset
, valid
);
298 for ( i
= 0; i
< pcnt
; ++i
)
303 gid
= FT_NEXT_USHORT( p
);
304 if ( gid
>= valid
->glyph_count
)
306 p
+= 2*4; /* skip the Start, End, Full, and Flags fields */
314 otv_MathGlyphConstruction_validate( FT_Bytes table
,
315 OTV_Validator valid
)
318 FT_UInt vcnt
, table_size
;
321 OTV_OPTIONAL_TABLE( GlyphAssembly
);
324 /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
326 OTV_LIMIT_CHECK( 4 );
328 OTV_OPTIONAL_OFFSET( GlyphAssembly
);
329 vcnt
= FT_NEXT_USHORT( p
);
331 OTV_LIMIT_CHECK( 4 * vcnt
);
332 table_size
= 4 + 4 * vcnt
;
334 for ( i
= 0; i
< vcnt
; ++i
)
339 gid
= FT_NEXT_USHORT( p
);
340 if ( gid
>= valid
->glyph_count
)
342 p
+= 2; /* skip the size */
345 OTV_SIZE_CHECK( GlyphAssembly
);
347 otv_GlyphAssembly_validate( table
+GlyphAssembly
, valid
);
354 otv_MathVariants_validate( FT_Bytes table
,
355 OTV_Validator valid
)
358 FT_UInt vcnt
, hcnt
, i
, table_size
;
360 OTV_OPTIONAL_TABLE( VCoverage
);
361 OTV_OPTIONAL_TABLE( HCoverage
);
362 OTV_OPTIONAL_TABLE( Offset
);
365 OTV_NAME_ENTER( "MathVariants" );
367 OTV_LIMIT_CHECK( 10 );
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
);
375 OTV_LIMIT_CHECK( 2 * vcnt
+ 2 * hcnt
);
376 table_size
= 10 + 2 * vcnt
+ 2 * hcnt
;
378 OTV_SIZE_CHECK( VCoverage
);
380 otv_Coverage_validate( table
+ VCoverage
, valid
, vcnt
);
382 OTV_SIZE_CHECK( HCoverage
);
384 otv_Coverage_validate( table
+ HCoverage
, valid
, hcnt
);
386 for ( i
= 0; i
< vcnt
; ++i
)
388 OTV_OPTIONAL_OFFSET( Offset
);
389 OTV_SIZE_CHECK( Offset
);
390 otv_MathGlyphConstruction_validate( table
+ Offset
, valid
);
393 for ( i
= 0; i
< hcnt
; ++i
)
395 OTV_OPTIONAL_OFFSET( Offset
);
396 OTV_SIZE_CHECK( Offset
);
397 otv_MathGlyphConstruction_validate( table
+ Offset
, valid
);
404 /*************************************************************************/
405 /*************************************************************************/
407 /***** MATH TABLE *****/
409 /*************************************************************************/
410 /*************************************************************************/
412 /* sets valid->glyph_count */
415 otv_MATH_validate( FT_Bytes table
,
417 FT_Validator ftvalid
)
419 OTV_ValidatorRec validrec
;
420 OTV_Validator valid
= &validrec
;
422 FT_UInt MathConstants
, MathGlyphInfo
, MathVariants
;
425 valid
->root
= ftvalid
;
427 FT_TRACE3(( "validating MATH table\n" ));
430 OTV_LIMIT_CHECK( 10 );
432 if ( FT_NEXT_ULONG( p
) != 0x10000UL
) /* Version */
435 MathConstants
= FT_NEXT_USHORT( p
);
436 MathGlyphInfo
= FT_NEXT_USHORT( p
);
437 MathVariants
= FT_NEXT_USHORT( p
);
439 valid
->glyph_count
= glyph_count
;
441 otv_MathConstants_validate( table
+ MathConstants
,
443 otv_MathGlyphInfo_validate( table
+ MathGlyphInfo
,
445 otv_MathVariants_validate ( table
+ MathVariants
,