shithub: freetype+ttf2subf

ref: 169a6d8a044c9c775c433c48a663151b20193e7f
dir: /src/gxvalid/gxvcommn.h/

View raw version
/***************************************************************************/
/*                                                                         */
/*  gxvcommn.h                                                             */
/*                                                                         */
/*    TrueTypeGX/AAT common tables validation (specification).             */
/*                                                                         */
/*  Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/***************************************************************************/

/***************************************************************************/
/* gxvalid is derived from both gxlayout module and otvalid module.        */
/* Development of gxlayout was support of Information-technology Promotion */
/* Agency(IPA), Japan.                                                     */
/***************************************************************************/

/*
 * keywords in variable naming
 * ---------------------------
 *  table: FT_Bytes typed, pointing the start of this table/subtable.
 *  limit: FT_Bytes typed, pointing the end of this table/subtable
 *         including padding for alignment.
 *  offset: FT_UInt typed, the number of octets from the start to target.
 *  length: FT_UInt typed, the number of octets from the start to the end.
 *          in this table/subtable, including padding for alignment.
 *
 *  _MIN, _MAX: should be added to the tail of macros, as INT_MIN etc.
 */

#ifndef __GXVCOMMN_H__
#define __GXVCOMMN_H__


#include <ft2build.h>
#include "gxvalid.h"
#include FT_INTERNAL_DEBUG_H
#include FT_SFNT_NAMES_H

FT_BEGIN_HEADER



  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                         VALIDATION                            *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  typedef struct GXV_ValidatorRec_*         GXV_Validator;

#define DUMMY_LIMIT 0
  typedef void  (*GXV_Validate_Func)( FT_Bytes      table,
                                      FT_Bytes      limit,
                                      GXV_Validator valid );

  /* ====================== LookupTable Validator ======================== */

  typedef union GXV_LookupValueDesc_
  {
    FT_UShort u;
    FT_Short  s;

  } GXV_LookupValueDesc;

  typedef enum  GXV_LookupValue_SignSpec_
  {
    GXV_LOOKUPVALUE_UNSIGNED = 0,
    GXV_LOOKUPVALUE_SIGNED

  } GXV_LookupValue_SignSpec;

  typedef void  (*GXV_Lookup_Value_Validate_Func)( FT_UShort           glyph,
                                                   GXV_LookupValueDesc value,
                                                   GXV_Validator       valid );

  typedef GXV_LookupValueDesc (*GXV_Lookup_Fmt4_Transit_Func)
  ( FT_UShort            relative_gindex,
    GXV_LookupValueDesc  base_value,
    FT_Bytes             lookuptbl_limit,
    GXV_Validator        valid );


  /* ====================== StateTable Validator ========================= */

  typedef enum  GXV_GlyphOffset_Format_
  {
    GXV_GLYPHOFFSET_NONE   = -1,
    GXV_GLYPHOFFSET_UCHAR  = 2,
    GXV_GLYPHOFFSET_CHAR,
    GXV_GLYPHOFFSET_USHORT = 4,
    GXV_GLYPHOFFSET_SHORT,
    GXV_GLYPHOFFSET_ULONG  = 8,
    GXV_GLYPHOFFSET_LONG

  } GXV_GlyphOffset_Format;


#define GXV_GLYPHOFFSET_FMT( table ) \
        ( valid-> table . entry_glyphoffset_fmt )

