update for HEAD-2003050101
[reactos.git] / lib / freetype / src / otlayout / otlgdef.c
diff --git a/lib/freetype/src/otlayout/otlgdef.c b/lib/freetype/src/otlayout/otlgdef.c
new file mode 100644 (file)
index 0000000..ff1c2a1
--- /dev/null
@@ -0,0 +1,175 @@
+#include "otlgdef.h"
+#include "otlcommn.h"
+
+ /************************************************************************/
+ /************************************************************************/
+ /*****                                                              *****/
+ /*****                      ATTACHMENTS LIST                        *****/
+ /*****                                                              *****/
+ /************************************************************************/
+ /************************************************************************/
+
+  static void
+  otl_attach_point_validate( OTL_Bytes      table,
+                             OTL_Validator  valid )
+  {
+    OTL_Bytes  p = table;
+    OTL_UInt   count;
+
+    if ( p + 2 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+
+    count = OTL_NEXT_USHORT( p );
+    if ( table + count*2 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+  }
+
+
+  static void
+  otl_attach_list_validate( OTL_Bytes      table,
+                            OTL_Validator  valid )
+  {
+    OTL_Bytes  p = table;
+    OTL_Bytes  coverage;
+    OTL_UInt   count;
+
+    if ( p + 4 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+
+    coverage = table + OTL_NEXT_USHORT( p );
+    count    = OTL_NEXT_USHORT( p );
+
+    otl_coverage_validate( coverage, valid );
+    if ( count != otl_coverage_get_count( coverage ) )
+      OTL_INVALID_DATA;
+
+    if ( p + count*2 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+
+    for ( ; count > 0; count-- )
+      otl_attach_point_validate( table + OTL_NEXT_USHORT( p ) );
+  }
+
+
+ /************************************************************************/
+ /************************************************************************/
+ /*****                                                              *****/
+ /*****                      LIGATURE CARETS                         *****/
+ /*****                                                              *****/
+ /************************************************************************/
+ /************************************************************************/
+
+  static void
+  otl_caret_value_validate( OTL_Bytes      table,
+                            OTL_Validator  valid )
+  {
+    OTL_Bytes  p = table;
+
+    if ( p + 4 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+
+    format = OTL_NEXT_USHORT( p );
+    switch ( format )
+    {
+      case 1:
+      case 2:
+        break;
+
+      case 3:
+        {
+          OTL_Bytes  device;
+
+          p += 2;
+          if ( p + 2 > valid->limit )
+            OTL_INVALID_TOO_SHORT;
+
+          otl_device_table_validate( table + OTL_PEEK_USHORT( p ) );
+        }
+        break;
+
+      default:
+        OTL_INVALID_DATA;
+    }
+  }
+
+
+  static void
+  otl_ligature_glyph_validate( OTL_Bytes      table,
+                               OTL_Validator  valid )
+  {
+    OTL_Bytes  p = table;
+    OTL_UInt   count;
+
+    if ( p + 2 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+
+    count = OTL_NEXT_USHORT( p );
+
+    if ( p + count*2 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+
+    for ( ; count > 0; count-- )
+      otl_caret_value_validate( table + OTL_NEXT_USHORT( p ) );
+  }
+
+
+  static void
+  otl_ligature_caret_list_validate( OTL_Bytes      table,
+                                    OTL_Validator  valid )
+  {
+    OTL_Bytes  p = table;
+    OTL_Bytes  coverage;
+    OTL_UInt   count;
+
+    if ( p + 4 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+
+    coverage = table + OTL_NEXT_USHORT( p );
+    count    = OTL_NEXT_USHORT( p );
+
+    otl_coverage_validate( coverage, valid );
+    if ( count != otl_coverage_get_count( coverage ) )
+      OTL_INVALID_DATA;
+
+    if ( p + count*2 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+
+    for ( ; count > 0; count-- )
+      otl_ligature_glyph_validate( table + OTL_NEXT_USHORT( p ) );
+  }
+
+
+ /************************************************************************/
+ /************************************************************************/
+ /*****                                                              *****/
+ /*****                         GDEF TABLE                           *****/
+ /*****                                                              *****/
+ /************************************************************************/
+ /************************************************************************/
+
+  OTL_APIDEF( void )
+  otl_gdef_validate( OTL_Bytes      table,
+                     OTL_Validator  valid )
+  {
+    OTL_Bytes  p = table;
+
+    if ( p + 12 > valid->limit )
+      OTL_INVALID_TOO_SHORT;
+
+    /* check format */
+    if ( OTL_NEXT_ULONG( p ) != 0x00010000UL )
+      OTL_INVALID_FORMAT;
+
+    /* validate class definition table */
+    otl_class_definition_validate( table + OTL_NEXT_USHORT( p ) );
+
+    /* validate attachment point list */
+    otl_attach_list_validate( table + OTL_NEXT_USHORT( p ) );
+
+    /* validate ligature caret list */
+    otl_ligature_caret_list_validate( table + OTL_NEXT_USHORT( p ) );
+
+    /* validate mark attach class */
+    otl_class_definition_validate( table + OTL_NEXT_USHORT( p ) );
+  }
+