Adding OpenType validation module. The code is based on the

(unfinished) `otlayout' module but has been heavily modified to make
it much more compact.

* src/otvalid/*: New module.

* include/freetype/ftotval.h, src/base/ftotval.c,
include/freetype/internal/services/svotval.h: New files.

* include/freetype/config/ftmodule.h: Add otv_module_class.
* include/freetype/config/ftheader.h (FT_OPENTYPE_VALIDATE_H): New
macro.
* include/freetype/internal/ftserv.h
(FT_SERVICE_OPENTYPE_VALIDATE_H): New macro.
* include/freetype/internal/fttrace.h (otvmodule, otvcommon,
otvbase, otvgdef, otvgpos, otvgsub, otvjstf): New trace components.

* include/freetype/ftchapters.h: Updated.

* src/base/Jamfile (Library), src/base/descrip.mms (OBJS),
src/base/rules.mk (BASE_EXT_SRC): Updated.

* docs/CHANGES: Updated.
This commit is contained in:
Werner Lemberg 2004-09-10 14:39:00 +00:00
parent 2c1e57096f
commit ee95b6f0d4
42 changed files with 4884 additions and 52 deletions

View File

@ -1,3 +1,29 @@
2004-09-09 Werner Lemberg <wl@gnu.org>
Adding OpenType validation module. The code is based on the
(unfinished) `otlayout' module but has been heavily modified to make
it much more compact.
* src/otvalid/*: New module.
* include/freetype/ftotval.h, src/base/ftotval.c,
include/freetype/internal/services/svotval.h: New files.
* include/freetype/config/ftmodule.h: Add otv_module_class.
* include/freetype/config/ftheader.h (FT_OPENTYPE_VALIDATE_H): New
macro.
* include/freetype/internal/ftserv.h
(FT_SERVICE_OPENTYPE_VALIDATE_H): New macro.
* include/freetype/internal/fttrace.h (otvmodule, otvcommon,
otvbase, otvgdef, otvgpos, otvgsub, otvjstf): New trace components.
* include/freetype/ftchapters.h: Updated.
* src/base/Jamfile (Library), src/base/descrip.mms (OBJS),
src/base/rules.mk (BASE_EXT_SRC): Updated.
* docs/CHANGES: Updated.
2004-09-08 Werner Lemberg <wl@gnu.org>
* src/tools/docmaker/sources.py (re_source_block_format2) <column>:
@ -13,7 +39,7 @@
* include/freetype/internal/ftobjs.h: Don't include
FT_CONFIG_STANDARD_LIBRARY_H.
(FT_Validator, FT_VAlidationLevel, FT_ValidatorRec, FT_VALIDATOR,
(FT_Validator, FT_ValidationLevel, FT_ValidatorRec, FT_VALIDATOR,
ft_validator_init, ft_validator_run, ft_validator_error, FT_INVALID,
FT_INVALID_TOO_SHORT, FT_INVALID_OFFSET, FT_INVALID_FORMAT,
FT_INVALID_GLYPH_ID, FT_INVALID_DATA): Move to...

View File

@ -23,6 +23,11 @@ LATEST CHANGES BETWEEN 2.1.10 and 2.1.9
- A new API `FT_Sfnt_Table_Info' (in FT_TRUETYPE_TABLES_H) has
been added to retrieve name and size information of SFNT tables.
- A new API `FT_OpenType_Validate' (in FT_OPENTYPE_VALIDATE_H) has
been added to validate OpenType tables (BASE, GDEF, GPOS, GSUB,
JSTF). After validation it is no longer necessary to check
for errors in those tables.
LATEST CHANGES BETWEEN 2.1.9 and 2.1.8

View File

@ -18,6 +18,7 @@
#ifndef __FT_HEADER_H__
#define __FT_HEADER_H__
/*@***********************************************************************/
/* */
/* <Macro> */
@ -92,6 +93,7 @@
/* */
/*************************************************************************/
/* configuration files */
/*************************************************************************/
@ -362,6 +364,7 @@
/* */
#define FT_BDF_H <freetype/ftbdf.h>
/*************************************************************************/
/* */
/* @macro: */
@ -529,6 +532,20 @@
/* */
#define FT_SFNT_NAMES_H <freetype/ftsnames.h>
/*************************************************************************/
/* */
/* @macro: */
/* FT_OPENTYPE_VALIDATE_H */
/* */
/* @description: */
/* A macro used in #include statements to name the file containing */
/* the optional FreeType 2 API used to validate OpenType tables */
/* (BASE, GDEF, GPOS, GSUB, JSTF). */
/* */
#define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h>
/* */
#define FT_TRIGONOMETRY_H <freetype/fttrigon.h>

View File

@ -16,4 +16,4 @@ FT_USE_MODULE(ft_smooth_lcdv_renderer_class)
FT_USE_MODULE(t42_driver_class)
FT_USE_MODULE(pfr_driver_class)
FT_USE_MODULE(winfnt_driver_class)
FT_USE_MODULE(otv_module_class)

View File

@ -2883,7 +2883,7 @@ FT_BEGIN_HEADER
/* Computations */
/* */
/* <Abstract> */
/* Crunching fixed numbers and vectors */
/* Crunching fixed numbers and vectors. */
/* */
/* <Description> */
/* This section contains various functions used to perform */

View File

@ -4,7 +4,7 @@
/* */
/* FreeType API for accessing BDF-specific strings (specification). */
/* */
/* Copyright 2002, 2003 by */
/* Copyright 2002, 2003, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -38,13 +38,13 @@ FT_BEGIN_HEADER
/* bdf_fonts */
/* */
/* <Title> */
/* BDF Fonts */
/* BDF Files */
/* */
/* <Abstract> */
/* BDF-specific APIs */
/* BDF specific API. */
/* */
/* <Description> */
/* This section contains the declaration of BDF-specific functions. */
/* This section contains the declaration of BDF specific functions. */
/* */
/*************************************************************************/

View File

@ -1,3 +1,11 @@
/***************************************************************************/
/* */
/* This file defines the structure of the FreeType reference. */
/* It is used by the python script which generates the HTML files. */
/* */
/***************************************************************************/
/***************************************************************************/
/* */
/* <Chapter> */
@ -31,6 +39,8 @@
/* sfnt_names */
/* bdf_fonts */
/* pfr_fonts */
/* winfnt_fonts */
/* ot_validation */
/* */
/***************************************************************************/
@ -62,8 +72,11 @@
/* list_processing */
/* outline_processing */
/* raster */
/* glyph_stroker */
/* system_interface */
/* module_management */
/* gzip */
/* lzw */
/* */
/***************************************************************************/

View File

@ -4,7 +4,7 @@
/* */
/* Gzip-compressed stream support. */
/* */
/* Copyright 2002, 2003 by */
/* Copyright 2002, 2003, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -40,7 +40,7 @@ FT_BEGIN_HEADER
/* GZIP Streams */
/* */
/* <Abstract> */
/* Using gzip-compressed font files */
/* Using gzip-compressed font files. */
/* */
/* <Description> */
/* This section contains the declaration of Gzip-specific functions. */

View File

@ -772,7 +772,7 @@ FT_BEGIN_HEADER
/* raster */
/* */
/* <Title> */
/* Scanline converter */
/* Scanline Converter */
/* */
/* <Abstract> */
/* How vectorial outlines are converted into bitmaps and pixmaps. */

View File

@ -40,7 +40,7 @@ FT_BEGIN_HEADER
/* LZW Streams */
/* */
/* <Abstract> */
/* Using LZW-compressed font files */
/* Using LZW-compressed font files. */
/* */
/* <Description> */
/* This section contains the declaration of LZW-specific functions. */

View File

@ -41,7 +41,7 @@ FT_BEGIN_HEADER
/* mac_specific */
/* */
/* <Title> */
/* Mac-Specific Interface */
/* Mac Specific Interface */
/* */
/* <Abstract> */
/* Only available on the Macintosh. */

159
include/freetype/ftotval.h Normal file
View File

