Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.     {
  100.       GXV_TRACE(( "  found non-zero advance in zero-advance glyph\n" ));
  101.       FT_INVALID_DATA;
  102.     }
  103.  
  104.     GXV_EXIT;
  105.   }
  106.  
  107.  
  108.   /* Pass 0 as GLYPH to check the default property */
  109.   static void
  110.   gxv_prop_property_validate( FT_UShort      property,
  111.                               FT_UShort      glyph,
  112.                               GXV_Validator  valid )
  113.   {
  114.     if ( glyph != 0 && ( property & GXV_PROP_FLOATER ) )
  115.       gxv_prop_zero_advance_validate( glyph, valid );
  116.  
  117.     if ( property & GXV_PROP_USE_COMPLEMENTARY_BRACKET )
  118.     {
  119.       FT_UShort  offset;
  120.       char       complement;
  121.  
  122.  
  123.       offset = (FT_UShort)( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET );
  124.       if ( offset == 0 )
  125.       {
  126.         GXV_TRACE(( "  found zero offset to property\n" ));
  127.         FT_INVALID_OFFSET;
  128.       }
  129.  
  130.       complement = (char)( offset >> 8 );
  131.       if ( complement & 0x08 )
  132.       {
  133.         /* Top bit is set: negative */
  134.  
  135.         /* Calculate the absolute offset */
  136.         complement = (char)( ( complement & 0x07 ) + 1 );
  137.  
  138.         /* The gid for complement must be greater than 0 */
  139.         if ( glyph <= complement )
  140.         {
  141.           GXV_TRACE(( "  found non-positive glyph complement\n" ));
  142.           FT_INVALID_DATA;
  143.         }
  144.       }
  145.       else
  146.       {
  147.         /* The gid for complement must be the face. */
  148.         gxv_glyphid_validate( (FT_UShort)( glyph + complement ), valid );
  149.       }
  150.     }
  151.     else
  152.     {
  153.       if ( property & GXV_PROP_COMPLEMENTARY_BRACKET_OFFSET )
  154.         GXV_TRACE(( "glyph %d cannot have complementary bracketing\n",
  155.                     glyph ));
  156.     }
  157.  
  158.     /* this is introduced in version 2.0 */
  159.     if ( property & GXV_PROP_ATTACHING_TO_RIGHT )
  160.     {
  161.       if ( GXV_PROP_DATA( version ) == 0x00010000UL )
  162.       {
  163.         GXV_TRACE(( "  found older version (1.0) in new version table\n" ));
  164.         FT_INVALID_DATA;
  165.       }
  166.     }
  167.  
  168.     if ( property & GXV_PROP_RESERVED )
  169.     {
  170.       GXV_TRACE(( "  found non-zero bits in reserved bits\n" ));
  171.       FT_INVALID_DATA;
  172.     }
  173.  
  174.     if ( ( property & GXV_PROP_DIRECTIONALITY_CLASS ) > 11 )
  175.     {
  176.       /* TODO: Too restricted. Use the validation level. */
  177.       if ( GXV_PROP_DATA( version ) == 0x00010000UL ||
  178.            GXV_PROP_DATA( version ) == 0x00020000UL )
  179.       {
  180.         GXV_TRACE(( "  found too old version in directionality class\n" ));
  181.         FT_INVALID_DATA;
  182.       }
  183.     }
  184.   }
  185.  
  186.  
  187.   static void
  188.   gxv_prop_LookupValue_validate( FT_UShort            glyph,
  189.                                  GXV_LookupValueCPtr  value_p,
  190.                                  GXV_Validator        valid )
  191.   {
  192.     gxv_prop_property_validate( value_p->u, glyph, valid );
  193.   }
  194.  
  195.  
  196.   /*
  197.     +===============+ --------+
  198.     | lookup header |         |
  199.     +===============+         |
  200.     | BinSrchHeader |         |
  201.     +===============+         |
  202.     | lastGlyph[0]  |         |
  203.     +---------------+         |
  204.     | firstGlyph[0] |         |    head of lookup table
  205.     +---------------+         |             +
  206.     | offset[0]     |    ->   |          offset            [byte]
  207.     +===============+         |             +
  208.     | lastGlyph[1]  |         | (glyphID - firstGlyph) * 2 [byte]
  209.     +---------------+         |
  210.     | firstGlyph[1] |         |
  211.     +---------------+         |
  212.     | offset[1]     |         |
  213.     +===============+         |
  214.                               |
  215.      ...                      |
  216.                               |
  217.     16bit value array         |
  218.     +===============+         |
  219.     |     value     | <-------+
  220.     ...
  221.   */
  222.  
  223.   static GXV_LookupValueDesc
  224.   gxv_prop_LookupFmt4_transit( FT_UShort            relative_gindex,
  225.                                GXV_LookupValueCPtr  base_value_p,
  226.                                FT_Bytes             lookuptbl_limit,
  227.                                GXV_Validator        valid )
  228.   {
  229.     FT_Bytes             p;
  230.     FT_Bytes             limit;
  231.     FT_UShort            offset;
  232.     GXV_LookupValueDesc  value;
  233.  
  234.     /* XXX: check range? */
  235.     offset = (FT_UShort)( base_value_p->u +
  236.                           relative_gindex * sizeof ( FT_UShort ) );
  237.     p      = valid->lookuptbl_head + offset;
  238.     limit  = lookuptbl_limit;
  239.  
  240.     GXV_LIMIT_CHECK ( 2 );
  241.     value.u = FT_NEXT_USHORT( p );
  242.  
  243.     return value;
  244.   }
  245.  
  246.  
  247.   /*************************************************************************/
  248.   /*************************************************************************/
  249.   /*****                                                               *****/
  250.   /*****                         prop TABLE                            *****/
  251.   /*****                                                               *****/
  252.   /*************************************************************************/
  253.   /*************************************************************************/
  254.  
  255.   FT_LOCAL_DEF( void )
  256.   gxv_prop_validate( FT_Bytes      table,
  257.                      FT_Face       face,
  258.                      FT_Validator  ftvalid )
  259.   {
  260.     FT_Bytes          p     = table;
  261.     FT_Bytes          limit = 0;
  262.     GXV_ValidatorRec  validrec;
  263.     GXV_Validator     valid = &validrec;
  264.  
  265.     GXV_prop_DataRec  proprec;
  266.     GXV_prop_Data     prop = &proprec;
  267.  
  268.     FT_Fixed          version;
  269.     FT_UShort         format;
  270.     FT_UShort         defaultProp;
  271.  
  272.  
  273.     valid->root       = ftvalid;
  274.     valid->table_data = prop;
  275.     valid->face       = face;
  276.  
  277.     FT_TRACE3(( "validating `prop' table\n" ));
  278.     GXV_INIT;
  279.  
  280.     GXV_LIMIT_CHECK( 4 + 2 + 2 );
  281.     version     = FT_NEXT_ULONG( p );
  282.     format      = FT_NEXT_USHORT( p );
  283.     defaultProp = FT_NEXT_USHORT( p );
  284.  
  285.     GXV_TRACE(( "  version 0x%08x\n", version ));
  286.     GXV_TRACE(( "  format  0x%04x\n", format ));
  287.     GXV_TRACE(( "  defaultProp  0x%04x\n", defaultProp ));
  288.  
  289.     /* only versions 1.0, 2.0, 3.0 are defined (1996) */
  290.     if ( version != 0x00010000UL &&
  291.          version != 0x00020000UL &&
  292.          version != 0x00030000UL )
  293.     {
  294.       GXV_TRACE(( "  found unknown version\n" ));
  295.       FT_INVALID_FORMAT;
  296.     }
  297.  
  298.  
  299.     /* only formats 0x0000, 0x0001 are defined (1996) */
  300.     if ( format > 1 )
  301.     {
  302.       GXV_TRACE(( "  found unknown format\n" ));
  303.       FT_INVALID_FORMAT;
  304.     }
  305.  
  306.     gxv_prop_property_validate( defaultProp, 0, valid );
  307.  
  308.     if ( format == 0 )
  309.     {
  310.       FT_TRACE3(( "(format 0, no per-glyph properties, "
  311.                   "remaining %d bytes are skipped)", limit - p ));
  312.       goto Exit;
  313.     }
  314.  
  315.     /* format == 1 */
  316.     GXV_PROP_DATA( version ) = version;
  317.  
  318.     valid->lookupval_sign   = GXV_LOOKUPVALUE_UNSIGNED;
  319.     valid->lookupval_func   = gxv_prop_LookupValue_validate;
  320.     valid->lookupfmt4_trans = gxv_prop_LookupFmt4_transit;
  321.  
  322.     gxv_LookupTable_validate( p, limit, valid );
  323.  
  324.   Exit:
  325.     FT_TRACE4(( "\n" ));
  326.   }
  327.  
  328.  
  329. /* END */
  330.