1 /***************************************************************************/ 2 /* */ 3 /* gxvlcar.c */ 4 /* */ 5 /* TrueTypeGX/AAT lcar table validation (body). */ 6 /* */ 7 /* Copyright 2004-2018 by */ 8 /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ 9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 10 /* */ 11 /* This file is part of the FreeType project, and may only be used, */ 12 /* modified, and distributed under the terms of the FreeType project */ 13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 14 /* this file you indicate that you have read the license and */ 15 /* understand and accept it fully. */ 16 /* */ 17 /***************************************************************************/ 18 19 /***************************************************************************/ 20 /* */ 21 /* gxvalid is derived from both gxlayout module and otvalid module. */ 22 /* Development of gxlayout is supported by the Information-technology */ 23 /* Promotion Agency(IPA), Japan. */ 24 /* */ 25 /***************************************************************************/ 26 27 28 #include "gxvalid.h" 29 #include "gxvcommn.h" 30 31 32 /*************************************************************************/ 33 /* */ 34 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 35 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 36 /* messages during execution. */ 37 /* */ 38 #undef FT_COMPONENT 39 #define FT_COMPONENT trace_gxvlcar 40 41 42 /*************************************************************************/ 43 /*************************************************************************/ 44 /***** *****/ 45 /***** Data and Types *****/ 46 /***** *****/ 47 /*************************************************************************/ 48 /*************************************************************************/ 49 50 typedef struct GXV_lcar_DataRec_ 51 { 52 FT_UShort format; 53 54 } GXV_lcar_DataRec, *GXV_lcar_Data; 55 56 57 #define GXV_LCAR_DATA( FIELD ) GXV_TABLE_DATA( lcar, FIELD ) 58 59 60 /*************************************************************************/ 61 /*************************************************************************/ 62 /***** *****/ 63 /***** UTILITY FUNCTIONS *****/ 64 /***** *****/ 65 /*************************************************************************/ 66 /*************************************************************************/ 67 68 static void gxv_lcar_partial_validate(FT_Short partial,FT_UShort glyph,GXV_Validator gxvalid)69 gxv_lcar_partial_validate( FT_Short partial, 70 FT_UShort glyph, 71 GXV_Validator gxvalid ) 72 { 73 GXV_NAME_ENTER( "partial" ); 74 75 if ( GXV_LCAR_DATA( format ) != 1 ) 76 goto Exit; 77 78 gxv_ctlPoint_validate( glyph, (FT_UShort)partial, gxvalid ); 79 80 Exit: 81 GXV_EXIT; 82 } 83 84 85 static void gxv_lcar_LookupValue_validate(FT_UShort glyph,GXV_LookupValueCPtr value_p,GXV_Validator gxvalid)86 gxv_lcar_LookupValue_validate( FT_UShort glyph, 87 GXV_LookupValueCPtr value_p, 88 GXV_Validator gxvalid ) 89 { 90 FT_Bytes p = gxvalid->root->base + value_p->u; 91 FT_Bytes limit = gxvalid->root->limit; 92 FT_UShort count; 93 FT_Short partial; 94 FT_UShort i; 95 96 97 GXV_NAME_ENTER( "element in lookupTable" ); 98 99 GXV_LIMIT_CHECK( 2 ); 100 count = FT_NEXT_USHORT( p ); 101 102 GXV_LIMIT_CHECK( 2 * count ); 103 for ( i = 0; i < count; i++ ) 104 { 105 partial = FT_NEXT_SHORT( p ); 106 gxv_lcar_partial_validate( partial, glyph, gxvalid ); 107 } 108 109 GXV_EXIT; 110 } 111 112 113 /* 114 +------ lcar --------------------+ 115 | | 116 | +===============+ | 117 | | lookup header | | 118 | +===============+ | 119 | | BinSrchHeader | | 120 | +===============+ | 121 | | lastGlyph[0] | | 122 | +---------------+ | 123 | | firstGlyph[0] | | head of lcar sfnt table 124 | +---------------+ | + 125 | | offset[0] | -> | offset [byte] 126 | +===============+ | + 127 | | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] 128 | +---------------+ | 129 | | firstGlyph[1] | | 130 | +---------------+ | 131 | | offset[1] | | 132 | +===============+ | 133 | | 134 | .... | 135 | | 136 | 16bit value array | 137 | +===============+ | 138 +------| value | <-------+ 139 | .... 140 | 141 | 142 | 143 | 144 | 145 +----> lcar values...handled by lcar callback function 146 */ 147 148 static GXV_LookupValueDesc gxv_lcar_LookupFmt4_transit(FT_UShort relative_gindex,GXV_LookupValueCPtr base_value_p,FT_Bytes lookuptbl_limit,GXV_Validator gxvalid)149 gxv_lcar_LookupFmt4_transit( FT_UShort relative_gindex, 150 GXV_LookupValueCPtr base_value_p, 151 FT_Bytes lookuptbl_limit, 152 GXV_Validator gxvalid ) 153 { 154 FT_Bytes p; 155 FT_Bytes limit; 156 FT_UShort offset; 157 GXV_LookupValueDesc value; 158 159 FT_UNUSED( lookuptbl_limit ); 160 161 /* XXX: check range? */ 162 offset = (FT_UShort)( base_value_p->u + 163 relative_gindex * sizeof ( FT_UShort ) ); 164 p = gxvalid->root->base + offset; 165 limit = gxvalid->root->limit; 166 167 GXV_LIMIT_CHECK ( 2 ); 168 value.u = FT_NEXT_USHORT( p ); 169 170 return value; 171 } 172 173 174 /*************************************************************************/ 175 /*************************************************************************/ 176 /***** *****/ 177 /***** lcar TABLE *****/ 178 /***** *****/ 179 /*************************************************************************/ 180 /*************************************************************************/ 181 182 FT_LOCAL_DEF( void ) gxv_lcar_validate(FT_Bytes table,FT_Face face,FT_Validator ftvalid)183 gxv_lcar_validate( FT_Bytes table, 184 FT_Face face, 185 FT_Validator ftvalid ) 186 { 187 FT_Bytes p = table; 188 FT_Bytes limit = 0; 189 GXV_ValidatorRec gxvalidrec; 190 GXV_Validator gxvalid = &gxvalidrec; 191 192 GXV_lcar_DataRec lcarrec; 193 GXV_lcar_Data lcar = &lcarrec; 194 195 FT_Fixed version; 196 197 198 gxvalid->root = ftvalid; 199 gxvalid->table_data = lcar; 200 gxvalid->face = face; 201 202 FT_TRACE3(( "validating `lcar' table\n" )); 203 GXV_INIT; 204 205 GXV_LIMIT_CHECK( 4 + 2 ); 206 version = FT_NEXT_LONG( p ); 207 GXV_LCAR_DATA( format ) = FT_NEXT_USHORT( p ); 208 209 if ( version != 0x00010000UL) 210 FT_INVALID_FORMAT; 211 212 if ( GXV_LCAR_DATA( format ) > 1 ) 213 FT_INVALID_FORMAT; 214 215 gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; 216 gxvalid->lookupval_func = gxv_lcar_LookupValue_validate; 217 gxvalid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; 218 gxv_LookupTable_validate( p, limit, gxvalid ); 219 220 FT_TRACE4(( "\n" )); 221 } 222 223 224 /* END */ 225