@ -0,0 +1,159 @@
/***************************************************************************/
/* */
/* ftotval.h */
/* */
/* FreeType API for validating OpenType tables (specification). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#ifndef __FTOTVAL_H__
#define __FTOTVAL_H__
#include <ft2build.h>
#include FT_FREETYPE_H
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/*************************************************************************/
/* */
/* <Section> */
/* ot_validation */
/* */
/* <Title> */
/* OpenType Validation */
/* */
/* <Abstract> */
/* An API to validate OpenType tables. */
/* */
/* <Description> */
/* This section contains the declaration of functions to validate */
/* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF). */
/* */
/*************************************************************************/
/**********************************************************************
*
* @enum:
* FT_VALIDATE_XXX
*
* @description:
* A list of bit-field constants used with @FT_OpenType_Validate to
* indicate which OpenType tables should be validated.
*
* @values:
* FT_VALIDATE_BASE ::
* Validate BASE table.
*
* FT_VALIDATE_GDEF ::
* Validate GDEF table.
*
* FT_VALIDATE_GPOS ::
* Validate GPOS table.
*
* FT_VALIDATE_GSUB ::
* Validate GSUB table.
*
* FT_VALIDATE_JSTF ::
* Validate JSTF table.
*
* FT_VALIDATE_OT ::
* Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF).
*
*/
#define FT_VALIDATE_BASE 0x0100
#define FT_VALIDATE_GDEF 0x0200
#define FT_VALIDATE_GPOS 0x0400
#define FT_VALIDATE_GSUB 0x0800
#define FT_VALIDATE_JSTF 0x1000
#define FT_VALIDATE_OT FT_VALIDATE_BASE | \
FT_VALIDATE_GDEF | \
FT_VALIDATE_GPOS | \
FT_VALIDATE_GSUB | \
FT_VALIDATE_JSTF
/* */
/**********************************************************************
*
* @function:
* FT_OpenType_Validate
*
* @description:
* Validate various OpenType tables to assure that all offsets and
* indices are valid. The idea is that a higher-level library which
* actually does the text layout can access those tables without
* error checking (which can be quite time consuming).
*
* @input:
* face ::
* A handle to the input face.
*
* validation_flags ::
* A bit field which specifies the tables to be validated. See
* @FT_VALIDATE_XXX for possible values.
*
* @output:
* BASE_table ::
* A pointer to the BASE table.
*
* GDEF_table ::
* A pointer to the GDEF table.
*
* GPOS_table ::
* A pointer to the GPOS table.
*
* GSUB_table ::
* A pointer to the GSUB table.
*
* JSTF_table ::
* A pointer to the JSTF table.
*
* @return:
* FreeType error code. 0 means success.
*
* @note:
* This function only works with OpenType fonts, returning an error
* otherwise.
*
* After use, the application should deallocate the five tables with
* `free'. A NULL value indicates that the table either doesn't exist
* in the font, or the application hasn't asked for validation.
*/
FT_EXPORT( FT_Error )
FT_OpenType_Validate( FT_Face face,
FT_UInt validation_flags,
FT_Bytes *BASE_table,
FT_Bytes *GDEF_table,
FT_Bytes *GPOS_table,
FT_Bytes *GSUB_table,
FT_Bytes *JSTF_table );
/* */
FT_END_HEADER
#endif /* __FTOTVAL_H__ */
/* END */

View File

@ -4,7 +4,7 @@
/* */
/* FreeType API for accessing PFR-specific data (specification only). */
/* */
/* Copyright 2002, 2003 by */
/* Copyright 2002, 2003, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -41,7 +41,7 @@ FT_BEGIN_HEADER
/* PFR Fonts */
/* */
/* <Abstract> */
/* PFR/TrueDoc specific APIs */
/* PFR/TrueDoc specific API. */
/* */
/* <Description> */
/* This section contains the declaration of PFR-specific functions. */
@ -166,7 +166,7 @@ FT_BEGIN_HEADER
FT_END_HEADER
#endif /* __FTBDF_H__ */
#endif /* __FTPFR_H__ */
/* END */

View File

@ -4,7 +4,7 @@
/* */
/* FreeType size objects management (specification). */
/* */
/* Copyright 1996-2001, 2003 by */
/* Copyright 1996-2001, 2003, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -48,10 +48,10 @@ FT_BEGIN_HEADER
/* sizes_management */
/* */
/* <Title> */
/* Size management */
/* Size Management */
/* */
/* <Abstract> */
/* Managing multiple sizes per face */
/* Managing multiple sizes per face. */
/* */
/* <Description> */
/* When creating a new face object (e.g. with @FT_New_Face), an */

View File

@ -30,7 +30,7 @@ FT_BEGIN_HEADER
/************************************************************************
*
* <Section>
* glyph stroker
* glyph_stroker
*
* <Title>
* Glyph Stroker

View File

@ -4,7 +4,7 @@
/* */
/* FreeType API for accessing Windows fnt-specific data. */
/* */
/* Copyright 2003 by */
/* Copyright 2003, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -38,10 +38,10 @@ FT_BEGIN_HEADER
/* winfnt_fonts */
/* */
/* <Title> */
/* Window FNT Fonts */
/* Window FNT Files */
/* */
/* <Abstract> */
/* Windows FNT specific APIs */
/* Windows FNT specific API. */
/* */
/* <Description> */
/* This section contains the declaration of Windows FNT specific */

View File

@ -4,7 +4,7 @@
/* */
/* The FreeType services (specification only). */
/* */
/* Copyright 2003 by */
/* Copyright 2003, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -238,17 +238,18 @@ FT_BEGIN_HEADER
* The header files containing the services.
*/
#define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h>
#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h>
#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h>
#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h>
#define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h>
#define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h>
#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h>
#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h>
#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h>
#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h>
#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h>
#define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h>
#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h>
#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h>
#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h>
#define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h>
#define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h>
#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h>
#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h>
#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h>
#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h>
#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h>
#define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h>
/* */

View File

@ -37,17 +37,17 @@ FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */
FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */
FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */
/* Cache sub-system */
/* Cache sub-system */
FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */
/* SFNT driver components */
/* SFNT driver components */
FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */
FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */
FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */
FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */
FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */
/* TrueType driver components */
/* TrueType driver components */
FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */
FT_TRACE_DEF( ttgload ) /* TT glyph loader (ttgload.c) */
FT_TRACE_DEF( ttinterp ) /* bytecode interpreter (ttinterp.c) */
@ -55,7 +55,7 @@ FT_TRACE_DEF( ttobjs ) /* TT objects manager (ttobjs.c) */
FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */
FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */
/* Type 1 driver components */
/* Type 1 driver components */
FT_TRACE_DEF( t1driver )
FT_TRACE_DEF( t1gload )
FT_TRACE_DEF( t1hint )
@ -63,26 +63,26 @@ FT_TRACE_DEF( t1load )
FT_TRACE_DEF( t1objs )
FT_TRACE_DEF( t1parse )
/* PostScript helper module `psaux' */
/* PostScript helper module `psaux' */
FT_TRACE_DEF( t1decode )
FT_TRACE_DEF( psobjs )
/* PostScript hinting module `pshinter' */
/* PostScript hinting module `pshinter' */
FT_TRACE_DEF( pshrec )
FT_TRACE_DEF( pshalgo1 )
FT_TRACE_DEF( pshalgo2 )
/* Type 2 driver components */
/* Type 2 driver components */
FT_TRACE_DEF( cffdriver )
FT_TRACE_DEF( cffgload )
FT_TRACE_DEF( cffload )
FT_TRACE_DEF( cffobjs )
FT_TRACE_DEF( cffparse )
/* Type 42 driver component */
/* Type 42 driver component */
FT_TRACE_DEF( t42 )
/* CID driver components */
/* CID driver components */
FT_TRACE_DEF( cidafm )
FT_TRACE_DEF( ciddriver )
FT_TRACE_DEF( cidgload )
@ -90,19 +90,28 @@ FT_TRACE_DEF( cidload )
FT_TRACE_DEF( cidobjs )
FT_TRACE_DEF( cidparse )
/* Windows fonts component */
/* Windows font component */
FT_TRACE_DEF( winfnt )
/* PCF fonts components */
/* PCF font components */
FT_TRACE_DEF( pcfdriver )
FT_TRACE_DEF( pcfread )
/* BDF fonts component */
/* BDF font components */
FT_TRACE_DEF( bdfdriver )
FT_TRACE_DEF( bdflib )
/* PFR fonts component */
/* PFR font component */
FT_TRACE_DEF( pfr )
/* OpenType validation components */
FT_TRACE_DEF( otvmodule )
FT_TRACE_DEF( otvcommon )
FT_TRACE_DEF( otvbase )
FT_TRACE_DEF( otvgdef )
FT_TRACE_DEF( otvgpos )
FT_TRACE_DEF( otvgsub )
FT_TRACE_DEF( otvjstf )
/* END */

View File

@ -49,7 +49,7 @@ FT_BEGIN_HEADER
/* FT_VALIDATE_DEFAULT :: */
/* A table that passes this validation level can be used reliably by */
/* FreeType. It generally means that all offsets have been checked to */
/* prevent out-of-bound reads, array counts are correct, etc. */
/* prevent out-of-bound reads, that array counts are correct, etc. */
/* */
/* FT_VALIDATE_TIGHT :: */
/* A table that passes this validation level can be used reliably and */
@ -58,7 +58,7 @@ FT_BEGIN_HEADER
/* be used with FreeType in default mode (the library will simply */
/* return an error later when trying to load the glyph). */
/* */
/* It also check that fields that must be a multiple of 2, 4, or 8 */
/* It also checks that fields which must be a multiple of 2, 4, or 8, */
/* don't have incorrect values, etc. */
/* */
/* FT_VALIDATE_PARANOID :: */

View File

