Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  otvmath.c                                                              */
  4. /*                                                                         */
  5. /*    OpenType MATH table validation (body).                               */
  6. /*                                                                         */
  7. /*  Copyright 2007, 2008 by                                                */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9. /*                                                                         */
  10. /*  Written by George Williams.                                            */
  11. /*                                                                         */
  12. /*  This file is part of the FreeType project, and may only be used,       */
  13. /*  modified, and distributed under the terms of the FreeType project      */
  14. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  15. /*  this file you indicate that you have read the license and              */
  16. /*  understand and accept it fully.                                        */
  17. /*                                                                         */
  18. /***************************************************************************/
  19.  
  20.  
  21. #include "otvalid.h"
  22. #include "otvcommn.h"
  23. #include "otvgpos.h"
  24.  
  25.  
  26.   /*************************************************************************/
  27.   /*                                                                       */
  28.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  29.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  30.   /* messages during execution.                                            */
  31.   /*                                                                       */
  32. #undef  FT_COMPONENT
  33. #define FT_COMPONENT  trace_otvmath
  34.  
  35.  
  36.  
  37.   /*************************************************************************/
  38.   /*************************************************************************/
  39.   /*****                                                               *****/
  40.   /*****                  MATH TYPOGRAPHIC CONSTANTS                   *****/
  41.   /*****                                                               *****/
  42.   /*************************************************************************/
  43.   /*************************************************************************/
  44.  
  45.   static void
  46.   otv_MathConstants_validate( FT_Bytes       table,
  47.                               OTV_Validator  valid )
  48.   {
  49.     FT_Bytes  p = table;
  50.     FT_UInt   i;
  51.     FT_UInt   table_size;
  52.  
  53.     OTV_OPTIONAL_TABLE( DeviceTableOffset );
  54.  
  55.  
  56.     OTV_NAME_ENTER( "MathConstants" );
  57.  
  58.     /* 56 constants, 51 have device tables */
  59.     OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) );
  60.     table_size = 2 * ( 56 + 51 );
  61.  
  62.     p += 4 * 2;                 /* First 4 constants have no device tables */
  63.     for ( i = 0; i < 51; ++i )
  64.     {
  65.       p += 2;                                            /* skip the value */
  66.       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
  67.       OTV_SIZE_CHECK( DeviceTableOffset );
  68.       if ( DeviceTableOffset )
  69.         otv_Device_validate( table + DeviceTableOffset, valid );
  70.     }
  71.  
  72.     OTV_EXIT;
  73.   }
  74.  
  75.  
  76.   /*************************************************************************/
  77.   /*************************************************************************/
  78.   /*****                                                               *****/
  79.   /*****                   MATH ITALICS CORRECTION                     *****/
  80.   /*****                 MATH TOP ACCENT ATTACHMENT                    *****/
  81.   /*****                                                               *****/
  82.   /*************************************************************************/
  83.   /*************************************************************************/
  84.  
  85.   static void
  86.   otv_MathItalicsCorrectionInfo_validate( FT_Bytes       table,
  87.                                           OTV_Validator  valid,
  88.                                           FT_Int         isItalic )
  89.   {
  90.     FT_Bytes  p = table;
  91.     FT_UInt   i, cnt, table_size ;
  92.  
  93.     OTV_OPTIONAL_TABLE( Coverage );
  94.     OTV_OPTIONAL_TABLE( DeviceTableOffset );
  95.  
  96.     FT_UNUSED( isItalic );  /* only used if tracing is active */
  97.  
  98.  
  99.     OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
  100.                              : "MathTopAccentAttachment" );
  101.  
  102.     OTV_LIMIT_CHECK( 4 );
  103.  
  104.     OTV_OPTIONAL_OFFSET( Coverage );
  105.     cnt = FT_NEXT_USHORT( p );
  106.  
  107.     OTV_LIMIT_CHECK( 4 * cnt );
  108.     table_size = 4 + 4 * cnt;
  109.  
  110.     OTV_SIZE_CHECK( Coverage );
  111.     otv_Coverage_validate( table + Coverage, valid, cnt );
  112.  
  113.     for ( i = 0; i < cnt; ++i )
  114.     {
  115.       p += 2;                                            /* Skip the value */
  116.       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
  117.       OTV_SIZE_CHECK( DeviceTableOffset );
  118.       if ( DeviceTableOffset )
  119.         otv_Device_validate( table + DeviceTableOffset, valid );
  120.     }
  121.  
  122.     OTV_EXIT;
  123.   }
  124.  
  125.  
  126.   /*************************************************************************/
  127.   /*************************************************************************/
  128.   /*****                                                               *****/
  129.   /*****                           MATH KERNING                        *****/
  130.   /*****                                                               *****/
  131.   /*************************************************************************/
  132.   /*************************************************************************/
  133.  
  134.   static void
  135.   otv_MathKern_validate( FT_Bytes       table,
  136.                          OTV_Validator  valid )
  137.   {
  138.     FT_Bytes  p = table;
  139.     FT_UInt   i, cnt, table_size;
  140.  
  141.     OTV_OPTIONAL_TABLE( DeviceTableOffset );
  142.  
  143.  
  144.     /* OTV_NAME_ENTER( "MathKern" );*/
  145.  
  146.     OTV_LIMIT_CHECK( 2 );
  147.  
  148.     cnt = FT_NEXT_USHORT( p );
  149.  
  150.     OTV_LIMIT_CHECK( 4 * cnt + 2 );
  151.     table_size = 4 + 4 * cnt;
  152.  
  153.     /* Heights */
  154.     for ( i = 0; i < cnt; ++i )
  155.     {
  156.       p += 2;                                            /* Skip the value */
  157.       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
  158.       OTV_SIZE_CHECK( DeviceTableOffset );
  159.       if ( DeviceTableOffset )
  160.         otv_Device_validate( table + DeviceTableOffset, valid );
  161.     }
  162.  
  163.     /* One more Kerning value */
  164.     for ( i = 0; i < cnt + 1; ++i )
  165.     {
  166.       p += 2;                                            /* Skip the value */
  167.       OTV_OPTIONAL_OFFSET( DeviceTableOffset );
  168.       OTV_SIZE_CHECK( DeviceTableOffset );
  169.       if ( DeviceTableOffset )
  170.         otv_Device_validate( table + DeviceTableOffset, valid );
  171.     }
  172.  
  173.     OTV_EXIT;
  174.   }
  175.  
  176.  
  177.   static void
  178.   otv_MathKernInfo_validate( FT_Bytes       table,
  179.                              OTV_Validator  valid )
  180.   {
  181.     FT_Bytes  p = table;
  182.     FT_UInt   i, j, cnt, table_size;
  183.  
  184.     OTV_OPTIONAL_TABLE( Coverage );
  185.     OTV_OPTIONAL_TABLE( MKRecordOffset );
  186.  
  187.  
  188.     OTV_NAME_ENTER( "MathKernInfo" );
  189.  
  190.     OTV_LIMIT_CHECK( 4 );
  191.  
  192.     OTV_OPTIONAL_OFFSET( Coverage );
  193.     cnt = FT_NEXT_USHORT( p );
  194.  
  195.     OTV_LIMIT_CHECK( 8 * cnt );
  196.     table_size = 4 + 8 * cnt;
  197.  
  198.     OTV_SIZE_CHECK( Coverage );
  199.     otv_Coverage_validate( table + Coverage, valid, cnt );
  200.  
  201.     for ( i = 0; i < cnt; ++i )
  202.     {
  203.       for ( j = 0; j < 4; ++j )
  204.       {
  205.         OTV_OPTIONAL_OFFSET( MKRecordOffset );
  206.         OTV_SIZE_CHECK( MKRecordOffset );
  207.         if ( MKRecordOffset )
  208.           otv_MathKern_validate( table + MKRecordOffset, valid );
  209.       }
  210.     }
  211.  
  212.     OTV_EXIT;
  213.   }
  214.  
  215.  
  216.   /*************************************************************************/
  217.   /*************************************************************************/
  218.   /*****                                                               *****/
  219.   /*****                         MATH GLYPH INFO                       *****/
  220.   /*****                                                               *****/
  221.   /*************************************************************************/
  222.   /*************************************************************************/
  223.  
  224.   static void
  225.   otv_MathGlyphInfo_validate( FT_Bytes       table,
  226.                               OTV_Validator  valid )
  227.   {
  228.     FT_Bytes  p = table;
  229.     FT_UInt   MathItalicsCorrectionInfo, MathTopAccentAttachment;
  230.     FT_UInt   ExtendedShapeCoverage, MathKernInfo;
  231.  
  232.  
  233.     OTV_NAME_ENTER( "MathGlyphInfo" );
  234.  
  235.     OTV_LIMIT_CHECK( 8 );
  236.  
  237.     MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
  238.     MathTopAccentAttachment   = FT_NEXT_USHORT( p );
  239.     ExtendedShapeCoverage     = FT_NEXT_USHORT( p );
  240.     MathKernInfo              = FT_NEXT_USHORT( p );
  241.  
  242.     if ( MathItalicsCorrectionInfo )
  243.       otv_MathItalicsCorrectionInfo_validate(
  244.         table + MathItalicsCorrectionInfo, valid, TRUE );
  245.  
  246.     /* Italic correction and Top Accent Attachment have the same format */
  247.     if ( MathTopAccentAttachment )
  248.       otv_MathItalicsCorrectionInfo_validate(
  249.         table + MathTopAccentAttachment, valid, FALSE );
  250.  
  251.     if ( ExtendedShapeCoverage )
  252.     {
  253.       OTV_NAME_ENTER( "ExtendedShapeCoverage" );
  254.       otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
  255.       OTV_EXIT;
  256.     }
  257.  
  258.     if ( MathKernInfo )
  259.       otv_MathKernInfo_validate( table + MathKernInfo, valid );
  260.  
  261.     OTV_EXIT;
  262.   }
  263.  
  264.  
  265.   /*************************************************************************/
  266.   /*************************************************************************/
  267.   /*****                                                               *****/
  268.   /*****                    MATH GLYPH CONSTRUCTION                    *****/
  269.   /*****                                                               *****/
  270.   /*************************************************************************/
  271.   /*************************************************************************/
  272.  
  273.   static void
  274.   otv_GlyphAssembly_validate( FT_Bytes       table,
  275.                               OTV_Validator  valid )
  276.   {
  277.     FT_Bytes  p = table;
  278.     FT_UInt   pcnt, table_size;
  279.     FT_UInt   i;
  280.  
  281.     OTV_OPTIONAL_TABLE( DeviceTableOffset );
  282.  
  283.  
  284.     /* OTV_NAME_ENTER( "GlyphAssembly" ); */
  285.  
  286.     OTV_LIMIT_CHECK( 6 );
  287.  
  288.     p += 2;                           /* Skip the Italics Correction value */
  289.     OTV_OPTIONAL_OFFSET( DeviceTableOffset );
  290.     pcnt = FT_NEXT_USHORT( p );
  291.  
  292.     OTV_LIMIT_CHECK( 8 * pcnt );
  293.     table_size = 6 + 8 * pcnt;
  294.  
  295.     OTV_SIZE_CHECK( DeviceTableOffset );
  296.     if ( DeviceTableOffset )
  297.       otv_Device_validate( table + DeviceTableOffset, valid );
  298.  
  299.     for ( i = 0; i < pcnt; ++i )
  300.     {
  301.       FT_UInt  gid;
  302.  
  303.  
  304.       gid = FT_NEXT_USHORT( p );
  305.       if ( gid >= valid->glyph_count )
  306.         FT_INVALID_GLYPH_ID;
  307.       p += 2*4;             /* skip the Start, End, Full, and Flags fields */
  308.     }
  309.  
  310.     /* OTV_EXIT; */
  311.   }
  312.  
  313.  
  314.   static void
  315.   otv_MathGlyphConstruction_validate( FT_Bytes       table,
  316.                                       OTV_Validator  valid )
  317.   {
  318.     FT_Bytes  p = table;
  319.     FT_UInt   vcnt, table_size;
  320.     FT_UInt   i;
  321.  
  322.     OTV_OPTIONAL_TABLE( GlyphAssembly );
  323.  
  324.  
  325.     /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
  326.  
  327.     OTV_LIMIT_CHECK( 4 );
  328.  
  329.     OTV_OPTIONAL_OFFSET( GlyphAssembly );
  330.     vcnt = FT_NEXT_USHORT( p );
  331.  
  332.     OTV_LIMIT_CHECK( 4 * vcnt );
  333.     table_size = 4 + 4 * vcnt;
  334.  
  335.     for ( i = 0; i < vcnt; ++i )
  336.     {
  337.       FT_UInt  gid;
  338.  
  339.  
  340.       gid = FT_NEXT_USHORT( p );
  341.       if ( gid >= valid->glyph_count )
  342.         FT_INVALID_GLYPH_ID;
  343.       p += 2;                          /* skip the size */
  344.     }
  345.  
  346.     OTV_SIZE_CHECK( GlyphAssembly );
  347.     if ( GlyphAssembly )
  348.       otv_GlyphAssembly_validate( table+GlyphAssembly, valid );
  349.  
  350.     /* OTV_EXIT; */
  351.   }
  352.  
  353.  
  354.   static void
  355.   otv_MathVariants_validate( FT_Bytes       table,
  356.                              OTV_Validator  valid )
  357.   {
  358.     FT_Bytes  p = table;
  359.     FT_UInt   vcnt, hcnt, i, table_size;
  360.  
  361.     OTV_OPTIONAL_TABLE( VCoverage );
  362.     OTV_OPTIONAL_TABLE( HCoverage );
  363.     OTV_OPTIONAL_TABLE( Offset );
  364.  
  365.  
  366.     OTV_NAME_ENTER( "MathVariants" );
  367.  
  368.     OTV_LIMIT_CHECK( 10 );
  369.  
  370.     p += 2;                       /* Skip the MinConnectorOverlap constant */
  371.     OTV_OPTIONAL_OFFSET( VCoverage );
  372.     OTV_OPTIONAL_OFFSET( HCoverage );
  373.     vcnt = FT_NEXT_USHORT( p );
  374.     hcnt = FT_NEXT_USHORT( p );
  375.  
  376.     OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
  377.     table_size = 10 + 2 * vcnt + 2 * hcnt;
  378.  
  379.     OTV_SIZE_CHECK( VCoverage );
  380.     if ( VCoverage )
  381.       otv_Coverage_validate( table + VCoverage, valid, vcnt );
  382.  
  383.     OTV_SIZE_CHECK( HCoverage );
  384.     if ( HCoverage )
  385.       otv_Coverage_validate( table + HCoverage, valid, hcnt );
  386.  
  387.     for ( i = 0; i < vcnt; ++i )
  388.     {
  389.       OTV_OPTIONAL_OFFSET( Offset );
  390.       OTV_SIZE_CHECK( Offset );
  391.       otv_MathGlyphConstruction_validate( table + Offset, valid );
  392.     }
  393.  
  394.     for ( i = 0; i < hcnt; ++i )
  395.     {
  396.       OTV_OPTIONAL_OFFSET( Offset );
  397.       OTV_SIZE_CHECK( Offset );
  398.       otv_MathGlyphConstruction_validate( table + Offset, valid );
  399.     }
  400.  
  401.     OTV_EXIT;
  402.   }
  403.  
  404.  
  405.   /*************************************************************************/
  406.   /*************************************************************************/
  407.   /*****                                                               *****/
  408.   /*****                          MATH TABLE                           *****/
  409.   /*****                                                               *****/
  410.   /*************************************************************************/
  411.   /*************************************************************************/
  412.  
  413.   /* sets valid->glyph_count */
  414.  
  415.   FT_LOCAL_DEF( void )
  416.   otv_MATH_validate( FT_Bytes      table,
  417.                      FT_UInt       glyph_count,
  418.                      FT_Validator  ftvalid )
  419.   {
  420.     OTV_ValidatorRec  validrec;
  421.     OTV_Validator     valid = &validrec;
  422.     FT_Bytes          p     = table;
  423.     FT_UInt           MathConstants, MathGlyphInfo, MathVariants;
  424.  
  425.  
  426.     valid->root = ftvalid;
  427.  
  428.     FT_TRACE3(( "validating MATH table\n" ));
  429.     OTV_INIT;
  430.  
  431.     OTV_LIMIT_CHECK( 10 );
  432.  
  433.     if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
  434.       FT_INVALID_FORMAT;
  435.  
  436.     MathConstants = FT_NEXT_USHORT( p );
  437.     MathGlyphInfo = FT_NEXT_USHORT( p );
  438.     MathVariants  = FT_NEXT_USHORT( p );
  439.  
  440.     valid->glyph_count = glyph_count;
  441.  
  442.     otv_MathConstants_validate( table + MathConstants,
  443.                                 valid );
  444.     otv_MathGlyphInfo_validate( table + MathGlyphInfo,
  445.                                 valid );
  446.     otv_MathVariants_validate ( table + MathVariants,
  447.                                 valid );
  448.  
  449.     FT_TRACE4(( "\n" ));
  450.   }
  451.  
  452.  
  453. /* END */
  454.