misc/libfreetype/src/gxvalid/gxvprop.c
changeset 9431 0f5961910e27
parent 9357 a501f5ec7b34
parent 9429 7a97a554ac80
child 9433 f0a8ac191839
equal deleted inserted replaced
9357:a501f5ec7b34 9431:0f5961910e27
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  gxvprop.c                                                              */
       
     4 /*                                                                         */
       
     5 /*    TrueTypeGX/AAT prop table validation (body).                         */
       
     6 /*                                                                         */
       
     7 /*  Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
       
     8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
       
     9 /*                                                                         */
       
    10 /*  This file is part of the FreeType project, and may only be used,       */
       
    11 /*  modified, and distributed under the terms of the FreeType project      */
       
    12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
       
    13 /*  this file you indicate that you have read the license and              */
       
    14 /*  understand and accept it fully.                                        */
       
    15 /*                                                                         */
       
    16 /***************************************************************************/
       
    17 
       
    18 /***************************************************************************/
       
    19 /*                                                                         */
       
    20 /* gxvalid is derived from both gxlayout module and otvalid module.        */
       
    21 /* Development of gxlayout is supported by the Information-technology      */
       
    22 /* Promotion Agency(IPA), Japan.                                           */
       
    23 /*                                                                         */
       
    24 /***************************************************************************/
       
    25 
       
    26 
       
    27 #include "gxvalid.h"
       
    28 #include "gxvcommn.h"
       
    29 
       
    30 
       
    31   /*************************************************************************/
       
    32   /*                                                                       */
       
    33   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
       
    34   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
       
    35   /* messages during execution.                                            */
       
    36   /*                                                                       */
       
    37 #undef  FT_COMPONENT
       
    38 #define FT_COMPONENT  trace_gxvprop
       
    39 
       
    40 
       
    41   /*************************************************************************/
       
    42   /*************************************************************************/
       
    43   /*****                                                               *****/
       
    44   /*****                      Data and Types                           *****/
       
    45   /*****                                                               *****/
       
    46   /*************************************************************************/
       
    47   /*************************************************************************/
       
    48 
       
    49 #define GXV_PROP_HEADER_SIZE  ( 4 + 2 + 2 )
       
    50 #define GXV_PROP_SIZE_MIN     GXV_PROP_HEADER_SIZE
       
    51 
       
    52   typedef struct  GXV_prop_DataRec_
       
    53   {
       
    54     FT_Fixed  version;
       
    55 
       
    56   } GXV_prop_DataRec, *GXV_prop_Data;
       
    57 
       
    58 #define GXV_PROP_DATA( field )  GXV_TABLE_DATA( prop, field )
       
    59 
       
    60 #define GXV_PROP_FLOATER                      0x8000U
       
    61 #define GXV_PROP_USE_COMPLEMENTARY_BRACKET    0x1000U
       
    62 #define GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET 0x0F00U
       
    63 #define GXV_PROP_ATTACHING_TO_RIGHT           0x0080U
       
    64 #define GXV_PROP_RESERVED                     0x0060U
       
    65 #define GXV_PROP_DIRECTIONALITY_CLASS         0x001FU
       
    66 
       
    67 
       
    68   /*************************************************************************/
       
    69   /*************************************************************************/
       
    70   /*****                                                               *****/
       
    71   /*****                      UTILITY FUNCTIONS                        *****/
       
    72   /*****                                                               *****/
       
    73   /*************************************************************************/
       
    74   /*************************************************************************/
       
    75 
       
    76   static void
       
    77   gxv_prop_zero_advance_validate( FT_UShort      gid,
       
    78                                   GXV_Validator  valid )
       
    79   {
       
    80     FT_Face       face;
       
    81     FT_Error      error;
       
    82     FT_GlyphSlot  glyph;
       
    83 
       
    84 
       
    85     GXV_NAME_ENTER( "zero advance" );
       
    86 
       
    87     face = valid->face;
       
    88 
       
    89     error = FT_Load_Glyph( face,
       
    90                            gid,
       
    91                            FT_LOAD_IGNORE_TRANSFORM );
       
    92     if ( error )
       
    93       FT_INVALID_GLYPH_ID;
       
    94 
       
    95     glyph = face->glyph;
       
    96 
       
    97     if ( glyph->advance.x != (FT_Pos)0 ||
       
    98          glyph->advance.y != (FT_Pos)0 )
       
    99       FT_INVALID_DATA;
       
   100 
       
   101     GXV_EXIT;
       
   102   }
       
   103 
       
   104 
       
   105   /* Pass 0 as GLYPH to check the default property */
       
   106   static void
       
   107   gxv_prop_property_validate( FT_UShort      property,
       
   108                               FT_UShort      glyph,
       
   109                               GXV_Validator  valid )
       
   110   {
       
   111     if ( glyph != 0 && ( property & GXV_PROP_FLOATER ) )
       
   112       gxv_prop_zero_advance_validate( glyph, valid );
       
   113 
       
   114     if ( property & GXV_PROP_USE_COMPLEMENTARY_BRACKET )
       
   115     {
       
   116       FT_UShort  offset;
       
   117       char       complement;
       
   118 
       
   119 
       
   120       offset = (FT_UShort)( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET );
       
   121       if ( offset == 0 )
       
   122         FT_INVALID_DATA;
       
   123 
       
   124       complement = (char)( offset >> 8 );
       
   125       if ( complement & 0x08 )
       
   126       {
       
   127         /* Top bit is set: negative */
       
   128 
       
   129         /* Calculate the absolute offset */
       
   130         complement = (char)( ( complement & 0x07 ) + 1 );
       
   131 
       
   132         /* The gid for complement must be greater than 0 */
       
   133         if ( glyph <= complement )
       
   134           FT_INVALID_DATA;
       
   135       }
       
   136       else
       
   137       {
       
   138         /* The gid for complement must be the face. */
       
   139         gxv_glyphid_validate( (FT_UShort)( glyph + complement ), valid );
       
   140       }
       
   141     }
       
   142     else
       
   143     {
       
   144       if ( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET )
       
   145         GXV_TRACE(( "glyph %d cannot have complementary bracketing\n",
       
   146                     glyph ));
       
   147     }
       
   148 
       
   149     /* this is introduced in version 2.0 */
       
   150     if ( property & GXV_PROP_ATTACHING_TO_RIGHT )
       
   151     {
       
   152       if ( GXV_PROP_DATA( version ) == 0x00010000UL )
       
   153         FT_INVALID_DATA;
       
   154     }
       
   155 
       
   156     if ( property & GXV_PROP_RESERVED )
       
   157       FT_INVALID_DATA;
       
   158 
       
   159     if ( ( property & GXV_PROP_DIRECTIONALITY_CLASS ) > 11 )
       
   160     {
       
   161       /* TODO: Too restricted. Use the validation level. */
       
   162       if ( GXV_PROP_DATA( version ) == 0x00010000UL ||
       
   163            GXV_PROP_DATA( version ) == 0x00020000UL )
       
   164         FT_INVALID_DATA;
       
   165     }
       
   166   }
       
   167 
       
   168 
       
   169   static void
       
   170   gxv_prop_LookupValue_validate( FT_UShort            glyph,
       
   171                                  GXV_LookupValueCPtr  value_p,
       
   172                                  GXV_Validator        valid )
       
   173   {
       
   174     gxv_prop_property_validate( value_p->u, glyph, valid );
       
   175   }
       
   176 
       
   177 
       
   178   /*
       
   179     +===============+ --------+
       
   180     | lookup header |         |
       
   181     +===============+         |
       
   182     | BinSrchHeader |         |
       
   183     +===============+         |
       
   184     | lastGlyph[0]  |         |
       
   185     +---------------+         |
       
   186     | firstGlyph[0] |         |    head of lookup table
       
   187     +---------------+         |             +
       
   188     | offset[0]     |    ->   |          offset            [byte]
       
   189     +===============+         |             +
       
   190     | lastGlyph[1]  |         | (glyphID - firstGlyph) * 2 [byte]
       
   191     +---------------+         |
       
   192     | firstGlyph[1] |         |
       
   193     +---------------+         |
       
   194     | offset[1]     |         |
       
   195     +===============+         |
       
   196                               |
       
   197      ...                      |
       
   198                               |
       
   199     16bit value array         |
       
   200     +===============+         |
       
   201     |     value     | <-------+
       
   202     ...
       
   203   */
       
   204 
       
   205   static GXV_LookupValueDesc
       
   206   gxv_prop_LookupFmt4_transit( FT_UShort            relative_gindex,
       
   207                                GXV_LookupValueCPtr  base_value_p,
       
   208                                FT_Bytes             lookuptbl_limit,
       
   209                                GXV_Validator        valid )
       
   210   {
       
   211     FT_Bytes             p;
       
   212     FT_Bytes             limit;
       
   213     FT_UShort            offset;
       
   214     GXV_LookupValueDesc  value;
       
   215 
       
   216     /* XXX: check range? */
       
   217     offset = (FT_UShort)( base_value_p->u +
       
   218                           relative_gindex * sizeof( FT_UShort ) );
       
   219     p      = valid->lookuptbl_head + offset;
       
   220     limit  = lookuptbl_limit;
       
   221 
       
   222     GXV_LIMIT_CHECK ( 2 );
       
   223     value.u = FT_NEXT_USHORT( p );
       
   224 
       
   225     return value;
       
   226   }
       
   227 
       
   228 
       
   229   /*************************************************************************/
       
   230   /*************************************************************************/
       
   231   /*****                                                               *****/
       
   232   /*****                         prop TABLE                            *****/
       
   233   /*****                                                               *****/
       
   234   /*************************************************************************/
       
   235   /*************************************************************************/
       
   236 
       
   237   FT_LOCAL_DEF( void )
       
   238   gxv_prop_validate( FT_Bytes      table,
       
   239                      FT_Face       face,
       
   240                      FT_Validator  ftvalid )
       
   241   {
       
   242     FT_Bytes          p     = table;
       
   243     FT_Bytes          limit = 0;
       
   244     GXV_ValidatorRec  validrec;
       
   245     GXV_Validator     valid = &validrec;
       
   246 
       
   247     GXV_prop_DataRec  proprec;
       
   248     GXV_prop_Data     prop = &proprec;
       
   249 
       
   250     FT_Fixed          version;
       
   251     FT_UShort         format;
       
   252     FT_UShort         defaultProp;
       
   253 
       
   254 
       
   255     valid->root       = ftvalid;
       
   256     valid->table_data = prop;
       
   257     valid->face       = face;
       
   258 
       
   259     FT_TRACE3(( "validating `prop' table\n" ));
       
   260     GXV_INIT;
       
   261 
       
   262     GXV_LIMIT_CHECK( 4 + 2 + 2 );
       
   263     version     = FT_NEXT_ULONG( p );
       
   264     format      = FT_NEXT_USHORT( p );
       
   265     defaultProp = FT_NEXT_USHORT( p );
       
   266 
       
   267     /* only versions 1.0, 2.0, 3.0 are defined (1996) */
       
   268     if ( version != 0x00010000UL &&
       
   269          version != 0x00020000UL &&
       
   270          version != 0x00030000UL )
       
   271       FT_INVALID_FORMAT;
       
   272 
       
   273 
       
   274     /* only formats 0x0000, 0x0001 are defined (1996) */
       
   275     if ( format > 1 )
       
   276       FT_INVALID_FORMAT;
       
   277 
       
   278     gxv_prop_property_validate( defaultProp, 0, valid );
       
   279 
       
   280     if ( format == 0 )
       
   281     {
       
   282       FT_TRACE3(( "(format 0, no per-glyph properties, "
       
   283                   "remaining %d bytes are skipped)", limit - p ));
       
   284       goto Exit;
       
   285     }
       
   286 
       
   287     /* format == 1 */
       
   288     GXV_PROP_DATA( version ) = version;
       
   289 
       
   290     valid->lookupval_sign   = GXV_LOOKUPVALUE_UNSIGNED;
       
   291     valid->lookupval_func   = gxv_prop_LookupValue_validate;
       
   292     valid->lookupfmt4_trans = gxv_prop_LookupFmt4_transit;
       
   293 
       
   294     gxv_LookupTable_validate( p, limit, valid );
       
   295 
       
   296   Exit:
       
   297     FT_TRACE4(( "\n" ));
       
   298   }
       
   299 
       
   300 
       
   301 /* END */