@ -0,0 +1,53 @@
/***************************************************************************/
/* */
/* svotval.h */
/* */
/* The FreeType OpenType validation service (specification). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#ifndef __SVOTVAL_H__
#define __SVOTVAL_H__
FT_BEGIN_HEADER
#define FT_SERVICE_ID_OPENTYPE_VALIDATE "opentype-validate"
typedef FT_Error
(*otv_validate_func)( FT_Face face,
FT_UInt ot_flags,
FT_Bytes *base,
FT_Bytes *gdef,
FT_Bytes *gpos,
FT_Bytes *gsub,
FT_Bytes *jstf );
FT_DEFINE_SERVICE( OTvalidate )
{
otv_validate_func validate;
};
/* */
FT_END_HEADER
#endif /* __SVOTVAL_H__ */
/* END */

View File

@ -42,7 +42,7 @@ FT_BEGIN_HEADER
/* TrueType Tables */
/* */
/* <Abstract> */
/* TrueType-specific table types and functions. */
/* TrueType specific table types and functions. */
/* */
/* <Description> */
/* This section contains the definition of TrueType-specific tables */

View File

@ -24,7 +24,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ;
#
Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c
ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c
ftstroke.c ftwinfnt.c ;
ftstroke.c ftwinfnt.c ftotval.c ;
# Add Macintosh-specific file to the library when necessary.
#

View File

@ -15,7 +15,7 @@
CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base])
OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj,ftstroke.obj,ftwinfnt.obj,ftbbox.obj
OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj,ftstroke.obj,ftwinfnt.obj,ftbbox.obj,ftotval.obj
all : $(OBJS)
library [--.lib]freetype.olb $(OBJS)

72
src/base/ftotval.c Normal file
View File

@ -0,0 +1,72 @@
/***************************************************************************/
/* */
/* ftotval.c */
/* */
/* FreeType API for validating OpenType tables (body). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
#include FT_SERVICE_OPENTYPE_VALIDATE_H
/* documentation is in ftotval.h */
FT_EXPORT_DEF( FT_Error )
FT_OpenType_Validate( FT_Face face,
FT_UInt validation_flags,
FT_Bytes *BASE_table,
FT_Bytes *GDEF_table,
FT_Bytes *GPOS_table,
FT_Bytes *GSUB_table,
FT_Bytes *JSTF_table )
{
FT_Service_OTvalidate service;
FT_Error error;
if ( !face )
{
error = FT_Err_Invalid_Face_Handle;
goto Exit;
}
if ( !( BASE_table &&
GDEF_table &&
GPOS_table &&
GSUB_table &&
JSTF_table ) )
{
error = FT_Err_Invalid_Argument;
goto Exit;
}
FT_FACE_FIND_GLOBAL_SERVICE( face, service, OPENTYPE_VALIDATE );
if ( service )
error = service->validate( face,
validation_flags,
BASE_table,
GDEF_table,
GPOS_table,
GSUB_table,
JSTF_table );
else
error = FT_Err_Invalid_Argument;
Exit:
return error;
}
/* END */

View File

@ -54,6 +54,7 @@ BASE_EXT_SRC := $(BASE_DIR)/ftbbox.c \
$(BASE_DIR)/ftbdf.c \
$(BASE_DIR)/ftglyph.c \
$(BASE_DIR)/ftmm.c \
$(BASE_DIR)/ftotval.c \
$(BASE_DIR)/ftpfr.c \
$(BASE_DIR)/ftstroke.c \
$(BASE_DIR)/fttype1.c \

21
src/otvalid/Jamfile Normal file
View File

@ -0,0 +1,21 @@
# FreeType 2 src/otvalid Jamfile (c) 2004 Werner Lemberg
#
SubDir FT2_TOP $(FT2_SRC_DIR) otvalid ;
{
local _sources ;
if $(FT2_MULTI)
{
_sources = otvbase otvcommn otvgdef otvgpos otvgsub otvjstf otvmod ;
}
else
{
_sources = otvalid ;
}
Library $(FT2_LIB) : $(_sources).c ;
}
# end of src/otvalid Jamfile

23
src/otvalid/descrip.mms Normal file
View File

@ -0,0 +1,23 @@
#
# FreeType 2 OpenType validation module compilation rules for VMS
#
# Copyright 2004 by
# 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.
CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.otvalid])
OBJS=otvalid.obj
all : $(OBJS)
library [--.lib]freetype.olb $(OBJS)
# EOF

22
src/otvalid/module.mk Normal file
View File

@ -0,0 +1,22 @@
#
# FreeType 2 otvalid module definition
#
# Copyright 2004 by
# 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.
make_module_list: add_otvalid_module
add_otvalid_module:
$(OPEN_DRIVER)otvalid_module_class$(CLOSE_DRIVER)
$(ECHO_DRIVER)otvalid $(ECHO_DRIVER_DESC)OpenType validation module$(ECHO_DRIVER_DONE)
# EOF

30
src/otvalid/otvalid.c Normal file
View File

@ -0,0 +1,30 @@
/***************************************************************************/
/* */
/* otvalid.c */
/* */
/* FreeType validator for OpenType tables (body only). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include <ft2build.h>
#include "otvbase.c"
#include "otvcommn.c"
#include "otvgdef.c"
#include "otvgpos.c"
#include "otvgsub.c"
#include "otvjstf.c"
#include "otvmod.c"
/* END */

72
src/otvalid/otvalid.h Normal file
View File

@ -0,0 +1,72 @@
/***************************************************************************/
/* */
/* otvalid.h */
/* */
/* OpenType table validation (specification only). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#ifndef __OTVALID_H__
#define __OTVALID_H__
#include <ft2build.h>
#include FT_FREETYPE_H
#include "otverror.h" /* must come before FT_INTERNAL_VALIDATE_H */
#include FT_INTERNAL_VALIDATE_H
#include FT_INTERNAL_STREAM_H
FT_BEGIN_HEADER
FT_LOCAL( void )
otv_BASE_validate( FT_Bytes table,
FT_Validator valid );
/* GSUB and GPOS tables should already be validated; */
/* if missing, set corresponding argument to 0 */
FT_LOCAL( void )
otv_GDEF_validate( FT_Bytes table,
FT_Bytes gsub,
FT_Bytes gpos,
FT_Validator valid );
FT_LOCAL( void )
otv_GPOS_validate( FT_Bytes table,
FT_UInt glyph_count,
FT_Validator valid );
FT_LOCAL( void )
otv_GSUB_validate( FT_Bytes table,
FT_UInt glyph_count,
FT_Validator valid );
/* GSUB and GPOS tables should already be validated; */
/* if missing, set corresponding argument to 0 */
FT_LOCAL( void )
otv_JSTF_validate( FT_Bytes table,
FT_Bytes gsub,
FT_Bytes gpos,
FT_UInt glyph_count,
FT_Validator valid );
FT_END_HEADER
#endif /* __OTVALID_H__ */
/* END */

318
src/otvalid/otvbase.c Normal file
View File

