Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  gxvmort1.c                                                             */
  4. /*                                                                         */
  5. /*    TrueTypeGX/AAT mort table validation                                 */
  6. /*    body for type1 (Contextual Substitution) subtable.                   */
  7. /*                                                                         */
  8. /*  Copyright 2005, 2007 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
  9. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  10. /*                                                                         */
  11. /*  This file is part of the FreeType project, and may only be used,       */
  12. /*  modified, and distributed under the terms of the FreeType project      */
  13. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  14. /*  this file you indicate that you have read the license and              */
  15. /*  understand and accept it fully.                                        */
  16. /*                                                                         */
  17. /***************************************************************************/
  18.  
  19. /***************************************************************************/
  20. /*                                                                         */
  21. /* gxvalid is derived from both gxlayout module and otvalid module.        */
  22. /* Development of gxlayout is supported by the Information-technology      */
  23. /* Promotion Agency(IPA), Japan.                                           */
  24. /*                                                                         */
  25. /***************************************************************************/
  26.  
  27.  
  28. #include "gxvmort.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_gxvmort
  39.  
  40.  
  41.   typedef struct  GXV_mort_subtable_type1_StateOptRec_
  42.   {
  43.     FT_UShort  substitutionTable;
  44.     FT_UShort  substitutionTable_length;
  45.  
  46.   }  GXV_mort_subtable_type1_StateOptRec,
  47.     *GXV_mort_subtable_type1_StateOptRecData;
  48.  
  49. #define GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE \
  50.           ( GXV_STATETABLE_HEADER_SIZE + 2 )
  51.  
  52.  
  53.   static void
  54.   gxv_mort_subtable_type1_substitutionTable_load( FT_Bytes       table,
  55.                                                   FT_Bytes       limit,
  56.                                                   GXV_Validator  valid )
  57.   {
  58.     FT_Bytes  p = table;
  59.  
  60.     GXV_mort_subtable_type1_StateOptRecData  optdata =
  61.       (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata;
  62.  
  63.  
  64.     GXV_LIMIT_CHECK( 2 );
  65.     optdata->substitutionTable = FT_NEXT_USHORT( p );
  66.   }
  67.  
  68.  
  69.   static void
  70.   gxv_mort_subtable_type1_subtable_setup( FT_UShort      table_size,
  71.                                           FT_UShort      classTable,
  72.                                           FT_UShort      stateArray,
  73.                                           FT_UShort      entryTable,
  74.                                           FT_UShort*     classTable_length_p,
  75.                                           FT_UShort*     stateArray_length_p,
  76.                                           FT_UShort*     entryTable_length_p,
  77.                                           GXV_Validator  valid )
  78.   {
  79.     FT_UShort  o[4];
  80.     FT_UShort  *l[4];
  81.     FT_UShort  buff[5];
  82.  
  83.     GXV_mort_subtable_type1_StateOptRecData  optdata =
  84.       (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata;
  85.  
  86.  
  87.     o[0] = classTable;
  88.     o[1] = stateArray;
  89.     o[2] = entryTable;
  90.     o[3] = optdata->substitutionTable;
  91.     l[0] = classTable_length_p;
  92.     l[1] = stateArray_length_p;
  93.     l[2] = entryTable_length_p;
  94.     l[3] = &( optdata->substitutionTable_length );
  95.  
  96.     gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid );
  97.   }
  98.  
  99.  
  100.   static void
  101.   gxv_mort_subtable_type1_offset_to_subst_validate(
  102.     FT_Short          wordOffset,
  103.     const FT_String*  tag,
  104.     FT_Byte           state,
  105.     GXV_Validator     valid )
  106.   {
  107.     FT_UShort  substTable;
  108.     FT_UShort  substTable_limit;
  109.  
  110.     FT_UNUSED( tag );
  111.     FT_UNUSED( state );
  112.  
  113.  
  114.     substTable =
  115.       ((GXV_mort_subtable_type1_StateOptRec *)
  116.        (valid->statetable.optdata))->substitutionTable;
  117.     substTable_limit =
  118.       (FT_UShort)( substTable +
  119.                    ((GXV_mort_subtable_type1_StateOptRec *)
  120.                     (valid->statetable.optdata))->substitutionTable_length );
  121.  
  122.     valid->min_gid = (FT_UShort)( ( substTable       - wordOffset * 2 ) / 2 );
  123.     valid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 );
  124.     valid->max_gid = (FT_UShort)( FT_MAX( valid->max_gid,
  125.                                           valid->face->num_glyphs ) );
  126.  
  127.     /* XXX: check range? */
  128.  
  129.     /* TODO: min_gid & max_gid comparison with ClassTable contents */
  130.   }
  131.  
  132.  
  133.   static void
  134.   gxv_mort_subtable_type1_entry_validate(
  135.     FT_Byte                         state,
  136.     FT_UShort                       flags,
  137.     GXV_StateTable_GlyphOffsetCPtr  glyphOffset_p,
  138.     FT_Bytes                        table,
  139.     FT_Bytes                        limit,
  140.     GXV_Validator                   valid )
  141.   {
  142. #ifdef GXV_LOAD_UNUSED_VARS
  143.     FT_UShort  setMark;
  144.     FT_UShort  dontAdvance;
  145. #endif
  146.     FT_UShort  reserved;
  147.     FT_Short   markOffset;
  148.     FT_Short   currentOffset;
  149.  
  150.     FT_UNUSED( table );
  151.     FT_UNUSED( limit );
  152.  
  153.  
  154. #ifdef GXV_LOAD_UNUSED_VARS
  155.     setMark       = (FT_UShort)(   flags >> 15            );
  156.     dontAdvance   = (FT_UShort)( ( flags >> 14 ) & 1      );
  157. #endif
  158.     reserved      = (FT_Short)(    flags         & 0x3FFF );
  159.  
  160.     markOffset    = (FT_Short)( glyphOffset_p->ul >> 16 );
  161.     currentOffset = (FT_Short)( glyphOffset_p->ul       );
  162.  
  163.     if ( 0 < reserved )
  164.     {
  165.       GXV_TRACE(( " non-zero bits found in reserved range\n" ));
  166.       GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
  167.     }
  168.  
  169.     gxv_mort_subtable_type1_offset_to_subst_validate( markOffset,
  170.                                                       "markOffset",
  171.                                                       state,
  172.                                                       valid );
  173.  
  174.     gxv_mort_subtable_type1_offset_to_subst_validate( currentOffset,
  175.                                                       "currentOffset",
  176.                                                       state,
  177.                                                       valid );
  178.   }
  179.  
  180.  
  181.   static void
  182.   gxv_mort_subtable_type1_substTable_validate( FT_Bytes       table,
  183.                                                FT_Bytes       limit,
  184.                                                GXV_Validator  valid )
  185.   {
  186.     FT_Bytes   p = table;
  187.     FT_UShort  num_gids = (FT_UShort)(
  188.                  ((GXV_mort_subtable_type1_StateOptRec *)
  189.                   (valid->statetable.optdata))->substitutionTable_length / 2 );
  190.     FT_UShort  i;
  191.  
  192.  
  193.     GXV_NAME_ENTER( "validating contents of substitutionTable" );
  194.     for ( i = 0; i < num_gids ; i ++ )
  195.     {
  196.       FT_UShort  dst_gid;
  197.  
  198.  
  199.       GXV_LIMIT_CHECK( 2 );
  200.       dst_gid = FT_NEXT_USHORT( p );
  201.  
  202.       if ( dst_gid >= 0xFFFFU )
  203.         continue;
  204.  
  205.       if ( dst_gid < valid->min_gid || valid->max_gid < dst_gid )
  206.       {
  207.         GXV_TRACE(( "substTable include a strange gid[%d]=%d >"
  208.                     " out of define range (%d..%d)\n",
  209.                     i, dst_gid, valid->min_gid, valid->max_gid ));
  210.         GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
  211.       }
  212.     }
  213.  
  214.     GXV_EXIT;
  215.   }
  216.  
  217.  
  218.   /*
  219.    * subtable for Contextual glyph substitution is a modified StateTable.
  220.    * In addition to classTable, stateArray, and entryTable, the field
  221.    * `substitutionTable' is added.
  222.    */
  223.   FT_LOCAL_DEF( void )
  224.   gxv_mort_subtable_type1_validate( FT_Bytes       table,
  225.                                     FT_Bytes       limit,
  226.                                     GXV_Validator  valid )
  227.   {
  228.     FT_Bytes  p = table;
  229.  
  230.     GXV_mort_subtable_type1_StateOptRec  st_rec;
  231.  
  232.  
  233.     GXV_NAME_ENTER( "mort chain subtable type1 (Contextual Glyph Subst)" );
  234.  
  235.     GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE );
  236.  
  237.     valid->statetable.optdata =
  238.       &st_rec;
  239.     valid->statetable.optdata_load_func =
  240.       gxv_mort_subtable_type1_substitutionTable_load;
  241.     valid->statetable.subtable_setup_func =
  242.       gxv_mort_subtable_type1_subtable_setup;
  243.     valid->statetable.entry_glyphoffset_fmt =
  244.       GXV_GLYPHOFFSET_ULONG;
  245.     valid->statetable.entry_validate_func =
  246.  
  247.       gxv_mort_subtable_type1_entry_validate;
  248.     gxv_StateTable_validate( p, limit, valid );
  249.  
  250.     gxv_mort_subtable_type1_substTable_validate(
  251.       table + st_rec.substitutionTable,
  252.       table + st_rec.substitutionTable + st_rec.substitutionTable_length,
  253.       valid );
  254.  
  255.     GXV_EXIT;
  256.   }
  257.  
  258.  
  259. /* END */
  260.