/*
- * Copyright (C) 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
*
- * This is part of HarfBuzz, an OpenType Layout engine library.
+ * This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
#include "hb-open-type-private.hh"
+HB_BEGIN_DECLS
+
/*
*
struct OffsetTable;
struct TTCHeader;
-typedef struct TableDirectory
+
+typedef struct TableRecord
{
- inline bool sanitize (SANITIZE_ARG_DEF, const void *base) {
- return SANITIZE_SELF () && SANITIZE (tag) &&
- SANITIZE_MEM (CONST_CHARP(base) + (unsigned long) offset, length);
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE ();
+ return c->check_struct (this);
}
Tag tag; /* 4-byte identifier. */
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);
- DEFINE_TAG_ARRAY_INTERFACE (OpenTypeTable, table); /* get_table_count(), get_table(i), get_table_tag(i) */
- DEFINE_TAG_FIND_INTERFACE (OpenTypeTable, table); /* find_table_index(tag), get_table_by_tag(tag) */
-
- unsigned int get_face_count (void) const { return 1; }
-
- private:
- /* OpenTypeTables, in no particular order */
- DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables);
-
- public:
- inline bool sanitize (SANITIZE_ARG_DEF, const void *base) {
- if (!(SANITIZE_SELF () && SANITIZE_MEM (tableDir, sizeof (tableDir[0]) * numTables))) return false;
+ inline unsigned int get_table_count (void) const
+ { return numTables; }
+ inline const TableRecord& get_table (unsigned int i) const
+ {
+ 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);
unsigned int count = numTables;
for (unsigned int i = 0; i < count; i++)
- if (!SANITIZE_BASE (tableDir[i], base))
- return false;
- return true;
+ {
+ if (t == tables[i].tag)
+ {
+ if (table_index) *table_index = i;
+ return true;
+ }
+ }
+ if (table_index) *table_index = Index::NOT_FOUND_INDEX;
+ return false;
+ }
+ 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);
+ }
+
+ public:
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE ();
+ return c->check_struct (this)
+ && c->check_array (tables, TableRecord::static_size, numTables);
}
private:
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[]; /* TableDirectory entries. numTables items */
+ TableRecord tables[VAR]; /* TableRecord entries. numTables items */
+ public:
+ DEFINE_SIZE_ARRAY (12, tables);
} OpenTypeFontFace;
-ASSERT_SIZE (OffsetTable, 12);
+
/*
* 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);
-
- unsigned int get_face_count (void) const { return table.len; }
+ private:
- const OpenTypeFontFace& get_face (unsigned int i) const
+ inline unsigned int get_face_count (void) 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_count ();
+ default:return 0;
+ }
+ }
+ inline const OpenTypeFontFace& get_face (unsigned int i) const
+ {
+ 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);
+ }
}
- bool sanitize (SANITIZE_ARG_DEF) {
- if (!SANITIZE (version)) return false;
- if (version.major < 1 || version.major > 2) return true;
- /* XXX Maybe we shouldn't NEUTER these offsets, they may cause a full copy of
- * the whole font right now. */
- //if (!table.sanitize (SANITIZE_ARG)) return false;
- return table.sanitize (SANITIZE_ARG, CONST_CHARP(this), CONST_CHARP(this));
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE ();
+ 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);
/*
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; }
- unsigned int get_face_count (void) const
+ inline unsigned int get_face_count (void) const
{
- switch (tag) {
- default: return 0;
- case TrueTypeTag: case CFFTag: return OffsetTable::get_for_data (CONST_CHARP(this)).get_face_count ();
- case TTCTag: return TTCHeader::get_for_data (CONST_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;
}
}
- const OpenTypeFontFace& get_face (unsigned int i) const
+ 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 (CONST_CHARP(this));
- case TTCTag: return TTCHeader::get_for_data (CONST_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 ((const char*) this) + table.offset;
- }
-
- bool sanitize (SANITIZE_ARG_DEF) {
- switch (tag) {
- default: return true;
- case TrueTypeTag: case CFFTag: return SANITIZE_THIS (CAST (OffsetTable, *this, 0));
- case TTCTag: return SANITIZE (CAST (TTCHeader, *this, 0));
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE ();
+ 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 */