@ -0,0 +1,318 @@
/***************************************************************************/
/* */
/* otvbase.c */
/* */
/* OpenType BASE table validation (body). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#include "otvalid.h"
#include "otvcommn.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_otvbase
static void
otv_BaseCoord_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt BaseCoordFormat;
OTV_NAME_ENTER( "BaseCoord" );
OTV_LIMIT_CHECK( 4 );
BaseCoordFormat = FT_NEXT_USHORT( p );
p += 2; /* skip Coordinate */
OTV_TRACE(( " (format %d)\n", BaseCoordFormat ));
switch ( BaseCoordFormat )
{
case 1: /* BaseCoordFormat1 */
break;
case 2: /* BaseCoordFormat2 */
OTV_LIMIT_CHECK( 4 ); /* ReferenceGlyph, BaseCoordPoint */
break;
case 3: /* BaseCoordFormat3 */
OTV_LIMIT_CHECK( 2 );
/* DeviceTable */
otv_Device_validate( table + FT_NEXT_USHORT( p ), valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
static void
otv_BaseTagList_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt BaseTagCount;
OTV_NAME_ENTER( "BaseTagList" );
OTV_LIMIT_CHECK( 2 );
BaseTagCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (BaseTagCount = %d)\n", BaseTagCount ));
OTV_LIMIT_CHECK( BaseTagCount * 4 ); /* BaselineTag */
OTV_EXIT;
}
static void
otv_BaseValues_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt BaseCoordCount;
OTV_NAME_ENTER( "BaseValues" );
OTV_LIMIT_CHECK( 4 );
p += 2; /* skip DefaultIndex */
BaseCoordCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (BaseCoordCount = %d)\n", BaseCoordCount ));
OTV_LIMIT_CHECK( BaseCoordCount * 2 );
/* BaseCoord */
for ( ; BaseCoordCount > 0; BaseCoordCount-- )
otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), valid );
OTV_EXIT;
}
static void
otv_MinMax_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt table_size;
FT_UInt FeatMinMaxCount;
OTV_OPTIONAL_TABLE( MinCoord );
OTV_OPTIONAL_TABLE( MaxCoord );
OTV_NAME_ENTER( "MinMax" );
OTV_LIMIT_CHECK( 6 );
OTV_OPTIONAL_OFFSET( MinCoord );
OTV_OPTIONAL_OFFSET( MaxCoord );
FeatMinMaxCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (FeatMinMaxCount = %d)\n", FeatMinMaxCount ));
table_size = FeatMinMaxCount * 8 + 6;
OTV_SIZE_CHECK( MinCoord );
if ( MinCoord )
otv_BaseCoord_validate( table + MinCoord, valid );
OTV_SIZE_CHECK( MaxCoord );
if ( MaxCoord )
otv_BaseCoord_validate( table + MaxCoord, valid );
OTV_LIMIT_CHECK( FeatMinMaxCount * 8 );
/* FeatMinMaxRecord */
for ( ; FeatMinMaxCount > 0; FeatMinMaxCount-- )
{
p += 4; /* skip FeatureTableTag */
OTV_OPTIONAL_OFFSET( MinCoord );
OTV_OPTIONAL_OFFSET( MaxCoord );
OTV_SIZE_CHECK( MinCoord );
if ( MinCoord )
otv_BaseCoord_validate( table + MinCoord, valid );
OTV_SIZE_CHECK( MaxCoord );
if ( MaxCoord )
otv_BaseCoord_validate( table + MaxCoord, valid );
}
OTV_EXIT;
}
static void
otv_BaseScript_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt table_size;
FT_UInt BaseLangSysCount;
OTV_OPTIONAL_TABLE( BaseValues );
OTV_OPTIONAL_TABLE( DefaultMinMax );
OTV_NAME_ENTER( "BaseScript" );
OTV_LIMIT_CHECK( 6 );
OTV_OPTIONAL_OFFSET( BaseValues );
OTV_OPTIONAL_OFFSET( DefaultMinMax );
BaseLangSysCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (BaseLangSysCount = %d)\n", BaseLangSysCount ));
table_size = BaseLangSysCount * 6 + 6;
OTV_SIZE_CHECK( BaseValues );
if ( BaseValues )
otv_BaseValues_validate( table + BaseValues, valid );
OTV_SIZE_CHECK( DefaultMinMax );
if ( DefaultMinMax )
otv_MinMax_validate( table + DefaultMinMax, valid );
OTV_LIMIT_CHECK( BaseLangSysCount * 6 );
/* BaseLangSysRecord */
for ( ; BaseLangSysCount > 0; BaseLangSysCount-- )
{
p += 4; /* skip BaseLangSysTag */
otv_MinMax_validate( table + FT_NEXT_USHORT( p ), valid );
}
OTV_EXIT;
}
static void
otv_BaseScriptList_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt BaseScriptCount;
OTV_NAME_ENTER( "BaseScriptList" );
OTV_LIMIT_CHECK( 2 );
BaseScriptCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (BaseScriptCount = %d)\n", BaseScriptCount ));
OTV_LIMIT_CHECK( BaseScriptCount * 6 );
/* BaseScriptRecord */
for ( ; BaseScriptCount > 0; BaseScriptCount-- )
{
p += 4; /* skip BaseScriptTag */
/* BaseScript */
otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), valid );
}
OTV_EXIT;
}
static void
otv_Axis_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt table_size;
OTV_OPTIONAL_TABLE( BaseTagList );
OTV_NAME_ENTER( "Axis" );
OTV_LIMIT_CHECK( 4 );
OTV_OPTIONAL_OFFSET( BaseTagList );
table_size = 4;
OTV_SIZE_CHECK( BaseTagList );
if ( BaseTagList )
otv_BaseTagList_validate( table + BaseTagList, valid );
/* BaseScriptList */
otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), valid );
OTV_EXIT;
}
FT_LOCAL_DEF( void )
otv_BASE_validate( FT_Bytes table,
FT_Validator ftvalid )
{
OTV_ValidatorRec validrec;
OTV_Validator valid = &validrec;
FT_Bytes p = table;
FT_UInt table_size;
OTV_OPTIONAL_TABLE( HorizAxis );
OTV_OPTIONAL_TABLE( VertAxis );
valid->root = ftvalid;
FT_TRACE3(( "validating BASE table\n" ));
OTV_INIT;
OTV_LIMIT_CHECK( 6 );
if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
FT_INVALID_DATA;
table_size = 6;
OTV_OPTIONAL_OFFSET( HorizAxis );
OTV_SIZE_CHECK( HorizAxis );
if ( HorizAxis )
otv_Axis_validate( table + HorizAxis, valid );
OTV_OPTIONAL_OFFSET( VertAxis );
OTV_SIZE_CHECK( VertAxis );
if ( VertAxis )
otv_Axis_validate( table + VertAxis, valid );
FT_TRACE4(( "\n" ));
}
/* END */

1052
src/otvalid/otvcommn.c Normal file

File diff suppressed because it is too large Load Diff

442
src/otvalid/otvcommn.h Normal file
View File

