0,0 → 1,285 |
/***************************************************************************/ |
/* */ |
/* gxvmod.c */ |
/* */ |
/* FreeType's TrueTypeGX/AAT validation module implementation (body). */ |
/* */ |
/* Copyright 2004-2006, 2013 */ |
/* by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ |
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
/* */ |
/* This file is part of the FreeType project, and may only be used, */ |
/* modified, and distributed under the terms of the FreeType project */ |
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
/* this file you indicate that you have read the license and */ |
/* understand and accept it fully. */ |
/* */ |
/***************************************************************************/ |
|
/***************************************************************************/ |
/* */ |
/* gxvalid is derived from both gxlayout module and otvalid module. */ |
/* Development of gxlayout is supported by the Information-technology */ |
/* Promotion Agency(IPA), Japan. */ |
/* */ |
/***************************************************************************/ |
|
|
#include <ft2build.h> |
#include FT_TRUETYPE_TABLES_H |
#include FT_TRUETYPE_TAGS_H |
#include FT_GX_VALIDATE_H |
#include FT_INTERNAL_OBJECTS_H |
#include FT_SERVICE_GX_VALIDATE_H |
|
#include "gxvmod.h" |
#include "gxvalid.h" |
#include "gxvcommn.h" |
|
|
/*************************************************************************/ |
/* */ |
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
/* messages during execution. */ |
/* */ |
#undef FT_COMPONENT |
#define FT_COMPONENT trace_gxvmodule |
|
|
static FT_Error |
gxv_load_table( FT_Face face, |
FT_Tag tag, |
FT_Byte* volatile* table, |
FT_ULong* table_len ) |
{ |
FT_Error error; |
FT_Memory memory = FT_FACE_MEMORY( face ); |
|
|
error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len ); |
if ( FT_ERR_EQ( error, Table_Missing ) ) |
return FT_Err_Ok; |
if ( error ) |
goto Exit; |
|
if ( FT_ALLOC( *table, *table_len ) ) |
goto Exit; |
|
error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len ); |
|
Exit: |
return error; |
} |
|
|
#define GXV_TABLE_DECL( _sfnt ) \ |
FT_Byte* volatile _sfnt = NULL; \ |
FT_ULong len_ ## _sfnt = 0 |
|
#define GXV_TABLE_LOAD( _sfnt ) \ |
if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \ |
( gx_flags & FT_VALIDATE_ ## _sfnt ) ) \ |
{ \ |
error = gxv_load_table( face, TTAG_ ## _sfnt, \ |
&_sfnt, &len_ ## _sfnt ); \ |
if ( error ) \ |
goto Exit; \ |
} |
|
#define GXV_TABLE_VALIDATE( _sfnt ) \ |
if ( _sfnt ) \ |
{ \ |
ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \ |
FT_VALIDATE_DEFAULT ); \ |
if ( ft_setjmp( valid.jump_buffer ) == 0 ) \ |
gxv_ ## _sfnt ## _validate( _sfnt, face, &valid ); \ |
error = valid.error; \ |
if ( error ) \ |
goto Exit; \ |
} |
|
#define GXV_TABLE_SET( _sfnt ) \ |
if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) \ |
tables[FT_VALIDATE_ ## _sfnt ## _INDEX] = (FT_Bytes)_sfnt |
|
|
static FT_Error |
gxv_validate( FT_Face face, |
FT_UInt gx_flags, |
FT_Bytes tables[FT_VALIDATE_GX_LENGTH], |
FT_UInt table_count ) |
{ |
FT_Memory volatile memory = FT_FACE_MEMORY( face ); |
|
FT_Error error = FT_Err_Ok; |
FT_ValidatorRec volatile valid; |
|
FT_UInt i; |
|
|
GXV_TABLE_DECL( feat ); |
GXV_TABLE_DECL( bsln ); |
GXV_TABLE_DECL( trak ); |
GXV_TABLE_DECL( just ); |
GXV_TABLE_DECL( mort ); |
GXV_TABLE_DECL( morx ); |
GXV_TABLE_DECL( kern ); |
GXV_TABLE_DECL( opbd ); |
GXV_TABLE_DECL( prop ); |
GXV_TABLE_DECL( lcar ); |
|
for ( i = 0; i < table_count; i++ ) |
tables[i] = 0; |
|
/* load tables */ |
GXV_TABLE_LOAD( feat ); |
GXV_TABLE_LOAD( bsln ); |
GXV_TABLE_LOAD( trak ); |
GXV_TABLE_LOAD( just ); |
GXV_TABLE_LOAD( mort ); |
GXV_TABLE_LOAD( morx ); |
GXV_TABLE_LOAD( kern ); |
GXV_TABLE_LOAD( opbd ); |
GXV_TABLE_LOAD( prop ); |
GXV_TABLE_LOAD( lcar ); |
|
/* validate tables */ |
GXV_TABLE_VALIDATE( feat ); |
GXV_TABLE_VALIDATE( bsln ); |
GXV_TABLE_VALIDATE( trak ); |
GXV_TABLE_VALIDATE( just ); |
GXV_TABLE_VALIDATE( mort ); |
GXV_TABLE_VALIDATE( morx ); |
GXV_TABLE_VALIDATE( kern ); |
GXV_TABLE_VALIDATE( opbd ); |
GXV_TABLE_VALIDATE( prop ); |
GXV_TABLE_VALIDATE( lcar ); |
|
/* Set results */ |
GXV_TABLE_SET( feat ); |
GXV_TABLE_SET( mort ); |
GXV_TABLE_SET( morx ); |
GXV_TABLE_SET( bsln ); |
GXV_TABLE_SET( just ); |
GXV_TABLE_SET( kern ); |
GXV_TABLE_SET( opbd ); |
GXV_TABLE_SET( trak ); |
GXV_TABLE_SET( prop ); |
GXV_TABLE_SET( lcar ); |
|
Exit: |
if ( error ) |
{ |
FT_FREE( feat ); |
FT_FREE( bsln ); |
FT_FREE( trak ); |
FT_FREE( just ); |
FT_FREE( mort ); |
FT_FREE( morx ); |
FT_FREE( kern ); |
FT_FREE( opbd ); |
FT_FREE( prop ); |
FT_FREE( lcar ); |
} |
|
return error; |
} |
|
|
static FT_Error |
classic_kern_validate( FT_Face face, |
FT_UInt ckern_flags, |
FT_Bytes* ckern_table ) |
{ |
FT_Memory volatile memory = FT_FACE_MEMORY( face ); |
|
FT_Byte* volatile ckern = NULL; |
FT_ULong len_ckern = 0; |
|
/* without volatile on `error' GCC 4.1.1. emits: */ |
/* warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */ |
/* this warning seems spurious but --- */ |
FT_Error volatile error; |
FT_ValidatorRec volatile valid; |
|
|
*ckern_table = NULL; |
|
error = gxv_load_table( face, TTAG_kern, &ckern, &len_ckern ); |
if ( error ) |
goto Exit; |
|
if ( ckern ) |
{ |
ft_validator_init( &valid, ckern, ckern + len_ckern, |
FT_VALIDATE_DEFAULT ); |
if ( ft_setjmp( valid.jump_buffer ) == 0 ) |
gxv_kern_validate_classic( ckern, face, |
ckern_flags & FT_VALIDATE_CKERN, &valid ); |
error = valid.error; |
if ( error ) |
goto Exit; |
} |
|
*ckern_table = ckern; |
|
Exit: |
if ( error ) |
FT_FREE( ckern ); |
|
return error; |
} |
|
|
static |
const FT_Service_GXvalidateRec gxvalid_interface = |
{ |
gxv_validate |
}; |
|
|
static |
const FT_Service_CKERNvalidateRec ckernvalid_interface = |
{ |
classic_kern_validate |
}; |
|
|
static |
const FT_ServiceDescRec gxvalid_services[] = |
{ |
{ FT_SERVICE_ID_GX_VALIDATE, &gxvalid_interface }, |
{ FT_SERVICE_ID_CLASSICKERN_VALIDATE, &ckernvalid_interface }, |
{ NULL, NULL } |
}; |
|
|
static FT_Pointer |
gxvalid_get_service( FT_Module module, |
const char* service_id ) |
{ |
FT_UNUSED( module ); |
|
return ft_service_list_lookup( gxvalid_services, service_id ); |
} |
|
|
FT_CALLBACK_TABLE_DEF |
const FT_Module_Class gxv_module_class = |
{ |
0, |
sizeof ( FT_ModuleRec ), |
"gxvalid", |
0x10000L, |
0x20000L, |
|
0, /* module-specific interface */ |
|
(FT_Module_Constructor)0, |
(FT_Module_Destructor) 0, |
(FT_Module_Requester) gxvalid_get_service |
}; |
|
|
/* END */ |