#define GXV_GLYPHOFFSET_SIZE( table ) \
        ( ( valid-> table . entry_glyphoffset_fmt ) / 2 )

  /* ----------------------- 16bit StateTable ---------------------------- */

  typedef union  GXV_StateTable_GlyphOffsetDesc_
  {
    FT_Byte   uc;
    FT_UShort u;   /* same with GXV_LookupValueDesc */
    FT_ULong  ul;
    FT_Char   c;
    FT_Short  s;   /* same with GXV_LookupValueDesc */
    FT_Long   l;

  } GXV_StateTable_GlyphOffsetDesc;

  typedef void  (*GXV_StateTable_Subtable_Setup_Func)( FT_UShort      table_size,
                                                       FT_UShort      classTable,
                                                       FT_UShort      stateArray,
                                                       FT_UShort      entryTable,
                                                       FT_UShort*     classTable_length_p,
                                                       FT_UShort*     stateArray_length_p,
                                                       FT_UShort*     entryTable_length_p,
                                                       GXV_Validator  valid );

  typedef void  (*GXV_StateTable_Entry_Validate_Func)( FT_Byte                         state,
                                                       FT_UShort                       flags,
                                                       GXV_StateTable_GlyphOffsetDesc  glyphOffset,
                                                       FT_Bytes                        statetable_table,
                                                       FT_Bytes                        statetable_limit,
                                                       GXV_Validator                   valid );

  typedef void  (*GXV_StateTable_OptData_Load_Func)( FT_Bytes       table,
                                                     FT_Bytes       limit,
                                                     GXV_Validator  valid );

  typedef struct GXV_StateTable_ValidatorRec_
  {
    GXV_GlyphOffset_Format  entry_glyphoffset_fmt;
    void*                   optdata;
    GXV_StateTable_Subtable_Setup_Func
                            subtable_setup_func;
    GXV_StateTable_Entry_Validate_Func
                            entry_validate_func;
    GXV_StateTable_OptData_Load_Func
                            optdata_load_func;

  } GXV_StateTable_ValidatorRec, *GXV_StateTable_ValidatorRecData;


  /* ---------------------- 32bit XStateTable ---------------------------- */

  typedef GXV_StateTable_GlyphOffsetDesc GXV_XStateTable_GlyphOffsetDesc;

  typedef void  (*GXV_XStateTable_Subtable_Setup_Func)( FT_ULong       table_size,
                                                        FT_ULong       classTable,
                                                        FT_ULong       stateArray,
                                                        FT_ULong       entryTable,
                                                        FT_ULong*      classTable_length_p,
                                                        FT_ULong*      stateArray_length_p,
                                                        FT_ULong*      entryTable_length_p,
                                                        GXV_Validator  valid );

  typedef void  (*GXV_XStateTable_Entry_Validate_Func)( FT_UShort      state,
                                                        FT_UShort      flags,
                                                        GXV_StateTable_GlyphOffsetDesc
                                                                       glyphOffset,
                                                        FT_Bytes       xstatetable_table,
                                                        FT_Bytes       xstatetable_limit,
                                                        GXV_Validator  valid );

  typedef GXV_StateTable_OptData_Load_Func GXV_XStateTable_OptData_Load_Func;

  typedef struct GXV_XStateTable_ValidatorRec_
  {
    int        entry_glyphoffset_fmt;
    void*      optdata;
    GXV_XStateTable_Subtable_Setup_Func
               subtable_setup_func;
    GXV_XStateTable_Entry_Validate_Func
               entry_validate_func;
    GXV_XStateTable_OptData_Load_Func
               optdata_load_func;
    FT_ULong   nClasses;
    FT_UShort  maxClassID;

  } GXV_XStateTable_ValidatorRec, *GXV_XStateTable_ValidatorRecData;

  /* ===================================================================== */

  typedef struct GXV_ValidatorRec_
  {
    FT_Validator  root;

    FT_Face       face;
    void*         table_data;

    FT_ULong      subtable_length;

    GXV_LookupValue_SignSpec        lookupval_sign;
    GXV_Lookup_Value_Validate_Func  lookupval_func;
    GXV_Lookup_Fmt4_Transit_Func    lookupfmt4_trans;
    FT_Bytes                        lookuptbl_head;

    GXV_StateTable_ValidatorRec     statetable;
    GXV_XStateTable_ValidatorRec    xstatetable;

#ifdef FT_DEBUG_LEVEL_TRACE
    FT_UInt             debug_indent;
    const FT_String*    debug_function_name[3];
#endif

  } GXV_ValidatorRec;

