Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 1 | /***************************************************************************/ |
| 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 19 | /* */ |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 20 | /* gxvalid is derived from both gxlayout module and otvalid module. */ |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 21 | /* Development of gxlayout is supported by the Information-technology */ |
| 22 | /* Promotion Agency(IPA), Japan. */ |
| 23 | /* */ |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 24 | /***************************************************************************/ |
| 25 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 26 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 27 | #include "gxvalid.h" |
| 28 | #include "gxvcommn.h" |
| 29 | |
| 30 | #include FT_SFNT_NAMES_H |
| 31 | |
| 32 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 33 | /*************************************************************************/ |
| 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 42 | /* |
| 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 (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 55 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 64 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 65 | #define GXV_JUST_DATA( a ) GXV_TABLE_DATA( just, a ) |
| 66 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 67 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 68 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 92 | /* TODO: decode flags for human readability */ |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 93 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 94 | valid->subtable_length = p - table; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 95 | } |
| 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 Lemberg | 99aa14c | 2005-09-05 19:31:27 +0000 | [diff] [blame] | 111 | GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count )); |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 112 | gxv_just_wdp_entry_validate( p, limit, valid ); |
| 113 | p += valid->subtable_length; |
| 114 | } |
| 115 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 116 | valid->subtable_length = p - table; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 117 | } |
| 118 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 119 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 120 | static void |
| 121 | gxv_just_widthDeltaClusters_validate( FT_Bytes table, |
| 122 | FT_Bytes limit, |
| 123 | GXV_Validator valid ) |
| 124 | { |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 125 | FT_Bytes p = table ; |
| 126 | FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max ); |
| 127 | FT_UInt i; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 128 | |
| 129 | |
| 130 | GXV_NAME_ENTER( "just justDeltaClusters" ); |
| 131 | |
| 132 | if ( limit <= wdc_end ) |
| 133 | FT_INVALID_OFFSET; |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 134 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 135 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 141 | valid->subtable_length = p - table; |
| 142 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 143 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 152 | 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 (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 161 | |
| 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 178 | valid->subtable_length = p - table; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 179 | } |
| 180 | |
| 181 | |
| 182 | static void |
| 183 | gxv_just_actSubrecord_type1_validate( FT_Bytes table, |
| 184 | FT_Bytes limit, |
| 185 | GXV_Validator valid ) |
| 186 | { |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 187 | FT_Bytes p = table; |
| 188 | FT_UShort addGlyph; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 189 | |
| 190 | |
| 191 | GXV_LIMIT_CHECK( 2 ); |
| 192 | addGlyph = FT_NEXT_USHORT( p ); |
| 193 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 194 | valid->subtable_length = p - table; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 195 | } |
| 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 214 | valid->subtable_length = p - table; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 215 | } |
| 216 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 217 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 218 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 236 | valid->subtable_length = p - table; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 237 | } |
| 238 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 239 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 240 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 254 | valid->subtable_length = p - table; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 255 | } |
| 256 | |
| 257 | |
| 258 | /* parse single actSubrecord */ |
| 259 | static void |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 260 | gxv_just_actSubrecord_validate( FT_Bytes table, |
| 261 | FT_Bytes limit, |
| 262 | GXV_Validator valid ) |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 263 | { |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 264 | FT_Bytes p = table; |
| 265 | FT_UShort actionClass; |
| 266 | FT_UShort actionType; |
| 267 | FT_ULong actionLength; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 268 | |
| 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 284 | ; /* Stretch glyph action: no actionData */ |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 285 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 293 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 294 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 318 | valid->subtable_length = p - table; |
| 319 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 320 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 329 | FT_UNUSED( glyph ); |
| 330 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 331 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 345 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 346 | GXV_NAME_ENTER( "just pcLookupTable" ); |
| 347 | GXV_JUST_DATA( pc_offset_max ) = 0x0000; |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 348 | GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 349 | |
| 350 | valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; |
| 351 | valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate; |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 352 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 353 | gxv_LookupTable_validate( p, limit, valid ); |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 354 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 355 | /* subtable_length is set by gxv_LookupTable_validate() */ |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 356 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 357 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 366 | FT_Bytes p = table; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 367 | |
| 368 | |
| 369 | GXV_NAME_ENTER( "just postcompTable" ); |
| 370 | |
| 371 | gxv_just_pcLookupTable_validate( p, limit, valid ); |
| 372 | p += valid->subtable_length; |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 373 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 374 | gxv_just_pcActionRecord_validate( p, limit, valid ); |
| 375 | p += valid->subtable_length; |
| 376 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 377 | valid->subtable_length = p - table; |
| 378 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 379 | GXV_EXIT; |
| 380 | } |
| 381 | |
| 382 | |
| 383 | static void |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 384 | 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 (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 391 | { |
| 392 | FT_UShort setMark; |
| 393 | FT_UShort dontAdvance; |
| 394 | FT_UShort markClass; |
| 395 | FT_UShort currentClass; |
| 396 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 397 | FT_UNUSED( state ); |
| 398 | FT_UNUSED( glyphOffset ); |
| 399 | FT_UNUSED( table ); |
| 400 | FT_UNUSED( limit ); |
| 401 | FT_UNUSED( valid ); |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 402 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 403 | |
Werner Lemberg | 7c25946 | 2005-09-28 07:34:45 +0000 | [diff] [blame] | 404 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 408 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 409 | /* 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 431 | GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s)", |
| 432 | coverage, |
| 433 | ( 0x4000 & coverage ) == 0 ? "ascending" : "descending" )); |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 434 | |
| 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 439 | valid->statetable.entry_validate_func = |
| 440 | gxv_just_classTable_entry_validate; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 441 | |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 442 | gxv_StateTable_validate( p, table + length, valid ); |
| 443 | |
| 444 | /* subtable_length is set by gxv_LookupTable_validate() */ |
| 445 | |
| 446 | GXV_EXIT; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 447 | } |
| 448 | |
| 449 | |
| 450 | static void |
| 451 | gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph, |
| 452 | GXV_LookupValueDesc value, |
| 453 | GXV_Validator valid ) |
| 454 | { |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 455 | FT_UNUSED( glyph ); |
| 456 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 457 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 469 | FT_Bytes p = table; |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 470 | |
| 471 | |
| 472 | GXV_JUST_DATA( wdc_offset_max ) = 0x0000; |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 473 | GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU; |
| 474 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 475 | valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; |
| 476 | valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate; |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 477 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 478 | gxv_LookupTable_validate( p, limit, valid ); |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 479 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 480 | /* subtable_length is set by gxv_LookupTable_validate() */ |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 481 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 482 | GXV_EXIT; |
| 483 | } |
| 484 | |
| 485 | |
| 486 | /* |
| 487 | * gxv_just_justData_validate() parses and validates horizData, vertData. |
| 488 | */ |
| 489 | static void |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 490 | gxv_just_justData_validate( FT_Bytes table, |
| 491 | FT_Bytes limit, |
| 492 | GXV_Validator valid ) |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 493 | { |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 494 | /* |
| 495 | * following 3 offsets are measured from the start of `just' |
| 496 | * (which table points to), not justData |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 497 | */ |
| 498 | FT_UShort justClassTableOffset; |
| 499 | FT_UShort wdcTableOffset; |
| 500 | FT_UShort pcTableOffset; |
| 501 | FT_Bytes p = table; |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 502 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 503 | 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 (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 518 | gxv_just_justData_lookuptable_validate( p, limit, valid ); |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 519 | gxv_odtect_add_range( p, valid->subtable_length, |
| 520 | "just_LookupTable", odtect ); |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 521 | |
| 522 | if ( wdcTableOffset ) |
| 523 | { |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 524 | gxv_just_widthDeltaClusters_validate( |
| 525 | valid->root->base + wdcTableOffset, limit, valid ); |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 526 | 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 540 | gxv_just_justClassTable_validate( |
| 541 | valid->root->base + justClassTableOffset, limit, valid ); |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 542 | gxv_odtect_add_range( valid->root->base + justClassTableOffset, |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 543 | valid->subtable_length, "just_justClassTable", |
| 544 | odtect ); |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 545 | } |
| 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 Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 581 | FT_TRACE3(( "validating `just' table\n" )); |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 582 | GXV_INIT; |
| 583 | |
| 584 | limit = valid->root->limit; |
| 585 | table_size = limit - table; |
Werner Lemberg | a4aa1c5 | 2005-08-31 22:39:23 +0000 | [diff] [blame] | 586 | |
Suzuki, Toshiya (鈴木俊哉) | a438621 | 2005-08-24 04:31:31 +0000 | [diff] [blame] | 587 | 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 */ |