/src/freetype/src/otvalid/otvjstf.c
C | 258 lines | 158 code | 64 blank | 36 comment | 18 complexity | ab964cdc3c9211a50cddc563c7f3a2a0 MD5 | raw file
1/***************************************************************************/ 2/* */ 3/* otvjstf.c */ 4/* */ 5/* OpenType JSTF table validation (body). */ 6/* */ 7/* Copyright 2004, 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#include "otvgpos.h" 22 23 24 /*************************************************************************/ 25 /* */ 26 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 27 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 28 /* messages during execution. */ 29 /* */ 30#undef FT_COMPONENT 31#define FT_COMPONENT trace_otvjstf 32 33 34#define JstfPriorityFunc otv_JstfPriority_validate 35#define JstfLookupFunc otv_GPOS_subtable_validate 36 37 /* uses valid->extra1 (GSUB lookup count) */ 38 /* uses valid->extra2 (GPOS lookup count) */ 39 /* sets valid->extra1 (counter) */ 40 41 static void 42 otv_JstfPriority_validate( FT_Bytes table, 43 OTV_Validator valid ) 44 { 45 FT_Bytes p = table; 46 FT_UInt table_size; 47 FT_UInt gsub_lookup_count, gpos_lookup_count; 48 49 OTV_OPTIONAL_TABLE( ShrinkageEnableGSUB ); 50 OTV_OPTIONAL_TABLE( ShrinkageDisableGSUB ); 51 OTV_OPTIONAL_TABLE( ShrinkageEnableGPOS ); 52 OTV_OPTIONAL_TABLE( ShrinkageDisableGPOS ); 53 OTV_OPTIONAL_TABLE( ExtensionEnableGSUB ); 54 OTV_OPTIONAL_TABLE( ExtensionDisableGSUB ); 55 OTV_OPTIONAL_TABLE( ExtensionEnableGPOS ); 56 OTV_OPTIONAL_TABLE( ExtensionDisableGPOS ); 57 OTV_OPTIONAL_TABLE( ShrinkageJstfMax ); 58 OTV_OPTIONAL_TABLE( ExtensionJstfMax ); 59 60 61 OTV_ENTER; 62 OTV_TRACE(( "JstfPriority table\n" )); 63 64 OTV_LIMIT_CHECK( 20 ); 65 66 gsub_lookup_count = valid->extra1; 67 gpos_lookup_count = valid->extra2; 68 69 table_size = 20; 70 71 valid->extra1 = gsub_lookup_count; 72 73 OTV_OPTIONAL_OFFSET( ShrinkageEnableGSUB ); 74 OTV_SIZE_CHECK( ShrinkageEnableGSUB ); 75 if ( ShrinkageEnableGSUB ) 76 otv_x_ux( table + ShrinkageEnableGSUB, valid ); 77 78 OTV_OPTIONAL_OFFSET( ShrinkageDisableGSUB ); 79 OTV_SIZE_CHECK( ShrinkageDisableGSUB ); 80 if ( ShrinkageDisableGSUB ) 81 otv_x_ux( table + ShrinkageDisableGSUB, valid ); 82 83 valid->extra1 = gpos_lookup_count; 84 85 OTV_OPTIONAL_OFFSET( ShrinkageEnableGPOS ); 86 OTV_SIZE_CHECK( ShrinkageEnableGPOS ); 87 if ( ShrinkageEnableGPOS ) 88 otv_x_ux( table + ShrinkageEnableGPOS, valid ); 89 90 OTV_OPTIONAL_OFFSET( ShrinkageDisableGPOS ); 91 OTV_SIZE_CHECK( ShrinkageDisableGPOS ); 92 if ( ShrinkageDisableGPOS ) 93 otv_x_ux( table + ShrinkageDisableGPOS, valid ); 94 95 OTV_OPTIONAL_OFFSET( ShrinkageJstfMax ); 96 OTV_SIZE_CHECK( ShrinkageJstfMax ); 97 if ( ShrinkageJstfMax ) 98 { 99 /* XXX: check lookup types? */ 100 OTV_NEST2( JstfMax, JstfLookup ); 101 OTV_RUN( table + ShrinkageJstfMax, valid ); 102 } 103 104 valid->extra1 = gsub_lookup_count; 105 106 OTV_OPTIONAL_OFFSET( ExtensionEnableGSUB ); 107 OTV_SIZE_CHECK( ExtensionEnableGSUB ); 108 if ( ExtensionEnableGSUB ) 109 otv_x_ux( table + ExtensionEnableGSUB, valid ); 110 111 OTV_OPTIONAL_OFFSET( ExtensionDisableGSUB ); 112 OTV_SIZE_CHECK( ExtensionDisableGSUB ); 113 if ( ExtensionDisableGSUB ) 114 otv_x_ux( table + ExtensionDisableGSUB, valid ); 115 116 valid->extra1 = gpos_lookup_count; 117 118 OTV_OPTIONAL_OFFSET( ExtensionEnableGPOS ); 119 OTV_SIZE_CHECK( ExtensionEnableGPOS ); 120 if ( ExtensionEnableGPOS ) 121 otv_x_ux( table + ExtensionEnableGPOS, valid ); 122 123 OTV_OPTIONAL_OFFSET( ExtensionDisableGPOS ); 124 OTV_SIZE_CHECK( ExtensionDisableGPOS ); 125 if ( ExtensionDisableGPOS ) 126 otv_x_ux( table + ExtensionDisableGPOS, valid ); 127 128 OTV_OPTIONAL_OFFSET( ExtensionJstfMax ); 129 OTV_SIZE_CHECK( ExtensionJstfMax ); 130 if ( ExtensionJstfMax ) 131 { 132 /* XXX: check lookup types? */ 133 OTV_NEST2( JstfMax, JstfLookup ); 134 OTV_RUN( table + ExtensionJstfMax, valid ); 135 } 136 137 valid->extra1 = gsub_lookup_count; 138 valid->extra2 = gpos_lookup_count; 139 140 OTV_EXIT; 141 } 142 143 144 /* sets valid->extra (glyph count) */ 145 /* sets valid->func1 (otv_JstfPriority_validate) */ 146 147 static void 148 otv_JstfScript_validate( FT_Bytes table, 149 OTV_Validator valid ) 150 { 151 FT_Bytes p = table; 152 FT_UInt table_size; 153 FT_UInt JstfLangSysCount; 154 155 OTV_OPTIONAL_TABLE( ExtGlyph ); 156 OTV_OPTIONAL_TABLE( DefJstfLangSys ); 157 158 159 OTV_NAME_ENTER( "JstfScript" ); 160 161 OTV_LIMIT_CHECK( 6 ); 162 OTV_OPTIONAL_OFFSET( ExtGlyph ); 163 OTV_OPTIONAL_OFFSET( DefJstfLangSys ); 164 JstfLangSysCount = FT_NEXT_USHORT( p ); 165 166 OTV_TRACE(( " (JstfLangSysCount = %d)\n", JstfLangSysCount )); 167 168 table_size = JstfLangSysCount * 6 + 6; 169 170 OTV_SIZE_CHECK( ExtGlyph ); 171 if ( ExtGlyph ) 172 { 173 valid->extra1 = valid->glyph_count; 174 OTV_NEST1( ExtenderGlyph ); 175 OTV_RUN( table + ExtGlyph, valid ); 176 } 177 178 OTV_SIZE_CHECK( DefJstfLangSys ); 179 if ( DefJstfLangSys ) 180 { 181 OTV_NEST2( JstfLangSys, JstfPriority ); 182 OTV_RUN( table + DefJstfLangSys, valid ); 183 } 184 185 OTV_LIMIT_CHECK( 6 * JstfLangSysCount ); 186 187 /* JstfLangSysRecord */ 188 OTV_NEST2( JstfLangSys, JstfPriority ); 189 for ( ; JstfLangSysCount > 0; JstfLangSysCount-- ) 190 { 191 p += 4; /* skip JstfLangSysTag */ 192 193 OTV_RUN( table + FT_NEXT_USHORT( p ), valid ); 194 } 195 196 OTV_EXIT; 197 } 198 199 200 /* sets valid->extra1 (GSUB lookup count) */ 201 /* sets valid->extra2 (GPOS lookup count) */ 202 /* sets valid->glyph_count */ 203 204 FT_LOCAL_DEF( void ) 205 otv_JSTF_validate( FT_Bytes table, 206 FT_Bytes gsub, 207 FT_Bytes gpos, 208 FT_UInt glyph_count, 209 FT_Validator ftvalid ) 210 { 211 OTV_ValidatorRec validrec; 212 OTV_Validator valid = &validrec; 213 FT_Bytes p = table; 214 FT_UInt JstfScriptCount; 215 216 217 valid->root = ftvalid; 218 219 FT_TRACE3(( "validating JSTF table\n" )); 220 OTV_INIT; 221 222 OTV_LIMIT_CHECK( 6 ); 223 224 if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ 225 FT_INVALID_FORMAT; 226 227 JstfScriptCount = FT_NEXT_USHORT( p ); 228 229 FT_TRACE3(( " (JstfScriptCount = %d)\n", JstfScriptCount )); 230 231 OTV_LIMIT_CHECK( JstfScriptCount * 6 ); 232 233 if ( gsub ) 234 valid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub ); 235 else 236 valid->extra1 = 0; 237 238 if ( gpos ) 239 valid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos ); 240 else 241 valid->extra2 = 0; 242 243 valid->glyph_count = glyph_count; 244 245 /* JstfScriptRecord */ 246 for ( ; JstfScriptCount > 0; JstfScriptCount-- ) 247 { 248 p += 4; /* skip JstfScriptTag */ 249 250 /* JstfScript */ 251 otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), valid ); 252 } 253 254 FT_TRACE4(( "\n" )); 255 } 256 257 258/* END */