1 /***************************************************************************/ 2 /* */ 3 /* gxvbsln.c */ 4 /* */ 5 /* TrueTypeGX/AAT bsln table validation (body). */ 6 /* */ 7 /* Copyright 2004, 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 /***************************************************************************/ 19 /* */ 20 /* gxvalid is derived from both gxlayout module and otvalid module. */ 21 /* Development of gxlayout is supported by the Information-technology */ 22 /* Promotion Agency(IPA), Japan. */ 23 /* */ 24 /***************************************************************************/ 25 26 27 #include "gxvalid.h" 28 #include "gxvcommn.h" 29 30 31 /*************************************************************************/ 32 /* */ 33 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 34 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 35 /* messages during execution. */ 36 /* */ 37 #undef FT_COMPONENT 38 #define FT_COMPONENT trace_gxvbsln 39 40 41 /*************************************************************************/ 42 /*************************************************************************/ 43 /***** *****/ 44 /***** Data and Types *****/ 45 /***** *****/ 46 /*************************************************************************/ 47 /*************************************************************************/ 48 49 #define GXV_BSLN_VALUE_COUNT 32 50 #define GXV_BSLN_VALUE_EMPTY 0xFFFFU 51 52 53 typedef struct GXV_bsln_DataRec_ 54 { 55 FT_Bytes ctlPoints_p; 56 FT_UShort defaultBaseline; 57 58 } GXV_bsln_DataRec, *GXV_bsln_Data; 59 60 61 #define GXV_BSLN_DATA( field ) GXV_TABLE_DATA( bsln, field ) 62 63 64 /*************************************************************************/ 65 /*************************************************************************/ 66 /***** *****/ 67 /***** UTILITY FUNCTIONS *****/ 68 /***** *****/ 69 /*************************************************************************/ 70 /*************************************************************************/ 71 72 static void gxv_bsln_LookupValue_validate(FT_UShort glyph,GXV_LookupValueCPtr value_p,GXV_Validator valid)73 gxv_bsln_LookupValue_validate( FT_UShort glyph, 74 GXV_LookupValueCPtr value_p, 75 GXV_Validator valid ) 76 { 77 FT_UShort v = value_p->u; 78 FT_UShort* ctlPoints; 79 80 FT_UNUSED( glyph ); 81 82 83 GXV_NAME_ENTER( "lookup value" ); 84 85 if ( v >= GXV_BSLN_VALUE_COUNT ) 86 FT_INVALID_DATA; 87 88 ctlPoints = (FT_UShort*)GXV_BSLN_DATA( ctlPoints_p ); 89 if ( ctlPoints && ctlPoints[v] == GXV_BSLN_VALUE_EMPTY ) 90 FT_INVALID_DATA; 91 92 GXV_EXIT; 93 } 94 95 96 /* 97 +===============+ --------+ 98 | lookup header | | 99 +===============+ | 100 | BinSrchHeader | | 101 +===============+ | 102 | lastGlyph[0] | | 103 +---------------+ | 104 | firstGlyph[0] | | head of lookup table 105 +---------------+ | + 106 | offset[0] | -> | offset [byte] 107 +===============+ | + 108 | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] 109 +---------------+ | 110 | firstGlyph[1] | | 111 +---------------+ | 112 | offset[1] | | 113 +===============+ | 114 | 115 ... | 116 | 117 16bit value array | 118 +===============+ | 119 | value | <-------+ 120 ... 121 */ 122 123 static GXV_LookupValueDesc gxv_bsln_LookupFmt4_transit(FT_UShort relative_gindex,GXV_LookupValueCPtr base_value_p,FT_Bytes lookuptbl_limit,GXV_Validator valid)124 gxv_bsln_LookupFmt4_transit( FT_UShort relative_gindex, 125 GXV_LookupValueCPtr base_value_p, 126 FT_Bytes lookuptbl_limit, 127 GXV_Validator valid ) 128 { 129 FT_Bytes p; 130 FT_Bytes limit; 131 FT_UShort offset; 132 GXV_LookupValueDesc value; 133 134 /* XXX: check range ? */ 135 offset = (FT_UShort)( base_value_p->u + 136 ( relative_gindex * sizeof ( FT_UShort ) ) ); 137 138 p = valid->lookuptbl_head + offset; 139 limit = lookuptbl_limit; 140 GXV_LIMIT_CHECK( 2 ); 141 142 value.u = FT_NEXT_USHORT( p ); 143 144 return value; 145 } 146 147 148 static void gxv_bsln_parts_fmt0_validate(FT_Bytes tables,FT_Bytes limit,GXV_Validator valid)149 gxv_bsln_parts_fmt0_validate( FT_Bytes tables, 150 FT_Bytes limit, 151 GXV_Validator valid ) 152 { 153 FT_Bytes p = tables; 154 155 156 GXV_NAME_ENTER( "parts format 0" ); 157 158 /* deltas */ 159 GXV_LIMIT_CHECK( 2 * GXV_BSLN_VALUE_COUNT ); 160 161 valid->table_data = NULL; /* No ctlPoints here. */ 162 163 GXV_EXIT; 164 } 165 166 167 static void gxv_bsln_parts_fmt1_validate(FT_Bytes tables,FT_Bytes limit,GXV_Validator valid)168 gxv_bsln_parts_fmt1_validate( FT_Bytes tables, 169 FT_Bytes limit, 170 GXV_Validator valid ) 171 { 172 FT_Bytes p = tables; 173 174 175 GXV_NAME_ENTER( "parts format 1" ); 176 177 /* deltas */ 178 gxv_bsln_parts_fmt0_validate( p, limit, valid ); 179 180 /* mappingData */ 181 valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; 182 valid->lookupval_func = gxv_bsln_LookupValue_validate; 183 valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; 184 gxv_LookupTable_validate( p + 2 * GXV_BSLN_VALUE_COUNT, 185 limit, 186 valid ); 187 188 GXV_EXIT; 189 } 190 191 192 static void gxv_bsln_parts_fmt2_validate(FT_Bytes tables,FT_Bytes limit,GXV_Validator valid)193 gxv_bsln_parts_fmt2_validate( FT_Bytes tables, 194 FT_Bytes limit, 195 GXV_Validator valid ) 196 { 197 FT_Bytes p = tables; 198 199 FT_UShort stdGlyph; 200 FT_UShort ctlPoint; 201 FT_Int i; 202 203 FT_UShort defaultBaseline = GXV_BSLN_DATA( defaultBaseline ); 204 205 206 GXV_NAME_ENTER( "parts format 2" ); 207 208 GXV_LIMIT_CHECK( 2 + ( 2 * GXV_BSLN_VALUE_COUNT ) ); 209 210 /* stdGlyph */ 211 stdGlyph = FT_NEXT_USHORT( p ); 212 GXV_TRACE(( " (stdGlyph = %u)\n", stdGlyph )); 213 214 gxv_glyphid_validate( stdGlyph, valid ); 215 216 /* Record the position of ctlPoints */ 217 GXV_BSLN_DATA( ctlPoints_p ) = p; 218 219 /* ctlPoints */ 220 for ( i = 0; i < GXV_BSLN_VALUE_COUNT; i++ ) 221 { 222 ctlPoint = FT_NEXT_USHORT( p ); 223 if ( ctlPoint == GXV_BSLN_VALUE_EMPTY ) 224 { 225 if ( i == defaultBaseline ) 226 FT_INVALID_DATA; 227 } 228 else 229 gxv_ctlPoint_validate( stdGlyph, (FT_Short)ctlPoint, valid ); 230 } 231 232 GXV_EXIT; 233 } 234 235 236 static void gxv_bsln_parts_fmt3_validate(FT_Bytes tables,FT_Bytes limit,GXV_Validator valid)237 gxv_bsln_parts_fmt3_validate( FT_Bytes tables, 238 FT_Bytes limit, 239 GXV_Validator valid) 240 { 241 FT_Bytes p = tables; 242 243 244 GXV_NAME_ENTER( "parts format 3" ); 245 246 /* stdGlyph + ctlPoints */ 247 gxv_bsln_parts_fmt2_validate( p, limit, valid ); 248 249 /* mappingData */ 250 valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; 251 valid->lookupval_func = gxv_bsln_LookupValue_validate; 252 valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; 253 gxv_LookupTable_validate( p + ( 2 + 2 * GXV_BSLN_VALUE_COUNT ), 254 limit, 255 valid ); 256 257 GXV_EXIT; 258 } 259 260 261 /*************************************************************************/ 262 /*************************************************************************/ 263 /***** *****/ 264 /***** bsln TABLE *****/ 265 /***** *****/ 266 /*************************************************************************/ 267 /*************************************************************************/ 268 269 FT_LOCAL_DEF( void ) gxv_bsln_validate(FT_Bytes table,FT_Face face,FT_Validator ftvalid)270 gxv_bsln_validate( FT_Bytes table, 271 FT_Face face, 272 FT_Validator ftvalid ) 273 { 274 GXV_ValidatorRec validrec; 275 GXV_Validator valid = &validrec; 276 277 GXV_bsln_DataRec bslnrec; 278 GXV_bsln_Data bsln = &bslnrec; 279 280 FT_Bytes p = table; 281 FT_Bytes limit = 0; 282 283 FT_ULong version; 284 FT_UShort format; 285 FT_UShort defaultBaseline; 286 287 GXV_Validate_Func fmt_funcs_table [] = 288 { 289 gxv_bsln_parts_fmt0_validate, 290 gxv_bsln_parts_fmt1_validate, 291 gxv_bsln_parts_fmt2_validate, 292 gxv_bsln_parts_fmt3_validate, 293 }; 294 295 296 valid->root = ftvalid; 297 valid->table_data = bsln; 298 valid->face = face; 299 300 FT_TRACE3(( "validating `bsln' table\n" )); 301 GXV_INIT; 302 303 304 GXV_LIMIT_CHECK( 4 + 2 + 2 ); 305 version = FT_NEXT_ULONG( p ); 306 format = FT_NEXT_USHORT( p ); 307 defaultBaseline = FT_NEXT_USHORT( p ); 308 309 /* only version 1.0 is defined (1996) */ 310 if ( version != 0x00010000UL ) 311 FT_INVALID_FORMAT; 312 313 /* only format 1, 2, 3 are defined (1996) */ 314 GXV_TRACE(( " (format = %d)\n", format )); 315 if ( format > 3 ) 316 FT_INVALID_FORMAT; 317 318 if ( defaultBaseline > 31 ) 319 FT_INVALID_FORMAT; 320 321 bsln->defaultBaseline = defaultBaseline; 322 323 fmt_funcs_table[format]( p, limit, valid ); 324 325 FT_TRACE4(( "\n" )); 326 } 327 328 329 /* arch-tag: ebe81143-fdaa-4c68-a4d1-b57227daa3bc 330 (do not change this comment) */ 331 332 333 /* END */ 334