@ -0,0 +1,442 @@
/***************************************************************************/
/* */
/* otvcommn.h */
/* */
/* OpenType common tables validation (specification). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#ifndef __OTVCOMMN_H__
#define __OTVCOMMN_H__
#include <ft2build.h>
#include "otvalid.h"
#include FT_INTERNAL_DEBUG_H
FT_BEGIN_HEADER
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** VALIDATION *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
typedef struct OTV_ValidatorRec_* OTV_Validator;
typedef void (*OTV_Validate_Func)( FT_Bytes table,
OTV_Validator valid );
typedef struct OTV_ValidatorRec_
{
FT_Validator root;
FT_UInt type_count;
OTV_Validate_Func* type_funcs;
FT_UInt lookup_count;
FT_UInt glyph_count;
FT_UInt nesting_level;
OTV_Validate_Func func[3];
FT_UInt extra1; /* for passing parameters */
FT_UInt extra2;
FT_Bytes extra3;
#ifdef FT_DEBUG_LEVEL_TRACE
FT_UInt debug_indent;
const FT_String* debug_function_name[3];
#endif
} OTV_ValidatorRec;
#undef FT_INVALID_
#define FT_INVALID_( _prefix, _error ) \
ft_validator_error( valid->root, _prefix ## _error )
#define OTV_OPTIONAL_TABLE( _table ) FT_UInt _table; \
FT_Bytes _table ## _p
#define OTV_OPTIONAL_OFFSET( _offset ) \
FT_BEGIN_STMNT \
_offset ## _p = p; \
_offset = FT_NEXT_USHORT( p ); \
FT_END_STMNT
#define OTV_LIMIT_CHECK( _count ) \
FT_BEGIN_STMNT \
if ( p + (_count) > valid->root->limit ) \
FT_INVALID_TOO_SHORT; \
FT_END_STMNT
#define OTV_SIZE_CHECK( _size ) \
FT_BEGIN_STMNT \
if ( _size > 0 && _size < table_size ) \
{ \
if ( valid->root->level == FT_VALIDATE_PARANOID ) \
FT_INVALID_OFFSET; \
else \
{ \
/* strip off `const' */ \
FT_Byte* pp = (FT_Byte*)_size ## _p; \
\
\
FT_TRACE3(( "\n" \
"Invalid offset to optional table `%s'!\n" \
"Set to zero.\n" \
"\n", #_size )); \
\
/* always assume 16bit entities */ \
_size = pp[0] = pp[1] = 0; \
} \
} \
FT_END_STMNT
#ifdef FT_DEBUG_LEVEL_TRACE
/* use preprocessor's argument prescan to expand one argument into two */
#define OTV_NEST1( x ) OTV_NEST1_( x )
#define OTV_NEST1_( func0, name0 ) \
FT_BEGIN_STMNT \
valid->nesting_level = 0; \
valid->func[0] = func0; \
valid->debug_function_name[0] = name0; \
FT_END_STMNT
/* use preprocessor's argument prescan to expand two arguments into four */
#define OTV_NEST2( x, y ) OTV_NEST2_( x, y )
#define OTV_NEST2_( func0, name0, func1, name1 ) \
FT_BEGIN_STMNT \
valid->nesting_level = 0; \
valid->func[0] = func0; \
valid->func[1] = func1; \
valid->debug_function_name[0] = name0; \
valid->debug_function_name[1] = name1; \
FT_END_STMNT
/* use preprocessor's argument prescan to expand three arguments into six */
#define OTV_NEST3( x, y, z ) OTV_NEST3_( x, y, z )
#define OTV_NEST3_( func0, name0, func1, name1, func2, name2 ) \
FT_BEGIN_STMNT \
valid->nesting_level = 0; \
valid->func[0] = func0; \
valid->func[1] = func1; \
valid->func[2] = func2; \
valid->debug_function_name[0] = name0; \
valid->debug_function_name[1] = name1; \
valid->debug_function_name[2] = name2; \
FT_END_STMNT
#define OTV_INIT valid->debug_indent = 0
#define OTV_ENTER \
FT_BEGIN_STMNT \
valid->debug_indent += 2; \
FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \
FT_TRACE4(( "%s table\n", \
valid->debug_function_name[valid->nesting_level] )); \
FT_END_STMNT
#define OTV_NAME_ENTER( name ) \
FT_BEGIN_STMNT \
valid->debug_indent += 2; \
FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \
FT_TRACE4(( "%s table\n", name )); \
FT_END_STMNT
#define OTV_EXIT valid->debug_indent -= 2
#define OTV_TRACE( s ) \
FT_BEGIN_STMNT \
FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \
FT_TRACE4( s ); \
FT_END_STMNT
#else /* !FT_DEBUG_LEVEL_TRACE */
/* use preprocessor's argument prescan to expand one argument into two */
#define OTV_NEST1( x ) OTV_NEST1_( x )
#define OTV_NEST1_( func0, name0 ) \
FT_BEGIN_STMNT \
valid->nesting_level = 0; \
valid->func[0] = func0; \
FT_END_STMNT
/* use preprocessor's argument prescan to expand two arguments into four */
#define OTV_NEST2( x, y ) OTV_NEST2_( x, y )
#define OTV_NEST2_( func0, name0, func1, name1 ) \
FT_BEGIN_STMNT \
valid->nesting_level = 0; \
valid->func[0] = func0; \
valid->func[1] = func1; \
FT_END_STMNT
/* use preprocessor's argument prescan to expand three arguments into six */
#define OTV_NEST3( x, y, z ) OTV_NEST3_( x, y, z )
#define OTV_NEST3_( func0, name0, func1, name1, func2, name2 ) \
FT_BEGIN_STMNT \
valid->nesting_level = 0; \
valid->func[0] = func0; \
valid->func[1] = func1; \
valid->func[2] = func2; \
FT_END_STMNT
#define OTV_INIT do ; while ( 0 )
#define OTV_ENTER do ; while ( 0 )
#define OTV_NAME_ENTER( name ) do ; while ( 0 )
#define OTV_EXIT do ; while ( 0 )
#define OTV_TRACE( s ) do ; while ( 0 )
#endif /* !FT_DEBUG_LEVEL_TRACE */
#define OTV_RUN valid->func[0]
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** COVERAGE TABLE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
otv_Coverage_validate( FT_Bytes table,
OTV_Validator valid );
/* return first covered glyph */
FT_LOCAL( FT_UInt )
otv_Coverage_get_first( FT_Bytes table );
/* return last covered glyph */
FT_LOCAL( FT_UInt )
otv_Coverage_get_last( FT_Bytes table );
/* return number of covered glyphs */
FT_LOCAL( FT_UInt )
otv_Coverage_get_count( FT_Bytes table );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CLASS DEFINITION TABLE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
otv_ClassDef_validate( FT_Bytes table,
OTV_Validator valid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** DEVICE TABLE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
otv_Device_validate( FT_Bytes table,
OTV_Validator valid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** LOOKUPS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
otv_Lookup_validate( FT_Bytes table,
OTV_Validator valid );
FT_LOCAL( void )
otv_LookupList_validate( FT_Bytes table,
OTV_Validator valid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** FEATURES *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
otv_Feature_validate( FT_Bytes table,
OTV_Validator valid );
/* lookups must already be validated */
FT_LOCAL( void )
otv_FeatureList_validate( FT_Bytes table,
FT_Bytes lookups,
OTV_Validator valid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** LANGUAGE SYSTEM *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
otv_LangSys_validate( FT_Bytes table,
OTV_Validator valid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** SCRIPTS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
otv_Script_validate( FT_Bytes table,
OTV_Validator valid );
/* features must already be validated */
FT_LOCAL( void )
otv_ScriptList_validate( FT_Bytes table,
FT_Bytes features,
OTV_Validator valid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** UTILITY FUNCTIONS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define ChainPosClassSet otv_x_Ox, "ChainPosClassSet"
#define ChainPosRuleSet otv_x_Ox, "ChainPosRuleSet"
#define ChainSubClassSet otv_x_Ox, "ChainSubClassSet"
#define ChainSubRuleSet otv_x_Ox, "ChainSubRuleSet"
#define JstfLangSys otv_x_Ox, "JstfLangSys"
#define JstfMax otv_x_Ox, "JstfMax"
#define LigGlyph otv_x_Ox, "LigGlyph"
#define LigatureArray otv_x_Ox, "LigatureArray"
#define LigatureSet otv_x_Ox, "LigatureSet"
#define PosClassSet otv_x_Ox, "PosClassSet"
#define PosRuleSet otv_x_Ox, "PosRuleSet"
#define SubClassSet otv_x_Ox, "SubClassSet"
#define SubRuleSet otv_x_Ox, "SubRuleSet"
FT_LOCAL( void )
otv_x_Ox ( FT_Bytes table,
OTV_Validator valid );
#define AlternateSubstFormat1 otv_u_C_x_Ox, "AlternateSubstFormat1"
#define ChainContextPosFormat1 otv_u_C_x_Ox, "ChainContextPosFormat1"
#define ChainContextSubstFormat1 otv_u_C_x_Ox, "ChainContextSubstFormat1"
#define ContextPosFormat1 otv_u_C_x_Ox, "ContextPosFormat1"
#define ContextSubstFormat1 otv_u_C_x_Ox, "ContextSubstFormat1"
#define LigatureSubstFormat1 otv_u_C_x_Ox, "LigatureSubstFormat1"
#define MultipleSubstFormat1 otv_u_C_x_Ox, "MultipleSubstFormat1"
FT_LOCAL( void )
otv_u_C_x_Ox( FT_Bytes table,
OTV_Validator valid );
#define AlternateSet otv_x_ux, "AlternateSet"
#define AttachPoint otv_x_ux, "AttachPoint"
#define ExtenderGlyph otv_x_ux, "ExtenderGlyph"
#define JstfGPOSModList otv_x_ux, "JstfGPOSModList"
#define JstfGSUBModList otv_x_ux, "JstfGSUBModList"
#define Sequence otv_x_ux, "Sequence"
FT_LOCAL( void )
otv_x_ux( FT_Bytes table,
OTV_Validator valid );
#define PosClassRule otv_x_y_ux_sy, "PosClassRule"
#define PosRule otv_x_y_ux_sy, "PosRule"
#define SubClassRule otv_x_y_ux_sy, "SubClassRule"
#define SubRule otv_x_y_ux_sy, "SubRule"
FT_LOCAL( void )
otv_x_y_ux_sy( FT_Bytes table,
OTV_Validator valid );
#define ChainPosClassRule otv_x_ux_y_uy_z_uz_p_sp, "ChainPosClassRule"
#define ChainPosRule otv_x_ux_y_uy_z_uz_p_sp, "ChainPosRule"
#define ChainSubClassRule otv_x_ux_y_uy_z_uz_p_sp, "ChainSubClassRule"
#define ChainSubRule otv_x_ux_y_uy_z_uz_p_sp, "ChainSubRule"
FT_LOCAL( void )
otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table,
OTV_Validator valid );
#define ContextPosFormat2 otv_u_O_O_x_Onx, "ContextPosFormat2"
#define ContextSubstFormat2 otv_u_O_O_x_Onx, "ContextSubstFormat2"
FT_LOCAL( void )
otv_u_O_O_x_Onx( FT_Bytes table,
OTV_Validator valid );
#define ContextPosFormat3 otv_u_x_y_Ox_sy, "ContextPosFormat3"
#define ContextSubstFormat3 otv_u_x_y_Ox_sy, "ContextSubstFormat3"
FT_LOCAL( void )
otv_u_x_y_Ox_sy( FT_Bytes table,
OTV_Validator valid );
#define ChainContextPosFormat2 otv_u_O_O_O_O_x_Onx, "ChainContextPosFormat2"
#define ChainContextSubstFormat2 otv_u_O_O_O_O_x_Onx, "ChainContextSubstFormat2"
FT_LOCAL( void )
otv_u_O_O_O_O_x_Onx( FT_Bytes table,
OTV_Validator valid );
#define ChainContextPosFormat3 otv_u_x_Ox_y_Oy_z_Oz_p_sp, "ChainContextPosFormat3"
#define ChainContextSubstFormat3 otv_u_x_Ox_y_Oy_z_Oz_p_sp, "ChainContextSubstFormat3"
FT_LOCAL( void )
otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table,
OTV_Validator valid );
FT_LOCAL( FT_UInt )
otv_GSUBGPOS_get_Lookup_count( FT_Bytes table );
FT_LOCAL( FT_UInt )
otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table );
/* */
FT_END_HEADER
#endif /* __OTVCOMMN_H__ */
/* END */

43
src/otvalid/otverror.h Normal file
View File

@ -0,0 +1,43 @@
/***************************************************************************/
/* */
/* otverror.h */
/* */
/* OpenType validation module error codes (specification only). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
/*************************************************************************/
/* */
/* This file is used to define the OpenType validation module error */
/* enumeration constants. */
/* */
/*************************************************************************/
#ifndef __OTVERROR_H__
#define __OTVERROR_H__
#include FT_MODULE_ERRORS_H
#undef __FTERRORS_H__
#define FT_ERR_PREFIX OTV_Err_
#define FT_ERR_BASE FT_Mod_Err_OTV
#define FT_KEEP_ERR_PREFIX
#include FT_ERRORS_H
#endif /* __OTVERROR_H__ */
/* END */

219
src/otvalid/otvgdef.c Normal file
View File

@ -0,0 +1,219 @@
/***************************************************************************/
/* */
/* otvgdef.c */
/* */
/* OpenType GDEF table validation (body). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#include "otvalid.h"
#include "otvcommn.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_otvgdef
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** UTILITY FUNCTIONS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define AttachList otv_O_x_Ox, "AttachList"
#define LigCaretList otv_O_x_Ox, "LigCaretList"
/* sets valid->extra1 (0) */
static void
otv_O_x_Ox( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_Bytes Coverage;
FT_UInt GlyphCount;
OTV_Validate_Func func;
OTV_ENTER;
OTV_LIMIT_CHECK( 4 );
Coverage = table + FT_NEXT_USHORT( p );
GlyphCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
otv_Coverage_validate( Coverage, valid );
if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
FT_INVALID_DATA;
OTV_LIMIT_CHECK( GlyphCount * 2 );
valid->nesting_level++;
func = valid->func[valid->nesting_level];
valid->extra1 = 0;
for ( ; GlyphCount > 0; GlyphCount-- )
func( table + FT_NEXT_USHORT( p ), valid );
valid->nesting_level--;
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** LIGATURE CARETS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define CaretValue otv_CaretValue_validate, "CaretValue"
static void
otv_CaretValue_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt CaretValueFormat;
OTV_ENTER;
OTV_LIMIT_CHECK( 4 );
CaretValueFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format = %d)\n", CaretValueFormat ));
switch ( CaretValueFormat )
{
case 1: /* CaretValueFormat1 */
/* skip Coordinate, no test */
break;
case 2: /* CaretValueFormat2 */
/* skip CaretValuePoint, no test */
break;
case 3: /* CaretValueFormat3 */
p += 2; /* skip Coordinate */
OTV_LIMIT_CHECK( 2 );
/* DeviceTable */
otv_Device_validate( table + FT_NEXT_USHORT( p ), valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GDEF TABLE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL_DEF( void )
otv_GDEF_validate( FT_Bytes table,
FT_Bytes gsub,
FT_Bytes gpos,
FT_Validator ftvalid )
{
OTV_ValidatorRec validrec;
OTV_Validator valid = &validrec;
FT_Bytes p = table;
FT_UInt table_size;
FT_Bool need_MarkAttachClassDef;
OTV_OPTIONAL_TABLE( GlyphClassDef );
OTV_OPTIONAL_TABLE( AttachListOffset );
OTV_OPTIONAL_TABLE( LigCaretListOffset );
OTV_OPTIONAL_TABLE( MarkAttachClassDef );
valid->root = ftvalid;
FT_TRACE3(( "validating GDEF table\n" ));
OTV_INIT;
OTV_LIMIT_CHECK( 12 );
if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
FT_INVALID_FORMAT;
/* MarkAttachClassDef has been added to the OpenType */
/* specification without increasing GDEF's version, */
/* so we use this ugly hack to find out whether the */
/* table is needed actually. */
need_MarkAttachClassDef =
otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) ||
otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos );
if ( need_MarkAttachClassDef )
table_size = 12; /* OpenType >= 1.2 */
else
table_size = 10; /* OpenType < 1.2 */
OTV_OPTIONAL_OFFSET( GlyphClassDef );
OTV_SIZE_CHECK( GlyphClassDef );
if ( GlyphClassDef )
otv_ClassDef_validate( table + GlyphClassDef, valid );
OTV_OPTIONAL_OFFSET( AttachListOffset );
OTV_SIZE_CHECK( AttachListOffset );
if ( AttachListOffset )
{
OTV_NEST2( AttachList, AttachPoint );
OTV_RUN( table + AttachListOffset, valid );
}
OTV_OPTIONAL_OFFSET( LigCaretListOffset );
OTV_SIZE_CHECK( LigCaretListOffset );
if ( LigCaretListOffset )
{
OTV_NEST3( LigCaretList, LigGlyph, CaretValue );
OTV_RUN( table + LigCaretListOffset, valid );
}
if ( need_MarkAttachClassDef )
{
OTV_OPTIONAL_OFFSET( MarkAttachClassDef );
OTV_SIZE_CHECK( MarkAttachClassDef );
if ( MarkAttachClassDef )
otv_ClassDef_validate( table + MarkAttachClassDef, valid );
}
FT_TRACE4(( "\n" ));
}
/* END */

1013
src/otvalid/otvgpos.c Normal file

File diff suppressed because it is too large Load Diff

36
src/otvalid/otvgpos.h Normal file
View File

@ -0,0 +1,36 @@
/***************************************************************************/
/* */
/* otvgpos.h */
/* */
/* OpenType GPOS table validator (specification). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#ifndef __OTVGPOS_H__
#define __OTVGPOS_H__
FT_BEGIN_HEADER
FT_LOCAL( void )
otv_GPOS_subtable_validate( FT_Bytes table,
OTV_Validator valid );
FT_END_HEADER
#endif /* __OTVGPOS_H__ */
/* END */

584
src/otvalid/otvgsub.c Normal file
View File

@ -0,0 +1,584 @@
/***************************************************************************/
/* */
/* otvgsub.c */
/* */
/* OpenType GSUB table validation (body). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#include "otvalid.h"
#include "otvcommn.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_otvgsub
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 1 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* uses valid->glyph_count */
static void
otv_SingleSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "SingleSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1: /* SingleSubstFormat1 */
{
FT_Bytes Coverage;
FT_Int DeltaGlyphID;
FT_Long idx;
OTV_LIMIT_CHECK( 4 );
Coverage = table + FT_NEXT_USHORT( p );
DeltaGlyphID = FT_NEXT_SHORT( p );
otv_Coverage_validate( Coverage, valid );
idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID;
if ( idx < 0 )
FT_INVALID_DATA;
idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID;
if ( (FT_UInt)idx >= valid->glyph_count )
FT_INVALID_DATA;
}
break;
case 2: /* SingleSubstFormat2 */
{
FT_UInt Coverage, GlyphCount;
OTV_LIMIT_CHECK( 4 );
Coverage = FT_NEXT_USHORT( p );
GlyphCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
otv_Coverage_validate( table + Coverage, valid );
OTV_LIMIT_CHECK( GlyphCount * 2 );
/* Substitute */
for ( ; GlyphCount > 0; GlyphCount-- )
if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
FT_INVALID_DATA;
}
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 2 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* sets valid->extra1 (glyph count) */
static void
otv_MultipleSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "MultipleSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1:
valid->extra1 = valid->glyph_count;
OTV_NEST2( MultipleSubstFormat1, Sequence );
OTV_RUN( table, valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 3 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* sets valid->extra1 (glyph count) */
static void
otv_AlternateSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "AlternateSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1:
valid->extra1 = valid->glyph_count;
OTV_NEST2( AlternateSubstFormat1, AlternateSet );
OTV_RUN( table, valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 4 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define Ligature otv_Ligature_validate, "Ligature"
/* uses valid->glyph_count */
static void
otv_Ligature_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt LigatureGlyph, CompCount;
OTV_ENTER;
OTV_LIMIT_CHECK( 4 );
LigatureGlyph = FT_NEXT_USHORT( p );
if ( LigatureGlyph >= valid->glyph_count )
FT_INVALID_DATA;
CompCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (CompCount = %d)\n", CompCount ));
if ( CompCount == 0 )
FT_INVALID_DATA;
CompCount--;
OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */
/* no need to check the Component glyph indices */
OTV_EXIT;
}
static void
otv_LigatureSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "LigatureSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1:
OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature );
OTV_RUN( table, valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 5 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* sets valid->extra1 (lookup count) */
static void
otv_ContextSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "ContextSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1:
/* no need to check glyph indices/classes used as input for these */
/* context rules since even invalid glyph indices/classes return */
/* meaningful results */
valid->extra1 = valid->lookup_count;
OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule );
OTV_RUN( table, valid );
break;
case 2:
/* no need to check glyph indices/classes used as input for these */
/* context rules since even invalid glyph indices/classes return */
/* meaningful results */
OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule );
OTV_RUN( table, valid );
break;
case 3:
OTV_NEST1( ContextSubstFormat3 );
OTV_RUN( table, valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 6 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* sets valid->extra1 (lookup count) */
static void
otv_ChainContextSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "ChainContextSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1:
/* no need to check glyph indices/classes used as input for these */
/* context rules since even invalid glyph indices/classes return */
/* meaningful results */
valid->extra1 = valid->lookup_count;
OTV_NEST3( ChainContextSubstFormat1,
ChainSubRuleSet, ChainSubRule );
OTV_RUN( table, valid );
break;
case 2:
/* no need to check glyph indices/classes used as input for these */
/* context rules since even invalid glyph indices/classes return */
/* meaningful results */
OTV_NEST3( ChainContextSubstFormat2,
ChainSubClassSet, ChainSubClassRule );
OTV_RUN( table, valid );
break;
case 3:
OTV_NEST1( ChainContextSubstFormat3 );
OTV_RUN( table, valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 7 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* uses valid->type_funcs */
static void
otv_ExtensionSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "ExtensionSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1: /* ExtensionSubstFormat1 */
{
FT_UInt ExtensionLookupType, ExtensionOffset;
OTV_Validate_Func validate;
OTV_LIMIT_CHECK( 6 );
ExtensionLookupType = FT_NEXT_USHORT( p );
ExtensionOffset = FT_NEXT_ULONG( p );
if ( ExtensionLookupType == 0 ||
ExtensionLookupType == 7 ||
ExtensionLookupType > 8 )
FT_INVALID_DATA;
validate = valid->type_funcs[ExtensionLookupType - 1];
validate( table + ExtensionOffset, valid );
}
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 8 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* uses valid->glyph_count */
static void
otv_ReverseChainSingleSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table, Coverage;
FT_UInt SubstFormat;
FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount;
OTV_NAME_ENTER( "ReverseChainSingleSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1: /* ReverseChainSingleSubstFormat1 */
OTV_LIMIT_CHECK( 4 );
Coverage = table + FT_NEXT_USHORT( p );
BacktrackGlyphCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
otv_Coverage_validate( Coverage, valid );
OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid );
LookaheadGlyphCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid );
GlyphCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
FT_INVALID_DATA;
OTV_LIMIT_CHECK( GlyphCount * 2 );
/* Substitute */
for ( ; GlyphCount > 0; GlyphCount-- )
if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
FT_INVALID_DATA;
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
static OTV_Validate_Func otv_gsub_validate_funcs[8] =
{
otv_SingleSubst_validate,
otv_MultipleSubst_validate,
otv_AlternateSubst_validate,
otv_LigatureSubst_validate,
otv_ContextSubst_validate,
otv_ChainContextSubst_validate,
otv_ExtensionSubst_validate,
otv_ReverseChainSingleSubst_validate
};
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB TABLE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* sets valid->type_count */
/* sets valid->type_funcs */
/* sets valid->glyph_count */
FT_LOCAL_DEF( void )
otv_GSUB_validate( FT_Bytes table,
FT_UInt glyph_count,
FT_Validator ftvalid )
{
OTV_ValidatorRec validrec;
OTV_Validator valid = &validrec;
FT_Bytes p = table;
FT_UInt ScriptList, FeatureList, LookupList;
valid->root = ftvalid;
FT_TRACE3(( "validating GSUB table\n" ));
OTV_INIT;
OTV_LIMIT_CHECK( 10 );
if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
FT_INVALID_DATA;
ScriptList = FT_NEXT_USHORT( p );
FeatureList = FT_NEXT_USHORT( p );
LookupList = FT_NEXT_USHORT( p );
valid->type_count = 8;
valid->type_funcs = otv_gsub_validate_funcs;
valid->glyph_count = glyph_count;
otv_LookupList_validate( table + LookupList,
valid );
otv_FeatureList_validate( table + FeatureList, table + LookupList,
valid );
otv_ScriptList_validate( table + ScriptList, table + FeatureList,
valid );
FT_TRACE4(( "\n" ));
}
/* END */

258
src/otvalid/otvjstf.c Normal file
View File

@ -0,0 +1,258 @@
/***************************************************************************/
/* */
/* otvjstf.c */
/* */
/* OpenType JSTF table validation (body). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#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_otvjstf
#define JstfPriority otv_JstfPriority_validate, "JstfPriority"
#define JstfLookup otv_GPOS_subtable_validate, ""
/* uses valid->extra1 (GSUB lookup count) */
/* uses valid->extra2 (GPOS lookup count) */
/* sets valid->extra1 (counter) */
static void
otv_JstfPriority_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt table_size;
FT_UInt gsub_lookup_count, gpos_lookup_count;
OTV_OPTIONAL_TABLE( ShrinkageEnableGSUB );
OTV_OPTIONAL_TABLE( ShrinkageDisableGSUB );
OTV_OPTIONAL_TABLE( ShrinkageEnableGPOS );
OTV_OPTIONAL_TABLE( ShrinkageDisableGPOS );
OTV_OPTIONAL_TABLE( ExtensionEnableGSUB );
OTV_OPTIONAL_TABLE( ExtensionDisableGSUB );
OTV_OPTIONAL_TABLE( ExtensionEnableGPOS );
OTV_OPTIONAL_TABLE( ExtensionDisableGPOS );
OTV_OPTIONAL_TABLE( ShrinkageJstfMax );
OTV_OPTIONAL_TABLE( ExtensionJstfMax );
OTV_ENTER;
OTV_TRACE(( "JstfPriority table\n" ));
OTV_LIMIT_CHECK( 20 );
gsub_lookup_count = valid->extra1;
gpos_lookup_count = valid->extra2;
table_size = 20;
valid->extra1 = gsub_lookup_count;
OTV_OPTIONAL_OFFSET( ShrinkageEnableGSUB );
OTV_SIZE_CHECK( ShrinkageEnableGSUB );
if ( ShrinkageEnableGSUB )
otv_x_ux( table + ShrinkageEnableGSUB, valid );
OTV_OPTIONAL_OFFSET( ShrinkageDisableGSUB );
OTV_SIZE_CHECK( ShrinkageDisableGSUB );
if ( ShrinkageDisableGSUB )
otv_x_ux( table + ShrinkageDisableGSUB, valid );
valid->extra1 = gpos_lookup_count;
OTV_OPTIONAL_OFFSET( ShrinkageEnableGPOS );
OTV_SIZE_CHECK( ShrinkageEnableGPOS );
if ( ShrinkageEnableGPOS )
otv_x_ux( table + ShrinkageEnableGPOS, valid );
OTV_OPTIONAL_OFFSET( ShrinkageDisableGPOS );
OTV_SIZE_CHECK( ShrinkageDisableGPOS );
if ( ShrinkageDisableGPOS )
otv_x_ux( table + ShrinkageDisableGPOS, valid );
OTV_OPTIONAL_OFFSET( ShrinkageJstfMax );
OTV_SIZE_CHECK( ShrinkageJstfMax );
if ( ShrinkageJstfMax )
{
/* XXX: check lookup types? */
OTV_NEST2( JstfMax, JstfLookup );
OTV_RUN( table + ShrinkageJstfMax, valid );
}
valid->extra1 = gsub_lookup_count;
OTV_OPTIONAL_OFFSET( ExtensionEnableGSUB );
OTV_SIZE_CHECK( ExtensionEnableGSUB );
if ( ExtensionEnableGSUB )
otv_x_ux( table + ExtensionEnableGSUB, valid );
OTV_OPTIONAL_OFFSET( ExtensionDisableGSUB );
OTV_SIZE_CHECK( ExtensionDisableGSUB );
if ( ExtensionDisableGSUB )
otv_x_ux( table + ExtensionDisableGSUB, valid );
valid->extra1 = gpos_lookup_count;
OTV_OPTIONAL_OFFSET( ExtensionEnableGPOS );
OTV_SIZE_CHECK( ExtensionEnableGPOS );
if ( ExtensionEnableGPOS )
otv_x_ux( table + ExtensionEnableGPOS, valid );
OTV_OPTIONAL_OFFSET( ExtensionDisableGPOS );
OTV_SIZE_CHECK( ExtensionDisableGPOS );
if ( ExtensionDisableGPOS )
otv_x_ux( table + ExtensionDisableGPOS, valid );
OTV_OPTIONAL_OFFSET( ExtensionJstfMax );
OTV_SIZE_CHECK( ExtensionJstfMax );
if ( ExtensionJstfMax )
{
/* XXX: check lookup types? */
OTV_NEST2( JstfMax, JstfLookup );
OTV_RUN( table + ExtensionJstfMax, valid );
}
valid->extra1 = gsub_lookup_count;
valid->extra2 = gpos_lookup_count;
OTV_EXIT;
}
/* sets valid->extra (glyph count) */
/* sets valid->func1 (otv_JstfPriority_validate) */
static void
otv_JstfScript_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt table_size;
FT_UInt JstfLangSysCount;
OTV_OPTIONAL_TABLE( ExtGlyph );
OTV_OPTIONAL_TABLE( DefJstfLangSys );
OTV_NAME_ENTER( "JstfScript" );
OTV_LIMIT_CHECK( 6 );
OTV_OPTIONAL_OFFSET( ExtGlyph );
OTV_OPTIONAL_OFFSET( DefJstfLangSys );
JstfLangSysCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (JstfLangSysCount = %d)\n", JstfLangSysCount ));
table_size = JstfLangSysCount * 6 + 6;
OTV_SIZE_CHECK( ExtGlyph );
if ( ExtGlyph )
{
valid->extra1 = valid->glyph_count;
OTV_NEST1( ExtenderGlyph );
OTV_RUN( table + ExtGlyph, valid );
}
OTV_SIZE_CHECK( DefJstfLangSys );
if ( DefJstfLangSys )
{
OTV_NEST2( JstfLangSys, JstfPriority );
OTV_RUN( table + DefJstfLangSys, valid );
}
OTV_LIMIT_CHECK( 6 * JstfLangSysCount );
/* JstfLangSysRecord */
OTV_NEST2( JstfLangSys, JstfPriority );
for ( ; JstfLangSysCount > 0; JstfLangSysCount-- )
{
p += 4; /* skip JstfLangSysTag */
OTV_RUN( table + FT_NEXT_USHORT( p ), valid );
}
OTV_EXIT;
}
/* sets valid->extra1 (GSUB lookup count) */
/* sets valid->extra2 (GPOS lookup count) */
/* sets valid->glyph_count */
FT_LOCAL_DEF( void )
otv_JSTF_validate( FT_Bytes table,
FT_Bytes gsub,
FT_Bytes gpos,
FT_UInt glyph_count,
FT_Validator ftvalid )
{
OTV_ValidatorRec validrec;
OTV_Validator valid = &validrec;
FT_Bytes p = table;
FT_UInt JstfScriptCount;
valid->root = ftvalid;
FT_TRACE3(( "validating JSTF table\n" ));
OTV_INIT;
OTV_LIMIT_CHECK( 6 );
if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
FT_INVALID_DATA;
JstfScriptCount = FT_NEXT_USHORT( p );
FT_TRACE3(( " (JstfScriptCount = %d)\n", JstfScriptCount ));
OTV_LIMIT_CHECK( JstfScriptCount * 6 );
if ( gsub )
valid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub );
else
valid->extra1 = 0;
if ( gpos )
valid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos );
else
valid->extra2 = 0;
valid->glyph_count = glyph_count;
/* JstfScriptRecord */
for ( ; JstfScriptCount > 0; JstfScriptCount-- )
{
p += 4; /* skip JstfScriptTag */
/* JstfScript */
otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), valid );
}
FT_TRACE4(( "\n" ));
}
/* END */

