From d76fe5a1af5fb9a08b38d4d426688ee9cd34996b Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 8 Aug 2007 06:38:06 +0000 Subject: [PATCH] * src/otvalid/otvbase.c, src/otvalid/otvcommn.c, src/otvalid/otvgdef.c, src/otvalid/otvgpos.c, src/otvalid/otvgsub.c, src/otvalid/otvjstf.c: s/FT_INVALID_DATA/FT_INVALID_FORMAT/ where appropriate. Reported by George. * include/freetype/internal/fttrace.h: Define `trace_otvmath'. * src/otvalid/rules.mk (OTV_DRV_SRC): Add otvmath.c. * docs/CHANGES: Updated. Add `MATH' validating support to otvalid module. * include/freetype/tttags.h (TTAG_MATH): New macro. * include/freetype/ftotval.h (FT_VALIDATE_MATH): New macro. (FT_VALIDATE_OT): Updated. * src/otvalid/otmath.c: New file. * src/otvalid/otvalid.c: Include otvmath.c. * src/otvalid/otvmod.c (otv_validate): Handle `MATH' table. --- ChangeLog | 26 ++ docs/CHANGES | 3 + include/freetype/ftotval.h | 11 +- include/freetype/internal/fttrace.h | 3 +- include/freetype/tttags.h | 3 +- src/otvalid/otvalid.c | 3 +- src/otvalid/otvbase.c | 6 +- src/otvalid/otvcommn.c | 7 +- src/otvalid/otvgdef.c | 4 +- src/otvalid/otvgpos.c | 26 +- src/otvalid/otvgsub.c | 20 +- src/otvalid/otvjstf.c | 4 +- src/otvalid/otvmath.c | 426 ++++++++++++++++++++++++++++ src/otvalid/otvmod.c | 31 +- src/otvalid/rules.mk | 9 +- 15 files changed, 537 insertions(+), 45 deletions(-) create mode 100644 src/otvalid/otvmath.c diff --git a/ChangeLog b/ChangeLog index c5c876539..ffad12efc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2007-08-08 Werner Lemberg + + * src/otvalid/otvbase.c, src/otvalid/otvcommn.c, + src/otvalid/otvgdef.c, src/otvalid/otvgpos.c, src/otvalid/otvgsub.c, + src/otvalid/otvjstf.c: s/FT_INVALID_DATA/FT_INVALID_FORMAT/ where + appropriate. Reported by George. + + * include/freetype/internal/fttrace.h: Define `trace_otvmath'. + + * src/otvalid/rules.mk (OTV_DRV_SRC): Add otvmath.c. + + * docs/CHANGES: Updated. + +2007-08-08 George Williams + + Add `MATH' validating support to otvalid module. + + * include/freetype/tttags.h (TTAG_MATH): New macro. + * include/freetype/ftotval.h (FT_VALIDATE_MATH): New macro. + (FT_VALIDATE_OT): Updated. + + * src/otvalid/otmath.c: New file. + + * src/otvalid/otvalid.c: Include otvmath.c. + * src/otvalid/otvmod.c (otv_validate): Handle `MATH' table. + 2007-08-04 Werner Lemberg * builds/unix/configure.raw: Add call to AC_LIBTOOL_WIN32_DLL. diff --git a/docs/CHANGES b/docs/CHANGES index 1c42b8657..7b98d5841 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -7,6 +7,9 @@ CHANGES BETWEEN 2.3.6 and 2.3.5 access to those fields in a CID-keyed font. The code has been contributed by Derek Clegg. + - George Williams contributed code to validate the new `MATH' + OpenType table (within the `otvalid' module). The `ftvalid' + demo program has been extended accordingly. ====================================================================== diff --git a/include/freetype/ftotval.h b/include/freetype/ftotval.h index 7c488fdf4..419190d72 100644 --- a/include/freetype/ftotval.h +++ b/include/freetype/ftotval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (specification). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -86,8 +86,11 @@ FT_BEGIN_HEADER * FT_VALIDATE_JSTF :: * Validate JSTF table. * + * FT_VALIDATE_MATH :: + * Validate MATH table. + * * FT_VALIDATE_OT :: - * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF). + * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). * */ #define FT_VALIDATE_BASE 0x0100 @@ -95,12 +98,14 @@ FT_BEGIN_HEADER #define FT_VALIDATE_GPOS 0x0400 #define FT_VALIDATE_GSUB 0x0800 #define FT_VALIDATE_JSTF 0x1000 +#define FT_VALIDATE_MATH 0x2000 #define FT_VALIDATE_OT FT_VALIDATE_BASE | \ FT_VALIDATE_GDEF | \ FT_VALIDATE_GPOS | \ FT_VALIDATE_GSUB | \ - FT_VALIDATE_JSTF + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH /* */ diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h index 81916fc6a..4d38a4628 100644 --- a/include/freetype/internal/fttrace.h +++ b/include/freetype/internal/fttrace.h @@ -4,7 +4,7 @@ /* */ /* Tracing handling (specification only). */ /* */ -/* Copyright 2002, 2004, 2005, 2006 by */ +/* Copyright 2002, 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -114,6 +114,7 @@ FT_TRACE_DEF( otvgdef ) FT_TRACE_DEF( otvgpos ) FT_TRACE_DEF( otvgsub ) FT_TRACE_DEF( otvjstf ) +FT_TRACE_DEF( otvmath ) /* TrueTypeGX/AAT validation components */ FT_TRACE_DEF( gxvmodule ) diff --git a/include/freetype/tttags.h b/include/freetype/tttags.h index e10244ca7..5a7900820 100644 --- a/include/freetype/tttags.h +++ b/include/freetype/tttags.h @@ -4,7 +4,7 @@ /* */ /* Tags for TrueType and OpenType tables (specification only). */ /* */ -/* Copyright 1996-2001, 2004, 2005 by */ +/* Copyright 1996-2001, 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,6 +67,7 @@ FT_BEGIN_HEADER #define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) #define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) #define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) #define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) #define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) #define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) diff --git a/src/otvalid/otvalid.c b/src/otvalid/otvalid.c index 2f85f601b..d5c2b75ab 100644 --- a/src/otvalid/otvalid.c +++ b/src/otvalid/otvalid.c @@ -4,7 +4,7 @@ /* */ /* FreeType validator for OpenType tables (body only). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,6 +25,7 @@ #include "otvgpos.c" #include "otvgsub.c" #include "otvjstf.c" +#include "otvmath.c" #include "otvmod.c" /* END */ diff --git a/src/otvalid/otvbase.c b/src/otvalid/otvbase.c index 8ad2238d6..d742d2dc9 100644 --- a/src/otvalid/otvbase.c +++ b/src/otvalid/otvbase.c @@ -4,7 +4,7 @@ /* */ /* OpenType BASE table validation (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -62,7 +62,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -297,7 +297,7 @@ OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; table_size = 6; diff --git a/src/otvalid/otvcommn.c b/src/otvalid/otvcommn.c index d94e4f3cb..36c4c5e3d 100644 --- a/src/otvalid/otvcommn.c +++ b/src/otvalid/otvcommn.c @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -291,7 +291,10 @@ EndSize = FT_NEXT_USHORT( p ); DeltaFormat = FT_NEXT_USHORT( p ); - if ( DeltaFormat < 1 || DeltaFormat > 3 || EndSize < StartSize ) + if ( DeltaFormat < 1 || DeltaFormat > 3 ) + FT_INVALID_FORMAT; + + if ( EndSize < StartSize ) FT_INVALID_DATA; count = EndSize - StartSize + 1; diff --git a/src/otvalid/otvgdef.c b/src/otvalid/otvgdef.c index 7d24902e8..e4c32a0f1 100644 --- a/src/otvalid/otvgdef.c +++ b/src/otvalid/otvgdef.c @@ -4,7 +4,7 @@ /* */ /* OpenType GDEF table validation (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -126,7 +126,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; diff --git a/src/otvalid/otvgpos.c b/src/otvalid/otvgpos.c index ed347053d..af8269a83 100644 --- a/src/otvalid/otvgpos.c +++ b/src/otvalid/otvgpos.c @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validation (body). */ /* */ -/* Copyright 2002, 2004, 2005, 2006 by */ +/* Copyright 2002, 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -191,7 +191,7 @@ #endif if ( format >= 0x100 ) - FT_INVALID_DATA; + FT_INVALID_FORMAT; for ( count = 4; count > 0; count-- ) { @@ -294,7 +294,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -409,7 +409,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -558,7 +558,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -629,7 +629,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -670,7 +670,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -711,7 +711,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -752,7 +752,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -811,7 +811,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -872,7 +872,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -925,7 +925,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -989,7 +989,7 @@ OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); diff --git a/src/otvalid/otvgsub.c b/src/otvalid/otvgsub.c index 91dae0bb1..9412bda2b 100644 --- a/src/otvalid/otvgsub.c +++ b/src/otvalid/otvgsub.c @@ -4,7 +4,7 @@ /* */ /* OpenType GSUB table validation (body). */ /* */ -/* Copyright 2004, 2005 by */ +/* Copyright 2004, 2005, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -103,7 +103,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -144,7 +144,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -185,7 +185,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -259,7 +259,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -318,7 +318,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -379,7 +379,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -434,7 +434,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -509,7 +509,7 @@ break; default: - FT_INVALID_DATA; + FT_INVALID_FORMAT; } OTV_EXIT; @@ -560,7 +560,7 @@ OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); diff --git a/src/otvalid/otvjstf.c b/src/otvalid/otvjstf.c index 80b8dd660..a616a2343 100644 --- a/src/otvalid/otvjstf.c +++ b/src/otvalid/otvjstf.c @@ -4,7 +4,7 @@ /* */ /* OpenType JSTF table validation (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -222,7 +222,7 @@ OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ - FT_INVALID_DATA; + FT_INVALID_FORMAT; JstfScriptCount = FT_NEXT_USHORT( p ); diff --git a/src/otvalid/otvmath.c b/src/otvalid/otvmath.c new file mode 100644 index 000000000..e85357597 --- /dev/null +++ b/src/otvalid/otvmath.c @@ -0,0 +1,426 @@ +/***************************************************************************/ +/* */ +/* otvmath.c */ +/* */ +/* OpenType MATH table validation (body). */ +/* */ +/* Copyright 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by George Williams. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#include "otvalid.h" +#include "otvcommn.h" +#include "otvgpos.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_otvmath + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TYPOGRAPHIC CONSTANTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathConstants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i; + FT_UInt table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + OTV_NAME_ENTER( "MathConstants" ); + + /* 57 constants, 52 have device tables */ + OTV_LIMIT_CHECK( 2 * ( 57 + 52 ) ); + table_size = 2 * ( 57 + 52 ); + + p += 4 * 2; /* First 4 constants have no device tables */ + for ( i = 0; i < 52; ++i ) + { + p += 2; /* skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH ITALICS CORRECTION *****/ + /***** MATH TOP ACCENT ATTACHMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, + OTV_Validator valid, + FT_Int isItalic ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size ; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo" + : "MathTopAccentAttachment" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt ); + table_size = 4 + 4 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid ); + + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH KERNING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathKern_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, cnt, table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "MathKern" );*/ + + OTV_LIMIT_CHECK( 2 ); + + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * cnt + 2 ); + table_size = 4 + 4 * cnt; + + /* Heights */ + for ( i = 0; i < cnt; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + /* One more Kerning value */ + for ( i = 0; i < cnt + 1; ++i ) + { + p += 2; /* Skip the value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + } + + OTV_EXIT; + } + + + static void + otv_MathKernInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt i, j, cnt, table_size; + + OTV_OPTIONAL_TABLE( Coverage ); + OTV_OPTIONAL_TABLE( MKRecordOffset ); + + + OTV_NAME_ENTER( "MathKernInfo" ); + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( Coverage ); + cnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * cnt ); + table_size = 4 + 8 * cnt; + + OTV_SIZE_CHECK( Coverage ); + otv_Coverage_validate( table + Coverage, valid ); + + for ( i = 0; i < cnt; ++i ) + { + for ( j = 0; j < 4; ++j ) + { + OTV_OPTIONAL_OFFSET( MKRecordOffset ); + OTV_SIZE_CHECK( MKRecordOffset ); + if ( MKRecordOffset ) + otv_MathKern_validate( table + MKRecordOffset, valid ); + } + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH INFO *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MathGlyphInfo_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment; + FT_UInt ExtendedShapeCoverage, MathKernInfo; + + + OTV_NAME_ENTER( "MathGlyphInfo" ); + + OTV_LIMIT_CHECK( 8 ); + + MathItalicsCorrectionInfo = FT_NEXT_USHORT( p ); + MathTopAccentAttachment = FT_NEXT_USHORT( p ); + ExtendedShapeCoverage = FT_NEXT_USHORT( p ); + MathKernInfo = FT_NEXT_USHORT( p ); + + if ( MathItalicsCorrectionInfo ) + otv_MathItalicsCorrectionInfo_validate( + table + MathItalicsCorrectionInfo, valid, TRUE ); + + /* Italic correction and Top Accent Attachment have the same format */ + if ( MathTopAccentAttachment ) + otv_MathItalicsCorrectionInfo_validate( + table + MathTopAccentAttachment, valid, FALSE ); + + if ( ExtendedShapeCoverage ) { + OTV_NAME_ENTER( "ExtendedShapeCoverage" ); + otv_Coverage_validate( table + ExtendedShapeCoverage, valid ); + OTV_EXIT; + } + + if ( MathKernInfo ) + otv_MathKernInfo_validate( table + MathKernInfo, valid ); + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH GLYPH CONSTRUCTION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_GlyphAssembly_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt pcnt, table_size; + + OTV_OPTIONAL_TABLE( DeviceTableOffset ); + + + /* OTV_NAME_ENTER( "GlyphAssembly" ); */ + + OTV_LIMIT_CHECK( 6 ); + + p += 2; /* Skip the Italics Correction value */ + OTV_OPTIONAL_OFFSET( DeviceTableOffset ); + pcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 8 * pcnt ); + table_size = 6 + 8 * pcnt; + + OTV_SIZE_CHECK( DeviceTableOffset ); + if ( DeviceTableOffset ) + otv_Device_validate( table + DeviceTableOffset, valid ); + + /* OTV_EXIT; */ + } + + + static void + otv_MathGlyphConstruction_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, table_size; + + OTV_OPTIONAL_TABLE( GlyphAssembly ); + + + /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */ + + OTV_LIMIT_CHECK( 4 ); + + OTV_OPTIONAL_OFFSET( GlyphAssembly ); + vcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 4 * vcnt ); + table_size = 4 + 4 * vcnt; + + OTV_SIZE_CHECK( GlyphAssembly ); + if ( GlyphAssembly ) + otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); + + /* OTV_EXIT; */ + } + + + static void + otv_MathVariants_validate( FT_Bytes table, + OTV_Validator valid ) + { + FT_Bytes p = table; + FT_UInt vcnt, hcnt, i, table_size; + + OTV_OPTIONAL_TABLE( VCoverage ); + OTV_OPTIONAL_TABLE( HCoverage ); + OTV_OPTIONAL_TABLE( Offset ); + + + OTV_NAME_ENTER( "MathVariants" ); + + OTV_LIMIT_CHECK( 10 ); + + p += 2; /* Skip the MinConnectorOverlap constant */ + OTV_OPTIONAL_OFFSET( VCoverage ); + OTV_OPTIONAL_OFFSET( HCoverage ); + vcnt = FT_NEXT_USHORT( p ); + hcnt = FT_NEXT_USHORT( p ); + + OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt ); + table_size = 10 + 2 * vcnt + 2 * hcnt; + + OTV_SIZE_CHECK( VCoverage ); + if ( VCoverage ) + otv_Coverage_validate( table + VCoverage, valid ); + + OTV_SIZE_CHECK( HCoverage ); + if ( HCoverage ) + otv_Coverage_validate( table + HCoverage, valid ); + + for ( i = 0; i < vcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + for ( i = 0; i < hcnt; ++i ) + { + OTV_OPTIONAL_OFFSET( Offset ); + OTV_SIZE_CHECK( Offset ); + otv_MathGlyphConstruction_validate( table + Offset, valid ); + } + + OTV_EXIT; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MATH TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* sets valid->glyph_count */ + + FT_LOCAL_DEF( void ) + otv_MATH_validate( FT_Bytes table, + FT_UInt glyph_count, + FT_Validator ftvalid ) + { + OTV_ValidatorRec validrec; + OTV_Validator valid = &validrec; + FT_Bytes p = table; + FT_UInt MathConstants, MathGlyphInfo, MathVariants; + + + valid->root = ftvalid; + + FT_TRACE3(( "validating MATH table\n" )); + OTV_INIT; + + OTV_LIMIT_CHECK( 10 ); + + if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + FT_INVALID_FORMAT; + + MathConstants = FT_NEXT_USHORT( p ); + MathGlyphInfo = FT_NEXT_USHORT( p ); + MathVariants = FT_NEXT_USHORT( p ); + + valid->glyph_count = glyph_count; + + otv_MathConstants_validate( table + MathConstants, + valid ); + otv_MathGlyphInfo_validate( table + MathGlyphInfo, + valid ); + otv_MathVariants_validate ( table + MathVariants, + valid ); + + FT_TRACE4(( "\n" )); + } + + +/* END */ diff --git a/src/otvalid/otvmod.c b/src/otvalid/otvmod.c index 157272f1a..c28029915 100644 --- a/src/otvalid/otvmod.c +++ b/src/otvalid/otvmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType's OpenType validation module implementation (body). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,12 +79,14 @@ FT_Byte* volatile gpos; FT_Byte* volatile gsub; FT_Byte* volatile jstf; + FT_Byte* volatile math; FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf; + FT_ULong len_math; FT_ValidatorRec volatile valid; - base = gdef = gpos = gsub = jstf = NULL; - len_base = len_gdef = len_gpos = len_gsub = len_jstf = 0; + base = gdef = gpos = gsub = jstf = math = NULL; + len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0; /* load tables */ @@ -123,6 +125,13 @@ goto Exit; } + if ( ot_flags & FT_VALIDATE_MATH ) + { + error = otv_load_table( face, TTAG_MATH, &math, &len_math ); + if ( error ) + goto Exit; + } + /* validate tables */ if ( base ) @@ -175,6 +184,16 @@ goto Exit; } + if ( math ) + { + ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT ); + if ( ft_setjmp( valid.jump_buffer ) == 0 ) + otv_MATH_validate( math, face->num_glyphs, &valid ); + error = valid.error; + if ( error ) + goto Exit; + } + *ot_base = (FT_Bytes)base; *ot_gdef = (FT_Bytes)gdef; *ot_gpos = (FT_Bytes)gpos; @@ -192,6 +211,12 @@ FT_FREE( gsub ); FT_FREE( jstf ); } + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( math ); /* Can't return this as API is frozen */ + } return error; } diff --git a/src/otvalid/rules.mk b/src/otvalid/rules.mk index 48f12336f..53bd41e5e 100644 --- a/src/otvalid/rules.mk +++ b/src/otvalid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2004 by +# Copyright 2004, 2007 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -31,14 +31,15 @@ OTV_DRV_SRC := $(OTV_DIR)/otvbase.c \ $(OTV_DIR)/otvgpos.c \ $(OTV_DIR)/otvgsub.c \ $(OTV_DIR)/otvjstf.c \ + $(OTV_DIR)/otvmath.c \ $(OTV_DIR)/otvmod.c # OTV driver headers # -OTV_DRV_H := $(OTV_DIR)/otvalid.h \ - $(OTV_DIR)/otverror.h \ +OTV_DRV_H := $(OTV_DIR)/otvalid.h \ $(OTV_DIR)/otvcommn.h \ - $(OTV_DIR)/otvgpos.h \ + $(OTV_DIR)/otverror.h \ + $(OTV_DIR)/otvgpos.h \ $(OTV_DIR)/otvmod.h