summaryrefslogtreecommitdiffstats
path: root/src/gxvalid/gxvmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gxvalid/gxvmod.c')
-rw-r--r--src/gxvalid/gxvmod.c285
1 files changed, 285 insertions, 0 deletions
diff --git a/src/gxvalid/gxvmod.c b/src/gxvalid/gxvmod.c
new file mode 100644
index 0000000..b2b16b1
--- /dev/null
+++ b/src/gxvalid/gxvmod.c
@@ -0,0 +1,285 @@
+/***************************************************************************/
+/* */
+/* gxvmod.c */
+/* */
+/* FreeType's TrueTypeGX/AAT validation module implementation (body). */
+/* */
+/* Copyright 2004, 2005, 2006 */
+/* 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 ( error == GXV_Err_Table_Missing )
+ return GXV_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 = GXV_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 = GXV_Err_Ok;
+ 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 */