Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygengxvjust.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* gxvjust.c */ 00004 /* */ 00005 /* TrueTypeGX/AAT just table validation (body). */ 00006 /* */ 00007 /* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 /***************************************************************************/ 00019 /* */ 00020 /* gxvalid is derived from both gxlayout module and otvalid module. */ 00021 /* Development of gxlayout is supported by the Information-technology */ 00022 /* Promotion Agency(IPA), Japan. */ 00023 /* */ 00024 /***************************************************************************/ 00025 00026 00027 #include "gxvalid.h" 00028 #include "gxvcommn.h" 00029 00030 #include FT_SFNT_NAMES_H 00031 00032 00033 /*************************************************************************/ 00034 /* */ 00035 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00036 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00037 /* messages during execution. */ 00038 /* */ 00039 #undef FT_COMPONENT 00040 #define FT_COMPONENT trace_gxvjust 00041 00042 /* 00043 * referred `just' table format specification: 00044 * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6just.html 00045 * last updated 2000. 00046 * ---------------------------------------------- 00047 * [JUST HEADER]: GXV_JUST_HEADER_SIZE 00048 * version (fixed: 32bit) = 0x00010000 00049 * format (uint16: 16bit) = 0 is only defined (2000) 00050 * horizOffset (uint16: 16bit) 00051 * vertOffset (uint16: 16bit) 00052 * ---------------------------------------------- 00053 */ 00054 00055 typedef struct GXV_just_DataRec_ 00056 { 00057 FT_UShort wdc_offset_max; 00058 FT_UShort wdc_offset_min; 00059 FT_UShort pc_offset_max; 00060 FT_UShort pc_offset_min; 00061 00062 } GXV_just_DataRec, *GXV_just_Data; 00063 00064 00065 #define GXV_JUST_DATA( a ) GXV_TABLE_DATA( just, a ) 00066 00067 00068 static void 00069 gxv_just_wdp_entry_validate( FT_Bytes table, 00070 FT_Bytes limit, 00071 GXV_Validator valid ) 00072 { 00073 FT_Bytes p = table; 00074 FT_ULong justClass; 00075 FT_Fixed beforeGrowLimit; 00076 FT_Fixed beforeShrinkGrowLimit; 00077 FT_Fixed afterGrowLimit; 00078 FT_Fixed afterShrinkGrowLimit; 00079 FT_UShort growFlags; 00080 FT_UShort shrinkFlags; 00081 00082 00083 GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 ); 00084 justClass = FT_NEXT_ULONG( p ); 00085 beforeGrowLimit = FT_NEXT_ULONG( p ); 00086 beforeShrinkGrowLimit = FT_NEXT_ULONG( p ); 00087 afterGrowLimit = FT_NEXT_ULONG( p ); 00088 afterShrinkGrowLimit = FT_NEXT_ULONG( p ); 00089 growFlags = FT_NEXT_USHORT( p ); 00090 shrinkFlags = FT_NEXT_USHORT( p ); 00091 00092 /* TODO: decode flags for human readability */ 00093 00094 valid->subtable_length = p - table; 00095 } 00096 00097 00098 static void 00099 gxv_just_wdc_entry_validate( FT_Bytes table, 00100 FT_Bytes limit, 00101 GXV_Validator valid ) 00102 { 00103 FT_Bytes p = table; 00104 FT_ULong count, i; 00105 00106 00107 GXV_LIMIT_CHECK( 4 ); 00108 count = FT_NEXT_ULONG( p ); 00109 for ( i = 0; i < count; i++ ) 00110 { 00111 GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count )); 00112 gxv_just_wdp_entry_validate( p, limit, valid ); 00113 p += valid->subtable_length; 00114 } 00115 00116 valid->subtable_length = p - table; 00117 } 00118 00119 00120 static void 00121 gxv_just_widthDeltaClusters_validate( FT_Bytes table, 00122 FT_Bytes limit, 00123 GXV_Validator valid ) 00124 { 00125 FT_Bytes p = table ; 00126 FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max ); 00127 FT_UInt i; 00128 00129 00130 GXV_NAME_ENTER( "just justDeltaClusters" ); 00131 00132 if ( limit <= wdc_end ) 00133 FT_INVALID_OFFSET; 00134 00135 for ( i = 0; p <= wdc_end; i++ ) 00136 { 00137 gxv_just_wdc_entry_validate( p, limit, valid ); 00138 p += valid->subtable_length; 00139 } 00140 00141 valid->subtable_length = p - table; 00142 00143 GXV_EXIT; 00144 } 00145 00146 00147 static void 00148 gxv_just_actSubrecord_type0_validate( FT_Bytes table, 00149 FT_Bytes limit, 00150 GXV_Validator valid ) 00151 { 00152 FT_Bytes p = table; 00153 00154 FT_Fixed lowerLimit; 00155 FT_Fixed upperLimit; 00156 00157 FT_UShort order; 00158 FT_UShort decomposedCount; 00159 00160 FT_UInt i; 00161 00162 00163 GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); 00164 lowerLimit = FT_NEXT_ULONG( p ); 00165 upperLimit = FT_NEXT_ULONG( p ); 00166 order = FT_NEXT_USHORT( p ); 00167 decomposedCount = FT_NEXT_USHORT( p ); 00168 00169 for ( i = 0; i < decomposedCount; i++ ) 00170 { 00171 FT_UShort glyphs; 00172 00173 00174 GXV_LIMIT_CHECK( 2 ); 00175 glyphs = FT_NEXT_USHORT( p ); 00176 } 00177 00178 valid->subtable_length = p - table; 00179 } 00180 00181 00182 static void 00183 gxv_just_actSubrecord_type1_validate( FT_Bytes table, 00184 FT_Bytes limit, 00185 GXV_Validator valid ) 00186 { 00187 FT_Bytes p = table; 00188 FT_UShort addGlyph; 00189 00190 00191 GXV_LIMIT_CHECK( 2 ); 00192 addGlyph = FT_NEXT_USHORT( p ); 00193 00194 valid->subtable_length = p - table; 00195 } 00196 00197 00198 static void 00199 gxv_just_actSubrecord_type2_validate( FT_Bytes table, 00200 FT_Bytes limit, 00201 GXV_Validator valid ) 00202 { 00203 FT_Bytes p = table; 00204 FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */ 00205 FT_UShort addGlyph; 00206 FT_UShort substGlyph; 00207 00208 00209 GXV_LIMIT_CHECK( 4 + 2 + 2 ); 00210 substThreshhold = FT_NEXT_ULONG( p ); 00211 addGlyph = FT_NEXT_USHORT( p ); 00212 substGlyph = FT_NEXT_USHORT( p ); 00213 00214 valid->subtable_length = p - table; 00215 } 00216 00217 00218 static void 00219 gxv_just_actSubrecord_type4_validate( FT_Bytes table, 00220 FT_Bytes limit, 00221 GXV_Validator valid ) 00222 { 00223 FT_Bytes p = table; 00224 FT_ULong variantsAxis; 00225 FT_Fixed minimumLimit; 00226 FT_Fixed noStretchValue; 00227 FT_Fixed maximumLimit; 00228 00229 00230 GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); 00231 variantsAxis = FT_NEXT_ULONG( p ); 00232 minimumLimit = FT_NEXT_ULONG( p ); 00233 noStretchValue = FT_NEXT_ULONG( p ); 00234 maximumLimit = FT_NEXT_ULONG( p ); 00235 00236 valid->subtable_length = p - table; 00237 } 00238 00239 00240 static void 00241 gxv_just_actSubrecord_type5_validate( FT_Bytes table, 00242 FT_Bytes limit, 00243 GXV_Validator valid ) 00244 { 00245 FT_Bytes p = table; 00246 FT_UShort flags; 00247 FT_UShort glyph; 00248 00249 00250 GXV_LIMIT_CHECK( 2 + 2 ); 00251 flags = FT_NEXT_USHORT( p ); 00252 glyph = FT_NEXT_USHORT( p ); 00253 00254 valid->subtable_length = p - table; 00255 } 00256 00257 00258 /* parse single actSubrecord */ 00259 static void 00260 gxv_just_actSubrecord_validate( FT_Bytes table, 00261 FT_Bytes limit, 00262 GXV_Validator valid ) 00263 { 00264 FT_Bytes p = table; 00265 FT_UShort actionClass; 00266 FT_UShort actionType; 00267 FT_ULong actionLength; 00268 00269 00270 GXV_NAME_ENTER( "just actSubrecord" ); 00271 00272 GXV_LIMIT_CHECK( 2 + 2 + 4 ); 00273 actionClass = FT_NEXT_USHORT( p ); 00274 actionType = FT_NEXT_USHORT( p ); 00275 actionLength = FT_NEXT_ULONG( p ); 00276 00277 if ( actionType == 0 ) 00278 gxv_just_actSubrecord_type0_validate( p, limit, valid ); 00279 else if ( actionType == 1 ) 00280 gxv_just_actSubrecord_type1_validate( p, limit, valid ); 00281 else if ( actionType == 2 ) 00282 gxv_just_actSubrecord_type2_validate( p, limit, valid ); 00283 else if ( actionType == 3 ) 00284 ; /* Stretch glyph action: no actionData */ 00285 else if ( actionType == 4 ) 00286 gxv_just_actSubrecord_type4_validate( p, limit, valid ); 00287 else if ( actionType == 5 ) 00288 gxv_just_actSubrecord_type5_validate( p, limit, valid ); 00289 else 00290 FT_INVALID_DATA; 00291 00292 valid->subtable_length = actionLength; 00293 00294 GXV_EXIT; 00295 } 00296 00297 00298 static void 00299 gxv_just_pcActionRecord_validate( FT_Bytes table, 00300 FT_Bytes limit, 00301 GXV_Validator valid ) 00302 { 00303 FT_Bytes p = table; 00304 FT_ULong actionCount; 00305 FT_ULong i; 00306 00307 00308 GXV_LIMIT_CHECK( 4 ); 00309 actionCount = FT_NEXT_ULONG( p ); 00310 GXV_TRACE(( "actionCount = %d\n", actionCount )); 00311 00312 for ( i = 0; i < actionCount; i++ ) 00313 { 00314 gxv_just_actSubrecord_validate( p, limit, valid ); 00315 p += valid->subtable_length; 00316 } 00317 00318 valid->subtable_length = p - table; 00319 00320 GXV_EXIT; 00321 } 00322 00323 00324 static void 00325 gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph, 00326 GXV_LookupValueCPtr value_p, 00327 GXV_Validator valid ) 00328 { 00329 FT_UNUSED( glyph ); 00330 00331 if ( value_p->u > GXV_JUST_DATA( pc_offset_max ) ) 00332 GXV_JUST_DATA( pc_offset_max ) = value_p->u; 00333 if ( value_p->u < GXV_JUST_DATA( pc_offset_max ) ) 00334 GXV_JUST_DATA( pc_offset_min ) = value_p->u; 00335 } 00336 00337 00338 static void 00339 gxv_just_pcLookupTable_validate( FT_Bytes table, 00340 FT_Bytes limit, 00341 GXV_Validator valid ) 00342 { 00343 FT_Bytes p = table; 00344 00345 00346 GXV_NAME_ENTER( "just pcLookupTable" ); 00347 GXV_JUST_DATA( pc_offset_max ) = 0x0000; 00348 GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU; 00349 00350 valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; 00351 valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate; 00352 00353 gxv_LookupTable_validate( p, limit, valid ); 00354 00355 /* subtable_length is set by gxv_LookupTable_validate() */ 00356 00357 GXV_EXIT; 00358 } 00359 00360 00361 static void 00362 gxv_just_postcompTable_validate( FT_Bytes table, 00363 FT_Bytes limit, 00364 GXV_Validator valid ) 00365 { 00366 FT_Bytes p = table; 00367 00368 00369 GXV_NAME_ENTER( "just postcompTable" ); 00370 00371 gxv_just_pcLookupTable_validate( p, limit, valid ); 00372 p += valid->subtable_length; 00373 00374 gxv_just_pcActionRecord_validate( p, limit, valid ); 00375 p += valid->subtable_length; 00376 00377 valid->subtable_length = p - table; 00378 00379 GXV_EXIT; 00380 } 00381 00382 00383 static void 00384 gxv_just_classTable_entry_validate( 00385 FT_Byte state, 00386 FT_UShort flags, 00387 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, 00388 FT_Bytes table, 00389 FT_Bytes limit, 00390 GXV_Validator valid ) 00391 { 00392 FT_UShort setMark; 00393 FT_UShort dontAdvance; 00394 FT_UShort markClass; 00395 FT_UShort currentClass; 00396 00397 FT_UNUSED( state ); 00398 FT_UNUSED( glyphOffset_p ); 00399 FT_UNUSED( table ); 00400 FT_UNUSED( limit ); 00401 FT_UNUSED( valid ); 00402 00403 00404 setMark = (FT_UShort)( ( flags >> 15 ) & 1 ); 00405 dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); 00406 markClass = (FT_UShort)( ( flags >> 7 ) & 0x7F ); 00407 currentClass = (FT_UShort)( flags & 0x7F ); 00408 00409 /* TODO: validate markClass & currentClass */ 00410 } 00411 00412 00413 static void 00414 gxv_just_justClassTable_validate ( FT_Bytes table, 00415 FT_Bytes limit, 00416 GXV_Validator valid ) 00417 { 00418 FT_Bytes p = table; 00419 FT_UShort length; 00420 FT_UShort coverage; 00421 FT_ULong subFeatureFlags; 00422 00423 00424 GXV_NAME_ENTER( "just justClassTable" ); 00425 00426 GXV_LIMIT_CHECK( 2 + 2 + 4 ); 00427 length = FT_NEXT_USHORT( p ); 00428 coverage = FT_NEXT_USHORT( p ); 00429 subFeatureFlags = FT_NEXT_ULONG( p ); 00430 00431 GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s)", 00432 coverage, 00433 ( 0x4000 & coverage ) == 0 ? "ascending" : "descending" )); 00434 00435 valid->statetable.optdata = NULL; 00436 valid->statetable.optdata_load_func = NULL; 00437 valid->statetable.subtable_setup_func = NULL; 00438 valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; 00439 valid->statetable.entry_validate_func = 00440 gxv_just_classTable_entry_validate; 00441 00442 gxv_StateTable_validate( p, table + length, valid ); 00443 00444 /* subtable_length is set by gxv_LookupTable_validate() */ 00445 00446 GXV_EXIT; 00447 } 00448 00449 00450 static void 00451 gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph, 00452 GXV_LookupValueCPtr value_p, 00453 GXV_Validator valid ) 00454 { 00455 FT_UNUSED( glyph ); 00456 00457 if ( value_p->u > GXV_JUST_DATA( wdc_offset_max ) ) 00458 GXV_JUST_DATA( wdc_offset_max ) = value_p->u; 00459 if ( value_p->u < GXV_JUST_DATA( wdc_offset_min ) ) 00460 GXV_JUST_DATA( wdc_offset_min ) = value_p->u; 00461 } 00462 00463 00464 static void 00465 gxv_just_justData_lookuptable_validate( FT_Bytes table, 00466 FT_Bytes limit, 00467 GXV_Validator valid ) 00468 { 00469 FT_Bytes p = table; 00470 00471 00472 GXV_JUST_DATA( wdc_offset_max ) = 0x0000; 00473 GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU; 00474 00475 valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; 00476 valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate; 00477 00478 gxv_LookupTable_validate( p, limit, valid ); 00479 00480 /* subtable_length is set by gxv_LookupTable_validate() */ 00481 00482 GXV_EXIT; 00483 } 00484 00485 00486 /* 00487 * gxv_just_justData_validate() parses and validates horizData, vertData. 00488 */ 00489 static void 00490 gxv_just_justData_validate( FT_Bytes table, 00491 FT_Bytes limit, 00492 GXV_Validator valid ) 00493 { 00494 /* 00495 * following 3 offsets are measured from the start of `just' 00496 * (which table points to), not justData 00497 */ 00498 FT_UShort justClassTableOffset; 00499 FT_UShort wdcTableOffset; 00500 FT_UShort pcTableOffset; 00501 FT_Bytes p = table; 00502 00503 GXV_ODTECT( 4, odtect ); 00504 00505 00506 GXV_NAME_ENTER( "just justData" ); 00507 00508 GXV_ODTECT_INIT( odtect ); 00509 GXV_LIMIT_CHECK( 2 + 2 + 2 ); 00510 justClassTableOffset = FT_NEXT_USHORT( p ); 00511 wdcTableOffset = FT_NEXT_USHORT( p ); 00512 pcTableOffset = FT_NEXT_USHORT( p ); 00513 00514 GXV_TRACE(( " (justClassTableOffset = 0x%04x)\n", justClassTableOffset )); 00515 GXV_TRACE(( " (wdcTableOffset = 0x%04x)\n", wdcTableOffset )); 00516 GXV_TRACE(( " (pcTableOffset = 0x%04x)\n", pcTableOffset )); 00517 00518 gxv_just_justData_lookuptable_validate( p, limit, valid ); 00519 gxv_odtect_add_range( p, valid->subtable_length, 00520 "just_LookupTable", odtect ); 00521 00522 if ( wdcTableOffset ) 00523 { 00524 gxv_just_widthDeltaClusters_validate( 00525 valid->root->base + wdcTableOffset, limit, valid ); 00526 gxv_odtect_add_range( valid->root->base + wdcTableOffset, 00527 valid->subtable_length, "just_wdcTable", odtect ); 00528 } 00529 00530 if ( pcTableOffset ) 00531 { 00532 gxv_just_postcompTable_validate( valid->root->base + pcTableOffset, 00533 limit, valid ); 00534 gxv_odtect_add_range( valid->root->base + pcTableOffset, 00535 valid->subtable_length, "just_pcTable", odtect ); 00536 } 00537 00538 if ( justClassTableOffset ) 00539 { 00540 gxv_just_justClassTable_validate( 00541 valid->root->base + justClassTableOffset, limit, valid ); 00542 gxv_odtect_add_range( valid->root->base + justClassTableOffset, 00543 valid->subtable_length, "just_justClassTable", 00544 odtect ); 00545 } 00546 00547 gxv_odtect_validate( odtect, valid ); 00548 00549 GXV_EXIT; 00550 } 00551 00552 00553 FT_LOCAL_DEF( void ) 00554 gxv_just_validate( FT_Bytes table, 00555 FT_Face face, 00556 FT_Validator ftvalid ) 00557 { 00558 FT_Bytes p = table; 00559 FT_Bytes limit = 0; 00560 FT_Offset table_size; 00561 00562 GXV_ValidatorRec validrec; 00563 GXV_Validator valid = &validrec; 00564 GXV_just_DataRec justrec; 00565 GXV_just_Data just = &justrec; 00566 00567 FT_ULong version; 00568 FT_UShort format; 00569 FT_UShort horizOffset; 00570 FT_UShort vertOffset; 00571 00572 GXV_ODTECT( 3, odtect ); 00573 00574 00575 GXV_ODTECT_INIT( odtect ); 00576 00577 valid->root = ftvalid; 00578 valid->table_data = just; 00579 valid->face = face; 00580 00581 FT_TRACE3(( "validating `just' table\n" )); 00582 GXV_INIT; 00583 00584 limit = valid->root->limit; 00585 table_size = limit - table; 00586 00587 GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 ); 00588 version = FT_NEXT_ULONG( p ); 00589 format = FT_NEXT_USHORT( p ); 00590 horizOffset = FT_NEXT_USHORT( p ); 00591 vertOffset = FT_NEXT_USHORT( p ); 00592 gxv_odtect_add_range( table, p - table, "just header", odtect ); 00593 00594 00595 /* Version 1.0 (always:2000) */ 00596 GXV_TRACE(( " (version = 0x%08x)\n", version )); 00597 if ( version != 0x00010000UL ) 00598 FT_INVALID_FORMAT; 00599 00600 /* format 0 (always:2000) */ 00601 GXV_TRACE(( " (format = 0x%04x)\n", format )); 00602 if ( format != 0x0000 ) 00603 FT_INVALID_FORMAT; 00604 00605 GXV_TRACE(( " (horizOffset = %d)\n", horizOffset )); 00606 GXV_TRACE(( " (vertOffset = %d)\n", vertOffset )); 00607 00608 00609 /* validate justData */ 00610 if ( 0 < horizOffset ) 00611 { 00612 gxv_just_justData_validate( table + horizOffset, limit, valid ); 00613 gxv_odtect_add_range( table + horizOffset, valid->subtable_length, 00614 "horizJustData", odtect ); 00615 } 00616 00617 if ( 0 < vertOffset ) 00618 { 00619 gxv_just_justData_validate( table + vertOffset, limit, valid ); 00620 gxv_odtect_add_range( table + vertOffset, valid->subtable_length, 00621 "vertJustData", odtect ); 00622 } 00623 00624 gxv_odtect_validate( odtect, valid ); 00625 00626 FT_TRACE4(( "\n" )); 00627 } 00628 00629 00630 /* END */ Generated on Sat May 26 2012 04:32:44 for ReactOS by
1.7.6.1
|