Register buffer vars in Indic shaper
[framework/uifw/harfbuzz.git] / src / hb-open-file-private.hh
index 993e7eb..7d43e46 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -29,6 +29,8 @@
 
 #include "hb-open-type-private.hh"
 
+HB_BEGIN_DECLS
+
 
 /*
  *
@@ -45,13 +47,12 @@ struct OpenTypeFontFile;
 struct OffsetTable;
 struct TTCHeader;
 
-typedef struct TableDirectory
-{
-  static inline unsigned int get_size () { return sizeof (TableDirectory); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+typedef struct TableRecord
+{
+  inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
-    return SANITIZE_SELF ();
+    return c->check_struct (this);
   }
 
   Tag          tag;            /* 4-byte identifier. */
@@ -59,67 +60,49 @@ typedef struct TableDirectory
   ULONG                offset;         /* Offset from beginning of TrueType font
                                 * file. */
   ULONG                length;         /* Length of this table. */
+  public:
+  DEFINE_SIZE_STATIC (16);
 } OpenTypeTable;
-ASSERT_SIZE (TableDirectory, 16);
 
 typedef struct OffsetTable
 {
   friend struct OpenTypeFontFile;
-  friend struct TTCHeader;
-
-  STATIC_DEFINE_GET_FOR_DATA (OffsetTable);
 
   inline unsigned int get_table_count (void) const
   { return numTables; }
-  inline const Tag& get_table_tag (unsigned int i) const
+  inline const TableRecord& get_table (unsigned int i) const
   {
-    if (HB_UNLIKELY (i >= numTables)) return Null(Tag);
-    return tableDir[i].tag;
-  }
-  inline const TableDirectory& get_table (unsigned int i) const
-  {
-    if (HB_UNLIKELY (i >= numTables)) return Null(TableDirectory);
-    return tableDir[i];
+    if (unlikely (i >= numTables)) return Null(TableRecord);
+    return tables[i];
   }
   inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
   {
     Tag t;
     t.set (tag);
-    // TODO bsearch
     unsigned int count = numTables;
     for (unsigned int i = 0; i < count; i++)
     {
-      if (t == tableDir[i].tag)
+      if (t == tables[i].tag)
       {
         if (table_index) *table_index = i;
         return true;
       }
     }
-    if (table_index) *table_index = NO_INDEX;
+    if (table_index) *table_index = Index::NOT_FOUND_INDEX;
     return false;
   }
-  inline const TableDirectory& get_table_by_tag (hb_tag_t tag) const
+  inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
   {
     unsigned int table_index;
     find_table_index (tag, &table_index);
     return get_table (table_index);
   }
 
-  inline unsigned int get_face_count (void) const { return 1; }
-
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base) {
+  inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
-    if (!(SANITIZE_SELF () && SANITIZE_ARRAY (tableDir, TableDirectory::get_size (), numTables))) return false;
-    return true;
-    /* No need to check tables individually since we don't sanitize the
-     * referenced table, just the table directory.  Code retaind to make
-     * sure TableDirectory has a baseless sanitize(). */
-    unsigned int count = numTables;
-    for (unsigned int i = 0; i < count; i++)
-      if (!SANITIZE (tableDir[i]))
-        return false;
-    return true;
+    return c->check_struct (this)
+       && c->check_array (tables, TableRecord::static_size, numTables);
   }
 
   private:
@@ -128,43 +111,82 @@ typedef struct OffsetTable
   USHORT       searchRange;    /* (Maximum power of 2 <= numTables) x 16 */
   USHORT       entrySelector;  /* Log2(maximum power of 2 <= numTables). */
   USHORT       rangeShift;     /* NumTables x 16-searchRange. */
-  TableDirectory tableDir[VAR];        /* TableDirectory entries. numTables items */
+  TableRecord  tables[VAR];    /* TableRecord entries. numTables items */
+  public:
+  DEFINE_SIZE_ARRAY (12, tables);
 } OpenTypeFontFace;
-ASSERT_SIZE_VAR (OffsetTable, 12, TableDirectory);
+
 
 /*
  * TrueType Collections
  */
 
