blob: 29bf840b57a1b07c3ed9007871d9a49703a575e3 [file] [log] [blame]
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +00001/***************************************************************************/
2/* */
3/* gxvjust.c */
4/* */
5/* TrueTypeGX/AAT just table validation (body). */
6/* */
7/* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
8/* David Turner, Robert Wilhelm, and Werner Lemberg. */
9/* */
10/* This file is part of the FreeType project, and may only be used, */
11/* modified, and distributed under the terms of the FreeType project */
12/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13/* this file you indicate that you have read the license and */
14/* understand and accept it fully. */
15/* */
16/***************************************************************************/
17
18/***************************************************************************/
Werner Lemberga4aa1c52005-08-31 22:39:23 +000019/* */
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +000020/* gxvalid is derived from both gxlayout module and otvalid module. */
Werner Lemberga4aa1c52005-08-31 22:39:23 +000021/* Development of gxlayout is supported by the Information-technology */
22/* Promotion Agency(IPA), Japan. */
23/* */
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +000024/***************************************************************************/
25
Werner Lemberga4aa1c52005-08-31 22:39:23 +000026
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +000027#include "gxvalid.h"
28#include "gxvcommn.h"
29
30#include FT_SFNT_NAMES_H
31
32
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +000033 /*************************************************************************/
34 /* */
35 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
36 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
37 /* messages during execution. */
38 /* */
39#undef FT_COMPONENT
40#define FT_COMPONENT trace_gxvjust
41
Werner Lemberga4aa1c52005-08-31 22:39:23 +000042 /*
43 * referred `just' table format specification:
44 * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6just.html
45 * last updated 2000.
46 * ----------------------------------------------
47 * [JUST HEADER]: GXV_JUST_HEADER_SIZE
48 * version (fixed: 32bit) = 0x00010000
49 * format (uint16: 16bit) = 0 is only defined (2000)
50 * horizOffset (uint16: 16bit)
51 * vertOffset (uint16: 16bit)
52 * ----------------------------------------------
53 */
54
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +000055 typedef struct GXV_just_DataRec_
56 {
57 FT_UShort wdc_offset_max;
58 FT_UShort wdc_offset_min;
59 FT_UShort pc_offset_max;
60 FT_UShort pc_offset_min;
61
62 } GXV_just_DataRec, *GXV_just_Data;
63
Werner Lemberga4aa1c52005-08-31 22:39:23 +000064
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +000065#define GXV_JUST_DATA( a ) GXV_TABLE_DATA( just, a )
66
Werner Lemberga4aa1c52005-08-31 22:39:23 +000067
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +000068 static void
69 gxv_just_wdp_entry_validate( FT_Bytes table,
70 FT_Bytes limit,
71 GXV_Validator valid )
72 {
73 FT_Bytes p = table;
74 FT_ULong justClass;
75 FT_Fixed beforeGrowLimit;
76 FT_Fixed beforeShrinkGrowLimit;
77 FT_Fixed afterGrowLimit;
78 FT_Fixed afterShrinkGrowLimit;
79 FT_UShort growFlags;
80 FT_UShort shrinkFlags;
81
82
83 GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 );
84 justClass = FT_NEXT_ULONG( p );
85 beforeGrowLimit = FT_NEXT_ULONG( p );
86 beforeShrinkGrowLimit = FT_NEXT_ULONG( p );
87 afterGrowLimit = FT_NEXT_ULONG( p );
88 afterShrinkGrowLimit = FT_NEXT_ULONG( p );
89 growFlags = FT_NEXT_USHORT( p );
90 shrinkFlags = FT_NEXT_USHORT( p );
91
Werner Lemberga4aa1c52005-08-31 22:39:23 +000092 /* TODO: decode flags for human readability */
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +000093
Werner Lemberga4aa1c52005-08-31 22:39:23 +000094 valid->subtable_length = p - table;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +000095 }
96
97
98 static void
99 gxv_just_wdc_entry_validate( FT_Bytes table,
100 FT_Bytes limit,
101 GXV_Validator valid )
102 {
103 FT_Bytes p = table;
104 FT_ULong count, i;
105
106
107 GXV_LIMIT_CHECK( 4 );
108 count = FT_NEXT_ULONG( p );
109 for ( i = 0; i < count; i++ )
110 {
Werner Lemberg99aa14c2005-09-05 19:31:27 +0000111 GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count ));
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000112 gxv_just_wdp_entry_validate( p, limit, valid );
113 p += valid->subtable_length;
114 }
115
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000116 valid->subtable_length = p - table;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000117 }
118
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000119
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000120 static void
121 gxv_just_widthDeltaClusters_validate( FT_Bytes table,
122 FT_Bytes limit,
123 GXV_Validator valid )
124 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000125 FT_Bytes p = table ;
126 FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max );
127 FT_UInt i;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000128
129
130 GXV_NAME_ENTER( "just justDeltaClusters" );
131
132 if ( limit <= wdc_end )
133 FT_INVALID_OFFSET;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000134
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000135 for ( i = 0; p <= wdc_end; i++ )
136 {
137 gxv_just_wdc_entry_validate( p, limit, valid );
138 p += valid->subtable_length;
139 }
140
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000141 valid->subtable_length = p - table;
142
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000143 GXV_EXIT;
144 }
145
146
147 static void
148 gxv_just_actSubrecord_type0_validate( FT_Bytes table,
149 FT_Bytes limit,
150 GXV_Validator valid )
151 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000152 FT_Bytes p = table;
153
154 FT_Fixed lowerLimit;
155 FT_Fixed upperLimit;
156
157 FT_UShort order;
158 FT_UShort decomposedCount;
159
160 FT_UInt i;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000161
162
163 GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
164 lowerLimit = FT_NEXT_ULONG( p );
165 upperLimit = FT_NEXT_ULONG( p );
166 order = FT_NEXT_USHORT( p );
167 decomposedCount = FT_NEXT_USHORT( p );
168
169 for ( i = 0; i < decomposedCount; i++ )
170 {
171 FT_UShort glyphs;
172
173
174 GXV_LIMIT_CHECK( 2 );
175 glyphs = FT_NEXT_USHORT( p );
176 }
177
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000178 valid->subtable_length = p - table;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000179 }
180
181
182 static void
183 gxv_just_actSubrecord_type1_validate( FT_Bytes table,
184 FT_Bytes limit,
185 GXV_Validator valid )
186 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000187 FT_Bytes p = table;
188 FT_UShort addGlyph;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000189
190
191 GXV_LIMIT_CHECK( 2 );
192 addGlyph = FT_NEXT_USHORT( p );
193
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000194 valid->subtable_length = p - table;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000195 }
196
197
198 static void
199 gxv_just_actSubrecord_type2_validate( FT_Bytes table,
200 FT_Bytes limit,
201 GXV_Validator valid )
202 {
203 FT_Bytes p = table;
204 FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */
205 FT_UShort addGlyph;
206 FT_UShort substGlyph;
207
208
209 GXV_LIMIT_CHECK( 4 + 2 + 2 );
210 substThreshhold = FT_NEXT_ULONG( p );
211 addGlyph = FT_NEXT_USHORT( p );
212 substGlyph = FT_NEXT_USHORT( p );
213
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000214 valid->subtable_length = p - table;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000215 }
216
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000217
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000218 static void
219 gxv_just_actSubrecord_type4_validate( FT_Bytes table,
220 FT_Bytes limit,
221 GXV_Validator valid )
222 {
223 FT_Bytes p = table;
224 FT_ULong variantsAxis;
225 FT_Fixed minimumLimit;
226 FT_Fixed noStretchValue;
227 FT_Fixed maximumLimit;
228
229
230 GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
231 variantsAxis = FT_NEXT_ULONG( p );
232 minimumLimit = FT_NEXT_ULONG( p );
233 noStretchValue = FT_NEXT_ULONG( p );
234 maximumLimit = FT_NEXT_ULONG( p );
235
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000236 valid->subtable_length = p - table;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000237 }
238
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000239
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000240 static void
241 gxv_just_actSubrecord_type5_validate( FT_Bytes table,
242 FT_Bytes limit,
243 GXV_Validator valid )
244 {
245 FT_Bytes p = table;
246 FT_UShort flags;
247 FT_UShort glyph;
248
249
250 GXV_LIMIT_CHECK( 2 + 2 );
251 flags = FT_NEXT_USHORT( p );
252 glyph = FT_NEXT_USHORT( p );
253
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000254 valid->subtable_length = p - table;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000255 }
256
257
258 /* parse single actSubrecord */
259 static void
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000260 gxv_just_actSubrecord_validate( FT_Bytes table,
261 FT_Bytes limit,
262 GXV_Validator valid )
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000263 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000264 FT_Bytes p = table;
265 FT_UShort actionClass;
266 FT_UShort actionType;
267 FT_ULong actionLength;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000268
269
270 GXV_NAME_ENTER( "just actSubrecord" );
271
272 GXV_LIMIT_CHECK( 2 + 2 + 4 );
273 actionClass = FT_NEXT_USHORT( p );
274 actionType = FT_NEXT_USHORT( p );
275 actionLength = FT_NEXT_ULONG( p );
276
277 if ( actionType == 0 )
278 gxv_just_actSubrecord_type0_validate( p, limit, valid );
279 else if ( actionType == 1 )
280 gxv_just_actSubrecord_type1_validate( p, limit, valid );
281 else if ( actionType == 2 )
282 gxv_just_actSubrecord_type2_validate( p, limit, valid );
283 else if ( actionType == 3 )
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000284 ; /* Stretch glyph action: no actionData */
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000285 else if ( actionType == 4 )
286 gxv_just_actSubrecord_type4_validate( p, limit, valid );
287 else if ( actionType == 5 )
288 gxv_just_actSubrecord_type5_validate( p, limit, valid );
289 else
290 FT_INVALID_DATA;
291
292 valid->subtable_length = actionLength;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000293
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000294 GXV_EXIT;
295 }
296
297
298 static void
299 gxv_just_pcActionRecord_validate( FT_Bytes table,
300 FT_Bytes limit,
301 GXV_Validator valid )
302 {
303 FT_Bytes p = table;
304 FT_ULong actionCount;
305 FT_ULong i;
306
307
308 GXV_LIMIT_CHECK( 4 );
309 actionCount = FT_NEXT_ULONG( p );
310 GXV_TRACE(( "actionCount = %d\n", actionCount ));
311
312 for ( i = 0; i < actionCount; i++ )
313 {
314 gxv_just_actSubrecord_validate( p, limit, valid );
315 p += valid->subtable_length;
316 }
317
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000318 valid->subtable_length = p - table;
319
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000320 GXV_EXIT;
321 }
322
323
324 static void
325 gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph,
326 GXV_LookupValueDesc value,
327 GXV_Validator valid )
328 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000329 FT_UNUSED( glyph );
330
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000331 if ( value.u > GXV_JUST_DATA( pc_offset_max ) )
332 GXV_JUST_DATA( pc_offset_max ) = value.u;
333 if ( value.u < GXV_JUST_DATA( pc_offset_max ) )
334 GXV_JUST_DATA( pc_offset_min ) = value.u;
335 }
336
337
338 static void
339 gxv_just_pcLookupTable_validate( FT_Bytes table,
340 FT_Bytes limit,
341 GXV_Validator valid )
342 {
343 FT_Bytes p = table;
344
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000345
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000346 GXV_NAME_ENTER( "just pcLookupTable" );
347 GXV_JUST_DATA( pc_offset_max ) = 0x0000;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000348 GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000349
350 valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
351 valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000352
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000353 gxv_LookupTable_validate( p, limit, valid );
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000354
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000355 /* subtable_length is set by gxv_LookupTable_validate() */
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000356
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000357 GXV_EXIT;
358 }
359
360
361 static void
362 gxv_just_postcompTable_validate( FT_Bytes table,
363 FT_Bytes limit,
364 GXV_Validator valid )
365 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000366 FT_Bytes p = table;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000367
368
369 GXV_NAME_ENTER( "just postcompTable" );
370
371 gxv_just_pcLookupTable_validate( p, limit, valid );
372 p += valid->subtable_length;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000373
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000374 gxv_just_pcActionRecord_validate( p, limit, valid );
375 p += valid->subtable_length;
376
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000377 valid->subtable_length = p - table;
378
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000379 GXV_EXIT;
380 }
381
382
383 static void
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000384 gxv_just_classTable_entry_validate(
385 FT_Byte state,
386 FT_UShort flags,
387 GXV_StateTable_GlyphOffsetDesc glyphOffset,
388 FT_Bytes table,
389 FT_Bytes limit,
390 GXV_Validator valid )
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000391 {
392 FT_UShort setMark;
393 FT_UShort dontAdvance;
394 FT_UShort markClass;
395 FT_UShort currentClass;
396
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000397 FT_UNUSED( state );
398 FT_UNUSED( glyphOffset );
399 FT_UNUSED( table );
400 FT_UNUSED( limit );
401 FT_UNUSED( valid );
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000402
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000403
Werner Lemberg7c259462005-09-28 07:34:45 +0000404 setMark = (FT_UShort)( ( flags >> 15 ) & 1 );
405 dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
406 markClass = (FT_UShort)( ( flags >> 7 ) & 0x7F );
407 currentClass = (FT_UShort)( flags & 0x7F );
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000408
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000409 /* TODO: validate markClass & currentClass */
410 }
411
412
413 static void
414 gxv_just_justClassTable_validate ( FT_Bytes table,
415 FT_Bytes limit,
416 GXV_Validator valid )
417 {
418 FT_Bytes p = table;
419 FT_UShort length;
420 FT_UShort coverage;
421 FT_ULong subFeatureFlags;
422
423
424 GXV_NAME_ENTER( "just justClassTable" );
425
426 GXV_LIMIT_CHECK( 2 + 2 + 4 );
427 length = FT_NEXT_USHORT( p );
428 coverage = FT_NEXT_USHORT( p );
429 subFeatureFlags = FT_NEXT_ULONG( p );
430
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000431 GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s)",
432 coverage,
433 ( 0x4000 & coverage ) == 0 ? "ascending" : "descending" ));
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000434
435 valid->statetable.optdata = NULL;
436 valid->statetable.optdata_load_func = NULL;
437 valid->statetable.subtable_setup_func = NULL;
438 valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000439 valid->statetable.entry_validate_func =
440 gxv_just_classTable_entry_validate;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000441
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000442 gxv_StateTable_validate( p, table + length, valid );
443
444 /* subtable_length is set by gxv_LookupTable_validate() */
445
446 GXV_EXIT;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000447 }
448
449
450 static void
451 gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph,
452 GXV_LookupValueDesc value,
453 GXV_Validator valid )
454 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000455 FT_UNUSED( glyph );
456
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000457 if ( value.u > GXV_JUST_DATA( wdc_offset_max ) )
458 GXV_JUST_DATA( wdc_offset_max ) = value.u;
459 if ( value.u < GXV_JUST_DATA( wdc_offset_min ) )
460 GXV_JUST_DATA( wdc_offset_min ) = value.u;
461 }
462
463
464 static void
465 gxv_just_justData_lookuptable_validate( FT_Bytes table,
466 FT_Bytes limit,
467 GXV_Validator valid )
468 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000469 FT_Bytes p = table;
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000470
471
472 GXV_JUST_DATA( wdc_offset_max ) = 0x0000;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000473 GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU;
474
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000475 valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
476 valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000477
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000478 gxv_LookupTable_validate( p, limit, valid );
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000479
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000480 /* subtable_length is set by gxv_LookupTable_validate() */
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000481
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000482 GXV_EXIT;
483 }
484
485
486 /*
487 * gxv_just_justData_validate() parses and validates horizData, vertData.
488 */
489 static void
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000490 gxv_just_justData_validate( FT_Bytes table,
491 FT_Bytes limit,
492 GXV_Validator valid )
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000493 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000494 /*
495 * following 3 offsets are measured from the start of `just'
496 * (which table points to), not justData
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000497 */
498 FT_UShort justClassTableOffset;
499 FT_UShort wdcTableOffset;
500 FT_UShort pcTableOffset;
501 FT_Bytes p = table;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000502
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000503 GXV_ODTECT( 4, odtect );
504
505
506 GXV_NAME_ENTER( "just justData" );
507
508 GXV_ODTECT_INIT( odtect );
509 GXV_LIMIT_CHECK( 2 + 2 + 2 );
510 justClassTableOffset = FT_NEXT_USHORT( p );
511 wdcTableOffset = FT_NEXT_USHORT( p );
512 pcTableOffset = FT_NEXT_USHORT( p );
513
514 GXV_TRACE(( " (justClassTableOffset = 0x%04x)\n", justClassTableOffset ));
515 GXV_TRACE(( " (wdcTableOffset = 0x%04x)\n", wdcTableOffset ));
516 GXV_TRACE(( " (pcTableOffset = 0x%04x)\n", pcTableOffset ));
517
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000518 gxv_just_justData_lookuptable_validate( p, limit, valid );
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000519 gxv_odtect_add_range( p, valid->subtable_length,
520 "just_LookupTable", odtect );
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000521
522 if ( wdcTableOffset )
523 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000524 gxv_just_widthDeltaClusters_validate(
525 valid->root->base + wdcTableOffset, limit, valid );
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000526 gxv_odtect_add_range( valid->root->base + wdcTableOffset,
527 valid->subtable_length, "just_wdcTable", odtect );
528 }
529
530 if ( pcTableOffset )
531 {
532 gxv_just_postcompTable_validate( valid->root->base + pcTableOffset,
533 limit, valid );
534 gxv_odtect_add_range( valid->root->base + pcTableOffset,
535 valid->subtable_length, "just_pcTable", odtect );
536 }
537
538 if ( justClassTableOffset )
539 {
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000540 gxv_just_justClassTable_validate(
541 valid->root->base + justClassTableOffset, limit, valid );
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000542 gxv_odtect_add_range( valid->root->base + justClassTableOffset,
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000543 valid->subtable_length, "just_justClassTable",
544 odtect );
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000545 }
546
547 gxv_odtect_validate( odtect, valid );
548
549 GXV_EXIT;
550 }
551
552
553 FT_LOCAL_DEF( void )
554 gxv_just_validate( FT_Bytes table,
555 FT_Face face,
556 FT_Validator ftvalid )
557 {
558 FT_Bytes p = table;
559 FT_Bytes limit = 0;
560 FT_UInt table_size;
561
562 GXV_ValidatorRec validrec;
563 GXV_Validator valid = &validrec;
564 GXV_just_DataRec justrec;
565 GXV_just_Data just = &justrec;
566
567 FT_ULong version;
568 FT_UShort format;
569 FT_UShort horizOffset;
570 FT_UShort vertOffset;
571
572 GXV_ODTECT( 3, odtect );
573
574
575 GXV_ODTECT_INIT( odtect );
576
577 valid->root = ftvalid;
578 valid->table_data = just;
579 valid->face = face;
580
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000581 FT_TRACE3(( "validating `just' table\n" ));
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000582 GXV_INIT;
583
584 limit = valid->root->limit;
585 table_size = limit - table;
Werner Lemberga4aa1c52005-08-31 22:39:23 +0000586
Suzuki, Toshiya (鈴木俊哉)a4386212005-08-24 04:31:31 +0000587 GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 );
588 version = FT_NEXT_ULONG( p );
589 format = FT_NEXT_USHORT( p );
590 horizOffset = FT_NEXT_USHORT( p );
591 vertOffset = FT_NEXT_USHORT( p );
592 gxv_odtect_add_range( table, p - table, "just header", odtect );
593
594
595 /* Version 1.0 (always:2000) */
596 GXV_TRACE(( " (version = 0x%08x)\n", version ));
597 if ( version != 0x00010000UL )
598 FT_INVALID_FORMAT;
599
600 /* format 0 (always:2000) */
601 GXV_TRACE(( " (format = 0x%04x)\n", format ));
602 if ( format != 0x0000 )
603 FT_INVALID_FORMAT;
604
605 GXV_TRACE(( " (horizOffset = %d)\n", horizOffset ));
606 GXV_TRACE(( " (vertOffset = %d)\n", vertOffset ));
607
608
609 /* validate justData */
610 if ( 0 < horizOffset )
611 {
612 gxv_just_justData_validate( table + horizOffset, limit, valid );
613 gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
614 "horizJustData", odtect );
615 }
616
617 if ( 0 < vertOffset )
618 {
619 gxv_just_justData_validate( table + vertOffset, limit, valid );
620 gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
621 "vertJustData", odtect );
622 }
623
624 gxv_odtect_validate( odtect, valid );
625
626 FT_TRACE4(( "\n" ));
627 }
628
629
630/* END */