#define GXV_TABLE_DATA( tag, field ) \
        ( ( (GXV_ ## tag ## _Data)valid->table_data )->field )

#undef  FT_INVALID_
#define FT_INVALID_( _prefix, _error )                         \
          ft_validator_error( valid->root, _prefix ## _error )

#define GXV_LIMIT_CHECK( _count )                                      \
          FT_BEGIN_STMNT                                               \
            if ( p + _count > ( limit? limit : valid->root->limit ) )  \
                FT_INVALID_TOO_SHORT;                                  \
          FT_END_STMNT

#ifdef FT_DEBUG_LEVEL_TRACE
#define GXV_INIT  valid->debug_indent = 0

#define GXV_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 GXV_EXIT  valid->debug_indent -= 2

#define GXV_TRACE( s )                                     \
          FT_BEGIN_STMNT                                   \
            FT_TRACE4(( "%*.s", valid->debug_indent, 0 )); \
            FT_TRACE4( s );                                \
          FT_END_STMNT

#else   /* !FT_DEBUG_LEVEL_TRACE */
#define GXV_INIT                do ; while ( 0 )
#define GXV_NAME_ENTER( name )  do ; while ( 0 )
#define GXV_EXIT                do ; while ( 0 )

#define GXV_TRACE( s )          do ; while ( 0 )

#endif  /* !FT_DEBUG_LEVEL_TRACE */

  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                    32bit alignment checking                   *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

#define GXV_32BIT_ALIGNMENT_VALIDATE( a )               \
        FT_BEGIN_STMNT                                  \
          {                                             \
            if ( 0 != ( (a) % 4 ) ) FT_INVALID_OFFSET ; \
          }                                             \
        FT_END_STMNT


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                    Dumping Binary Data                        *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

#define  GXV_TRACE_HEXDUMP( p, len )                 \
         FT_BEGIN_STMNT                              \
           {                                         \
             FT_Bytes b;                             \
             for (b = p; b < (FT_Bytes)p + len; b++) \
               FT_TRACE1(("\\x%02x", *b)) ;          \
           }                                         \
         FT_END_STMNT

#define  GXV_TRACE_HEXDUMP_C( p, len )               \
         FT_BEGIN_STMNT                              \
           {                                         \
             FT_Bytes b;                             \
             for (b = p; b < (FT_Bytes)p + len; b++) \
               if (0x40 < *b && *b < 0x7e)           \
                 FT_TRACE1(("%c", *b)) ;             \
               else                                  \
                 FT_TRACE1(("\\x%02x", *b)) ;        \
           }                                         \
         FT_END_STMNT

#define  GXV_TRACE_HEXDUMP_SFNTNAME( n )   GXV_TRACE_HEXDUMP( n.string, n.string_len )

  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                         LOOKUP TABLE                          *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  FT_LOCAL( void )
  gxv_BinSrchHeader_validate( FT_Bytes       p,
                              FT_Bytes       limit,
                              FT_UShort*     unitSize_p,
                              FT_UShort*     nUnits_p,
                              GXV_Validator  valid );

  FT_LOCAL( void )
  gxv_LookupTable_validate( FT_Bytes       table,
                            FT_Bytes       limit,
                            GXV_Validator  valid );


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                          Glyph ID                             *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  FT_LOCAL( FT_Int )
  gxv_glyphid_validate( FT_UShort      gid,
                        GXV_Validator  valid );

  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                        CONTROL POINT                          *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  FT_LOCAL( void )
  gxv_ctlPoint_validate( FT_UShort      gid,
                         FT_Short       ctl_point,
                         GXV_Validator  valid );


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                          SFNT NAME                            *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  FT_LOCAL( void )
  gxv_sfntName_validate( FT_UShort      name_index,
                         FT_UShort      min_index,
                         FT_UShort      max_index,
                         GXV_Validator  valid );


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                          STATE TABLE                          *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  FT_LOCAL( void )
  gxv_StateTable_validate( FT_Bytes       table,
                           FT_Bytes       limit,
                           GXV_Validator  valid );


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                         UTILITY MACRO                         *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

#define GXV_SUBTABLE_OFFSET_CHECK( _offset )        \
         FT_BEGIN_STMNT                             \
          if ( (_offset) > valid->subtable_length ) \
            FT_INVALID_OFFSET;                      \
         FT_END_STMNT

#define GXV_SUBTABLE_LIMIT_CHECK( _count ) \
         FT_BEGIN_STMNT                    \
          if ( ( p + (_count) - valid->subtable_start ) > valid->subtable_length ) \
            FT_INVALID_TOO_SHORT;          \
         FT_END_STMNT

#define GXV_USHORT_TO_SHORT( _us ) \
         ( ( 0x8000 < ( _us ) ) ? ( ( _us ) - 0x8000 ) : ( _us ) )

  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                        Table overlapping                      *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/

  typedef struct GXV_odtect_DataRec_
  {
    FT_Bytes    start;
    FT_ULong    length;
    FT_String*  name;

  } GXV_odtect_DataRec,  *GXV_odtect_Data;

  typedef struct GXV_odtect_RangeRec_
  {
    FT_UInt          nRanges;
    GXV_odtect_Data  range;

  } GXV_odtect_RangeRec, *GXV_odtect_Range;

#define GXV_ODTECT( n, odtect )                       \
  GXV_odtect_DataRec   odtect ## _range[ n ];         \
  GXV_odtect_RangeRec  odtect ## _rec = { 0, NULL };  \
  GXV_odtect_Range     odtect = NULL

#define GXV_ODTECT_INIT( odtect )                     \
        FT_BEGIN_STMNT                                \
          odtect ## _rec.nRanges = 0;                 \
          odtect ## _rec.range   = odtect ## _range;  \
          odtect                 = & odtect ## _rec;  \
        FT_END_STMNT

 /* */

FT_END_HEADER

#endif /* Not def: __GXVCOMMN_H__ */


/* END */