+struct TTCHeaderVersion1
+{
+  friend struct TTCHeader;
+
+  inline unsigned int get_face_count (void) const { return table.len; }
+  inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) {
+    TRACE_SANITIZE ();
+    return table.sanitize (c, this);
+  }
+
+  private:
+  Tag          ttcTag;         /* TrueType Collection ID string: 'ttcf' */
+  FixedVersion version;        /* Version of the TTC Header (1.0),
+                                * 0x00010000 */
+  LongOffsetLongArrayOf<OffsetTable>
+               table;          /* Array of offsets to the OffsetTable for each font
+                                * from the beginning of the file */
+  public:
+  DEFINE_SIZE_ARRAY (12, table);
+};
+
 struct TTCHeader
 {
   friend struct OpenTypeFontFile;
 
-  STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (TTCHeader, 1, 2);
-
-  inline unsigned int get_face_count (void) const { return table.len; }
+  private:
 
+  inline unsigned int get_face_count (void) const
+  {
+    switch (u.header.version.major) {
+    case 2: /* version 2 is compatible with version 1 */
+    case 1: return u.version1.get_face_count ();
+    default:return 0;
+    }
+  }
   inline const OpenTypeFontFace& get_face (unsigned int i) const
   {
-    return this+table[i];
+    switch (u.header.version.major) {
+    case 2: /* version 2 is compatible with version 1 */
+    case 1: return u.version1.get_face (i);
+    default:return Null(OpenTypeFontFace);
+    }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
-    if (!SANITIZE (version)) return false;
-    if (version.major < 1 || version.major > 2) return true;
-    return table.sanitize (SANITIZE_ARG, CharP(this), CharP(this));
+    if (unlikely (!u.header.version.sanitize (c))) return false;
+    switch (u.header.version.major) {
+    case 2: /* version 2 is compatible with version 1 */
+    case 1: return u.version1.sanitize (c);
+    default:return true;
+    }
   }
 
   private:
+  union {
+  struct {
   Tag          ttcTag;         /* TrueType Collection ID string: 'ttcf' */
   FixedVersion version;        /* Version of the TTC Header (1.0 or 2.0),
                                 * 0x00010000 or 0x00020000 */
-  LongOffsetLongArrayOf<OffsetTable>
-               table;          /* Array of offsets to the OffsetTable for each font
-                                * from the beginning of the file */
+  }                    header;
+  TTCHeaderVersion1    version1;
+  } u;
 };
-ASSERT_SIZE (TTCHeader, 12);
 
 
 /*
@@ -173,52 +195,64 @@ ASSERT_SIZE (TTCHeader, 12);
 
 struct OpenTypeFontFile
 {
-  static const hb_tag_t TrueTypeTag    = HB_TAG ( 0 , 1 , 0 , 0 );
-  static const hb_tag_t CFFTag         = HB_TAG ('O','T','T','O');
-  static const hb_tag_t TTCTag         = HB_TAG ('t','t','c','f');
+  static const hb_tag_t CFFTag         = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */
+  static const hb_tag_t TrueTypeTag    = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */
+  static const hb_tag_t TTCTag         = HB_TAG ('t','t','c','f'); /* TrueType Collection */
+  static const hb_tag_t TrueTag                = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */
+  static const hb_tag_t Typ1Tag                = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */
 
-  STATIC_DEFINE_GET_FOR_DATA (OpenTypeFontFile);
+  inline hb_tag_t get_tag (void) const { return u.tag; }
 
   inline unsigned int get_face_count (void) const
   {
-    switch (tag) {
-    default: return 0;
-    case TrueTypeTag: case CFFTag: return OffsetTable::get_for_data (CharP(this)).get_face_count ();
-    case TTCTag: return TTCHeader::get_for_data (CharP(this)).get_face_count ();
+    switch (u.tag) {
+    case CFFTag:       /* All the non-collection tags */
+    case TrueTag:
+    case Typ1Tag:
+    case TrueTypeTag:  return 1;
+    case TTCTag:       return u.ttcHeader.get_face_count ();
+    default:           return 0;
     }
   }
   inline const OpenTypeFontFace& get_face (unsigned int i) const
   {
-    switch (tag) {
-    default: return Null(OpenTypeFontFace);
+    switch (u.tag) {
     /* Note: for non-collection SFNT data we ignore index.  This is because
      * Apple dfont container is a container of SFNT's.  So each SFNT is a
      * non-TTC, but the index is more than zero. */
-    case TrueTypeTag: case CFFTag: return OffsetTable::get_for_data (CharP(this));
-    case TTCTag: return TTCHeader::get_for_data (CharP(this)).get_face (i);
+    case CFFTag:       /* All the non-collection tags */
+    case TrueTag:
+    case Typ1Tag:
+    case TrueTypeTag:  return u.fontFace;
+    case TTCTag:       return u.ttcHeader.get_face (i);
+    default:           return Null(OpenTypeFontFace);
     }
   }
 
-  /* This is how you get a table */
-  inline const char* get_table_data (const OpenTypeTable& table) const
-  {
-    if (HB_UNLIKELY (table.offset == 0)) return NULL;
-    return CharP(this) + table.offset;
-  }
-
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
-    if (!SANITIZE_SELF ()) return false;
-    switch (tag) {
-    default: return true;
-    case TrueTypeTag: case CFFTag: return SANITIZE_THIS (CAST (OffsetTable, *this, 0));
-    case TTCTag: return SANITIZE (CAST (TTCHeader, *this, 0));
+    if (unlikely (!u.tag.sanitize (c))) return false;
+    switch (u.tag) {
+    case CFFTag:       /* All the non-collection tags */
+    case TrueTag:
+    case Typ1Tag:
+    case TrueTypeTag:  return u.fontFace.sanitize (c);
+    case TTCTag:       return u.ttcHeader.sanitize (c);
+    default:           return true;
     }
   }
 
-  Tag          tag;            /* 4-byte identifier. */
+  private:
+  union {
+  Tag                  tag;            /* 4-byte identifier. */
+  OpenTypeFontFace     fontFace;
+  TTCHeader            ttcHeader;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (4, tag);
 };
-ASSERT_SIZE (OpenTypeFontFile, 4);
 
 
+HB_END_DECLS
+
 #endif /* HB_OPEN_FILE_PRIVATE_HH */