227
src/otvalid/otvmod.c Normal file
View File

@ -0,0 +1,227 @@
/***************************************************************************/
/* */
/* otvmod.c */
/* */
/* FreeType's OpenType validation module implementation (body). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_TRUETYPE_TABLES_H
#include FT_TRUETYPE_TAGS_H
#include FT_OPENTYPE_VALIDATE_H
#include FT_INTERNAL_OBJECTS_H
#include FT_SERVICE_OPENTYPE_VALIDATE_H
#include "otvmod.h"
#include "otvalid.h"
#include "otvcommn.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_otvmodule
static FT_Error
otv_load_table( FT_Face face,
FT_Tag tag,
FT_Byte* *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 == OTV_Err_Table_Missing )
return OTV_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;
}
static FT_Error
otv_validate( FT_Face face,
FT_UInt ot_flags,
FT_Bytes *ot_base,
FT_Bytes *ot_gdef,
FT_Bytes *ot_gpos,
FT_Bytes *ot_gsub,
FT_Bytes *ot_jstf )
{
FT_Error error = OTV_Err_Ok;
FT_Byte *base, *gdef, *gpos, *gsub, *jstf;
FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf;
FT_ValidatorRec valid;
base = gdef = gpos = gsub = jstf = NULL;
len_base = len_gdef = len_gpos = len_gsub = len_jstf = 0;
/* load tables */
if ( ot_flags & FT_VALIDATE_BASE )
{
error = otv_load_table( face, TTAG_BASE, &base, &len_base );
if ( error )
goto Exit;
}
if ( ot_flags & FT_VALIDATE_GDEF )
{
error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef );
if ( error )
goto Exit;
}
if ( ot_flags & FT_VALIDATE_GPOS )
{
error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos );
if ( error )
goto Exit;
}
if ( ot_flags & FT_VALIDATE_GSUB )
{
error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub );
if ( error )
goto Exit;
}
if ( ot_flags & FT_VALIDATE_JSTF )
{
error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf );
if ( error )
goto Exit;
}
/* validate tables */
if ( base )
{
ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT );
if ( ft_setjmp( valid.jump_buffer ) == 0 )
otv_BASE_validate( base, &valid );
error = valid.error;
if ( error )
goto Exit;
}
if ( gpos )
{
ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT );
if (ft_setjmp( valid.jump_buffer ) == 0 )
otv_GPOS_validate( gpos, face->num_glyphs, &valid );
error = valid.error;
if ( error )
goto Exit;
}
if ( gsub )
{
ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT );
if ( ft_setjmp( valid.jump_buffer ) == 0 )
otv_GSUB_validate( gsub, face->num_glyphs, &valid );
error = valid.error;
if ( error )
goto Exit;
}
if ( gdef )
{
ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT );
if ( ft_setjmp( valid.jump_buffer ) == 0 )
otv_GDEF_validate( gdef, gsub, gpos, &valid );
error = valid.error;
if ( error )
goto Exit;
}
if ( jstf )
{
ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT );
if ( ft_setjmp( valid.jump_buffer ) == 0 )
otv_JSTF_validate( jstf, gsub, gpos, 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;
*ot_gsub = (FT_Bytes)gsub;
*ot_jstf = (FT_Bytes)jstf;
Exit:
return error;
}
static
const FT_Service_OTvalidateRec otvalid_interface =
{
otv_validate
};
static
const FT_ServiceDescRec otvalid_services[] =
{
{ FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface },
{ NULL, NULL }
};
static FT_Pointer
otvalid_get_service( FT_Module module,
const char* service_id )
{
FT_UNUSED( module );
return ft_service_list_lookup( otvalid_services, service_id );
}
FT_CALLBACK_TABLE_DEF
const FT_Module_Class otv_module_class =
{
0,
sizeof( FT_ModuleRec ),
"otvalid",
0x10000L,
0x20000L,
0, /* module-specific interface */
(FT_Module_Constructor)0,
(FT_Module_Destructor) 0,
(FT_Module_Requester) otvalid_get_service
};
/* END */

