1 /***************************************************************************/ 2 /* */ 3 /* otvgdef.c */ 4 /* */ 5 /* OpenType GDEF table validation (body). */ 6 /* */ 7 /* Copyright 2004, 2005, 2007 by */ 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 #include "otvalid.h" 20 #include "otvcommn.h" 21 22 23 /*************************************************************************/ 24 /* */ 25 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 26 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 27 /* messages during execution. */ 28 /* */ 29 #undef FT_COMPONENT 30 #define FT_COMPONENT trace_otvgdef 31 32 33 /*************************************************************************/ 34 /*************************************************************************/ 35 /***** *****/ 36 /***** UTILITY FUNCTIONS *****/ 37 /***** *****/ 38 /*************************************************************************/ 39 /*************************************************************************/ 40 41 #define AttachListFunc otv_O_x_Ox 42 #define LigCaretListFunc otv_O_x_Ox 43 44 /* sets valid->extra1 (0) */ 45 46 static void otv_O_x_Ox(FT_Bytes table,OTV_Validator valid)47 otv_O_x_Ox( FT_Bytes table, 48 OTV_Validator valid ) 49 { 50 FT_Bytes p = table; 51 FT_Bytes Coverage; 52 FT_UInt GlyphCount; 53 OTV_Validate_Func func; 54 55 56 OTV_ENTER; 57 58 OTV_LIMIT_CHECK( 4 ); 59 Coverage = table + FT_NEXT_USHORT( p ); 60 GlyphCount = FT_NEXT_USHORT( p ); 61 62 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); 63 64 otv_Coverage_validate( Coverage, valid, GlyphCount ); 65 if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) 66 FT_INVALID_DATA; 67 68 OTV_LIMIT_CHECK( GlyphCount * 2 ); 69 70 valid->nesting_level++; 71 func = valid->func[valid->nesting_level]; 72 valid->extra1 = 0; 73 74 for ( ; GlyphCount > 0; GlyphCount-- ) 75 func( table + FT_NEXT_USHORT( p ), valid ); 76 77 valid->nesting_level--; 78 79 OTV_EXIT; 80 } 81 82 83 /*************************************************************************/ 84 /*************************************************************************/ 85 /***** *****/ 86 /***** LIGATURE CARETS *****/ 87 /***** *****/ 88 /*************************************************************************/ 89 /*************************************************************************/ 90 91 #define CaretValueFunc otv_CaretValue_validate 92 93 static void otv_CaretValue_validate(FT_Bytes table,OTV_Validator valid)94 otv_CaretValue_validate( FT_Bytes table, 95 OTV_Validator valid ) 96 { 97 FT_Bytes p = table; 98 FT_UInt CaretValueFormat; 99 100 101 OTV_ENTER; 102 103 OTV_LIMIT_CHECK( 4 ); 104 105 CaretValueFormat = FT_NEXT_USHORT( p ); 106 107 OTV_TRACE(( " (format = %d)\n", CaretValueFormat )); 108 109 switch ( CaretValueFormat ) 110 { 111 case 1: /* CaretValueFormat1 */ 112 /* skip Coordinate, no test */ 113 break; 114 115 case 2: /* CaretValueFormat2 */ 116 /* skip CaretValuePoint, no test */ 117 break; 118 119 case 3: /* CaretValueFormat3 */ 120 p += 2; /* skip Coordinate */ 121 122 OTV_LIMIT_CHECK( 2 ); 123 124 /* DeviceTable */ 125 otv_Device_validate( table + FT_NEXT_USHORT( p ), valid ); 126 break; 127 128 default: 129 FT_INVALID_FORMAT; 130 } 131 132 OTV_EXIT; 133 } 134 135 136 /*************************************************************************/ 137 /*************************************************************************/ 138 /***** *****/ 139 /***** GDEF TABLE *****/ 140 /***** *****/ 141 /*************************************************************************/ 142 /*************************************************************************/ 143 144 /* sets valid->glyph_count */ 145 146 FT_LOCAL_DEF( void ) otv_GDEF_validate(FT_Bytes table,FT_Bytes gsub,FT_Bytes gpos,FT_UInt glyph_count,FT_Validator ftvalid)147 otv_GDEF_validate( FT_Bytes table, 148 FT_Bytes gsub, 149 FT_Bytes gpos, 150 FT_UInt glyph_count, 151 FT_Validator ftvalid ) 152 { 153 OTV_ValidatorRec validrec; 154 OTV_Validator valid = &validrec; 155 FT_Bytes p = table; 156 FT_UInt table_size; 157 FT_Bool need_MarkAttachClassDef; 158 159 OTV_OPTIONAL_TABLE( GlyphClassDef ); 160 OTV_OPTIONAL_TABLE( AttachListOffset ); 161 OTV_OPTIONAL_TABLE( LigCaretListOffset ); 162 OTV_OPTIONAL_TABLE( MarkAttachClassDef ); 163 164 165 valid->root = ftvalid; 166 167 FT_TRACE3(( "validating GDEF table\n" )); 168 OTV_INIT; 169 170 OTV_LIMIT_CHECK( 12 ); 171 172 if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ 173 FT_INVALID_FORMAT; 174 175 /* MarkAttachClassDef has been added to the OpenType */ 176 /* specification without increasing GDEF's version, */ 177 /* so we use this ugly hack to find out whether the */ 178 /* table is needed actually. */ 179 180 need_MarkAttachClassDef = FT_BOOL( 181 otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) || 182 otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) ); 183 184 if ( need_MarkAttachClassDef ) 185 table_size = 12; /* OpenType >= 1.2 */ 186 else 187 table_size = 10; /* OpenType < 1.2 */ 188 189 valid->glyph_count = glyph_count; 190 191 OTV_OPTIONAL_OFFSET( GlyphClassDef ); 192 OTV_SIZE_CHECK( GlyphClassDef ); 193 if ( GlyphClassDef ) 194 otv_ClassDef_validate( table + GlyphClassDef, valid ); 195 196 OTV_OPTIONAL_OFFSET( AttachListOffset ); 197 OTV_SIZE_CHECK( AttachListOffset ); 198 if ( AttachListOffset ) 199 { 200 OTV_NEST2( AttachList, AttachPoint ); 201 OTV_RUN( table + AttachListOffset, valid ); 202 } 203 204 OTV_OPTIONAL_OFFSET( LigCaretListOffset ); 205 OTV_SIZE_CHECK( LigCaretListOffset ); 206 if ( LigCaretListOffset ) 207 { 208 OTV_NEST3( LigCaretList, LigGlyph, CaretValue ); 209 OTV_RUN( table + LigCaretListOffset, valid ); 210 } 211 212 if ( need_MarkAttachClassDef ) 213 { 214 OTV_OPTIONAL_OFFSET( MarkAttachClassDef ); 215 OTV_SIZE_CHECK( MarkAttachClassDef ); 216 if ( MarkAttachClassDef ) 217 otv_ClassDef_validate( table + MarkAttachClassDef, valid ); 218 } 219 220 FT_TRACE4(( "\n" )); 221 } 222 223 224 /* END */ 225