16 |
/***************************************************************************/ |
/***************************************************************************/ |
17 |
|
|
18 |
/***************************************************************************/ |
/***************************************************************************/ |
19 |
|
/* */ |
20 |
/* gxvalid is derived from both gxlayout module and otvalid module. */ |
/* gxvalid is derived from both gxlayout module and otvalid module. */ |
21 |
/* Development of gxlayout was support of Information-technology Promotion */ |
/* Development of gxlayout is supported by the Information-technology */ |
22 |
/* Agency(IPA), Japan. */ |
/* Promotion Agency(IPA), Japan. */ |
23 |
|
/* */ |
24 |
/***************************************************************************/ |
/***************************************************************************/ |
25 |
|
|
26 |
|
|
28 |
#include "gxvcommn.h" |
#include "gxvcommn.h" |
29 |
|
|
30 |
|
|
|
|
|
31 |
/*************************************************************************/ |
/*************************************************************************/ |
32 |
/* */ |
/* */ |
33 |
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
55 |
FT_Byte nSettings; |
FT_Byte nSettings; |
56 |
|
|
57 |
} GX_Feature_RegistryRec; |
} GX_Feature_RegistryRec; |
|
#define gxv_feat_registry_length ( sizeof ( gxv_feat_registry ) / sizeof ( GX_Feature_RegistryRec ) ) |
|
58 |
|
|
59 |
static GX_Feature_RegistryRec gxv_feat_registry [] = |
|
60 |
|
#define gxv_feat_registry_length \ |
61 |
|
( sizeof ( gxv_feat_registry ) / \ |
62 |
|
sizeof ( GX_Feature_RegistryRec ) ) |
63 |
|
|
64 |
|
|
65 |
|
static GX_Feature_RegistryRec gxv_feat_registry[] = |
66 |
{ |
{ |
67 |
/* Generated from gxvfgen.c */ |
/* Generated from gxvfgen.c */ |
68 |
{1, 0, 0, 1}, /* All Typographic Features */ |
{1, 0, 0, 1}, /* All Typographic Features */ |
171 |
{1, 0, 1, 4}, /* CJK Roman Spacing */ |
{1, 0, 1, 4}, /* CJK Roman Spacing */ |
172 |
}; |
}; |
173 |
|
|
174 |
|
|
175 |
/*************************************************************************/ |
/*************************************************************************/ |
176 |
/*************************************************************************/ |
/*************************************************************************/ |
177 |
/***** *****/ |
/***** *****/ |
180 |
/*************************************************************************/ |
/*************************************************************************/ |
181 |
/*************************************************************************/ |
/*************************************************************************/ |
182 |
|
|
|
|
|
183 |
typedef struct GXV_feat_DataRec_ |
typedef struct GXV_feat_DataRec_ |
184 |
{ |
{ |
185 |
FT_UInt reserved_size; |
FT_UInt reserved_size; |
187 |
FT_UShort setting; |
FT_UShort setting; |
188 |
|
|
189 |
} GXV_feat_DataRec, *GXV_feat_Data; |
} GXV_feat_DataRec, *GXV_feat_Data; |
190 |
#define GXV_FEAT_DATA(field) GXV_TABLE_DATA( feat, field ) |
|
191 |
|
|
192 |
|
#define GXV_FEAT_DATA( field ) GXV_TABLE_DATA( feat, field ) |
193 |
|
|
194 |
|
|
195 |
typedef enum |
typedef enum |
196 |
{ |
{ |
197 |
GXV_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000, |
GXV_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000U, |
198 |
GXV_FEAT_MASK_DYNAMIC_DEFAULT = 0x4000, |
GXV_FEAT_MASK_DYNAMIC_DEFAULT = 0x4000, |
199 |
GXV_FEAT_MASK_UNUSED = 0x3F00, |
GXV_FEAT_MASK_UNUSED = 0x3F00, |
200 |
GXV_FEAT_MASK_DEFAULT_SETTING = 0x00FF |
GXV_FEAT_MASK_DEFAULT_SETTING = 0x00FF |
201 |
|
|
202 |
} GXV_FeatureFlagsMask ; |
} GXV_FeatureFlagsMask; |
203 |
|
|
204 |
|
|
|
|
|
205 |
/*************************************************************************/ |
/*************************************************************************/ |
206 |
/*************************************************************************/ |
/*************************************************************************/ |
207 |
/***** *****/ |
/***** *****/ |
223 |
if ( feature >= gxv_feat_registry_length ) |
if ( feature >= gxv_feat_registry_length ) |
224 |
{ |
{ |
225 |
GXV_TRACE(( "feature number %d is out of range %d\n", |
GXV_TRACE(( "feature number %d is out of range %d\n", |
226 |
feature, gxv_feat_registry_length )); |
feature, gxv_feat_registry_length )); |
227 |
if ( valid->root->level == FT_VALIDATE_PARANOID ) |
if ( valid->root->level == FT_VALIDATE_PARANOID ) |
228 |
FT_INVALID_DATA; |
FT_INVALID_DATA; |
229 |
goto Exit; |
goto Exit; |
231 |
|
|
232 |
if ( gxv_feat_registry[feature].existence == 0 ) |
if ( gxv_feat_registry[feature].existence == 0 ) |
233 |
{ |
{ |
234 |
GXV_TRACE(( "feature number %d is in define range but inexistent\n", |
GXV_TRACE(( "feature number %d is in defined range but doesn't exist\n", |
235 |
feature )); |
feature )); |
236 |
if ( valid->root->level == FT_VALIDATE_PARANOID ) |
if ( valid->root->level == FT_VALIDATE_PARANOID ) |
237 |
FT_INVALID_DATA; |
FT_INVALID_DATA; |
238 |
goto Exit; |
goto Exit; |
241 |
if ( gxv_feat_registry[feature].apple_reserved ) |
if ( gxv_feat_registry[feature].apple_reserved ) |
242 |
{ |
{ |
243 |
/* Don't use here. Apple is reserved. */ |
/* Don't use here. Apple is reserved. */ |
244 |
GXV_TRACE(( "feature number %d is reserved by Apple\n", |
GXV_TRACE(( "feature number %d is reserved by Apple\n", feature )); |
|
feature )); |
|
245 |
if ( valid->root->level >= FT_VALIDATE_TIGHT ) |
if ( valid->root->level >= FT_VALIDATE_TIGHT ) |
246 |
FT_INVALID_DATA; |
FT_INVALID_DATA; |
247 |
} |
} |
249 |
if ( nSettings != gxv_feat_registry[feature].nSettings ) |
if ( nSettings != gxv_feat_registry[feature].nSettings ) |
250 |
{ |
{ |
251 |
GXV_TRACE(( "feature %d: nSettings %d != defined nSettings %d\n", |
GXV_TRACE(( "feature %d: nSettings %d != defined nSettings %d\n", |
252 |
feature, nSettings, gxv_feat_registry[feature].nSettings )); |
feature, nSettings, |
253 |
|
gxv_feat_registry[feature].nSettings )); |
254 |
if ( valid->root->level >= FT_VALIDATE_TIGHT ) |
if ( valid->root->level >= FT_VALIDATE_TIGHT ) |
255 |
FT_INVALID_DATA; |
FT_INVALID_DATA; |
256 |
} |
} |
258 |
if ( exclusive != gxv_feat_registry[feature].exclusive ) |
if ( exclusive != gxv_feat_registry[feature].exclusive ) |
259 |
{ |
{ |
260 |
GXV_TRACE(( "exclusive flag %d differs from predefined value\n", |
GXV_TRACE(( "exclusive flag %d differs from predefined value\n", |
261 |
exclusive )); |
exclusive )); |
262 |
if ( valid->root->level >= FT_VALIDATE_TIGHT ) |
if ( valid->root->level >= FT_VALIDATE_TIGHT ) |
263 |
FT_INVALID_DATA; |
FT_INVALID_DATA; |
264 |
} |
} |
273 |
FT_Bytes limit, |
FT_Bytes limit, |
274 |
GXV_Validator valid ) |
GXV_Validator valid ) |
275 |
{ |
{ |
276 |
FT_Bytes p = table; |
FT_Bytes p = table; |
277 |
|
|
278 |
FT_Short nameIndex; |
FT_Short nameIndex; |
279 |
|
|
280 |
|
|
281 |
GXV_NAME_ENTER( "nameIndex" ); |
GXV_NAME_ENTER( "nameIndex" ); |
286 |
|
|
287 |
gxv_sfntName_validate( (FT_UShort)nameIndex, |
gxv_sfntName_validate( (FT_UShort)nameIndex, |
288 |
255, |
255, |
289 |
32768, |
32768U, |
290 |
valid ); |
valid ); |
291 |
|
|
292 |
GXV_EXIT; |
GXV_EXIT; |
293 |
} |
} |
294 |
|
|
295 |
|
|
296 |
static void |
static void |
297 |
gxv_feat_setting_validate( FT_Bytes table, |
gxv_feat_setting_validate( FT_Bytes table, |
298 |
FT_Bytes limit, |
FT_Bytes limit, |
302 |
FT_Bytes p = table; |
FT_Bytes p = table; |
303 |
FT_UShort setting; |
FT_UShort setting; |
304 |
|
|
305 |
|
|
306 |
GXV_NAME_ENTER( "setting" ); |
GXV_NAME_ENTER( "setting" ); |
307 |
|
|
308 |
GXV_LIMIT_CHECK( 2 ); |
GXV_LIMIT_CHECK( 2 ); |
309 |
|
|
310 |
setting = FT_NEXT_USHORT( p ); |
setting = FT_NEXT_USHORT( p ); |
311 |
|
|
312 |
/* If exclusive setting, setting should be odd. */ |
/* If we have exclusive setting, the setting should be odd. */ |
313 |
if ( exclusive && ( ( setting % 2 ) == 0 ) ) |
if ( exclusive && ( setting % 2 ) == 0 ) |
314 |
FT_INVALID_DATA; |
FT_INVALID_DATA; |
315 |
|
|
316 |
gxv_feat_name_index_validate( p, limit, valid ); |
gxv_feat_name_index_validate( p, limit, valid ); |
336 |
|
|
337 |
FT_Bool exclusive; |
FT_Bool exclusive; |
338 |
FT_Int last_setting; |
FT_Int last_setting; |
339 |
FT_Int i; |
FT_UInt i; |
340 |
|
|
341 |
|
|
342 |
GXV_NAME_ENTER( "name" ); |
GXV_NAME_ENTER( "name" ); |
354 |
if ( settingTable < reserved_size ) |
if ( settingTable < reserved_size ) |
355 |
FT_INVALID_OFFSET; |
FT_INVALID_OFFSET; |
356 |
|
|
357 |
if ( valid->root->level == FT_VALIDATE_PARANOID && |
if ( valid->root->level == FT_VALIDATE_PARANOID && |
358 |
(featureFlags & GXV_FEAT_MASK_UNUSED) == 0 ) |
( featureFlags & GXV_FEAT_MASK_UNUSED ) == 0 ) |
359 |
FT_INVALID_DATA; |
FT_INVALID_DATA; |
360 |
|
|
361 |
exclusive = featureFlags & GXV_FEAT_MASK_EXCLUSIVE_SETTINGS; |
exclusive = featureFlags & GXV_FEAT_MASK_EXCLUSIVE_SETTINGS; |
362 |
if ( exclusive ) |
if ( exclusive ) |
363 |
{ |
{ |
364 |
FT_Byte dynamic_default; |
FT_Byte dynamic_default; |
365 |
|
|
366 |
|
|
367 |
if (featureFlags & GXV_FEAT_MASK_DYNAMIC_DEFAULT) |
if ( featureFlags & GXV_FEAT_MASK_DYNAMIC_DEFAULT ) |
368 |
dynamic_default = featureFlags & GXV_FEAT_MASK_DEFAULT_SETTING; |
dynamic_default = featureFlags & GXV_FEAT_MASK_DEFAULT_SETTING; |
369 |
else |
else |
370 |
dynamic_default = 0; |
dynamic_default = 0; |
383 |
{ |
{ |
384 |
gxv_feat_setting_validate( p, limit, exclusive, valid ); |
gxv_feat_setting_validate( p, limit, exclusive, valid ); |
385 |
|
|
386 |
if ( valid->root->level == FT_VALIDATE_PARANOID && |
if ( valid->root->level == FT_VALIDATE_PARANOID && |
387 |
(FT_Int)GXV_FEAT_DATA( setting ) <= last_setting ) |
(FT_Int)GXV_FEAT_DATA( setting ) <= last_setting ) |
388 |
FT_INVALID_FORMAT; |
FT_INVALID_FORMAT; |
389 |
|
|
420 |
|
|
421 |
FT_UInt featureNameCount; |
FT_UInt featureNameCount; |
422 |
|
|
423 |
FT_Int i; |
FT_UInt i; |
424 |
FT_Int last_feature; |
FT_Int last_feature; |
425 |
|
|
426 |
|
|
428 |
valid->table_data = feat; |
valid->table_data = feat; |
429 |
valid->face = face; |
valid->face = face; |
430 |
|
|
431 |
FT_TRACE3(( "validation feat table\n" )); |
FT_TRACE3(( "validating `feat' table\n" )); |
432 |
GXV_INIT; |
GXV_INIT; |
433 |
|
|
434 |
feat->reserved_size = 0; |
feat->reserved_size = 0; |
454 |
FT_INVALID_DATA; |
FT_INVALID_DATA; |
455 |
} |
} |
456 |
|
|
457 |
feat->reserved_size += ( featureNameCount * ( 2 + 2 + 4 + 2 + 2 ) ); |
feat->reserved_size += featureNameCount * ( 2 + 2 + 4 + 2 + 2 ); |
458 |
for( last_feature = -1, i = 0; i < featureNameCount; i++ ) |
|
459 |
|
for ( last_feature = -1, i = 0; i < featureNameCount; i++ ) |
460 |
{ |
{ |
461 |
gxv_feat_name_validate( p, limit, valid ); |
gxv_feat_name_validate( p, limit, valid ); |
462 |
|
|
463 |
if ( valid->root->level == FT_VALIDATE_PARANOID && |
if ( valid->root->level == FT_VALIDATE_PARANOID && |
464 |
(FT_Int)GXV_FEAT_DATA( feature ) <= last_feature ) |
(FT_Int)GXV_FEAT_DATA( feature ) <= last_feature ) |
465 |
FT_INVALID_FORMAT; |
FT_INVALID_FORMAT; |
466 |
|
|
467 |
last_feature = GXV_FEAT_DATA( feature ); |
last_feature = GXV_FEAT_DATA( feature ); |
468 |
p += ( 2 + 2 + 4 + 2 + 2 ); |
p += 2 + 2 + 4 + 2 + 2; |
469 |
} |
} |
470 |
|
|
471 |
FT_TRACE4(( "\n" )); |
FT_TRACE4(( "\n" )); |