39
src/otvalid/otvmod.h Normal file
View File

@ -0,0 +1,39 @@
/***************************************************************************/
/* */
/* otvmod.h */
/* */
/* FreeType's OpenType validation module implementation */
/* (specification). */
/* */
/* Copyright 2004 by */
/* 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. */
/* */
/***************************************************************************/
#ifndef __OTVMOD_H__
#define __OTVMOD_H__
#include <ft2build.h>
#include FT_MODULE_H
FT_BEGIN_HEADER
FT_EXPORT_VAR( const FT_Module_Class ) otv_module_class;
FT_END_HEADER
#endif /* __OTVMOD_H__ */
/* END */

77
src/otvalid/rules.mk Normal file
View File

@ -0,0 +1,77 @@
#
# FreeType 2 OpenType validation driver configuration rules
#
# Copyright 2004 by
# 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.
# OTV driver directory
#
OTV_DIR := $(SRC_DIR)/otvalid
# compilation flags for the driver
#
OTV_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(OTV_DIR))
# OTV driver sources (i.e., C files)
#
OTV_DRV_SRC := $(OTV_DIR)/otvbase.c \
$(OTV_DIR)/otvcommn.c \
$(OTV_DIR)/otvgdef.c \
$(OTV_DIR)/otvgpos.c \
$(OTV_DIR)/otvgsub.c \
$(OTV_DIR)/otvjstf.c \
$(OTV_DIR)/otvmod.c
# OTV driver headers
#
OTV_DRV_H := $(OTV_DIR)/otvalid.h \
$(OTV_DIR)/otverror.h \
$(OTV_DIR)/otvcommn.h \
$(OTV_DIR)/otvgpos.h \
$(OTV_DIR)/otvmod.h
# OTV driver object(s)
#
# OTV_DRV_OBJ_M is used during `multi' builds.
# OTV_DRV_OBJ_S is used during `single' builds.
#
OTV_DRV_OBJ_M := $(OTV_DRV_SRC:$(OTV_DIR)/%.c=$(OBJ_DIR)/%.$O)
OTV_DRV_OBJ_S := $(OBJ_DIR)/otvalid.$O
# OTV driver source file for single build
#
OTV_DRV_SRC_S := $(OTV_DIR)/otvalid.c
# OTV driver - single object
#
$(OTV_DRV_OBJ_S): $(OTV_DRV_SRC_S) $(OTV_DRV_SRC) \
$(FREETYPE_H) $(OTV_DRV_H)
$(OTV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(OTV_DRV_SRC_S))
# OTV driver - multiple objects
#
$(OBJ_DIR)/%.$O: $(OTV_DIR)/%.c $(FREETYPE_H) $(OTV_DRV_H)
$(OTV_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
# update main driver object lists
#
DRV_OBJS_S += $(OTV_DRV_OBJ_S)
DRV_OBJS_M += $(OTV_DRV_OBJ_M)
# EOF