From f78e70c301311ffcfb007c7fc4125d71cbcff1e2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 21 Dec 2006 22:30:38 -0500 Subject: [PATCH 01/56] First version. --- src/hb-types-private.cc | 116 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/hb-types-private.cc diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc new file mode 100644 index 000000000..ca1674c79 --- /dev/null +++ b/src/hb-types-private.cc @@ -0,0 +1,116 @@ +#include + +/* + * + * The OpenType Font File + * + */ + +/* + * Data Types: + */ + + +/* "All OpenType fonts use Motorola-style byte ordering (Big Endian)" + * So we define the following hb_be_* types as structs/unions, to + * disallow accidental access to them as an integer. */ + +typedef union { + uint8_t u8; + uint8_t v; +} hb_be_uint8_t; + +typedef union { + int8_t i8; + int8_t v; +} hb_be_int8_t; + +typedef union { + uint8_t u8x2[2]; + uint16_t u16; + uint16_t v; +} hb_be_uint16_t; + +typedef union { + uint8_t u8x2[2]; + int16_t i16; + int16_t v; +} hb_be_int16_t; + +typedef union { + uint8_t u8x4[4]; + uint16_t u16x2[2]; + uint32_t u32; + uint32_t v; + inline operator int () { return (u8x4[0]<<24)+(u8x4[1]<<16)+(u8x4[2]<<8)+u8x4[3]; } +} hb_be_uint32_t; + +typedef union { + uint8_t u8x4[4]; + uint16_t u16x2[2]; + int32_t i32; + int32_t v; +} hb_be_int32_t; + +typedef union { + uint8_t u8x8[8]; + uint16_t u16x4[4]; + uint32_t u32x2[2]; + uint64_t u64; + uint64_t v; +} hb_be_uint64_t; + +typedef union { + uint8_t u8x8[8]; + uint16_t u16x4[4]; + uint32_t u32x2[2]; + int64_t i64; + int64_t v; +} hb_be_int64_t; + + +/* "The following data types are used in the OpenType font file." */ + +typedef hb_be_uint8_t HB_BYTE; /* 8-bit unsigned integer. */ +typedef hb_be_int8_t HB_CHAR; /* 8-bit signed integer. */ +typedef hb_be_uint16_t HB_USHORT; /* 16-bit unsigned integer. */ +typedef hb_be_int16_t HB_SHORT; /* 16-bit signed integer. */ +typedef hb_be_uint32_t HB_ULONG; /* 32-bit unsigned integer. */ +typedef hb_be_int32_t HB_LONG; /* 32-bit signed integer. */ +typedef hb_be_int32_t HB_Fixed; /* 32-bit signed fixed-point number + * (16.16) */ +typedef struct _FUNIT HB_FUNIT; /* Smallest measurable distance + * in the em space. */ +typedef HB_SHORT HB_FWORD; /* 16-bit signed integer (SHORT) that + * describes a quantity in FUnits. */ +typedef HB_USHORT HB_UFWORD; /* 16-bit unsigned integer (USHORT) + * that describes a quantity in + * FUnits. */ +typedef hb_be_int16_t HB_F2DOT14; /* 16-bit signed fixed number with the + * low 14 bits of fraction (2.14). */ +typedef hb_be_int64_t HB_LONGDATETIME;/* Date represented in number of + * seconds since 12:00 midnight, + * January 1, 1904. The value is + * represented as a signed 64-bit + * integer. */ +typedef hb_be_uint32_t HB_Tag; /* Array of four uint8s (length = 32 + * bits) used to identify a script, + * language system, feature, or + * baseline */ +typedef hb_be_uint16_t HB_GlyphID; /* Glyph index number, same as + * uint16(length = 16 bits) */ +typedef hb_be_uint16_t HB_Offset; /* Offset to a table, same as uint16 + * (length = 16 bits), NULL offset = + * 0x0000 */ + +#include + +int +main (void) +{ + HB_Tag x = {{'a', 'b', 'c', 'd'}}; + HB_ULONG y = x; + + printf ("%d\n", x+0); + return 0; +} From 6b4ce01da121e12e1c78ad7eaedf469f35f3568d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 21 Dec 2006 22:31:10 -0500 Subject: [PATCH 02/56] Second version. Complete redesign, based on C++ classes to ensure endian correctness. --- src/hb-types-private.cc | 294 +++++++++++++++++++++++++++------------- 1 file changed, 202 insertions(+), 92 deletions(-) diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index ca1674c79..ec4487808 100644 --- a/src/hb-types-private.cc +++ b/src/hb-types-private.cc @@ -1,4 +1,5 @@ #include +#include /* * @@ -6,111 +7,220 @@ * */ + + /* - * Data Types: + * Data Types */ -/* "All OpenType fonts use Motorola-style byte ordering (Big Endian)" - * So we define the following hb_be_* types as structs/unions, to - * disallow accidental access to them as an integer. */ - -typedef union { - uint8_t u8; - uint8_t v; -} hb_be_uint8_t; - -typedef union { - int8_t i8; - int8_t v; -} hb_be_int8_t; - -typedef union { - uint8_t u8x2[2]; - uint16_t u16; - uint16_t v; -} hb_be_uint16_t; - -typedef union { - uint8_t u8x2[2]; - int16_t i16; - int16_t v; -} hb_be_int16_t; - -typedef union { - uint8_t u8x4[4]; - uint16_t u16x2[2]; - uint32_t u32; - uint32_t v; - inline operator int () { return (u8x4[0]<<24)+(u8x4[1]<<16)+(u8x4[2]<<8)+u8x4[3]; } -} hb_be_uint32_t; - -typedef union { - uint8_t u8x4[4]; - uint16_t u16x2[2]; - int32_t i32; - int32_t v; -} hb_be_int32_t; - -typedef union { - uint8_t u8x8[8]; - uint16_t u16x4[4]; - uint32_t u32x2[2]; - uint64_t u64; - uint64_t v; -} hb_be_uint64_t; - -typedef union { - uint8_t u8x8[8]; - uint16_t u16x4[4]; - uint32_t u32x2[2]; - int64_t i64; - int64_t v; -} hb_be_int64_t; +/* "The following data types are used in the OpenType font file. + * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ + + +/* Macros to convert to/from BigEndian */ +#define hb_be_uint8_t +#define hb_be_int8_t +#define hb_be_uint16_t GUINT16_TO_BE +#define hb_be_int16_t GINT16_TO_BE +#define hb_be_uint32_t GUINT32_TO_BE +#define hb_be_int32_t GINT32_TO_BE +#define hb_be_uint64_t GUINT64_TO_BE +#define hb_be_int64_t GINT64_TO_BE + +#define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN) \ +struct NAME { \ + inline NAME (TYPE i) { v = BIG_ENDIAN(i); } \ + inline TYPE operator = (TYPE i) { v = BIG_ENDIAN(i); return i; } \ + inline operator TYPE(void) { return BIG_ENDIAN(v); } \ + private: TYPE v; \ +} +#define DEFINE_INT_TYPE0(NAME, type) DEFINE_INT_TYPE1 (NAME, type, hb_be_##type) +#define DEFINE_INT_TYPE(NAME, u, w) DEFINE_INT_TYPE0 (NAME, u##int##w##_t) + +DEFINE_INT_TYPE (HB_BYTE, u, 8); /* 8-bit unsigned integer. */ +DEFINE_INT_TYPE (HB_CHAR, , 8); /* 8-bit signed integer. */ +DEFINE_INT_TYPE (HB_USHORT, u, 16); /* 16-bit unsigned integer. */ +DEFINE_INT_TYPE (HB_SHORT, , 16); /* 16-bit signed integer. */ +DEFINE_INT_TYPE (HB_ULONG, u, 32); /* 32-bit unsigned integer. */ +DEFINE_INT_TYPE (HB_LONG, , 32); /* 32-bit signed integer. */ + +/* Date represented in number of seconds since 12:00 midnight, January 1, + * 1904. The value is represented as a signed 64-bit integer. */ +DEFINE_INT_TYPE (HB_LONGDATETIME, , 64); + +/* 32-bit signed fixed-point number (16.16) */ +struct HB_Fixed : HB_LONG { + inline operator double(void) { return (uint32_t) this / 65536.; } + inline int16_t int_part (void) { return (uint32_t) this >> 16; } + inline int16_t frac_part (void) { return (uint32_t) this & 0xffff; } +}; + +/* Smallest measurable distance in the em space. */ +struct HB_FUNIT; + +/* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ +struct HB_FWORD : HB_SHORT { +}; + +/* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ +struct HB_UFWORD : HB_USHORT { +}; + +/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ +struct HB_F2DOT14 : HB_SHORT { + inline operator double() { return (uint32_t) this / 16384.; } +}; + +/* Array of four uint8s (length = 32 bits) used to identify a script, language + * system, feature, or baseline */ +struct HB_Tag : public HB_ULONG { + inline HB_Tag (char *c) : HB_ULONG(c ? *(uint32_t*)c : 0) {} +}; + +/* Glyph index number, same as uint16 (length = 16 bits) */ +struct HB_GlyphID : HB_USHORT { +}; + +/* Offset to a table, same as uint16 (length = 16 bits), NULL offset = 0x0000 */ +struct HB_Offset : HB_USHORT { +}; + +/* CheckSum */ +struct HB_CheckSum : HB_ULONG { + static uint32_t CalcTableChecksum (HB_ULONG *Table, uint32_t Length) { + uint32_t Sum = 0L; + HB_ULONG *EndPtr = Table+((Length+3) & ~3) / sizeof(HB_ULONG); + + while (Table < EndPtr) + Sum += *Table++; + return Sum; + } +}; + + + +/* + * Version Numbers + */ + + +struct HB_USHORT_Version : HB_USHORT { +}; + +struct HB_Fixed_Version : HB_Fixed { + inline int16_t major (void) { return this->int_part(); } + inline int16_t minor (void) { return this->frac_part(); } +}; + + + +/* + * Organization of an OpenType Font + */ + + +/* Offset Table */ +struct HB_OffsetTable { + HB_Fixed_Version sfnt_version; /* 0x00010000 for version 1.0. */ + HB_USHORT numTables; /* Number of tables. */ + HB_USHORT searchRange; /* (Maximum power of 2 <= numTables) + * x 16 */ + HB_USHORT entrySelector; /* Log2(maximum power of 2 <= + * numTables). */ + HB_USHORT rangeShift; /* NumTables x 16-searchRange. */ +}; + + +/* Table Directory */ +struct HB_TableDirectory { + HB_Tag tag; /* 4-byte identifier. */ + HB_CheckSum checkSum; /* CheckSum for this table. */ + HB_ULONG offset; /* Offset from beginning of TrueType font + * file. */ + HB_ULONG length; /* Length of this table. */ +}; + + + +/* + * TrueType Collections + */ + + +/* TTC Header Version 1.0 */ +struct HB_TTCHeader { + HB_Tag TTCTag; /* TrueType Collection ID string: 'ttcf' */ + HB_ULONG version; /* Version of the TTC Header (1.0 or 2.0), + * 0x00010000 or 0x00020000 */ + HB_ULONG numFonts; /* Number of fonts in TTC */ + HB_ULONG offsetTable[0]; /* Array of offsets to the OffsetTable for + * each font from the beginning of the file. + * numFonts entries long. */ + + inline int len(void) { return sizeof (HB_TTCHeader) + + sizeof (HB_ULONG) * numFonts; } +}; + + +/* TTC Header Version 2.0 tail + * Follows after HB_TTCHeader with appropriate size for the offsetTable. */ +struct HB_TTCHeaderVersion2Tail { + HB_ULONG ulDsigTag; /* Tag indicating that a DSIG table exists, + * 0x44534947 ('DSIG') (null if no signature) */ + HB_ULONG ulDsigLength; /* The length (in bytes) of the DSIG table + * (null if no signature) */ + HB_ULONG ulDsigOffset; /* The offset (in bytes) of the DSIG table + * from the beginning of the TTC file (null if + * no signature) */ +}; + + + + + + +/* + * + * OpenType Layout Common Table Formats + * + */ + + +/* + * Script List Table and Script Record + */ + +struct ScriptRecord { + Tag scriptTag; /* 4-byte ScriptTag identifier */ + Offset scriptOffset; /* Offset to Script table--from beginning of + * ScriptList */ +}; + +struct ScriptList { + USHORT scriptCount; /* Number of ScriptRecords */ + ScriptRecord scriptRecord[]; /* Array of ScriptRecords--listed alphabetically + * by ScriptTag. scriptCount entries long */ + + inline int len(void) { return sizeof (ScriptList) + + sizeof (ScriptRecord) * scriptCount; } +}; + + + -/* "The following data types are used in the OpenType font file." */ -typedef hb_be_uint8_t HB_BYTE; /* 8-bit unsigned integer. */ -typedef hb_be_int8_t HB_CHAR; /* 8-bit signed integer. */ -typedef hb_be_uint16_t HB_USHORT; /* 16-bit unsigned integer. */ -typedef hb_be_int16_t HB_SHORT; /* 16-bit signed integer. */ -typedef hb_be_uint32_t HB_ULONG; /* 32-bit unsigned integer. */ -typedef hb_be_int32_t HB_LONG; /* 32-bit signed integer. */ -typedef hb_be_int32_t HB_Fixed; /* 32-bit signed fixed-point number - * (16.16) */ -typedef struct _FUNIT HB_FUNIT; /* Smallest measurable distance - * in the em space. */ -typedef HB_SHORT HB_FWORD; /* 16-bit signed integer (SHORT) that - * describes a quantity in FUnits. */ -typedef HB_USHORT HB_UFWORD; /* 16-bit unsigned integer (USHORT) - * that describes a quantity in - * FUnits. */ -typedef hb_be_int16_t HB_F2DOT14; /* 16-bit signed fixed number with the - * low 14 bits of fraction (2.14). */ -typedef hb_be_int64_t HB_LONGDATETIME;/* Date represented in number of - * seconds since 12:00 midnight, - * January 1, 1904. The value is - * represented as a signed 64-bit - * integer. */ -typedef hb_be_uint32_t HB_Tag; /* Array of four uint8s (length = 32 - * bits) used to identify a script, - * language system, feature, or - * baseline */ -typedef hb_be_uint16_t HB_GlyphID; /* Glyph index number, same as - * uint16(length = 16 bits) */ -typedef hb_be_uint16_t HB_Offset; /* Offset to a table, same as uint16 - * (length = 16 bits), NULL offset = - * 0x0000 */ #include int main (void) { - HB_Tag x = {{'a', 'b', 'c', 'd'}}; - HB_ULONG y = x; + HB_Tag y("abcd"); + HB_Tag &x = y; + HB_BYTE b(0); - printf ("%d\n", x+0); + printf ("%d %04x %04x\n", sizeof (x), x+0, y+0); return 0; } From 01e4fcb032be601f272e62228881e2aabfb9d925 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 21 Dec 2006 22:31:31 -0500 Subject: [PATCH 03/56] Remove the annoying HB_ prefix. --- src/hb-types-private.cc | 107 +++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index ec4487808..40e25cf18 100644 --- a/src/hb-types-private.cc +++ b/src/hb-types-private.cc @@ -38,59 +38,59 @@ struct NAME { \ #define DEFINE_INT_TYPE0(NAME, type) DEFINE_INT_TYPE1 (NAME, type, hb_be_##type) #define DEFINE_INT_TYPE(NAME, u, w) DEFINE_INT_TYPE0 (NAME, u##int##w##_t) -DEFINE_INT_TYPE (HB_BYTE, u, 8); /* 8-bit unsigned integer. */ -DEFINE_INT_TYPE (HB_CHAR, , 8); /* 8-bit signed integer. */ -DEFINE_INT_TYPE (HB_USHORT, u, 16); /* 16-bit unsigned integer. */ -DEFINE_INT_TYPE (HB_SHORT, , 16); /* 16-bit signed integer. */ -DEFINE_INT_TYPE (HB_ULONG, u, 32); /* 32-bit unsigned integer. */ -DEFINE_INT_TYPE (HB_LONG, , 32); /* 32-bit signed integer. */ +DEFINE_INT_TYPE (BYTE, u, 8); /* 8-bit unsigned integer. */ +DEFINE_INT_TYPE (CHAR, , 8); /* 8-bit signed integer. */ +DEFINE_INT_TYPE (USHORT, u, 16); /* 16-bit unsigned integer. */ +DEFINE_INT_TYPE (SHORT, , 16); /* 16-bit signed integer. */ +DEFINE_INT_TYPE (ULONG, u, 32); /* 32-bit unsigned integer. */ +DEFINE_INT_TYPE (LONG, , 32); /* 32-bit signed integer. */ /* Date represented in number of seconds since 12:00 midnight, January 1, * 1904. The value is represented as a signed 64-bit integer. */ -DEFINE_INT_TYPE (HB_LONGDATETIME, , 64); +DEFINE_INT_TYPE (LONGDATETIME, , 64); /* 32-bit signed fixed-point number (16.16) */ -struct HB_Fixed : HB_LONG { +struct Fixed : LONG { inline operator double(void) { return (uint32_t) this / 65536.; } inline int16_t int_part (void) { return (uint32_t) this >> 16; } inline int16_t frac_part (void) { return (uint32_t) this & 0xffff; } }; /* Smallest measurable distance in the em space. */ -struct HB_FUNIT; +struct FUNIT; /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ -struct HB_FWORD : HB_SHORT { +struct FWORD : SHORT { }; /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ -struct HB_UFWORD : HB_USHORT { +struct UFWORD : USHORT { }; /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ -struct HB_F2DOT14 : HB_SHORT { +struct F2DOT14 : SHORT { inline operator double() { return (uint32_t) this / 16384.; } }; /* Array of four uint8s (length = 32 bits) used to identify a script, language * system, feature, or baseline */ -struct HB_Tag : public HB_ULONG { - inline HB_Tag (char *c) : HB_ULONG(c ? *(uint32_t*)c : 0) {} +struct Tag : public ULONG { + inline Tag (char *c) : ULONG(c ? *(uint32_t*)c : 0) {} }; /* Glyph index number, same as uint16 (length = 16 bits) */ -struct HB_GlyphID : HB_USHORT { +struct GlyphID : USHORT { }; /* Offset to a table, same as uint16 (length = 16 bits), NULL offset = 0x0000 */ -struct HB_Offset : HB_USHORT { +struct Offset : USHORT { }; /* CheckSum */ -struct HB_CheckSum : HB_ULONG { - static uint32_t CalcTableChecksum (HB_ULONG *Table, uint32_t Length) { +struct CheckSum : ULONG { + static uint32_t CalcTableChecksum (ULONG *Table, uint32_t Length) { uint32_t Sum = 0L; - HB_ULONG *EndPtr = Table+((Length+3) & ~3) / sizeof(HB_ULONG); + ULONG *EndPtr = Table+((Length+3) & ~3) / sizeof(ULONG); while (Table < EndPtr) Sum += *Table++; @@ -105,10 +105,10 @@ struct HB_CheckSum : HB_ULONG { */ -struct HB_USHORT_Version : HB_USHORT { +struct USHORT_Version : USHORT { }; -struct HB_Fixed_Version : HB_Fixed { +struct Fixed_Version : Fixed { inline int16_t major (void) { return this->int_part(); } inline int16_t minor (void) { return this->frac_part(); } }; @@ -121,24 +121,22 @@ struct HB_Fixed_Version : HB_Fixed { /* Offset Table */ -struct HB_OffsetTable { - HB_Fixed_Version sfnt_version; /* 0x00010000 for version 1.0. */ - HB_USHORT numTables; /* Number of tables. */ - HB_USHORT searchRange; /* (Maximum power of 2 <= numTables) - * x 16 */ - HB_USHORT entrySelector; /* Log2(maximum power of 2 <= - * numTables). */ - HB_USHORT rangeShift; /* NumTables x 16-searchRange. */ +struct OffsetTable { + Fixed_Version sfnt_version; /* 0x00010000 for version 1.0. */ + USHORT numTables; /* Number of tables. */ + USHORT searchRange; /* (Maximum power of 2 <= numTables) x 16 */ + USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */ + USHORT rangeShift; /* NumTables x 16-searchRange. */ }; /* Table Directory */ -struct HB_TableDirectory { - HB_Tag tag; /* 4-byte identifier. */ - HB_CheckSum checkSum; /* CheckSum for this table. */ - HB_ULONG offset; /* Offset from beginning of TrueType font +struct TableDirectory { + Tag tag; /* 4-byte identifier. */ + CheckSum checkSum; /* CheckSum for this table. */ + ULONG offset; /* Offset from beginning of TrueType font * file. */ - HB_ULONG length; /* Length of this table. */ + ULONG length; /* Length of this table. */ }; @@ -149,30 +147,29 @@ struct HB_TableDirectory { /* TTC Header Version 1.0 */ -struct HB_TTCHeader { - HB_Tag TTCTag; /* TrueType Collection ID string: 'ttcf' */ - HB_ULONG version; /* Version of the TTC Header (1.0 or 2.0), +struct TTCHeader { + Tag TTCTag; /* TrueType Collection ID string: 'ttcf' */ + ULONG version; /* Version of the TTC Header (1.0 or 2.0), * 0x00010000 or 0x00020000 */ - HB_ULONG numFonts; /* Number of fonts in TTC */ - HB_ULONG offsetTable[0]; /* Array of offsets to the OffsetTable for - * each font from the beginning of the file. - * numFonts entries long. */ + ULONG numFonts; /* Number of fonts in TTC */ + ULONG offsetTable[0]; /* Array of offsets to the OffsetTable for each font + * from the beginning of the file. + * numFonts entries long. */ - inline int len(void) { return sizeof (HB_TTCHeader) - + sizeof (HB_ULONG) * numFonts; } + inline int len(void) { return sizeof (TTCHeader) + + sizeof (ULONG) * numFonts; } }; /* TTC Header Version 2.0 tail - * Follows after HB_TTCHeader with appropriate size for the offsetTable. */ -struct HB_TTCHeaderVersion2Tail { - HB_ULONG ulDsigTag; /* Tag indicating that a DSIG table exists, - * 0x44534947 ('DSIG') (null if no signature) */ - HB_ULONG ulDsigLength; /* The length (in bytes) of the DSIG table - * (null if no signature) */ - HB_ULONG ulDsigOffset; /* The offset (in bytes) of the DSIG table - * from the beginning of the TTC file (null if - * no signature) */ + * Follows after TTCHeader with appropriate size for the offsetTable. */ +struct TTCHeaderVersion2Tail { + ULONG ulDsigTag; /* Tag indicating that a DSIG table exists, + * 0x44534947 ('DSIG') (null if no signature) */ + ULONG ulDsigLength; /* The length (in bytes) of the DSIG table (null if + * no signature) */ + ULONG ulDsigOffset; /* The offset (in bytes) of the DSIG table from the + * beginning of the TTC file (null if no signature) */ }; @@ -217,9 +214,9 @@ struct ScriptList { int main (void) { - HB_Tag y("abcd"); - HB_Tag &x = y; - HB_BYTE b(0); + Tag y("abcd"); + Tag &x = y; + BYTE b(0); printf ("%d %04x %04x\n", sizeof (x), x+0, y+0); return 0; From b6e62bc5db76ae342177b2b646c37f45eccad975 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 22 Dec 2006 02:21:55 -0500 Subject: [PATCH 04/56] After DEFINE_SCRIPT_ARRAY --- src/hb-types-private.cc | 221 ++++++++++++++++++++++++++-------------- 1 file changed, 143 insertions(+), 78 deletions(-) diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index 40e25cf18..f03df635d 100644 --- a/src/hb-types-private.cc +++ b/src/hb-types-private.cc @@ -1,6 +1,96 @@ #include +#include #include + + +/* Macros to convert to/from BigEndian */ +#define hb_be_uint8_t +#define hb_be_int8_t +#define hb_be_uint16_t GUINT16_TO_BE +#define hb_be_int16_t GINT16_TO_BE +#define hb_be_uint32_t GUINT32_TO_BE +#define hb_be_int32_t GINT32_TO_BE +#define hb_be_uint64_t GUINT64_TO_BE +#define hb_be_int64_t GINT64_TO_BE + +/* + * Int types + */ + +#define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN) \ +struct NAME { \ + inline NAME (TYPE i) { v = BIG_ENDIAN(i); } \ + inline NAME& operator = (TYPE i) { v = BIG_ENDIAN(i); return *this; } \ + inline operator TYPE(void) const { return BIG_ENDIAN(v); } \ + inline bool operator== (NAME o) const { return v == o.v; } \ + private: TYPE v; \ +} +#define DEFINE_INT_TYPE0(NAME, type) DEFINE_INT_TYPE1 (NAME, type, hb_be_##type) +#define DEFINE_INT_TYPE(NAME, u, w) DEFINE_INT_TYPE0 (NAME, u##int##w##_t) + + +/* + * Array types + */ + +/* get_len() is a method returning the number of items in an array-like object */ +#define DEFINE_LEN(Type, array, num) \ + inline unsigned int get_len(void) const { return num; } \ + +/* get_size() is a method returning the size in bytes of an array-like object */ +#define DEFINE_SIZE(Type, array, num) \ + inline unsigned int get_size(void) const { return sizeof (*this) + sizeof (Type) * num; } + +#define DEFINE_LEN_AND_SIZE(Type, array, num) \ + DEFINE_LEN(Type, array, num) \ + DEFINE_SIZE(Type, array, num) + +/* An array type is one that contains a variable number of objects + * as its last item. An array object is extended with len() and size() + * methods, as well as overloaded [] operator. */ +#define DEFINE_ARRAY_TYPE(Type, array, num) \ + DEFINE_INDEX_OPERATOR(const, Type, array, num) \ + DEFINE_INDEX_OPERATOR( , Type, array, num) \ + DEFINE_LEN_AND_SIZE(Type, array, num) +#define DEFINE_INDEX_OPERATOR(const, Type, array, num) \ + inline const Type& operator[] (unsigned int i) const { \ + assert (i < num); \ + return array[i]; \ + } + +/* An offset array type is like an array type, but it contains a table + * of offsets to the objects, relative to the beginning of the current + * object. */ +#define DEFINE_OFFSET_ARRAY_TYPE(Type, array, num) \ + DEFINE_OFFSET_INDEX_OPERATOR(const, Type, array, num) \ + DEFINE_OFFSET_INDEX_OPERATOR( , Type, array, num) \ + DEFINE_LEN_AND_SIZE(Offset, array, num) +#define DEFINE_OFFSET_INDEX_OPERATOR(const, Type, array, num) \ + inline const Type& operator[] (unsigned int i) const { \ + assert (i < num); \ + assert (array[i]); \ + return *(const Type *)((const char*)this + array[i]); \ + } + +#define DEFINE_RECORD_ARRAY_TYPE(Type, array, num) \ + DEFINE_RECORD_ACCESSOR(const, Type, array, num) \ + DEFINE_RECORD_ACCESSOR( , Type, array, num) \ + DEFINE_LEN_AND_SIZE(Record, array, num) +#define DEFINE_RECORD_ACCESSOR(const, Type, array, num) \ + inline const Type& operator[] (unsigned int i) const { \ + assert (i < num); \ + assert (array[i].offset); \ + return *(const Type *)((const char*)this + array[i].offset); \ + } \ + inline const Tag& get_tag (unsigned int i) const { \ + assert (i < num); \ + return array[i].tag; \ + } \ + /* TODO: implement find_tag() */ + + + /* * * The OpenType Font File @@ -18,26 +108,6 @@ * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ -/* Macros to convert to/from BigEndian */ -#define hb_be_uint8_t -#define hb_be_int8_t -#define hb_be_uint16_t GUINT16_TO_BE -#define hb_be_int16_t GINT16_TO_BE -#define hb_be_uint32_t GUINT32_TO_BE -#define hb_be_int32_t GINT32_TO_BE -#define hb_be_uint64_t GUINT64_TO_BE -#define hb_be_int64_t GINT64_TO_BE - -#define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN) \ -struct NAME { \ - inline NAME (TYPE i) { v = BIG_ENDIAN(i); } \ - inline TYPE operator = (TYPE i) { v = BIG_ENDIAN(i); return i; } \ - inline operator TYPE(void) { return BIG_ENDIAN(v); } \ - private: TYPE v; \ -} -#define DEFINE_INT_TYPE0(NAME, type) DEFINE_INT_TYPE1 (NAME, type, hb_be_##type) -#define DEFINE_INT_TYPE(NAME, u, w) DEFINE_INT_TYPE0 (NAME, u##int##w##_t) - DEFINE_INT_TYPE (BYTE, u, 8); /* 8-bit unsigned integer. */ DEFINE_INT_TYPE (CHAR, , 8); /* 8-bit signed integer. */ DEFINE_INT_TYPE (USHORT, u, 16); /* 16-bit unsigned integer. */ @@ -51,9 +121,9 @@ DEFINE_INT_TYPE (LONGDATETIME, , 64); /* 32-bit signed fixed-point number (16.16) */ struct Fixed : LONG { - inline operator double(void) { return (uint32_t) this / 65536.; } - inline int16_t int_part (void) { return (uint32_t) this >> 16; } - inline int16_t frac_part (void) { return (uint32_t) this & 0xffff; } + inline operator double(void) const { return (uint32_t) this / 65536.; } + inline int16_t int_part (void) const { return (uint32_t) this >> 16; } + inline int16_t frac_part (void) const { return (uint32_t) this & 0xffff; } }; /* Smallest measurable distance in the em space. */ @@ -69,13 +139,16 @@ struct UFWORD : USHORT { /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ struct F2DOT14 : SHORT { - inline operator double() { return (uint32_t) this / 16384.; } + inline operator double() const { return (uint32_t) this / 16384.; } }; /* Array of four uint8s (length = 32 bits) used to identify a script, language * system, feature, or baseline */ -struct Tag : public ULONG { - inline Tag (char *c) : ULONG(c ? *(uint32_t*)c : 0) {} +struct Tag { + inline Tag (void) { v[0] = v[1] = v[2] = v[3] = 0; } + inline Tag (char *c) { v[0] = c[0]; v[1] = c[1]; v[2] = c[2]; v[3] = c[3]; } + inline operator uint32_t(void) const { return (v[0]<<24)+(v[1]<<16) +(v[2]<<8)+v[3]; } \ + private: char v[4]; }; /* Glyph index number, same as uint16 (length = 16 bits) */ @@ -99,38 +172,23 @@ struct CheckSum : ULONG { }; - /* * Version Numbers */ - struct USHORT_Version : USHORT { }; struct Fixed_Version : Fixed { - inline int16_t major (void) { return this->int_part(); } - inline int16_t minor (void) { return this->frac_part(); } + inline int16_t major (void) const { return this->int_part(); } + inline int16_t minor (void) const { return this->frac_part(); } }; - /* * Organization of an OpenType Font */ - -/* Offset Table */ -struct OffsetTable { - Fixed_Version sfnt_version; /* 0x00010000 for version 1.0. */ - USHORT numTables; /* Number of tables. */ - USHORT searchRange; /* (Maximum power of 2 <= numTables) x 16 */ - USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */ - USHORT rangeShift; /* NumTables x 16-searchRange. */ -}; - - -/* Table Directory */ struct TableDirectory { Tag tag; /* 4-byte identifier. */ CheckSum checkSum; /* CheckSum for this table. */ @@ -139,41 +197,38 @@ struct TableDirectory { ULONG length; /* Length of this table. */ }; +struct OffsetTable { + DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables); + + Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */ + USHORT numTables; /* Number of tables. */ + 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 */ + +}; /* * TrueType Collections */ - -/* TTC Header Version 1.0 */ struct TTCHeader { + /* This works as an array type because TTCHeader is always located at the + * beginning of the file */ + DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); + Tag TTCTag; /* TrueType Collection ID string: 'ttcf' */ ULONG version; /* Version of the TTC Header (1.0 or 2.0), * 0x00010000 or 0x00020000 */ ULONG numFonts; /* Number of fonts in TTC */ - ULONG offsetTable[0]; /* Array of offsets to the OffsetTable for each font + ULONG offsetTable[]; /* Array of offsets to the OffsetTable for each font * from the beginning of the file. * numFonts entries long. */ - - inline int len(void) { return sizeof (TTCHeader) - + sizeof (ULONG) * numFonts; } }; -/* TTC Header Version 2.0 tail - * Follows after TTCHeader with appropriate size for the offsetTable. */ -struct TTCHeaderVersion2Tail { - ULONG ulDsigTag; /* Tag indicating that a DSIG table exists, - * 0x44534947 ('DSIG') (null if no signature) */ - ULONG ulDsigLength; /* The length (in bytes) of the DSIG table (null if - * no signature) */ - ULONG ulDsigOffset; /* The offset (in bytes) of the DSIG table from the - * beginning of the TTC file (null if no signature) */ -}; - - - @@ -183,30 +238,40 @@ struct TTCHeaderVersion2Tail { * */ +struct Script; +struct LangSys; -/* - * Script List Table and Script Record - */ -struct ScriptRecord { - Tag scriptTag; /* 4-byte ScriptTag identifier */ - Offset scriptOffset; /* Offset to Script table--from beginning of - * ScriptList */ -}; +typedef struct Record { + Tag tag; /* 4-byte Tag identifier */ + Offset offset; /* Offset from beginning of object holding + * the Record */ +} ScriptRecord, LangSysRecord, FeatureRecord; + +struct Script; struct ScriptList { + DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); + USHORT scriptCount; /* Number of ScriptRecords */ ScriptRecord scriptRecord[]; /* Array of ScriptRecords--listed alphabetically * by ScriptTag. scriptCount entries long */ - - inline int len(void) { return sizeof (ScriptList) - + sizeof (ScriptRecord) * scriptCount; } }; +struct Script { + DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); + Offset defaultLangSys; /* Offset to DefaultLangSys table--from + * beginning of Script table--may be NULL */ + USHORT langSysCount; /* Number of LangSysRecords for this script-- + * excluding the DefaultLangSys */ + LangSysRecord langSysRecord[];/* Array of LangSysRecords--listed + * alphabetically by LangSysTag */ +}; +struct LangSys { - +}; #include @@ -214,10 +279,10 @@ struct ScriptList { int main (void) { - Tag y("abcd"); - Tag &x = y; - BYTE b(0); +// Tag y("abcd"); +// Tag &x = y; +// BYTE b(0); - printf ("%d %04x %04x\n", sizeof (x), x+0, y+0); + printf ("%d\n", sizeof (ScriptList));//, x+0, y+0); return 0; } From 8596944b7421f982960e825019fc0263442520cb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 23 Dec 2006 17:49:25 -0500 Subject: [PATCH 05/56] Add Makefile --- src/Makefile | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/Makefile diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 000000000..431ade77e --- /dev/null +++ b/src/Makefile @@ -0,0 +1,3 @@ +all: hb-types-private + +CXXFLAGS = -Wall -Wextra `pkg-config --cflags glib-2.0` From b739c05ca4b7acfa45bd4b0812ecbb3747f726f0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 25 Dec 2006 05:39:20 -0500 Subject: [PATCH 06/56] Add OpenTypeFontFile. --- src/Makefile | 2 +- src/hb-types-private.cc | 113 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 107 insertions(+), 8 deletions(-) diff --git a/src/Makefile b/src/Makefile index 431ade77e..6c1a582d9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,3 @@ all: hb-types-private -CXXFLAGS = -Wall -Wextra `pkg-config --cflags glib-2.0` +CXXFLAGS = -Wall -Wextra `pkg-config --cflags --libs glib-2.0` diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index f03df635d..947d64df1 100644 --- a/src/hb-types-private.cc +++ b/src/hb-types-private.cc @@ -2,7 +2,13 @@ #include #include +/* Public header */ +typedef uint32_t hb_tag_t; +#define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d)) + + +/* Implementation */ /* Macros to convert to/from BigEndian */ #define hb_be_uint8_t @@ -146,7 +152,7 @@ struct F2DOT14 : SHORT { * system, feature, or baseline */ struct Tag { inline Tag (void) { v[0] = v[1] = v[2] = v[3] = 0; } - inline Tag (char *c) { v[0] = c[0]; v[1] = c[1]; v[2] = c[2]; v[3] = c[3]; } + inline Tag (const char *c) { v[0] = c[0]; v[1] = c[1]; v[2] = c[2]; v[3] = c[3]; } inline operator uint32_t(void) const { return (v[0]<<24)+(v[1]<<16) +(v[2]<<8)+v[3]; } \ private: char v[4]; }; @@ -189,6 +195,10 @@ struct Fixed_Version : Fixed { * Organization of an OpenType Font */ +struct OpenTypeFontFile; +struct OffsetTable; +struct TTCHeader; + struct TableDirectory { Tag tag; /* 4-byte identifier. */ CheckSum checkSum; /* CheckSum for this table. */ @@ -206,7 +216,6 @@ struct OffsetTable { USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */ USHORT rangeShift; /* NumTables x 16-searchRange. */ TableDirectory tableDir[]; /* TableDirectory entries. numTables items */ - }; @@ -229,6 +238,62 @@ struct TTCHeader { }; +/* + * OpenType Font File + */ + +struct OpenTypeFontFile { + Tag tag; /* 4-byte identifier. */ + + unsigned int get_len (void) const { + switch (tag) { + default: + return 0; + case HB_TAG (0,1,0,0): + case HB_TAG ('O','T','T','O'): + return 1; + case HB_TAG ('t','t','c','f'): + const TTCHeader &ttc = (TTCHeader&)*this; + return ttc.get_len (); + } + } + + inline const OffsetTable& operator[] (unsigned int i) const { + assert (i < get_len ()); + switch (tag) { + default: + case HB_TAG (0,1,0,0): + case HB_TAG ('O','T','T','O'): + return (const OffsetTable&)*this; + case HB_TAG ('t','t','c','f'): + const TTCHeader &ttc = (const TTCHeader&)*this; + return ttc[i]; + } + } + inline OffsetTable& operator[] (unsigned int i) { + assert (i < get_len ()); + switch (tag) { + default: + case HB_TAG (0,1,0,0): + case HB_TAG ('O','T','T','O'): + return (OffsetTable&)*this; + case HB_TAG ('t','t','c','f'): + TTCHeader &ttc = (TTCHeader&)*this; + return ttc[i]; + } + } + + /* ::get(font_data). This is how you get a handle to one of these */ + static inline const OpenTypeFontFile& get (const char *font_data) { + return (const OpenTypeFontFile&)*font_data; + } + static inline OpenTypeFontFile& get (char *font_data) { + return (OpenTypeFontFile&)*font_data; + } + + /* cannot be instantiated */ + private: OpenTypeFontFile() {} +}; @@ -270,19 +335,53 @@ struct Script { }; struct LangSys { + }; +#include #include int -main (void) +main (int argc, char **argv) { -// Tag y("abcd"); -// Tag &x = y; -// BYTE b(0); + if (argc != 2) { + fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); + exit (1); + } + + GMappedFile *mf = g_mapped_file_new (argv[1], FALSE, NULL); + const char *font_data = g_mapped_file_get_contents (mf); + int len = g_mapped_file_get_length (mf); + + printf ("Opened font file %s: %d bytes long\n", argv[1], len); + + const OpenTypeFontFile &ot = OpenTypeFontFile::get (font_data); + + switch (ot.tag) { + case HB_TAG (0,1,0,0): + printf ("OpenType font with TrueType outlines\n"); + break; + case HB_TAG ('O','T','T','O'): + printf ("OpenType font with CFF (Type1) outlines\n"); + break; + case HB_TAG ('t','t','c','f'): + printf ("TrueType Collection of OpenType fonts\n"); + break; + default: + fprintf (stderr, "Unknown font format\n"); + exit (1); + break; + } + + int num_fonts = ot.get_len (); + printf ("%d font(s) found in file\n", num_fonts); + for (int i = 0; i < num_fonts; i++) { + printf ("Font %d of %d\n", i+1, num_fonts); + const OffsetTable &offset_table = ot[i]; + + } - printf ("%d\n", sizeof (ScriptList));//, x+0, y+0); return 0; } From 808dbe283c1ad66091f2cb67380888b7cf265c01 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 25 Dec 2006 06:18:52 -0500 Subject: [PATCH 07/56] Make types not instantiable --- src/hb-types-private.cc | 112 ++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index 947d64df1..0d74e85d5 100644 --- a/src/hb-types-private.cc +++ b/src/hb-types-private.cc @@ -26,6 +26,7 @@ typedef uint32_t hb_tag_t; #define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN) \ struct NAME { \ + inline NAME (void) { v = 0; } \ inline NAME (TYPE i) { v = BIG_ENDIAN(i); } \ inline NAME& operator = (TYPE i) { v = BIG_ENDIAN(i); return *this; } \ inline operator TYPE(void) const { return BIG_ENDIAN(v); } \ @@ -52,6 +53,10 @@ struct NAME { \ DEFINE_LEN(Type, array, num) \ DEFINE_SIZE(Type, array, num) +#define DEFINE_NOT_INSTANTIABLE(Type) \ + private: inline Type() {} /* cannot be instantiated */ \ + public: + /* An array type is one that contains a variable number of objects * as its last item. An array object is extended with len() and size() * methods, as well as overloaded [] operator. */ @@ -154,6 +159,11 @@ struct Tag { inline Tag (void) { v[0] = v[1] = v[2] = v[3] = 0; } inline Tag (const char *c) { v[0] = c[0]; v[1] = c[1]; v[2] = c[2]; v[3] = c[3]; } inline operator uint32_t(void) const { return (v[0]<<24)+(v[1]<<16) +(v[2]<<8)+v[3]; } \ + + /* The char* these two return is NOT nul-terminated. Print using "%.4s" */ + inline operator const char* (void) const { return (const char *)this; } + inline operator char* (void) { return (char *)this; } + private: char v[4]; }; @@ -199,16 +209,18 @@ struct OpenTypeFontFile; struct OffsetTable; struct TTCHeader; -struct TableDirectory { +typedef struct TableDirectory { Tag tag; /* 4-byte identifier. */ CheckSum checkSum; /* CheckSum for this table. */ ULONG offset; /* Offset from beginning of TrueType font * file. */ ULONG length; /* Length of this table. */ -}; +} OpenTypeTable; -struct OffsetTable { +typedef struct OffsetTable { + DEFINE_NOT_INSTANTIABLE(OffsetTable); DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables); + // TODO: Implement find_table Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */ USHORT numTables; /* Number of tables. */ @@ -216,14 +228,14 @@ struct OffsetTable { USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */ USHORT rangeShift; /* NumTables x 16-searchRange. */ TableDirectory tableDir[]; /* TableDirectory entries. numTables items */ -}; - +} OpenTypeFont; /* * TrueType Collections */ struct TTCHeader { + DEFINE_NOT_INSTANTIABLE(TTCHeader); /* This works as an array type because TTCHeader is always located at the * beginning of the file */ DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); @@ -242,48 +254,15 @@ struct TTCHeader { * OpenType Font File */ -struct OpenTypeFontFile { - Tag tag; /* 4-byte identifier. */ +typedef struct OpenTypeFontFile { + DEFINE_NOT_INSTANTIABLE(OpenTypeFontFile); + static const hb_tag_t truetype_tag = HB_TAG ( 0 , 1 , 0 , 0 ); + static const hb_tag_t cff_tag = HB_TAG ('O','T','T','O'); + static const hb_tag_t ttc_tag = HB_TAG ('t','t','c','f'); - unsigned int get_len (void) const { - switch (tag) { - default: - return 0; - case HB_TAG (0,1,0,0): - case HB_TAG ('O','T','T','O'): - return 1; - case HB_TAG ('t','t','c','f'): - const TTCHeader &ttc = (TTCHeader&)*this; - return ttc.get_len (); - } - } - - inline const OffsetTable& operator[] (unsigned int i) const { - assert (i < get_len ()); - switch (tag) { - default: - case HB_TAG (0,1,0,0): - case HB_TAG ('O','T','T','O'): - return (const OffsetTable&)*this; - case HB_TAG ('t','t','c','f'): - const TTCHeader &ttc = (const TTCHeader&)*this; - return ttc[i]; - } - } - inline OffsetTable& operator[] (unsigned int i) { - assert (i < get_len ()); - switch (tag) { - default: - case HB_TAG (0,1,0,0): - case HB_TAG ('O','T','T','O'): - return (OffsetTable&)*this; - case HB_TAG ('t','t','c','f'): - TTCHeader &ttc = (TTCHeader&)*this; - return ttc[i]; - } - } - - /* ::get(font_data). This is how you get a handle to one of these */ + /* Factory: ::get(font_data) + * This is how you get a handle to one of these + */ static inline const OpenTypeFontFile& get (const char *font_data) { return (const OpenTypeFontFile&)*font_data; } @@ -291,8 +270,30 @@ struct OpenTypeFontFile { return (OpenTypeFontFile&)*font_data; } - /* cannot be instantiated */ - private: OpenTypeFontFile() {} + /* Array interface sans get_size() */ + inline unsigned int get_len (void) const { + switch (tag) { + default: return 0; + case truetype_tag: case cff_tag: return 1; + case ttc_tag: return ((const TTCHeader&)*this).get_len(); + } + } + inline const OpenTypeFont& operator[] (unsigned int i) const { + assert (i < get_len ()); + switch (tag) { + default: case truetype_tag: case cff_tag: return (const OffsetTable&)*this; + case ttc_tag: return ((const TTCHeader&)*this)[i]; + } + } + inline OpenTypeFont& operator[] (unsigned int i) { + assert (i < get_len ()); + switch (tag) { + default: case truetype_tag: case cff_tag: return (OffsetTable&)*this; + case ttc_tag: return ((TTCHeader&)*this)[i]; + } + } + + Tag tag; /* 4-byte identifier. */ }; @@ -316,6 +317,7 @@ typedef struct Record { struct Script; struct ScriptList { + DEFINE_NOT_INSTANTIABLE(ScriptList); DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); USHORT scriptCount; /* Number of ScriptRecords */ @@ -324,6 +326,7 @@ struct ScriptList { }; struct Script { + DEFINE_NOT_INSTANTIABLE(Script); DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); Offset defaultLangSys; /* Offset to DefaultLangSys table--from @@ -377,10 +380,17 @@ main (int argc, char **argv) int num_fonts = ot.get_len (); printf ("%d font(s) found in file\n", num_fonts); - for (int i = 0; i < num_fonts; i++) { - printf ("Font %d of %d\n", i+1, num_fonts); - const OffsetTable &offset_table = ot[i]; + for (int n_font = 0; n_font < num_fonts; n_font++) { + const OpenTypeFont &font = ot[n_font]; + printf ("Font %d of %d\n", n_font+1, num_fonts); + int num_tables = font.get_len (); + printf ("%d table(s) found in font\n", num_tables); + for (int n_table = 0; n_table < num_tables; n_table++) { + const OpenTypeTable &table = font[n_table]; + printf ("Table %d of %d: %.4s (%04x+%04x)\n", n_table+1, num_tables, + (const char *)table.tag, (int)table.offset, (int)table.length); + } } return 0; From c81efca149b08832d5d96a944fb5f303f3d0ca42 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 25 Dec 2006 06:22:08 -0500 Subject: [PATCH 08/56] Use CamelCaseTags. --- src/hb-types-private.cc | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index 0d74e85d5..2f070400d 100644 --- a/src/hb-types-private.cc +++ b/src/hb-types-private.cc @@ -256,9 +256,9 @@ struct TTCHeader { typedef struct OpenTypeFontFile { DEFINE_NOT_INSTANTIABLE(OpenTypeFontFile); - static const hb_tag_t truetype_tag = HB_TAG ( 0 , 1 , 0 , 0 ); - static const hb_tag_t cff_tag = HB_TAG ('O','T','T','O'); - static const hb_tag_t ttc_tag = HB_TAG ('t','t','c','f'); + 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'); /* Factory: ::get(font_data) * This is how you get a handle to one of these @@ -274,22 +274,22 @@ typedef struct OpenTypeFontFile { inline unsigned int get_len (void) const { switch (tag) { default: return 0; - case truetype_tag: case cff_tag: return 1; - case ttc_tag: return ((const TTCHeader&)*this).get_len(); + case TrueTypeTag: case CFFTag: return 1; + case TTCTag: return ((const TTCHeader&)*this).get_len(); } } inline const OpenTypeFont& operator[] (unsigned int i) const { assert (i < get_len ()); switch (tag) { - default: case truetype_tag: case cff_tag: return (const OffsetTable&)*this; - case ttc_tag: return ((const TTCHeader&)*this)[i]; + default: case TrueTypeTag: case CFFTag: return (const OffsetTable&)*this; + case TTCTag: return ((const TTCHeader&)*this)[i]; } } inline OpenTypeFont& operator[] (unsigned int i) { assert (i < get_len ()); switch (tag) { - default: case truetype_tag: case cff_tag: return (OffsetTable&)*this; - case ttc_tag: return ((TTCHeader&)*this)[i]; + default: case TrueTypeTag: case CFFTag: return (OffsetTable&)*this; + case TTCTag: return ((TTCHeader&)*this)[i]; } } @@ -363,18 +363,17 @@ main (int argc, char **argv) const OpenTypeFontFile &ot = OpenTypeFontFile::get (font_data); switch (ot.tag) { - case HB_TAG (0,1,0,0): + case OpenTypeFontFile::TrueTypeTag: printf ("OpenType font with TrueType outlines\n"); break; - case HB_TAG ('O','T','T','O'): + case OpenTypeFontFile::CFFTag: printf ("OpenType font with CFF (Type1) outlines\n"); break; - case HB_TAG ('t','t','c','f'): + case OpenTypeFontFile::TTCTag: printf ("TrueType Collection of OpenType fonts\n"); break; default: - fprintf (stderr, "Unknown font format\n"); - exit (1); + printf ("Unknown font format\n"); break; } @@ -382,7 +381,7 @@ main (int argc, char **argv) printf ("%d font(s) found in file\n", num_fonts); for (int n_font = 0; n_font < num_fonts; n_font++) { const OpenTypeFont &font = ot[n_font]; - printf ("Font %d of %d\n", n_font+1, num_fonts); + printf ("Font %d of %d:\n", n_font+1, num_fonts); int num_tables = font.get_len (); printf ("%d table(s) found in font\n", num_tables); From befc022affd2386b3f46cd7d11e4262f6c8bce9f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 25 Dec 2006 09:14:52 -0500 Subject: [PATCH 09/56] LangSys --- src/hb-types-private.cc | 51 +++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index 2f070400d..89c920f52 100644 --- a/src/hb-types-private.cc +++ b/src/hb-types-private.cc @@ -27,7 +27,7 @@ typedef uint32_t hb_tag_t; #define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN) \ struct NAME { \ inline NAME (void) { v = 0; } \ - inline NAME (TYPE i) { v = BIG_ENDIAN(i); } \ + explicit inline NAME (TYPE i) { v = BIG_ENDIAN(i); } \ inline NAME& operator = (TYPE i) { v = BIG_ENDIAN(i); return *this; } \ inline operator TYPE(void) const { return BIG_ENDIAN(v); } \ inline bool operator== (NAME o) const { return v == o.v; } \ @@ -157,10 +157,11 @@ struct F2DOT14 : SHORT { * system, feature, or baseline */ struct Tag { inline Tag (void) { v[0] = v[1] = v[2] = v[3] = 0; } + inline Tag (uint32_t v) { (ULONG&)(*this) = v; } inline Tag (const char *c) { v[0] = c[0]; v[1] = c[1]; v[2] = c[2]; v[3] = c[3]; } - inline operator uint32_t(void) const { return (v[0]<<24)+(v[1]<<16) +(v[2]<<8)+v[3]; } \ - - /* The char* these two return is NOT nul-terminated. Print using "%.4s" */ + inline bool operator== (Tag o) const { return v[0]==o.v[0]&&v[1]==o.v[1]&&v[2]==o.v[2]&&v[3]==o.v[3]; } + inline operator uint32_t(void) const { return (v[0]<<24)+(v[1]<<16) +(v[2]<<8)+v[3]; } + /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ inline operator const char* (void) const { return (const char *)this; } inline operator char* (void) { return (char *)this; } @@ -219,6 +220,7 @@ typedef struct TableDirectory { typedef struct OffsetTable { DEFINE_NOT_INSTANTIABLE(OffsetTable); + /* OpenTypeTables, in no particular order */ DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables); // TODO: Implement find_table @@ -236,8 +238,7 @@ typedef struct OffsetTable { struct TTCHeader { DEFINE_NOT_INSTANTIABLE(TTCHeader); - /* This works as an array type because TTCHeader is always located at the - * beginning of the file */ + /* OpenTypeFonts, in no particular order */ DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); Tag TTCTag; /* TrueType Collection ID string: 'ttcf' */ @@ -318,6 +319,7 @@ struct Script; struct ScriptList { DEFINE_NOT_INSTANTIABLE(ScriptList); + /* Scripts, in sorted alphabetical order */ DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); USHORT scriptCount; /* Number of ScriptRecords */ @@ -327,8 +329,21 @@ struct ScriptList { struct Script { DEFINE_NOT_INSTANTIABLE(Script); + /* LangSys', in sorted alphabetical order */ DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); + /* Return NULL if none */ + inline const LangSys* get_default_language_system (void) const { + if (!defaultLangSys) + return NULL; + return (const LangSys *)((const char*)this + defaultLangSys); + } + inline LangSys* get_default_language_system (void) { + if (!defaultLangSys) + return NULL; + return (LangSys *)((char*)this + defaultLangSys); + } + Offset defaultLangSys; /* Offset to DefaultLangSys table--from * beginning of Script table--may be NULL */ USHORT langSysCount; /* Number of LangSysRecords for this script-- @@ -338,8 +353,27 @@ struct Script { }; struct LangSys { + DEFINE_NOT_INSTANTIABLE(LangSys); + /* FeatureIndexes, in no particular order */ + DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount); + /* Returns -1 if none */ + inline int get_required_feature_index (void) const { + if (reqFeatureIndex == 0xffff) + return -1; + return reqFeatureIndex;; + } + Offset lookupOrder; /* = NULL (reserved for an offset to a + * reordering table) */ + USHORT reqFeatureIndex;/* Index of a feature required for this + * language system--if no required features + * = 0xFFFF */ + USHORT featureCount; /* Number of FeatureIndex values for this + * language system--excludes the required + * feature */ + USHORT featureIndex[]; /* Array of indices into the FeatureList--in + * arbitrary order */ }; @@ -387,10 +421,13 @@ main (int argc, char **argv) printf ("%d table(s) found in font\n", num_tables); for (int n_table = 0; n_table < num_tables; n_table++) { const OpenTypeTable &table = font[n_table]; - printf ("Table %d of %d: %.4s (%04x+%04x)\n", n_table+1, num_tables, + printf ("Table %2d of %2d: %.4s (0x%06x+0x%06x)\n", n_table+1, num_tables, (const char *)table.tag, (int)table.offset, (int)table.length); } } + Tag a; + a == ((Tag)"1234"); + return 0; } From 25ad92c8a68bf72464601a644ed57b9213126a78 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 25 Dec 2006 09:35:06 -0500 Subject: [PATCH 10/56] Implement Feature --- src/hb-types-private.cc | 46 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index 89c920f52..69c8b9e56 100644 --- a/src/hb-types-private.cc +++ b/src/hb-types-private.cc @@ -319,7 +319,7 @@ struct Script; struct ScriptList { DEFINE_NOT_INSTANTIABLE(ScriptList); - /* Scripts, in sorted alphabetical order */ + /* Scripts, in sorted alphabetical tag order */ DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); USHORT scriptCount; /* Number of ScriptRecords */ @@ -329,7 +329,7 @@ struct ScriptList { struct Script { DEFINE_NOT_INSTANTIABLE(Script); - /* LangSys', in sorted alphabetical order */ + /* LangSys', in sorted alphabetical tag order */ DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); /* Return NULL if none */ @@ -354,7 +354,7 @@ struct Script { struct LangSys { DEFINE_NOT_INSTANTIABLE(LangSys); - /* FeatureIndexes, in no particular order */ + /* Feature indices, in no particular order */ DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount); /* Returns -1 if none */ @@ -373,9 +373,47 @@ struct LangSys { * language system--excludes the required * feature */ USHORT featureIndex[]; /* Array of indices into the FeatureList--in - * arbitrary order */ + * arbitrary order. featureCount entires long */ }; +struct Feature; + +struct FeatureList { + DEFINE_NOT_INSTANTIABLE(FeatureList); + /* Feature indices, in sorted alphabetical tag order */ + DEFINE_RECORD_ARRAY_TYPE (Feature, featureRecord, featureCount); + + USHORT featureCount; /* Number of FeatureRecords in this table */ + FeatureRecord featureRecord[];/* Array of FeatureRecords--zero-based (first + * feature has FeatureIndex = 0)--listed + * alphabetically by FeatureTag. featureCount + * entries long */ +}; + +struct Feature { + DEFINE_NOT_INSTANTIABLE(Feature); + /* LookupList indices, in no particular order */ + DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount); + + // TODO: implement get_feature_params() + + Offset featureParams; /* Offset to Feature Parameters table (if one + * has been defined for the feature), relative + * to the beginning of the Feature Table; = NULL + * if not required */ + USHORT lookupCount; /* Number of LookupList indices for this + * feature */ + USHORT lookupIndex[]; /* Array of LookupList indices for this + * feature--zero-based (first lookup is + * LookupListIndex = 0). lookupCount + * entries long */ +}; + + + + + + #include #include From f8ba99f6f322800a915428ffc3b5eaf1be2e6c21 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 25 Dec 2006 09:58:02 -0500 Subject: [PATCH 11/56] LookupFlags --- src/hb-types-private.cc | 52 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index 69c8b9e56..ed817c55b 100644 --- a/src/hb-types-private.cc +++ b/src/hb-types-private.cc @@ -241,7 +241,7 @@ struct TTCHeader { /* OpenTypeFonts, in no particular order */ DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); - Tag TTCTag; /* TrueType Collection ID string: 'ttcf' */ + Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ ULONG version; /* Version of the TTC Header (1.0 or 2.0), * 0x00010000 or 0x00020000 */ ULONG numFonts; /* Number of fonts in TTC */ @@ -306,7 +306,13 @@ typedef struct OpenTypeFontFile { */ struct Script; +struct ScriptList; struct LangSys; +struct Feature; +struct FeatureList; +struct Lookup; +struct LookupList; +struct SubTable; typedef struct Record { @@ -315,8 +321,6 @@ typedef struct Record { * the Record */ } ScriptRecord, LangSysRecord, FeatureRecord; -struct Script; - struct ScriptList { DEFINE_NOT_INSTANTIABLE(ScriptList); /* Scripts, in sorted alphabetical tag order */ @@ -376,8 +380,6 @@ struct LangSys { * arbitrary order. featureCount entires long */ }; -struct Feature; - struct FeatureList { DEFINE_NOT_INSTANTIABLE(FeatureList); /* Feature indices, in sorted alphabetical tag order */ @@ -409,6 +411,46 @@ struct Feature { * entries long */ }; +struct LookupList { + DEFINE_NOT_INSTANTIABLE(LookupList); + /* Lookup indices, in sorted alphabetical tag order */ + DEFINE_OFFSET_ARRAY_TYPE (Lookup, lookupOffset, lookupCount); + + USHORT lookupCount; /* Number of lookups in this table */ + Offset lookupOffset[]; /* Array of offsets to Lookup tables--from + * beginning of LookupList--zero based (first + * lookup is Lookup index = 0). lookupCount + * entries long */ +}; + +struct LookupFlag : USHORT { + static const uint16_t RightToLeft = 0x0001u; + static const uint16_t IgnoreBaseGlyphs = 0x0002u; + static const uint16_t IgnoreLigatures = 0x0004u; + static const uint16_t IgnoreMarks = 0x0008u; + static const uint16_t Reserved = 0x00F0u; + static const uint16_t MarkAttachmentType = 0xFF00u; +}; + +struct Lookup { + DEFINE_NOT_INSTANTIABLE(Lookup); + /* SubTables, in the desired order */ + DEFINE_OFFSET_ARRAY_TYPE (SubTable, subTableOffset, subTableCount); + + inline bool is_right_to_left (void) const { return lookupFlag & LookupFlag::RightToLeft; } + inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; } + inline bool ignore_ligatures (void) const { return lookupFlag & LookupFlag::IgnoreLigatures; } + inline bool ignore_marks (void) const { return lookupFlag & LookupFlag::IgnoreMarks; } + inline bool get_mark_attachment_type (void) const { return (lookupFlag & LookupFlag::MarkAttachmentType) >> 8; } + + USHORT lookupType; /* Different enumerations for GSUB and GPOS */ + USHORT lookupFlag; /* Lookup qualifiers */ + USHORT subTableCount; /* Number of SubTables for this lookup */ + Offset subTableOffset[];/* Array of offsets to SubTables-from + * beginning of Lookup table. subTableCount + * entries long. */ +}; + From 882e52f59196535495af8ca8069df32308ad52cf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 25 Dec 2006 10:28:31 -0500 Subject: [PATCH 12/56] Rename to harfbuzz-ng.cc --- src/Makefile | 2 +- src/{hb-types-private.cc => harfbuzz-ng.cc} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{hb-types-private.cc => harfbuzz-ng.cc} (100%) diff --git a/src/Makefile b/src/Makefile index 6c1a582d9..55bc4e81c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,3 @@ -all: hb-types-private +all: harfbuzz-ng CXXFLAGS = -Wall -Wextra `pkg-config --cflags --libs glib-2.0` diff --git a/src/hb-types-private.cc b/src/harfbuzz-ng.cc similarity index 100% rename from src/hb-types-private.cc rename to src/harfbuzz-ng.cc From 0c0d55330ef4090f3e4864538e83a4344caaf3ba Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 26 Dec 2006 15:29:38 -0500 Subject: [PATCH 13/56] Coverage. --- src/harfbuzz-ng.cc | 91 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 12 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index ed817c55b..7fdefd64e 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -169,8 +169,9 @@ struct Tag { }; /* Glyph index number, same as uint16 (length = 16 bits) */ -struct GlyphID : USHORT { -}; +//struct GlyphID : USHORT { +//}; +DEFINE_INT_TYPE (GlyphID, u, 16); /* 16-bit unsigned integer. */ /* Offset to a table, same as uint16 (length = 16 bits), NULL offset = 0x0000 */ struct Offset : USHORT { @@ -219,7 +220,6 @@ typedef struct TableDirectory { } OpenTypeTable; typedef struct OffsetTable { - DEFINE_NOT_INSTANTIABLE(OffsetTable); /* OpenTypeTables, in no particular order */ DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables); // TODO: Implement find_table @@ -237,7 +237,6 @@ typedef struct OffsetTable { */ struct TTCHeader { - DEFINE_NOT_INSTANTIABLE(TTCHeader); /* OpenTypeFonts, in no particular order */ DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); @@ -255,7 +254,7 @@ struct TTCHeader { * OpenType Font File */ -typedef struct OpenTypeFontFile { +struct OpenTypeFontFile { DEFINE_NOT_INSTANTIABLE(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'); @@ -322,7 +321,6 @@ typedef struct Record { } ScriptRecord, LangSysRecord, FeatureRecord; struct ScriptList { - DEFINE_NOT_INSTANTIABLE(ScriptList); /* Scripts, in sorted alphabetical tag order */ DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); @@ -332,7 +330,6 @@ struct ScriptList { }; struct Script { - DEFINE_NOT_INSTANTIABLE(Script); /* LangSys', in sorted alphabetical tag order */ DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); @@ -357,7 +354,6 @@ struct Script { }; struct LangSys { - DEFINE_NOT_INSTANTIABLE(LangSys); /* Feature indices, in no particular order */ DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount); @@ -381,7 +377,6 @@ struct LangSys { }; struct FeatureList { - DEFINE_NOT_INSTANTIABLE(FeatureList); /* Feature indices, in sorted alphabetical tag order */ DEFINE_RECORD_ARRAY_TYPE (Feature, featureRecord, featureCount); @@ -393,7 +388,6 @@ struct FeatureList { }; struct Feature { - DEFINE_NOT_INSTANTIABLE(Feature); /* LookupList indices, in no particular order */ DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount); @@ -412,7 +406,6 @@ struct Feature { }; struct LookupList { - DEFINE_NOT_INSTANTIABLE(LookupList); /* Lookup indices, in sorted alphabetical tag order */ DEFINE_OFFSET_ARRAY_TYPE (Lookup, lookupOffset, lookupCount); @@ -433,7 +426,6 @@ struct LookupFlag : USHORT { }; struct Lookup { - DEFINE_NOT_INSTANTIABLE(Lookup); /* SubTables, in the desired order */ DEFINE_OFFSET_ARRAY_TYPE (SubTable, subTableOffset, subTableCount); @@ -451,6 +443,81 @@ struct Lookup { * entries long. */ }; +struct CoverageFormat1 { + /* GlyphIDs, in sorted numerical order */ + DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); + + inline unsigned int get_coverage (uint16_t glyph_id) const { + GlyphID gid (glyph_id); + // TODO: bsearch + for (int i = 0; i < glyphCount; i++) + if (gid == glyphArray[i]) + return i; + return -1; + } + + USHORT coverageFormat; /* Format identifier--format = 1 */ + USHORT glyphCount; /* Number of glyphs in the GlyphArray */ + GlyphID glyphArray[]; /* Array of GlyphIDs--in numerical + * order. glyphCount entries long */ +}; + +struct RangeRecord { + inline unsigned int get_coverage (uint16_t glyph_id) const { + if (glyph_id >= start && glyph_id <= end) + return startCoverageIndex + (glyph_id - start); + return -1; + } + + GlyphID start; /* First GlyphID in the range */ + GlyphID end; /* Last GlyphID in the range */ + USHORT startCoverageIndex; /* Coverage Index of first GlyphID in + * range */ +}; + +struct CoverageFormat2 { + /* RangeRecords, in sorted numerical start order */ + DEFINE_ARRAY_TYPE (RangeRecord, rangeRecord, rangeCount); + + inline unsigned int get_coverage (uint16_t glyph_id) const { + // TODO: bsearch + for (int i = 0; i < rangeCount; i++) { + int coverage = rangeRecord[i].get_coverage (glyph_id); + if (coverage >= 0) + return coverage; + } + return -1; + } + + USHORT coverageFormat; /* Format identifier--format = 2 */ + USHORT rangeCount; /* Number of RangeRecords */ + RangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by + * Start GlyphID. rangeCount entries + * long */ +}; + +struct CoverageFormat { + DEFINE_NOT_INSTANTIABLE(CoverageFormat); + + inline unsigned int get_size (void) const { + switch (coverageFormat) { + case 1: return ((const CoverageFormat1&)*this).get_size (); + case 2: return ((const CoverageFormat2&)*this).get_size (); + default: return sizeof (coverageFormat); + } + } + + /* Returns -1 if not covered. */ + inline unsigned int get_coverage (uint16_t glyph_id) const { + switch (coverageFormat) { + case 1: return ((const CoverageFormat1&)*this).get_coverage(glyph_id); + case 2: return ((const CoverageFormat2&)*this).get_coverage(glyph_id); + default: return -1; + } + } + + USHORT coverageFormat; /* Format identifier */ +}; From 915931b74a30e8652fac5fec153d499485513f63 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 26 Dec 2006 15:30:14 -0500 Subject: [PATCH 14/56] s/DEFINE_NOT_INSTANTIABLE/DEFINE_NON_INSTANTIABLE/ --- src/harfbuzz-ng.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index 7fdefd64e..1325a9acf 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -53,7 +53,7 @@ struct NAME { \ DEFINE_LEN(Type, array, num) \ DEFINE_SIZE(Type, array, num) -#define DEFINE_NOT_INSTANTIABLE(Type) \ +#define DEFINE_NON_INSTANTIABLE(Type) \ private: inline Type() {} /* cannot be instantiated */ \ public: @@ -255,7 +255,7 @@ struct TTCHeader { */ struct OpenTypeFontFile { - DEFINE_NOT_INSTANTIABLE(OpenTypeFontFile); + DEFINE_NON_INSTANTIABLE(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'); @@ -497,7 +497,7 @@ struct CoverageFormat2 { }; struct CoverageFormat { - DEFINE_NOT_INSTANTIABLE(CoverageFormat); + DEFINE_NON_INSTANTIABLE(CoverageFormat); inline unsigned int get_size (void) const { switch (coverageFormat) { From 0d6db2abcbe98456569ccf7934ba0a8b37c7f6f3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 26 Dec 2006 18:53:55 -0500 Subject: [PATCH 15/56] Define more structs using DEFINE_INT_TYPE. --- src/harfbuzz-ng.cc | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index 1325a9acf..c0e3edcd0 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -25,17 +25,19 @@ typedef uint32_t hb_tag_t; */ #define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN) \ -struct NAME { \ inline NAME (void) { v = 0; } \ explicit inline NAME (TYPE i) { v = BIG_ENDIAN(i); } \ inline NAME& operator = (TYPE i) { v = BIG_ENDIAN(i); return *this; } \ inline operator TYPE(void) const { return BIG_ENDIAN(v); } \ inline bool operator== (NAME o) const { return v == o.v; } \ private: TYPE v; \ -} + public: #define DEFINE_INT_TYPE0(NAME, type) DEFINE_INT_TYPE1 (NAME, type, hb_be_##type) #define DEFINE_INT_TYPE(NAME, u, w) DEFINE_INT_TYPE0 (NAME, u##int##w##_t) - +#define DEFINE_INT_TYPE_STRUCT(NAME, u, w) \ + struct NAME { \ + DEFINE_INT_TYPE(NAME, u, w) \ + } /* * Array types @@ -119,16 +121,16 @@ struct NAME { \ * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ -DEFINE_INT_TYPE (BYTE, u, 8); /* 8-bit unsigned integer. */ -DEFINE_INT_TYPE (CHAR, , 8); /* 8-bit signed integer. */ -DEFINE_INT_TYPE (USHORT, u, 16); /* 16-bit unsigned integer. */ -DEFINE_INT_TYPE (SHORT, , 16); /* 16-bit signed integer. */ -DEFINE_INT_TYPE (ULONG, u, 32); /* 32-bit unsigned integer. */ -DEFINE_INT_TYPE (LONG, , 32); /* 32-bit signed integer. */ +DEFINE_INT_TYPE_STRUCT (BYTE, u, 8); /* 8-bit unsigned integer. */ +DEFINE_INT_TYPE_STRUCT (CHAR, , 8); /* 8-bit signed integer. */ +DEFINE_INT_TYPE_STRUCT (USHORT, u, 16); /* 16-bit unsigned integer. */ +DEFINE_INT_TYPE_STRUCT (SHORT, , 16); /* 16-bit signed integer. */ +DEFINE_INT_TYPE_STRUCT (ULONG, u, 32); /* 32-bit unsigned integer. */ +DEFINE_INT_TYPE_STRUCT (LONG, , 32); /* 32-bit signed integer. */ /* Date represented in number of seconds since 12:00 midnight, January 1, * 1904. The value is represented as a signed 64-bit integer. */ -DEFINE_INT_TYPE (LONGDATETIME, , 64); +DEFINE_INT_TYPE_STRUCT (LONGDATETIME, , 64); /* 32-bit signed fixed-point number (16.16) */ struct Fixed : LONG { @@ -169,13 +171,10 @@ struct Tag { }; /* Glyph index number, same as uint16 (length = 16 bits) */ -//struct GlyphID : USHORT { -//}; -DEFINE_INT_TYPE (GlyphID, u, 16); /* 16-bit unsigned integer. */ +DEFINE_INT_TYPE_STRUCT (GlyphID, u, 16); /* Offset to a table, same as uint16 (length = 16 bits), NULL offset = 0x0000 */ -struct Offset : USHORT { -}; +DEFINE_INT_TYPE_STRUCT (Offset, u, 16); /* CheckSum */ struct CheckSum : ULONG { @@ -462,7 +461,7 @@ struct CoverageFormat1 { * order. glyphCount entries long */ }; -struct RangeRecord { +struct CoverageRangeRecord { inline unsigned int get_coverage (uint16_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return startCoverageIndex + (glyph_id - start); @@ -476,8 +475,8 @@ struct RangeRecord { }; struct CoverageFormat2 { - /* RangeRecords, in sorted numerical start order */ - DEFINE_ARRAY_TYPE (RangeRecord, rangeRecord, rangeCount); + /* CoverageRangeRecords, in sorted numerical start order */ + DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount); inline unsigned int get_coverage (uint16_t glyph_id) const { // TODO: bsearch @@ -490,8 +489,8 @@ struct CoverageFormat2 { } USHORT coverageFormat; /* Format identifier--format = 2 */ - USHORT rangeCount; /* Number of RangeRecords */ - RangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by + USHORT rangeCount; /* Number of CoverRangeRecords */ + CoverRangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by * Start GlyphID. rangeCount entries * long */ }; From 53502c6723dbf9cd3b6ba91b733678b3c7871715 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 26 Dec 2006 19:29:08 -0500 Subject: [PATCH 16/56] Rename CoverageFormat to Coverage --- src/harfbuzz-ng.cc | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index c0e3edcd0..999db3f98 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -303,6 +303,10 @@ struct OpenTypeFontFile { * */ +/* + * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList, SubTable + */ + struct Script; struct ScriptList; struct LangSys; @@ -312,7 +316,6 @@ struct Lookup; struct LookupList; struct SubTable; - typedef struct Record { Tag tag; /* 4-byte Tag identifier */ Offset offset; /* Offset from beginning of object holding @@ -442,6 +445,10 @@ struct Lookup { * entries long. */ }; +/* + * Coverage + */ + struct CoverageFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); @@ -490,19 +497,19 @@ struct CoverageFormat2 { USHORT coverageFormat; /* Format identifier--format = 2 */ USHORT rangeCount; /* Number of CoverRangeRecords */ - CoverRangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by + CoverageRangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by * Start GlyphID. rangeCount entries * long */ }; -struct CoverageFormat { - DEFINE_NON_INSTANTIABLE(CoverageFormat); +struct Coverage { + DEFINE_NON_INSTANTIABLE(Coverage); inline unsigned int get_size (void) const { switch (coverageFormat) { case 1: return ((const CoverageFormat1&)*this).get_size (); case 2: return ((const CoverageFormat2&)*this).get_size (); - default: return sizeof (coverageFormat); + default: return sizeof (Coverage); } } @@ -523,6 +530,7 @@ struct CoverageFormat { + #include #include From eb32e374f4d6de8d428d36144f6eef93514820d2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 26 Dec 2006 20:00:33 -0500 Subject: [PATCH 17/56] ClassDef --- src/harfbuzz-ng.cc | 121 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 97 insertions(+), 24 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index 999db3f98..13e563c35 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -244,8 +244,7 @@ struct TTCHeader { * 0x00010000 or 0x00020000 */ ULONG numFonts; /* Number of fonts in TTC */ ULONG offsetTable[]; /* Array of offsets to the OffsetTable for each font - * from the beginning of the file. - * numFonts entries long. */ + * from the beginning of the file */ }; @@ -328,7 +327,7 @@ struct ScriptList { USHORT scriptCount; /* Number of ScriptRecords */ ScriptRecord scriptRecord[]; /* Array of ScriptRecords--listed alphabetically - * by ScriptTag. scriptCount entries long */ + * by ScriptTag */ }; struct Script { @@ -385,8 +384,7 @@ struct FeatureList { USHORT featureCount; /* Number of FeatureRecords in this table */ FeatureRecord featureRecord[];/* Array of FeatureRecords--zero-based (first * feature has FeatureIndex = 0)--listed - * alphabetically by FeatureTag. featureCount - * entries long */ + * alphabetically by FeatureTag */ }; struct Feature { @@ -403,8 +401,7 @@ struct Feature { * feature */ USHORT lookupIndex[]; /* Array of LookupList indices for this * feature--zero-based (first lookup is - * LookupListIndex = 0). lookupCount - * entries long */ + * LookupListIndex = 0) */ }; struct LookupList { @@ -414,8 +411,7 @@ struct LookupList { USHORT lookupCount; /* Number of lookups in this table */ Offset lookupOffset[]; /* Array of offsets to Lookup tables--from * beginning of LookupList--zero based (first - * lookup is Lookup index = 0). lookupCount - * entries long */ + * lookup is Lookup index = 0) */ }; struct LookupFlag : USHORT { @@ -441,8 +437,7 @@ struct Lookup { USHORT lookupFlag; /* Lookup qualifiers */ USHORT subTableCount; /* Number of SubTables for this lookup */ Offset subTableOffset[];/* Array of offsets to SubTables-from - * beginning of Lookup table. subTableCount - * entries long. */ + * beginning of Lookup table */ }; /* @@ -453,7 +448,7 @@ struct CoverageFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); - inline unsigned int get_coverage (uint16_t glyph_id) const { + inline int get_coverage (uint16_t glyph_id) const { GlyphID gid (glyph_id); // TODO: bsearch for (int i = 0; i < glyphCount; i++) @@ -462,14 +457,14 @@ struct CoverageFormat1 { return -1; } - USHORT coverageFormat; /* Format identifier--format = 1 */ - USHORT glyphCount; /* Number of glyphs in the GlyphArray */ - GlyphID glyphArray[]; /* Array of GlyphIDs--in numerical - * order. glyphCount entries long */ + USHORT coverageFormat; /* Format identifier--format = 1 */ + USHORT glyphCount; /* Number of glyphs in the GlyphArray */ + GlyphID glyphArray[]; /* Array of GlyphIDs--in numerical order */ }; struct CoverageRangeRecord { - inline unsigned int get_coverage (uint16_t glyph_id) const { + + inline int get_coverage (uint16_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return startCoverageIndex + (glyph_id - start); return -1; @@ -485,7 +480,7 @@ struct CoverageFormat2 { /* CoverageRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount); - inline unsigned int get_coverage (uint16_t glyph_id) const { + inline int get_coverage (uint16_t glyph_id) const { // TODO: bsearch for (int i = 0; i < rangeCount; i++) { int coverage = rangeRecord[i].get_coverage (glyph_id); @@ -495,9 +490,9 @@ struct CoverageFormat2 { return -1; } - USHORT coverageFormat; /* Format identifier--format = 2 */ - USHORT rangeCount; /* Number of CoverRangeRecords */ - CoverageRangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by + USHORT coverageFormat; /* Format identifier--format = 2 */ + USHORT rangeCount; /* Number of CoverageRangeRecords */ + CoverageRangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by * Start GlyphID. rangeCount entries * long */ }; @@ -509,22 +504,100 @@ struct Coverage { switch (coverageFormat) { case 1: return ((const CoverageFormat1&)*this).get_size (); case 2: return ((const CoverageFormat2&)*this).get_size (); - default: return sizeof (Coverage); + default:return sizeof (Coverage); } } /* Returns -1 if not covered. */ - inline unsigned int get_coverage (uint16_t glyph_id) const { + inline int get_coverage (uint16_t glyph_id) const { switch (coverageFormat) { case 1: return ((const CoverageFormat1&)*this).get_coverage(glyph_id); case 2: return ((const CoverageFormat2&)*this).get_coverage(glyph_id); - default: return -1; + default:return -1; } } USHORT coverageFormat; /* Format identifier */ }; +/* + * Class Definition + */ + +struct ClassDefFormat1 { + /* GlyphIDs, in sorted numerical order */ + DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount); + + inline int get_class (uint16_t glyph_id) const { + if (glyph_id >= startGlyph && glyph_id < startGlyph + glyphCount) + return classValueArray[glyph_id - startGlyph]; + return 0; + } + + USHORT classFormat; /* Format identifier--format = 1 */ + GlyphID startGlyph; /* First GlyphID of the classValueArray */ + USHORT glyphCount; /* Size of the classValueArray */ + USHORT classValueArray[]; /* Array of Class Values--one per GlyphID */ +}; + +struct ClassRangeRecord { + + inline int get_class (uint16_t glyph_id) const { + if (glyph_id >= start && glyph_id <= end) + return classValue; + return 0; + } + + GlyphID start; /* First GlyphID in the range */ + GlyphID end; /* Last GlyphID in the range */ + USHORT classValue; /* Applied to all glyphs in the range + */ +}; + +struct ClassDefFormat2 { + /* ClassRangeRecords, in sorted numerical start order */ + DEFINE_ARRAY_TYPE (ClassRangeRecord, rangeRecord, rangeCount); + + inline int get_class (uint16_t glyph_id) const { + // TODO: bsearch + for (int i = 0; i < rangeCount; i++) { + int classValue = rangeRecord[i].get_class (glyph_id); + if (classValue > 0) + return classValue; + } + return 0; + } + + USHORT classFormat; /* Format identifier--format = 2 */ + USHORT rangeCount; /* Number of Number of ClassRangeRecords */ + ClassRangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by + * Start GlyphID */ +}; + +struct ClassDef { + DEFINE_NON_INSTANTIABLE(ClassDef); + + inline unsigned int get_size (void) const { + switch (classFormat) { + case 1: return ((const ClassDefFormat1&)*this).get_size (); + case 2: return ((const ClassDefFormat2&)*this).get_size (); + default:return sizeof (ClassDef); + } + } + + /* Returns 0 if not found. */ + inline int get_class (uint16_t glyph_id) const { + switch (classFormat) { + case 1: return ((const ClassDefFormat1&)*this).get_class(glyph_id); + case 2: return ((const ClassDefFormat2&)*this).get_class(glyph_id); + default:return 0; + } + } + + USHORT classFormat; /* Format identifier */ +}; + + From 2b7374519766825971f9f4ff5b1cb49b74cfcaf8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 26 Dec 2006 20:55:37 -0500 Subject: [PATCH 18/56] Device tables. --- src/harfbuzz-ng.cc | 49 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index 13e563c35..0303594c3 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -82,7 +82,7 @@ typedef uint32_t hb_tag_t; #define DEFINE_OFFSET_INDEX_OPERATOR(const, Type, array, num) \ inline const Type& operator[] (unsigned int i) const { \ assert (i < num); \ - assert (array[i]); \ + assert (array[i]); /* TODO: should just skip them */ \ return *(const Type *)((const char*)this + array[i]); \ } @@ -93,7 +93,7 @@ typedef uint32_t hb_tag_t; #define DEFINE_RECORD_ACCESSOR(const, Type, array, num) \ inline const Type& operator[] (unsigned int i) const { \ assert (i < num); \ - assert (array[i].offset); \ + assert (array[i].offset); /* TODO: should just skip them */ \ return *(const Type *)((const char*)this + array[i].offset); \ } \ inline const Tag& get_tag (unsigned int i) const { \ @@ -441,7 +441,7 @@ struct Lookup { }; /* - * Coverage + * Coverage Table */ struct CoverageFormat1 { @@ -521,7 +521,7 @@ struct Coverage { }; /* - * Class Definition + * Class Definition Table */ struct ClassDefFormat1 { @@ -597,7 +597,48 @@ struct ClassDef { USHORT classFormat; /* Format identifier */ }; +/* + * Device Tables + */ +struct Device { + + inline unsigned int get_size (void) const { + int count = endSize - startSize + 1; + if (count < 0) count = 0; + switch (deltaFormat) { + case 1: return sizeof (Device) + sizeof (USHORT) * ((count+7)/8); + case 2: return sizeof (Device) + sizeof (USHORT) * ((count+3)/4); + case 3: return sizeof (Device) + sizeof (USHORT) * ((count+1)/2); + default:return sizeof (Device); + } + } + + inline int get_delta (int ppem_size) { + if (ppem_size >= startSize && ppem_size <= endSize && + deltaFormat >= 1 && deltaFormat <= 3) { + int s = ppem_size - startSize; + int f = deltaFormat; + + uint16_t byte = deltaValue[s >> (4 - f)]; + uint16_t bits = byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)); + uint16_t mask = 0xFFFF >> (16 - (1 << f)); + + int delta = bits & mask; + + if (delta >= ((mask + 1) >> 1)) + delta -= mask + 1; + + return delta; + } + return 0; + } + + USHORT startSize; /* Smallest size to correct--in ppem */ + USHORT endSize; /* Largest size to correct--in ppem */ + USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 */ + USHORT deltaValue[]; /* Array of compressed data */ +}; From eebabd8b2ec5296deba6b09d7755933da0a7d9dc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 27 Dec 2006 00:21:31 -0500 Subject: [PATCH 19/56] Finished OpenType Common Table Formats --- src/harfbuzz-ng.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index 0303594c3..e70648e7b 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -123,7 +123,7 @@ typedef uint32_t hb_tag_t; DEFINE_INT_TYPE_STRUCT (BYTE, u, 8); /* 8-bit unsigned integer. */ DEFINE_INT_TYPE_STRUCT (CHAR, , 8); /* 8-bit signed integer. */ -DEFINE_INT_TYPE_STRUCT (USHORT, u, 16); /* 16-bit unsigned integer. */ +DEFINE_INT_TYPE_STRUCT (USHORT, u, 16); /* 16-bit unsigned integer. */ DEFINE_INT_TYPE_STRUCT (SHORT, , 16); /* 16-bit signed integer. */ DEFINE_INT_TYPE_STRUCT (ULONG, u, 32); /* 32-bit unsigned integer. */ DEFINE_INT_TYPE_STRUCT (LONG, , 32); /* 32-bit signed integer. */ From 71d62baab0429cdf56ba4019fd2a205f08188503 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 27 Dec 2006 01:29:24 -0500 Subject: [PATCH 20/56] GSUBGPOSHeader --- src/harfbuzz-ng.cc | 103 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 5 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index e70648e7b..56415f7dc 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -162,6 +162,7 @@ struct Tag { inline Tag (uint32_t v) { (ULONG&)(*this) = v; } inline Tag (const char *c) { v[0] = c[0]; v[1] = c[1]; v[2] = c[2]; v[3] = c[3]; } inline bool operator== (Tag o) const { return v[0]==o.v[0]&&v[1]==o.v[1]&&v[2]==o.v[2]&&v[3]==o.v[3]; } + inline bool operator== (const char *c) const { return v[0]==c[0]&&v[1]==c[1]&&v[2]==c[2]&&v[3]==c[3]; } inline operator uint32_t(void) const { return (v[0]<<24)+(v[1]<<16) +(v[2]<<8)+v[3]; } /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ inline operator const char* (void) const { return (const char *)this; } @@ -268,6 +269,20 @@ struct OpenTypeFontFile { return (OpenTypeFontFile&)*font_data; } + /* This is how you get a table */ + inline const char* get_table (const OpenTypeTable& table) const { + return ((const char*)this) + table.offset; + } + inline char* get_table (const OpenTypeTable& table) { + return ((char*)this) + table.offset; + } + inline const char* operator[] (const OpenTypeTable& table) const { + return ((const char*)this) + table.offset; + } + inline char* operator[] (const OpenTypeTable& table) { + return ((char*)this) + table.offset; + } + /* Array interface sans get_size() */ inline unsigned int get_len (void) const { switch (tag) { @@ -643,6 +658,45 @@ struct Device { +/* + * + * The Glyph Substitution Table + * + */ + + + + +#define DEFINE_LIST_ACCESSOR0(const, Type, name) \ + inline const Type##List* get_##name##_list (void) const { \ + assert (name##List); \ + return (const Type##List *)((const char*)this + name##List); \ + } \ + inline const Type& name (unsigned int i) const { \ + return (*get_##name##_list())[i]; \ + } +#define DEFINE_LIST_ACCESSOR(Type, name) \ + DEFINE_LIST_ACCESSOR0(const, Type, name) \ + DEFINE_LIST_ACCESSOR0( , Type, name) + +struct GSUBGPOSHeader { + + DEFINE_LIST_ACCESSOR(Script, script); /* get_script_list and script(i) */ + DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list and feature(i) */ + DEFINE_LIST_ACCESSOR(Lookup, lookup); /* get_lookup_list and lookup(i) */ + + Fixed_Version version; /* Version of the GSUB table-initially set to + * 0x00010000 */ + Offset scriptList; /* Offset to ScriptList table-from beginning of + * GSUB table */ + Offset featureList; /* Offset to FeatureList table-from beginning of + * GSUB table */ + Offset lookupList; /* Offset to LookupList table-from beginning of + * GSUB table */ +}; + +struct GSUB : GSUBGPOSHeader { +}; #include @@ -686,16 +740,55 @@ main (int argc, char **argv) printf ("Font %d of %d:\n", n_font+1, num_fonts); int num_tables = font.get_len (); - printf ("%d table(s) found in font\n", num_tables); + printf (" %d table(s) found in font\n", num_tables); for (int n_table = 0; n_table < num_tables; n_table++) { const OpenTypeTable &table = font[n_table]; - printf ("Table %2d of %2d: %.4s (0x%06x+0x%06x)\n", n_table+1, num_tables, + printf (" Table %2d of %2d: %.4s (0x%06x+0x%06x)\n", n_table+1, num_tables, (const char *)table.tag, (int)table.offset, (int)table.length); + + if (table.tag == "GSUB" || table.tag == "GPOS") { + const GSUBGPOSHeader &g = (const GSUBGPOSHeader&)*ot[table]; + + const ScriptList &scripts = *g.get_script_list(); + int num_scripts = scripts.get_len (); + printf (" %d script(s) found in table\n", num_scripts); + for (int n_script = 0; n_script < num_scripts; n_script++) { + const Script &script = scripts[n_script]; + printf (" Script %2d of %2d: %.4s\n", n_script+1, num_scripts, + (const char *)scripts.get_tag(n_script)); + + if (script.get_default_language_system () == NULL) + printf (" No default language system\n"); + int num_langsys = script.get_len (); + printf (" %d language system(s) found in script\n", num_langsys); + for (int n_langsys = 0; n_langsys < num_langsys; n_langsys++) { + const LangSys &langsys = script[n_langsys]; + printf (" Language System %2d of %2d: %.4s\n", n_langsys+1, num_langsys, + (const char *)script.get_tag(n_langsys)); + } + } + + const FeatureList &features = *g.get_feature_list(); + int num_features = features.get_len (); + printf (" %d feature(s) found in table\n", num_features); + for (int n_feature = 0; n_feature < num_features; n_feature++) { + const Feature &feature = features[n_feature]; + printf (" Feature %2d of %2d: %.4s; %d lookup(s)\n", n_feature+1, num_features, + (const char *)features.get_tag(n_feature), + (int)feature.lookupCount); + } + + const LookupList &lookups = *g.get_lookup_list(); + int num_lookups = lookups.get_len (); + printf (" %d lookup(s) found in table\n", num_lookups); + for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { + const Lookup &lookup = lookups[n_lookup]; + printf (" Lookup %2d of %2d: type %d, flags %04x\n", n_lookup+1, num_lookups, + (int)lookup.lookupType, (unsigned int)lookup.lookupFlag); + } + } } } - Tag a; - a == ((Tag)"1234"); - return 0; } From 133466177e104ddcd2501a88735670540252167c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 27 Dec 2006 19:58:32 -0500 Subject: [PATCH 21/56] s/OpenTypeFont/OpenTypeFontFace/g --- src/harfbuzz-ng.cc | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index 56415f7dc..ac945788a 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -207,7 +207,7 @@ struct Fixed_Version : Fixed { * Organization of an OpenType Font */ -struct OpenTypeFontFile; +struct OpenTypeFontFaceFile; struct OffsetTable; struct TTCHeader; @@ -230,14 +230,14 @@ typedef struct OffsetTable { USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */ USHORT rangeShift; /* NumTables x 16-searchRange. */ TableDirectory tableDir[]; /* TableDirectory entries. numTables items */ -} OpenTypeFont; +} OpenTypeFontFace; /* * TrueType Collections */ struct TTCHeader { - /* OpenTypeFonts, in no particular order */ + /* OpenTypeFontFaces, in no particular order */ DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ @@ -253,8 +253,8 @@ struct TTCHeader { * OpenType Font File */ -struct OpenTypeFontFile { - DEFINE_NON_INSTANTIABLE(OpenTypeFontFile); +struct OpenTypeFontFaceFile { + DEFINE_NON_INSTANTIABLE(OpenTypeFontFaceFile); 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'); @@ -262,11 +262,11 @@ struct OpenTypeFontFile { /* Factory: ::get(font_data) * This is how you get a handle to one of these */ - static inline const OpenTypeFontFile& get (const char *font_data) { - return (const OpenTypeFontFile&)*font_data; + static inline const OpenTypeFontFaceFile& get (const char *font_data) { + return (const OpenTypeFontFaceFile&)*font_data; } - static inline OpenTypeFontFile& get (char *font_data) { - return (OpenTypeFontFile&)*font_data; + static inline OpenTypeFontFaceFile& get (char *font_data) { + return (OpenTypeFontFaceFile&)*font_data; } /* This is how you get a table */ @@ -291,14 +291,14 @@ struct OpenTypeFontFile { case TTCTag: return ((const TTCHeader&)*this).get_len(); } } - inline const OpenTypeFont& operator[] (unsigned int i) const { + inline const OpenTypeFontFace& operator[] (unsigned int i) const { assert (i < get_len ()); switch (tag) { default: case TrueTypeTag: case CFFTag: return (const OffsetTable&)*this; case TTCTag: return ((const TTCHeader&)*this)[i]; } } - inline OpenTypeFont& operator[] (unsigned int i) { + inline OpenTypeFontFace& operator[] (unsigned int i) { assert (i < get_len ()); switch (tag) { default: case TrueTypeTag: case CFFTag: return (OffsetTable&)*this; @@ -318,7 +318,7 @@ struct OpenTypeFontFile { */ /* - * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList, SubTable + * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList */ struct Script; @@ -328,7 +328,6 @@ struct Feature; struct FeatureList; struct Lookup; struct LookupList; -struct SubTable; typedef struct Record { Tag tag; /* 4-byte Tag identifier */ @@ -440,7 +439,7 @@ struct LookupFlag : USHORT { struct Lookup { /* SubTables, in the desired order */ - DEFINE_OFFSET_ARRAY_TYPE (SubTable, subTableOffset, subTableCount); + DEFINE_OFFSET_ARRAY_TYPE (char*, subTableOffset, subTableCount); inline bool is_right_to_left (void) const { return lookupFlag & LookupFlag::RightToLeft; } inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; } @@ -716,16 +715,16 @@ main (int argc, char **argv) printf ("Opened font file %s: %d bytes long\n", argv[1], len); - const OpenTypeFontFile &ot = OpenTypeFontFile::get (font_data); + const OpenTypeFontFaceFile &ot = OpenTypeFontFaceFile::get (font_data); switch (ot.tag) { - case OpenTypeFontFile::TrueTypeTag: + case OpenTypeFontFaceFile::TrueTypeTag: printf ("OpenType font with TrueType outlines\n"); break; - case OpenTypeFontFile::CFFTag: + case OpenTypeFontFaceFile::CFFTag: printf ("OpenType font with CFF (Type1) outlines\n"); break; - case OpenTypeFontFile::TTCTag: + case OpenTypeFontFaceFile::TTCTag: printf ("TrueType Collection of OpenType fonts\n"); break; default: @@ -736,7 +735,7 @@ main (int argc, char **argv) int num_fonts = ot.get_len (); printf ("%d font(s) found in file\n", num_fonts); for (int n_font = 0; n_font < num_fonts; n_font++) { - const OpenTypeFont &font = ot[n_font]; + const OpenTypeFontFace &font = ot[n_font]; printf ("Font %d of %d:\n", n_font+1, num_fonts); int num_tables = font.get_len (); @@ -763,8 +762,11 @@ main (int argc, char **argv) printf (" %d language system(s) found in script\n", num_langsys); for (int n_langsys = 0; n_langsys < num_langsys; n_langsys++) { const LangSys &langsys = script[n_langsys]; - printf (" Language System %2d of %2d: %.4s\n", n_langsys+1, num_langsys, - (const char *)script.get_tag(n_langsys)); + printf (" Language System %2d of %2d: %.4s; %d features\n", n_langsys+1, num_langsys, + (const char *)script.get_tag(n_langsys), + langsys.get_len ()); + if (!langsys.get_required_feature_index ()) + printf (" No required feature\n"); } } From 86f450243dbaa82f187cf2d36364e9a59c0e64c7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 27 Dec 2006 19:59:07 -0500 Subject: [PATCH 22/56] Add GPOS stub --- src/harfbuzz-ng.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index ac945788a..97014f994 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -697,6 +697,9 @@ struct GSUBGPOSHeader { struct GSUB : GSUBGPOSHeader { }; +struct GPOS : GSUBGPOSHeader { +}; + #include #include From c46196d09c4ea879bf45182e8a0d649d4c750c39 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 27 Dec 2006 20:05:16 -0500 Subject: [PATCH 23/56] Use union for Coverage --- src/harfbuzz-ng.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index 97014f994..47d7ebe43 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -25,8 +25,6 @@ typedef uint32_t hb_tag_t; */ #define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN) \ - inline NAME (void) { v = 0; } \ - explicit inline NAME (TYPE i) { v = BIG_ENDIAN(i); } \ inline NAME& operator = (TYPE i) { v = BIG_ENDIAN(i); return *this; } \ inline operator TYPE(void) const { return BIG_ENDIAN(v); } \ inline bool operator== (NAME o) const { return v == o.v; } \ @@ -463,7 +461,8 @@ struct CoverageFormat1 { DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); inline int get_coverage (uint16_t glyph_id) const { - GlyphID gid (glyph_id); + GlyphID gid; + gid = glyph_id; // TODO: bsearch for (int i = 0; i < glyphCount; i++) if (gid == glyphArray[i]) @@ -511,27 +510,29 @@ struct CoverageFormat2 { * long */ }; -struct Coverage { +union Coverage { DEFINE_NON_INSTANTIABLE(Coverage); inline unsigned int get_size (void) const { switch (coverageFormat) { - case 1: return ((const CoverageFormat1&)*this).get_size (); - case 2: return ((const CoverageFormat2&)*this).get_size (); - default:return sizeof (Coverage); + case 1: return format1.get_size (); + case 2: return format2.get_size (); + default:return sizeof (coverageFormat); } } /* Returns -1 if not covered. */ inline int get_coverage (uint16_t glyph_id) const { switch (coverageFormat) { - case 1: return ((const CoverageFormat1&)*this).get_coverage(glyph_id); - case 2: return ((const CoverageFormat2&)*this).get_coverage(glyph_id); + case 1: return format1.get_coverage(glyph_id); + case 2: return format2.get_coverage(glyph_id); default:return -1; } } - USHORT coverageFormat; /* Format identifier */ + USHORT coverageFormat; /* Format identifier */ + CoverageFormat1 format1; + CoverageFormat2 format2; }; /* From bf0f9dd61375c5afce8e6b1664d0df5f6c8b2494 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 27 Dec 2006 20:06:42 -0500 Subject: [PATCH 24/56] Use union for ClassDef --- src/harfbuzz-ng.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index 47d7ebe43..ecde88a2b 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -594,22 +594,24 @@ struct ClassDef { inline unsigned int get_size (void) const { switch (classFormat) { - case 1: return ((const ClassDefFormat1&)*this).get_size (); - case 2: return ((const ClassDefFormat2&)*this).get_size (); - default:return sizeof (ClassDef); + case 1: return format1.get_size (); + case 2: return format2.get_size (); + default:return sizeof (classFormat); } } /* Returns 0 if not found. */ inline int get_class (uint16_t glyph_id) const { switch (classFormat) { - case 1: return ((const ClassDefFormat1&)*this).get_class(glyph_id); - case 2: return ((const ClassDefFormat2&)*this).get_class(glyph_id); + case 1: format1.get_class(glyph_id); + case 2: format2.get_class(glyph_id); default:return 0; } } USHORT classFormat; /* Format identifier */ + ClassDefFormat1 format1; + ClassDefFormat2 format2; }; /* From 3158d84b0dfe5032e7c56c03f2da97b8ab549d94 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 27 Dec 2006 20:08:07 -0500 Subject: [PATCH 25/56] Oops. s/OpenTypeFontFaceFile/OpenTypeFontFile/g --- src/harfbuzz-ng.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-ng.cc index ecde88a2b..d23021f0d 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-ng.cc @@ -205,7 +205,7 @@ struct Fixed_Version : Fixed { * Organization of an OpenType Font */ -struct OpenTypeFontFaceFile; +struct OpenTypeFontFile; struct OffsetTable; struct TTCHeader; @@ -251,8 +251,8 @@ struct TTCHeader { * OpenType Font File */ -struct OpenTypeFontFaceFile { - DEFINE_NON_INSTANTIABLE(OpenTypeFontFaceFile); +struct OpenTypeFontFile { + DEFINE_NON_INSTANTIABLE(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'); @@ -260,11 +260,11 @@ struct OpenTypeFontFaceFile { /* Factory: ::get(font_data) * This is how you get a handle to one of these */ - static inline const OpenTypeFontFaceFile& get (const char *font_data) { - return (const OpenTypeFontFaceFile&)*font_data; + static inline const OpenTypeFontFile& get (const char *font_data) { + return (const OpenTypeFontFile&)*font_data; } - static inline OpenTypeFontFaceFile& get (char *font_data) { - return (OpenTypeFontFaceFile&)*font_data; + static inline OpenTypeFontFile& get (char *font_data) { + return (OpenTypeFontFile&)*font_data; } /* This is how you get a table */ @@ -721,16 +721,16 @@ main (int argc, char **argv) printf ("Opened font file %s: %d bytes long\n", argv[1], len); - const OpenTypeFontFaceFile &ot = OpenTypeFontFaceFile::get (font_data); + const OpenTypeFontFile &ot = OpenTypeFontFile::get (font_data); switch (ot.tag) { - case OpenTypeFontFaceFile::TrueTypeTag: + case OpenTypeFontFile::TrueTypeTag: printf ("OpenType font with TrueType outlines\n"); break; - case OpenTypeFontFaceFile::CFFTag: + case OpenTypeFontFile::CFFTag: printf ("OpenType font with CFF (Type1) outlines\n"); break; - case OpenTypeFontFaceFile::TTCTag: + case OpenTypeFontFile::TTCTag: printf ("TrueType Collection of OpenType fonts\n"); break; default: From 12c4568c680ea2b9b98a16a8b7402ca185c90ef6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 28 Dec 2006 06:10:59 -0500 Subject: [PATCH 26/56] Break and rename, in the layout of old HarfBuzz codebase --- src/.gitignore | 1 + src/Makefile | 2 +- src/harfbuzz-common.h | 14 +++ ...harfbuzz-ng.cc => harfbuzz-open-private.h} | 117 +----------------- src/harfbuzz-open.h | 13 ++ src/main.cc | 98 +++++++++++++++ 6 files changed, 133 insertions(+), 112 deletions(-) create mode 100644 src/.gitignore create mode 100644 src/harfbuzz-common.h rename src/{harfbuzz-ng.cc => harfbuzz-open-private.h} (85%) create mode 100644 src/harfbuzz-open.h create mode 100644 src/main.cc diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 000000000..ba2906d06 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +main diff --git a/src/Makefile b/src/Makefile index 55bc4e81c..f5e9ac225 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,3 @@ -all: harfbuzz-ng +all: main CXXFLAGS = -Wall -Wextra `pkg-config --cflags --libs glib-2.0` diff --git a/src/harfbuzz-common.h b/src/harfbuzz-common.h new file mode 100644 index 000000000..b11539fd6 --- /dev/null +++ b/src/harfbuzz-common.h @@ -0,0 +1,14 @@ +#ifndef HARFBUZZ_COMMON_H +#define HARFBUZZ_COMMON_H + +#include + +# ifdef __cplusplus +# define HARFBUZZ_BEGIN_DECLS() extern "C" { extern int harfbuzz_dummy_prototype (int) +# define HARFBUZZ_END_DECLS() } extern "C" int harfbuzz_dummy_prototype (int) +# else /* !__cplusplus */ +# define HARFBUZZ_BEGIN_DECLS() extern int harfbuzz_dummy_prototype (int) +# define HARFBUZZ_END_DECLS() extern int harfbuzz_dummy_prototype (int) +# endif /* !__cplusplus */ + +#endif /* HARFBUZZ_COMMON_H */ diff --git a/src/harfbuzz-ng.cc b/src/harfbuzz-open-private.h similarity index 85% rename from src/harfbuzz-ng.cc rename to src/harfbuzz-open-private.h index d23021f0d..041d2ebc9 100644 --- a/src/harfbuzz-ng.cc +++ b/src/harfbuzz-open-private.h @@ -1,15 +1,12 @@ +#ifndef HARFBUZZ_OPEN_PRIVATE_H +#define HARFBUZZ_OPEN_PRIVATE_H + +#include "harfbuzz-open.h" + #include #include #include -/* Public header */ - -typedef uint32_t hb_tag_t; -#define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d)) - - -/* Implementation */ - /* Macros to convert to/from BigEndian */ #define hb_be_uint8_t #define hb_be_int8_t @@ -697,106 +694,4 @@ struct GSUBGPOSHeader { * GSUB table */ }; -struct GSUB : GSUBGPOSHeader { -}; - -struct GPOS : GSUBGPOSHeader { -}; - - -#include -#include - -int -main (int argc, char **argv) -{ - if (argc != 2) { - fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); - exit (1); - } - - GMappedFile *mf = g_mapped_file_new (argv[1], FALSE, NULL); - const char *font_data = g_mapped_file_get_contents (mf); - int len = g_mapped_file_get_length (mf); - - printf ("Opened font file %s: %d bytes long\n", argv[1], len); - - const OpenTypeFontFile &ot = OpenTypeFontFile::get (font_data); - - switch (ot.tag) { - case OpenTypeFontFile::TrueTypeTag: - printf ("OpenType font with TrueType outlines\n"); - break; - case OpenTypeFontFile::CFFTag: - printf ("OpenType font with CFF (Type1) outlines\n"); - break; - case OpenTypeFontFile::TTCTag: - printf ("TrueType Collection of OpenType fonts\n"); - break; - default: - printf ("Unknown font format\n"); - break; - } - - int num_fonts = ot.get_len (); - printf ("%d font(s) found in file\n", num_fonts); - for (int n_font = 0; n_font < num_fonts; n_font++) { - const OpenTypeFontFace &font = ot[n_font]; - printf ("Font %d of %d:\n", n_font+1, num_fonts); - - int num_tables = font.get_len (); - printf (" %d table(s) found in font\n", num_tables); - for (int n_table = 0; n_table < num_tables; n_table++) { - const OpenTypeTable &table = font[n_table]; - printf (" Table %2d of %2d: %.4s (0x%06x+0x%06x)\n", n_table+1, num_tables, - (const char *)table.tag, (int)table.offset, (int)table.length); - - if (table.tag == "GSUB" || table.tag == "GPOS") { - const GSUBGPOSHeader &g = (const GSUBGPOSHeader&)*ot[table]; - - const ScriptList &scripts = *g.get_script_list(); - int num_scripts = scripts.get_len (); - printf (" %d script(s) found in table\n", num_scripts); - for (int n_script = 0; n_script < num_scripts; n_script++) { - const Script &script = scripts[n_script]; - printf (" Script %2d of %2d: %.4s\n", n_script+1, num_scripts, - (const char *)scripts.get_tag(n_script)); - - if (script.get_default_language_system () == NULL) - printf (" No default language system\n"); - int num_langsys = script.get_len (); - printf (" %d language system(s) found in script\n", num_langsys); - for (int n_langsys = 0; n_langsys < num_langsys; n_langsys++) { - const LangSys &langsys = script[n_langsys]; - printf (" Language System %2d of %2d: %.4s; %d features\n", n_langsys+1, num_langsys, - (const char *)script.get_tag(n_langsys), - langsys.get_len ()); - if (!langsys.get_required_feature_index ()) - printf (" No required feature\n"); - } - } - - const FeatureList &features = *g.get_feature_list(); - int num_features = features.get_len (); - printf (" %d feature(s) found in table\n", num_features); - for (int n_feature = 0; n_feature < num_features; n_feature++) { - const Feature &feature = features[n_feature]; - printf (" Feature %2d of %2d: %.4s; %d lookup(s)\n", n_feature+1, num_features, - (const char *)features.get_tag(n_feature), - (int)feature.lookupCount); - } - - const LookupList &lookups = *g.get_lookup_list(); - int num_lookups = lookups.get_len (); - printf (" %d lookup(s) found in table\n", num_lookups); - for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { - const Lookup &lookup = lookups[n_lookup]; - printf (" Lookup %2d of %2d: type %d, flags %04x\n", n_lookup+1, num_lookups, - (int)lookup.lookupType, (unsigned int)lookup.lookupFlag); - } - } - } - } - - return 0; -} +#endif /* HARFBUZZ_OPEN_PRIVATE_H */ diff --git a/src/harfbuzz-open.h b/src/harfbuzz-open.h new file mode 100644 index 000000000..f52fda704 --- /dev/null +++ b/src/harfbuzz-open.h @@ -0,0 +1,13 @@ +#ifndef HARFBUZZ_OPEN_H +#define HARFBUZZ_OPEN_H + +#include "harfbuzz-common.h" + +HARFBUZZ_BEGIN_DECLS(); + +typedef uint32_t hb_tag_t; +#define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d)) + +HARFBUZZ_END_DECLS(); + +#endif /* HARFBUZZ_OPEN_H */ diff --git a/src/main.cc b/src/main.cc new file mode 100644 index 000000000..d5ddf16b1 --- /dev/null +++ b/src/main.cc @@ -0,0 +1,98 @@ +#include "harfbuzz-open-private.h" + +#include +#include + +int +main (int argc, char **argv) +{ + if (argc != 2) { + fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); + exit (1); + } + + GMappedFile *mf = g_mapped_file_new (argv[1], FALSE, NULL); + const char *font_data = g_mapped_file_get_contents (mf); + int len = g_mapped_file_get_length (mf); + + printf ("Opened font file %s: %d bytes long\n", argv[1], len); + + const OpenTypeFontFile &ot = OpenTypeFontFile::get (font_data); + + switch (ot.tag) { + case OpenTypeFontFile::TrueTypeTag: + printf ("OpenType font with TrueType outlines\n"); + break; + case OpenTypeFontFile::CFFTag: + printf ("OpenType font with CFF (Type1) outlines\n"); + break; + case OpenTypeFontFile::TTCTag: + printf ("TrueType Collection of OpenType fonts\n"); + break; + default: + printf ("Unknown font format\n"); + break; + } + + int num_fonts = ot.get_len (); + printf ("%d font(s) found in file\n", num_fonts); + for (int n_font = 0; n_font < num_fonts; n_font++) { + const OpenTypeFontFace &font = ot[n_font]; + printf ("Font %d of %d:\n", n_font+1, num_fonts); + + int num_tables = font.get_len (); + printf (" %d table(s) found in font\n", num_tables); + for (int n_table = 0; n_table < num_tables; n_table++) { + const OpenTypeTable &table = font[n_table]; + printf (" Table %2d of %2d: %.4s (0x%06x+0x%06x)\n", n_table+1, num_tables, + (const char *)table.tag, (int)table.offset, (int)table.length); + + if (table.tag == "GSUB" || table.tag == "GPOS") { + const GSUBGPOSHeader &g = (const GSUBGPOSHeader&)*ot[table]; + + const ScriptList &scripts = *g.get_script_list(); + int num_scripts = scripts.get_len (); + printf (" %d script(s) found in table\n", num_scripts); + for (int n_script = 0; n_script < num_scripts; n_script++) { + const Script &script = scripts[n_script]; + printf (" Script %2d of %2d: %.4s\n", n_script+1, num_scripts, + (const char *)scripts.get_tag(n_script)); + + if (script.get_default_language_system () == NULL) + printf (" No default language system\n"); + int num_langsys = script.get_len (); + printf (" %d language system(s) found in script\n", num_langsys); + for (int n_langsys = 0; n_langsys < num_langsys; n_langsys++) { + const LangSys &langsys = script[n_langsys]; + printf (" Language System %2d of %2d: %.4s; %d features\n", n_langsys+1, num_langsys, + (const char *)script.get_tag(n_langsys), + langsys.get_len ()); + if (!langsys.get_required_feature_index ()) + printf (" No required feature\n"); + } + } + + const FeatureList &features = *g.get_feature_list(); + int num_features = features.get_len (); + printf (" %d feature(s) found in table\n", num_features); + for (int n_feature = 0; n_feature < num_features; n_feature++) { + const Feature &feature = features[n_feature]; + printf (" Feature %2d of %2d: %.4s; %d lookup(s)\n", n_feature+1, num_features, + (const char *)features.get_tag(n_feature), + (int)feature.lookupCount); + } + + const LookupList &lookups = *g.get_lookup_list(); + int num_lookups = lookups.get_len (); + printf (" %d lookup(s) found in table\n", num_lookups); + for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { + const Lookup &lookup = lookups[n_lookup]; + printf (" Lookup %2d of %2d: type %d, flags %04x\n", n_lookup+1, num_lookups, + (int)lookup.lookupType, (unsigned int)lookup.lookupFlag); + } + } + } + } + + return 0; +} From 193b66d52ae2cb5ced7969e15b7f56dc1978ca8a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 28 Dec 2006 06:12:18 -0500 Subject: [PATCH 27/56] Remove stale comment --- src/harfbuzz-open-private.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h index 041d2ebc9..f3f7ecd57 100644 --- a/src/harfbuzz-open-private.h +++ b/src/harfbuzz-open-private.h @@ -656,16 +656,6 @@ struct Device { - -/* - * - * The Glyph Substitution Table - * - */ - - - - #define DEFINE_LIST_ACCESSOR0(const, Type, name) \ inline const Type##List* get_##name##_list (void) const { \ assert (name##List); \ From b3395a7aa36ff1ba5a17f494fbf359ec317a7e69 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 28 Dec 2006 06:31:18 -0500 Subject: [PATCH 28/56] Don't shift down the mark attachment type --- src/harfbuzz-open-private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h index f3f7ecd57..326e1c637 100644 --- a/src/harfbuzz-open-private.h +++ b/src/harfbuzz-open-private.h @@ -440,7 +440,7 @@ struct Lookup { inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; } inline bool ignore_ligatures (void) const { return lookupFlag & LookupFlag::IgnoreLigatures; } inline bool ignore_marks (void) const { return lookupFlag & LookupFlag::IgnoreMarks; } - inline bool get_mark_attachment_type (void) const { return (lookupFlag & LookupFlag::MarkAttachmentType) >> 8; } + inline bool get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; } USHORT lookupType; /* Different enumerations for GSUB and GPOS */ USHORT lookupFlag; /* Lookup qualifiers */ From 5b3f7702a64fe0513d08a67bdb72704e46fd7cd4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 28 Dec 2006 06:42:37 -0500 Subject: [PATCH 29/56] Add stub GDEF files --- src/harfbuzz-gdef-private.h | 8 ++++++++ src/harfbuzz-gdef.h | 11 +++++++++++ src/harfbuzz-open-private.h | 3 +-- src/harfbuzz-private.h | 6 ++++++ src/main.cc | 1 + 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/harfbuzz-gdef-private.h create mode 100644 src/harfbuzz-gdef.h create mode 100644 src/harfbuzz-private.h diff --git a/src/harfbuzz-gdef-private.h b/src/harfbuzz-gdef-private.h new file mode 100644 index 000000000..0d95dad59 --- /dev/null +++ b/src/harfbuzz-gdef-private.h @@ -0,0 +1,8 @@ +#ifndef HARFBUZZ_GDEF_PRIVATE_H +#define HARFBUZZ_GDEF_PRIVATE_H + +#include "harfbuzz-private.h" +#include "harfbuzz-gdef.h" + + +#endif /* HARFBUZZ_GDEF_PRIVATE_H */ diff --git a/src/harfbuzz-gdef.h b/src/harfbuzz-gdef.h new file mode 100644 index 000000000..35647df7f --- /dev/null +++ b/src/harfbuzz-gdef.h @@ -0,0 +1,11 @@ +#ifndef HARFBUZZ_GDEF_H +#define HARFBUZZ_GDEF_H + +#include "harfbuzz-common.h" + +HARFBUZZ_BEGIN_DECLS(); + + +HARFBUZZ_END_DECLS(); + +#endif /* HARFBUZZ_GDEF_H */ diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h index 326e1c637..0cd3a0ec6 100644 --- a/src/harfbuzz-open-private.h +++ b/src/harfbuzz-open-private.h @@ -1,10 +1,9 @@ #ifndef HARFBUZZ_OPEN_PRIVATE_H #define HARFBUZZ_OPEN_PRIVATE_H +#include "harfbuzz-private.h" #include "harfbuzz-open.h" -#include -#include #include /* Macros to convert to/from BigEndian */ diff --git a/src/harfbuzz-private.h b/src/harfbuzz-private.h new file mode 100644 index 000000000..4d3eb6968 --- /dev/null +++ b/src/harfbuzz-private.h @@ -0,0 +1,6 @@ +#ifndef HARFBUZZ_PRIVATE_H +#define HARFBUZZ_PRIVATE_H + +#include + +#endif /* HARFBUZZ_PRIVATE_H */ diff --git a/src/main.cc b/src/main.cc index d5ddf16b1..4a43bae05 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,4 +1,5 @@ #include "harfbuzz-open-private.h" +#include "harfbuzz-gdef-private.h" #include #include From 151df44346990728b5dd249db5740a9543ae33b9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 5 Jul 2007 17:22:07 -0400 Subject: [PATCH 30/56] Improve stupid Makefile --- src/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Makefile b/src/Makefile index f5e9ac225..56b0da32f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,5 @@ all: main CXXFLAGS = -Wall -Wextra `pkg-config --cflags --libs glib-2.0` + +main: *.h From 5b2e947fd2b7c5ea49b2bef1e0190d99a525058c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 6 Jul 2007 02:03:26 -0400 Subject: [PATCH 31/56] [open] small fixes, including not using unions for main structs --- src/harfbuzz-open-private.h | 54 ++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h index 0cd3a0ec6..9e1bd161d 100644 --- a/src/harfbuzz-open-private.h +++ b/src/harfbuzz-open-private.h @@ -236,7 +236,7 @@ struct TTCHeader { Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ ULONG version; /* Version of the TTC Header (1.0 or 2.0), - * 0x00010000 or 0x00020000 */ + * 0x00010000 or 0x00020000 */ ULONG numFonts; /* Number of fonts in TTC */ ULONG offsetTable[]; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ @@ -506,29 +506,31 @@ struct CoverageFormat2 { * long */ }; -union Coverage { +struct Coverage { DEFINE_NON_INSTANTIABLE(Coverage); inline unsigned int get_size (void) const { - switch (coverageFormat) { - case 1: return format1.get_size (); - case 2: return format2.get_size (); - default:return sizeof (coverageFormat); + switch (u.coverageFormat) { + case 1: return u.format1.get_size (); + case 2: return u.format2.get_size (); + default:return sizeof (u.coverageFormat); } } /* Returns -1 if not covered. */ inline int get_coverage (uint16_t glyph_id) const { - switch (coverageFormat) { - case 1: return format1.get_coverage(glyph_id); - case 2: return format2.get_coverage(glyph_id); + switch (u.coverageFormat) { + case 1: return u.format1.get_coverage(glyph_id); + case 2: return u.format2.get_coverage(glyph_id); default:return -1; } } + union { USHORT coverageFormat; /* Format identifier */ CoverageFormat1 format1; CoverageFormat2 format2; + } u; }; /* @@ -589,25 +591,27 @@ struct ClassDef { DEFINE_NON_INSTANTIABLE(ClassDef); inline unsigned int get_size (void) const { - switch (classFormat) { - case 1: return format1.get_size (); - case 2: return format2.get_size (); - default:return sizeof (classFormat); + switch (u.classFormat) { + case 1: return u.format1.get_size (); + case 2: return u.format2.get_size (); + default:return sizeof (u.classFormat); } } /* Returns 0 if not found. */ inline int get_class (uint16_t glyph_id) const { - switch (classFormat) { - case 1: format1.get_class(glyph_id); - case 2: format2.get_class(glyph_id); + switch (u.classFormat) { + case 1: u.format1.get_class(glyph_id); + case 2: u.format2.get_class(glyph_id); default:return 0; } } + union { USHORT classFormat; /* Format identifier */ ClassDefFormat1 format1; ClassDefFormat2 format2; + } u; }; /* @@ -627,7 +631,7 @@ struct Device { } } - inline int get_delta (int ppem_size) { + inline int get_delta (int ppem_size) const { if (ppem_size >= startSize && ppem_size <= endSize && deltaFormat >= 1 && deltaFormat <= 3) { int s = ppem_size - startSize; @@ -673,14 +677,14 @@ struct GSUBGPOSHeader { DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list and feature(i) */ DEFINE_LIST_ACCESSOR(Lookup, lookup); /* get_lookup_list and lookup(i) */ - Fixed_Version version; /* Version of the GSUB table-initially set to - * 0x00010000 */ - Offset scriptList; /* Offset to ScriptList table-from beginning of - * GSUB table */ - Offset featureList; /* Offset to FeatureList table-from beginning of - * GSUB table */ - Offset lookupList; /* Offset to LookupList table-from beginning of - * GSUB table */ + Fixed_Version version; /* Version of the GSUB/GPOS table--initially set + * to 0x00010000 */ + Offset scriptList; /* Offset to ScriptList table--from beginning of + * GSUB/GPOS table */ + Offset featureList; /* Offset to FeatureList table--from beginning of + * GSUB/GPOS table */ + Offset lookupList; /* Offset to LookupList table--from beginning of + * GSUB/GPOS table */ }; #endif /* HARFBUZZ_OPEN_PRIVATE_H */ From 4c2556cb4c38a56c3a5087deb54aa6262ab3aff9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 6 Jul 2007 11:29:21 -0400 Subject: [PATCH 32/56] [gdef] Initial implementation --- src/harfbuzz-gdef-private.h | 144 +++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 2 deletions(-) diff --git a/src/harfbuzz-gdef-private.h b/src/harfbuzz-gdef-private.h index 0d95dad59..91083c09e 100644 --- a/src/harfbuzz-gdef-private.h +++ b/src/harfbuzz-gdef-private.h @@ -1,8 +1,148 @@ #ifndef HARFBUZZ_GDEF_PRIVATE_H #define HARFBUZZ_GDEF_PRIVATE_H -#include "harfbuzz-private.h" -#include "harfbuzz-gdef.h" +#include "harfbuzz-open-private.h" +struct GDEFHeader { + Fixed version; /* Version of the GDEF table--initially + * 0x00010000 */ + Offset glyphClassDef; /* Offset to class definition table + * for glyph type--from beginning of + * GDEF header (may be NULL) */ + Offset attachList; /* Offset to list of glyphs with + * attachment points--from beginning + * of GDEF header (may be NULL) */ + Offset ligCaretList; /* Offset to list of positioning points + * for ligature carets--from beginning + * of GDEF header (may be NULL) */ + Offset markAttachClassDef; /* Offset to class definition table for + * mark attachment type--from beginning + * of GDEF header (may be NULL) */ +}; + +struct GlyphClassDef : ClassDef { + static const uint16_t BaseGlyph = 0x0001u; + static const uint16_t LigatureGlyph = 0x0002u; + static const uint16_t MarkGlyph = 0x0003u; + static const uint16_t ComponentGlyph = 0x0004u; +}; + + +struct AttachList { + /* XXX */ + + Offset coverage; /* Offset to Coverage table -- from + * beginning of AttachList table */ + USHORT glyphCount; /* Number of glyphs with attachment + * points */ + Offset attachPoint[]; /* Array of offsets to AttachPoint + * tables--from beginning of AttachList + * table--in Coverage Index order */ +}; + +struct AttachPoint { + /* XXX */ + + USHORT pointCount; /* Number of attachment points on + * this glyph */ + USHORT pointIndex[]; /* Array of contour point indices--in + * increasing numerical order */ +}; + +/* + * Ligature Caret Table + */ + +struct CaretValue; + +struct LigCaretList { + /* XXX */ + + Offset coverage; /* Offset to Coverage table--from + * beginning of LigCaretList table */ + USHORT ligGlyphCount; /* Number of ligature glyphs */ + Offset ligGlyph[]; /* Array of offsets to LigGlyph + * tables--from beginning of + * LigCaretList table--in Coverage + * Index order */ +}; + +struct LigGlyph { + /* Caret value tables, in increasing coordinate order */ + DEFINE_OFFSET_ARRAY_TYPE (CaretValue, caretValue, caretCount); + /* XXX */ + + USHORT caretCount; /* Number of CaretValues for this + * ligature (components - 1) */ + Offset caretValue[]; /* Array of offsets to CaretValue + * tables--from beginning of LigGlyph + * table--in increasing coordinate + * order */ +}; + +struct CaretValueFormat1 { + USHORT caretValueFormat; /* Format identifier--format = 1 */ + SHORT coordinate; /* X or Y value, in design units */ + + inline int get_caret_value (int ppem) const { + return /* XXX garbage */ coordinate / ppem; + } +}; + +struct CaretValueFormat2 { + USHORT caretValueFormat; /* Format identifier--format = 2 */ + USHORT caretValuePoint; /* Contour point index on glyph */ + + inline int get_caret_value (int ppem) const { + return /* XXX garbage */ 0 / ppem; + } +}; + +struct CaretValueFormat3 { + inline const Device* get_device (void) const { + return (const Device*)((const char*)this + deviceTable); + } + + USHORT caretValueFormat; /* Format identifier--format = 3 */ + SHORT coordinate; /* X or Y value, in design units */ + Offset deviceTable; /* Offset to Device table for X or Y + * value--from beginning of CaretValue + * table */ + + inline int get_caret_value (int ppem) const { + return /* XXX garbage */ (coordinate + get_device()->get_delta (ppem)) / ppem; + } +}; + +struct CaretValue { + DEFINE_NON_INSTANTIABLE(CaretValue); + + inline unsigned int get_size (void) const { + switch (u.caretValueFormat) { + case 1: return sizeof (u.format1); + case 2: return sizeof (u.format2); + case 3: return sizeof (u.format3); + default:return sizeof (u.caretValueFormat); + } + } + + /* XXX we need access to a load-contour-point vfunc here */ + inline int get_caret_value (int ppem) const { + switch (u.caretValueFormat) { + case 1: return u.format1.get_caret_value(ppem); + case 2: return u.format2.get_caret_value(ppem); + case 3: return u.format3.get_caret_value(ppem); + default:return 0; + } + } + + union { + USHORT caretValueFormat; /* Format identifier */ + CaretValueFormat1 format1; + CaretValueFormat2 format2; + CaretValueFormat3 format3; + /* XXX old HarfBuzz code has a format 4 here! */ + } u; +}; #endif /* HARFBUZZ_GDEF_PRIVATE_H */ From 303fe62824d4e99df554b6bfaacba05d068522fb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 00:20:48 -0500 Subject: [PATCH 33/56] Misc cleanup --- src/Makefile | 10 +++- src/harfbuzz-gdef-private.h | 67 +++++++++++++++++------ src/harfbuzz-open-private.h | 102 ++++++++++++++++++++++++++++++++---- src/harfbuzz-private.h | 6 +++ src/main.cc | 12 ++--- 5 files changed, 164 insertions(+), 33 deletions(-) diff --git a/src/Makefile b/src/Makefile index 56b0da32f..816269b47 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,11 @@ all: main -CXXFLAGS = -Wall -Wextra `pkg-config --cflags --libs glib-2.0` +CPPFLAGS = -Wall -Wextra `pkg-config --cflags glib-2.0` +LDFLAGS = `pkg-config --libs glib-2.0` +CXX = gcc $(GCCOPTS) -fno-rtti -fno-exceptions -Wabi -Wpadded -Wcast-align -main: *.h +main: main.cc *.h + $(CXX) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< + +clean: + rm -f main main.o diff --git a/src/harfbuzz-gdef-private.h b/src/harfbuzz-gdef-private.h index 91083c09e..135f1c476 100644 --- a/src/harfbuzz-gdef-private.h +++ b/src/harfbuzz-gdef-private.h @@ -4,6 +4,9 @@ #include "harfbuzz-open-private.h" struct GDEFHeader { + /* TODO */ + + private: Fixed version; /* Version of the GDEF table--initially * 0x00010000 */ Offset glyphClassDef; /* Offset to class definition table @@ -19,6 +22,7 @@ struct GDEFHeader { * mark attachment type--from beginning * of GDEF header (may be NULL) */ }; +ASSERT_SIZE (GDEFHeader, 12); struct GlyphClassDef : ClassDef { static const uint16_t BaseGlyph = 0x0001u; @@ -27,10 +31,24 @@ struct GlyphClassDef : ClassDef { static const uint16_t ComponentGlyph = 0x0004u; }; +struct AttachPoint; struct AttachList { - /* XXX */ + /* AttachPoint tables, in Coverage Index order */ + /* TODO get attach lists */ +/* DEFINE_INDIRECT_OFFSET_ARRAY_TYPE (AttachPoint, attachPoint, glyphCount, get_coverage); +// get_coverage + + inline Coverage* get_default_language_system (void) { + if (!defaultLangSys) + return NULL; + return (LangSys *)((char*)this + defaultLangSys); + } + +*/ + + private: Offset coverage; /* Offset to Coverage table -- from * beginning of AttachList table */ USHORT glyphCount; /* Number of glyphs with attachment @@ -39,15 +57,18 @@ struct AttachList { * tables--from beginning of AttachList * table--in Coverage Index order */ }; +ASSERT_SIZE (AttachList, 4); struct AttachPoint { - /* XXX */ + /* TODO */ + private: USHORT pointCount; /* Number of attachment points on * this glyph */ USHORT pointIndex[]; /* Array of contour point indices--in * increasing numerical order */ }; +ASSERT_SIZE (AttachPoint, 2); /* * Ligature Caret Table @@ -56,8 +77,9 @@ struct AttachPoint { struct CaretValue; struct LigCaretList { - /* XXX */ + /* TODO */ + private: Offset coverage; /* Offset to Coverage table--from * beginning of LigCaretList table */ USHORT ligGlyphCount; /* Number of ligature glyphs */ @@ -66,12 +88,14 @@ struct LigCaretList { * LigCaretList table--in Coverage * Index order */ }; +ASSERT_SIZE (LigCaretList, 4); struct LigGlyph { /* Caret value tables, in increasing coordinate order */ DEFINE_OFFSET_ARRAY_TYPE (CaretValue, caretValue, caretCount); - /* XXX */ + /* TODO */ + private: USHORT caretCount; /* Number of CaretValues for this * ligature (components - 1) */ Offset caretValue[]; /* Array of offsets to CaretValue @@ -79,40 +103,50 @@ struct LigGlyph { * table--in increasing coordinate * order */ }; +ASSERT_SIZE (LigGlyph, 2); struct CaretValueFormat1 { + + inline int get_caret_value (int ppem) const { + return /* TODO garbage */ coordinate / ppem; + } + + private: USHORT caretValueFormat; /* Format identifier--format = 1 */ SHORT coordinate; /* X or Y value, in design units */ - - inline int get_caret_value (int ppem) const { - return /* XXX garbage */ coordinate / ppem; - } }; +ASSERT_SIZE (CaretValueFormat1, 4); struct CaretValueFormat2 { - USHORT caretValueFormat; /* Format identifier--format = 2 */ - USHORT caretValuePoint; /* Contour point index on glyph */ inline int get_caret_value (int ppem) const { - return /* XXX garbage */ 0 / ppem; + return /* TODO garbage */ 0 / ppem; } + + private: + USHORT caretValueFormat; /* Format identifier--format = 2 */ + USHORT caretValuePoint; /* Contour point index on glyph */ }; +ASSERT_SIZE (CaretValueFormat2, 4); struct CaretValueFormat3 { + inline const Device* get_device (void) const { return (const Device*)((const char*)this + deviceTable); } + inline int get_caret_value (int ppem) const { + return /* TODO garbage */ (coordinate + get_device()->get_delta (ppem)) / ppem; + } + + private: USHORT caretValueFormat; /* Format identifier--format = 3 */ SHORT coordinate; /* X or Y value, in design units */ Offset deviceTable; /* Offset to Device table for X or Y * value--from beginning of CaretValue * table */ - - inline int get_caret_value (int ppem) const { - return /* XXX garbage */ (coordinate + get_device()->get_delta (ppem)) / ppem; - } }; +ASSERT_SIZE (CaretValueFormat3, 6); struct CaretValue { DEFINE_NON_INSTANTIABLE(CaretValue); @@ -136,12 +170,13 @@ struct CaretValue { } } + private: union { USHORT caretValueFormat; /* Format identifier */ CaretValueFormat1 format1; CaretValueFormat2 format2; CaretValueFormat3 format3; - /* XXX old HarfBuzz code has a format 4 here! */ + /* FIXME old HarfBuzz code has a format 4 here! */ } u; }; diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h index 9e1bd161d..ded36ace5 100644 --- a/src/harfbuzz-open-private.h +++ b/src/harfbuzz-open-private.h @@ -115,23 +115,38 @@ * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ -DEFINE_INT_TYPE_STRUCT (BYTE, u, 8); /* 8-bit unsigned integer. */ -DEFINE_INT_TYPE_STRUCT (CHAR, , 8); /* 8-bit signed integer. */ -DEFINE_INT_TYPE_STRUCT (USHORT, u, 16); /* 16-bit unsigned integer. */ +DEFINE_INT_TYPE_STRUCT (BYTE, u, 8); /* 8-bit unsigned integer. */ +ASSERT_SIZE (BYTE, 1); +DEFINE_INT_TYPE_STRUCT (CHAR, , 8); /* 8-bit signed integer. */ +ASSERT_SIZE (CHAR, 1); +DEFINE_INT_TYPE_STRUCT (USHORT, u, 16); /* 16-bit unsigned integer. */ +ASSERT_SIZE (USHORT, 2); DEFINE_INT_TYPE_STRUCT (SHORT, , 16); /* 16-bit signed integer. */ +ASSERT_SIZE (SHORT, 2); DEFINE_INT_TYPE_STRUCT (ULONG, u, 32); /* 32-bit unsigned integer. */ +ASSERT_SIZE (ULONG, 4); DEFINE_INT_TYPE_STRUCT (LONG, , 32); /* 32-bit signed integer. */ +ASSERT_SIZE (LONG, 4); /* Date represented in number of seconds since 12:00 midnight, January 1, * 1904. The value is represented as a signed 64-bit integer. */ DEFINE_INT_TYPE_STRUCT (LONGDATETIME, , 64); /* 32-bit signed fixed-point number (16.16) */ -struct Fixed : LONG { +struct Fixed { + inline Fixed& operator = (int32_t v) { i = (int16_t) (v >> 16); f = (uint16_t) v; return *this; } \ + inline operator int32_t(void) const { return (((int32_t) i) << 16) + (uint16_t) f; } \ + inline bool operator== (Fixed o) const { return i == o.i && f == o.f; } \ + inline operator double(void) const { return (uint32_t) this / 65536.; } - inline int16_t int_part (void) const { return (uint32_t) this >> 16; } - inline int16_t frac_part (void) const { return (uint32_t) this & 0xffff; } + inline int16_t int_part (void) const { return i; } + inline uint16_t frac_part (void) const { return f; } + + private: + SHORT i; + USHORT f; }; +ASSERT_SIZE (Fixed, 4); /* Smallest measurable distance in the em space. */ struct FUNIT; @@ -139,15 +154,18 @@ struct FUNIT; /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ struct FWORD : SHORT { }; +ASSERT_SIZE (FWORD, 2); /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ struct UFWORD : USHORT { }; +ASSERT_SIZE (UFWORD, 2); /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ struct F2DOT14 : SHORT { inline operator double() const { return (uint32_t) this / 16384.; } }; +ASSERT_SIZE (F2DOT14, 2); /* Array of four uint8s (length = 32 bits) used to identify a script, language * system, feature, or baseline */ @@ -162,14 +180,18 @@ struct Tag { inline operator const char* (void) const { return (const char *)this; } inline operator char* (void) { return (char *)this; } - private: char v[4]; + private: + char v[4]; }; +ASSERT_SIZE (Tag, 4); /* Glyph index number, same as uint16 (length = 16 bits) */ DEFINE_INT_TYPE_STRUCT (GlyphID, u, 16); +ASSERT_SIZE (GlyphID, 2); /* Offset to a table, same as uint16 (length = 16 bits), NULL offset = 0x0000 */ DEFINE_INT_TYPE_STRUCT (Offset, u, 16); +ASSERT_SIZE (Offset, 2); /* CheckSum */ struct CheckSum : ULONG { @@ -182,6 +204,7 @@ struct CheckSum : ULONG { return Sum; } }; +ASSERT_SIZE (CheckSum, 4); /* @@ -190,11 +213,13 @@ struct CheckSum : ULONG { struct USHORT_Version : USHORT { }; +ASSERT_SIZE (USHORT_Version, 2); struct Fixed_Version : Fixed { inline int16_t major (void) const { return this->int_part(); } inline int16_t minor (void) const { return this->frac_part(); } }; +ASSERT_SIZE (Fixed_Version, 4); /* @@ -206,18 +231,29 @@ struct OffsetTable; struct TTCHeader; typedef struct TableDirectory { + + friend struct OpenTypeFontFile; + + inline const Tag& get_tag (void) const { return tag; } + inline unsigned long get_checksum (void) const { return checkSum; } + inline unsigned long get_offset (void) const { return offset; } + inline unsigned long get_length (void) const { return length; } + + private: Tag tag; /* 4-byte identifier. */ CheckSum checkSum; /* CheckSum for this table. */ ULONG offset; /* Offset from beginning of TrueType font * file. */ ULONG length; /* Length of this table. */ } OpenTypeTable; +ASSERT_SIZE (TableDirectory, 16); typedef struct OffsetTable { /* OpenTypeTables, in no particular order */ DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables); // TODO: Implement find_table + private: Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */ USHORT numTables; /* Number of tables. */ USHORT searchRange; /* (Maximum power of 2 <= numTables) x 16 */ @@ -225,6 +261,7 @@ typedef struct OffsetTable { USHORT rangeShift; /* NumTables x 16-searchRange. */ TableDirectory tableDir[]; /* TableDirectory entries. numTables items */ } OpenTypeFontFace; +ASSERT_SIZE (OffsetTable, 12); /* * TrueType Collections @@ -234,6 +271,7 @@ struct TTCHeader { /* OpenTypeFontFaces, in no particular order */ DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); + private: Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ ULONG version; /* Version of the TTC Header (1.0 or 2.0), * 0x00010000 or 0x00020000 */ @@ -241,6 +279,7 @@ struct TTCHeader { ULONG offsetTable[]; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ }; +ASSERT_SIZE (TTCHeader, 12); /* @@ -299,9 +338,12 @@ struct OpenTypeFontFile { case TTCTag: return ((TTCHeader&)*this)[i]; } } + inline const Tag& get_tag (void) const { return tag; } + private: Tag tag; /* 4-byte identifier. */ }; +ASSERT_SIZE (OpenTypeFontFile, 4); @@ -328,15 +370,18 @@ typedef struct Record { Offset offset; /* Offset from beginning of object holding * the Record */ } ScriptRecord, LangSysRecord, FeatureRecord; +ASSERT_SIZE (Record, 6); struct ScriptList { /* Scripts, in sorted alphabetical tag order */ DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); + private: USHORT scriptCount; /* Number of ScriptRecords */ ScriptRecord scriptRecord[]; /* Array of ScriptRecords--listed alphabetically * by ScriptTag */ }; +ASSERT_SIZE (ScriptList, 2); struct Script { /* LangSys', in sorted alphabetical tag order */ @@ -354,6 +399,7 @@ struct Script { return (LangSys *)((char*)this + defaultLangSys); } + private: Offset defaultLangSys; /* Offset to DefaultLangSys table--from * beginning of Script table--may be NULL */ USHORT langSysCount; /* Number of LangSysRecords for this script-- @@ -361,6 +407,7 @@ struct Script { LangSysRecord langSysRecord[];/* Array of LangSysRecords--listed * alphabetically by LangSysTag */ }; +ASSERT_SIZE (Script, 4); struct LangSys { /* Feature indices, in no particular order */ @@ -373,6 +420,7 @@ struct LangSys { return reqFeatureIndex;; } + private: Offset lookupOrder; /* = NULL (reserved for an offset to a * reordering table) */ USHORT reqFeatureIndex;/* Index of a feature required for this @@ -384,16 +432,19 @@ struct LangSys { USHORT featureIndex[]; /* Array of indices into the FeatureList--in * arbitrary order. featureCount entires long */ }; +ASSERT_SIZE (LangSys, 6); struct FeatureList { /* Feature indices, in sorted alphabetical tag order */ DEFINE_RECORD_ARRAY_TYPE (Feature, featureRecord, featureCount); + private: USHORT featureCount; /* Number of FeatureRecords in this table */ FeatureRecord featureRecord[];/* Array of FeatureRecords--zero-based (first * feature has FeatureIndex = 0)--listed * alphabetically by FeatureTag */ }; +ASSERT_SIZE (FeatureList, 2); struct Feature { /* LookupList indices, in no particular order */ @@ -401,6 +452,7 @@ struct Feature { // TODO: implement get_feature_params() + private: Offset featureParams; /* Offset to Feature Parameters table (if one * has been defined for the feature), relative * to the beginning of the Feature Table; = NULL @@ -411,16 +463,19 @@ struct Feature { * feature--zero-based (first lookup is * LookupListIndex = 0) */ }; +ASSERT_SIZE (Feature, 4); struct LookupList { /* Lookup indices, in sorted alphabetical tag order */ DEFINE_OFFSET_ARRAY_TYPE (Lookup, lookupOffset, lookupCount); + private: USHORT lookupCount; /* Number of lookups in this table */ Offset lookupOffset[]; /* Array of offsets to Lookup tables--from * beginning of LookupList--zero based (first * lookup is Lookup index = 0) */ }; +ASSERT_SIZE (LookupList, 2); struct LookupFlag : USHORT { static const uint16_t RightToLeft = 0x0001u; @@ -430,6 +485,7 @@ struct LookupFlag : USHORT { static const uint16_t Reserved = 0x00F0u; static const uint16_t MarkAttachmentType = 0xFF00u; }; +ASSERT_SIZE (LookupFlag, 2); struct Lookup { /* SubTables, in the desired order */ @@ -441,12 +497,17 @@ struct Lookup { inline bool ignore_marks (void) const { return lookupFlag & LookupFlag::IgnoreMarks; } inline bool get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; } + inline uint16_t get_type (void) const { return lookupType; } + inline uint16_t get_flag (void) const { return lookupFlag; } + + private: USHORT lookupType; /* Different enumerations for GSUB and GPOS */ USHORT lookupFlag; /* Lookup qualifiers */ USHORT subTableCount; /* Number of SubTables for this lookup */ Offset subTableOffset[];/* Array of offsets to SubTables-from * beginning of Lookup table */ }; +ASSERT_SIZE (Lookup, 6); /* * Coverage Table @@ -466,10 +527,12 @@ struct CoverageFormat1 { return -1; } + private: USHORT coverageFormat; /* Format identifier--format = 1 */ USHORT glyphCount; /* Number of glyphs in the GlyphArray */ GlyphID glyphArray[]; /* Array of GlyphIDs--in numerical order */ }; +ASSERT_SIZE (CoverageFormat1, 4); struct CoverageRangeRecord { @@ -479,11 +542,13 @@ struct CoverageRangeRecord { return -1; } + private: GlyphID start; /* First GlyphID in the range */ GlyphID end; /* Last GlyphID in the range */ USHORT startCoverageIndex; /* Coverage Index of first GlyphID in * range */ }; +ASSERT_SIZE (CoverageRangeRecord, 6); struct CoverageFormat2 { /* CoverageRangeRecords, in sorted numerical start order */ @@ -499,12 +564,14 @@ struct CoverageFormat2 { return -1; } + private: USHORT coverageFormat; /* Format identifier--format = 2 */ USHORT rangeCount; /* Number of CoverageRangeRecords */ CoverageRangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by * Start GlyphID. rangeCount entries * long */ }; +ASSERT_SIZE (CoverageFormat2, 4); struct Coverage { DEFINE_NON_INSTANTIABLE(Coverage); @@ -526,6 +593,7 @@ struct Coverage { } } + private: union { USHORT coverageFormat; /* Format identifier */ CoverageFormat1 format1; @@ -547,11 +615,13 @@ struct ClassDefFormat1 { return 0; } + private: USHORT classFormat; /* Format identifier--format = 1 */ GlyphID startGlyph; /* First GlyphID of the classValueArray */ USHORT glyphCount; /* Size of the classValueArray */ USHORT classValueArray[]; /* Array of Class Values--one per GlyphID */ }; +ASSERT_SIZE (ClassDefFormat1, 6); struct ClassRangeRecord { @@ -561,11 +631,12 @@ struct ClassRangeRecord { return 0; } + private: GlyphID start; /* First GlyphID in the range */ GlyphID end; /* Last GlyphID in the range */ - USHORT classValue; /* Applied to all glyphs in the range - */ + USHORT classValue; /* Applied to all glyphs in the range */ }; +ASSERT_SIZE (ClassRangeRecord, 6); struct ClassDefFormat2 { /* ClassRangeRecords, in sorted numerical start order */ @@ -581,11 +652,13 @@ struct ClassDefFormat2 { return 0; } + private: USHORT classFormat; /* Format identifier--format = 2 */ USHORT rangeCount; /* Number of Number of ClassRangeRecords */ ClassRangeRecord rangeRecord[]; /* Array of glyph ranges--ordered by * Start GlyphID */ }; +ASSERT_SIZE (ClassDefFormat2, 4); struct ClassDef { DEFINE_NON_INSTANTIABLE(ClassDef); @@ -607,6 +680,7 @@ struct ClassDef { } } + private: union { USHORT classFormat; /* Format identifier */ ClassDefFormat1 format1; @@ -651,11 +725,13 @@ struct Device { return 0; } + private: USHORT startSize; /* Smallest size to correct--in ppem */ USHORT endSize; /* Largest size to correct--in ppem */ USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 */ USHORT deltaValue[]; /* Array of compressed data */ }; +ASSERT_SIZE (Device, 6); @@ -673,10 +749,17 @@ struct Device { struct GSUBGPOSHeader { +/* + inline unsigned int get_size (void) const { + return offsetof (GSUBGPOSHeader, padding); + } + */ + DEFINE_LIST_ACCESSOR(Script, script); /* get_script_list and script(i) */ DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list and feature(i) */ DEFINE_LIST_ACCESSOR(Lookup, lookup); /* get_lookup_list and lookup(i) */ + private: Fixed_Version version; /* Version of the GSUB/GPOS table--initially set * to 0x00010000 */ Offset scriptList; /* Offset to ScriptList table--from beginning of @@ -686,5 +769,6 @@ struct GSUBGPOSHeader { Offset lookupList; /* Offset to LookupList table--from beginning of * GSUB/GPOS table */ }; +ASSERT_SIZE (GSUBGPOSHeader, 10); #endif /* HARFBUZZ_OPEN_PRIVATE_H */ diff --git a/src/harfbuzz-private.h b/src/harfbuzz-private.h index 4d3eb6968..05b7ccc33 100644 --- a/src/harfbuzz-private.h +++ b/src/harfbuzz-private.h @@ -3,4 +3,10 @@ #include +#define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] +#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond)) +#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) + +#define ASSERT_SIZE(_type, _size) ASSERT_STATIC (sizeof (_type) == (_size)) + #endif /* HARFBUZZ_PRIVATE_H */ diff --git a/src/main.cc b/src/main.cc index 4a43bae05..dd2990bb2 100644 --- a/src/main.cc +++ b/src/main.cc @@ -20,7 +20,7 @@ main (int argc, char **argv) const OpenTypeFontFile &ot = OpenTypeFontFile::get (font_data); - switch (ot.tag) { + switch (ot.get_tag()) { case OpenTypeFontFile::TrueTypeTag: printf ("OpenType font with TrueType outlines\n"); break; @@ -45,10 +45,10 @@ main (int argc, char **argv) printf (" %d table(s) found in font\n", num_tables); for (int n_table = 0; n_table < num_tables; n_table++) { const OpenTypeTable &table = font[n_table]; - printf (" Table %2d of %2d: %.4s (0x%06x+0x%06x)\n", n_table+1, num_tables, - (const char *)table.tag, (int)table.offset, (int)table.length); + printf (" Table %2d of %2d: %.4s (0x%08lx+0x%08lx)\n", n_table+1, num_tables, + (const char *)table.get_tag(), table.get_offset(), table.get_length()); - if (table.tag == "GSUB" || table.tag == "GPOS") { + if (table.get_tag() == "GSUB" || table.get_tag() == "GPOS") { const GSUBGPOSHeader &g = (const GSUBGPOSHeader&)*ot[table]; const ScriptList &scripts = *g.get_script_list(); @@ -80,7 +80,7 @@ main (int argc, char **argv) const Feature &feature = features[n_feature]; printf (" Feature %2d of %2d: %.4s; %d lookup(s)\n", n_feature+1, num_features, (const char *)features.get_tag(n_feature), - (int)feature.lookupCount); + feature.get_len()); } const LookupList &lookups = *g.get_lookup_list(); @@ -89,7 +89,7 @@ main (int argc, char **argv) for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { const Lookup &lookup = lookups[n_lookup]; printf (" Lookup %2d of %2d: type %d, flags %04x\n", n_lookup+1, num_lookups, - (int)lookup.lookupType, (unsigned int)lookup.lookupFlag); + lookup.get_type(), lookup.get_flag()); } } } From b9d7688fb3d45894901484b74095c4f11cab6196 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 01:38:10 -0500 Subject: [PATCH 34/56] Finish and test GDEF --- src/harfbuzz-gdef-private.h | 72 ++++++++++++++++++++++++++----------- src/harfbuzz-open-private.h | 23 ++++++------ src/harfbuzz-open.h | 4 +++ src/main.cc | 10 ++++++ 4 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/harfbuzz-gdef-private.h b/src/harfbuzz-gdef-private.h index 135f1c476..182012755 100644 --- a/src/harfbuzz-gdef-private.h +++ b/src/harfbuzz-gdef-private.h @@ -3,27 +3,6 @@ #include "harfbuzz-open-private.h" -struct GDEFHeader { - /* TODO */ - - private: - Fixed version; /* Version of the GDEF table--initially - * 0x00010000 */ - Offset glyphClassDef; /* Offset to class definition table - * for glyph type--from beginning of - * GDEF header (may be NULL) */ - Offset attachList; /* Offset to list of glyphs with - * attachment points--from beginning - * of GDEF header (may be NULL) */ - Offset ligCaretList; /* Offset to list of positioning points - * for ligature carets--from beginning - * of GDEF header (may be NULL) */ - Offset markAttachClassDef; /* Offset to class definition table for - * mark attachment type--from beginning - * of GDEF header (may be NULL) */ -}; -ASSERT_SIZE (GDEFHeader, 12); - struct GlyphClassDef : ClassDef { static const uint16_t BaseGlyph = 0x0001u; static const uint16_t LigatureGlyph = 0x0002u; @@ -180,4 +159,55 @@ struct CaretValue { } u; }; + +#define DEFINE_ACCESSOR0(const, Type, name, Name) \ + inline const Type* name (void) const { \ + if (!Name) return NULL; \ + return (const Type *)((const char*)this + Name); \ + } +#define DEFINE_ACCESSOR(Type, name, Name) \ + DEFINE_ACCESSOR0(const, Type, name, Name) \ + DEFINE_ACCESSOR0( , Type, name, Name) + +struct GDEFHeader { + + DEFINE_ACCESSOR (ClassDef, get_glyph_class_def, glyphClassDef); + DEFINE_ACCESSOR (AttachList, get_attach_list, attachList); + DEFINE_ACCESSOR (LigCaretList, get_lig_caret_list, ligCaretList); + DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef); + + /* Returns 0 if not found. */ + inline int get_glyph_class (uint16_t glyph_id) const { + const ClassDef *class_def = get_glyph_class_def (); + if (!class_def) return 0; + return class_def->get_class (glyph_id); + } + + /* Returns 0 if not found. */ + inline int get_mark_attachment_type (uint16_t glyph_id) const { + const ClassDef *class_def = get_mark_attach_class_def (); + if (!class_def) return 0; + return class_def->get_class (glyph_id); + } + + /* TODO get_attach and get_lig_caret */ + + private: + Fixed version; /* Version of the GDEF table--initially + * 0x00010000 */ + Offset glyphClassDef; /* Offset to class definition table + * for glyph type--from beginning of + * GDEF header (may be NULL) */ + Offset attachList; /* Offset to list of glyphs with + * attachment points--from beginning + * of GDEF header (may be NULL) */ + Offset ligCaretList; /* Offset to list of positioning points + * for ligature carets--from beginning + * of GDEF header (may be NULL) */ + Offset markAttachClassDef; /* Offset to class definition table for + * mark attachment type--from beginning + * of GDEF header (may be NULL) */ +}; +ASSERT_SIZE (GDEFHeader, 12); + #endif /* HARFBUZZ_GDEF_PRIVATE_H */ diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h index ded36ace5..57f1bd332 100644 --- a/src/harfbuzz-open-private.h +++ b/src/harfbuzz-open-private.h @@ -175,6 +175,7 @@ struct Tag { inline Tag (const char *c) { v[0] = c[0]; v[1] = c[1]; v[2] = c[2]; v[3] = c[3]; } inline bool operator== (Tag o) const { return v[0]==o.v[0]&&v[1]==o.v[1]&&v[2]==o.v[2]&&v[3]==o.v[3]; } inline bool operator== (const char *c) const { return v[0]==c[0]&&v[1]==c[1]&&v[2]==c[2]&&v[3]==c[3]; } + inline bool operator== (uint32_t i) const { return i == (uint32_t) *this; } inline operator uint32_t(void) const { return (v[0]<<24)+(v[1]<<16) +(v[2]<<8)+v[3]; } /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ inline operator const char* (void) const { return (const char *)this; } @@ -399,6 +400,8 @@ struct Script { return (LangSys *)((char*)this + defaultLangSys); } + /* TODO implement find_language_system based on find_tag */ + private: Offset defaultLangSys; /* Offset to DefaultLangSys table--from * beginning of Script table--may be NULL */ @@ -420,6 +423,8 @@ struct LangSys { return reqFeatureIndex;; } + /* TODO implement find_feature */ + private: Offset lookupOrder; /* = NULL (reserved for an offset to a * reordering table) */ @@ -674,8 +679,8 @@ struct ClassDef { /* Returns 0 if not found. */ inline int get_class (uint16_t glyph_id) const { switch (u.classFormat) { - case 1: u.format1.get_class(glyph_id); - case 2: u.format2.get_class(glyph_id); + case 1: return u.format1.get_class(glyph_id); + case 2: return u.format2.get_class(glyph_id); default:return 0; } } @@ -740,7 +745,7 @@ ASSERT_SIZE (Device, 6); assert (name##List); \ return (const Type##List *)((const char*)this + name##List); \ } \ - inline const Type& name (unsigned int i) const { \ + inline const Type& get_##name (unsigned int i) const { \ return (*get_##name##_list())[i]; \ } #define DEFINE_LIST_ACCESSOR(Type, name) \ @@ -749,15 +754,11 @@ ASSERT_SIZE (Device, 6); struct GSUBGPOSHeader { -/* - inline unsigned int get_size (void) const { - return offsetof (GSUBGPOSHeader, padding); - } - */ + DEFINE_LIST_ACCESSOR(Script, script); /* get_script_list, get_script(i) */ + DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list, get_feature(i) */ + DEFINE_LIST_ACCESSOR(Lookup, lookup); /* get_lookup_list, get_lookup(i) */ - DEFINE_LIST_ACCESSOR(Script, script); /* get_script_list and script(i) */ - DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list and feature(i) */ - DEFINE_LIST_ACCESSOR(Lookup, lookup); /* get_lookup_list and lookup(i) */ + /* TODO implement find_script */ private: Fixed_Version version; /* Version of the GSUB/GPOS table--initially set diff --git a/src/harfbuzz-open.h b/src/harfbuzz-open.h index f52fda704..370bbdf32 100644 --- a/src/harfbuzz-open.h +++ b/src/harfbuzz-open.h @@ -7,6 +7,10 @@ HARFBUZZ_BEGIN_DECLS(); typedef uint32_t hb_tag_t; #define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d)) +#define HB_TAG_STR(s) (HB_TAG(((const char *) s)[0], \ + ((const char *) s)[1], \ + ((const char *) s)[2], \ + ((const char *) s)[3])) HARFBUZZ_END_DECLS(); diff --git a/src/main.cc b/src/main.cc index dd2990bb2..62e7cf05f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -91,6 +91,16 @@ main (int argc, char **argv) printf (" Lookup %2d of %2d: type %d, flags %04x\n", n_lookup+1, num_lookups, lookup.get_type(), lookup.get_flag()); } + } else if (table.get_tag() == "GDEF") { + const GDEFHeader &gdef = (const GDEFHeader&)*ot[table]; + + /* + for (int glyph = 0; glyph < 1000; glyph++) + printf (" glyph %d has class %d and mark attachment type %d\n", + glyph, + gdef.get_glyph_class (glyph), + gdef.get_mark_attachment_type (glyph)); + */ } } } From 600e5eb80f553ea8eb862e6784133574c74ca513 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 02:01:37 -0500 Subject: [PATCH 35/56] Define get_for_data() factories --- src/harfbuzz-gdef-private.h | 3 +++ src/harfbuzz-open-private.h | 42 +++++++++++++++++++++++++------------ src/main.cc | 10 ++++----- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/harfbuzz-gdef-private.h b/src/harfbuzz-gdef-private.h index 182012755..db3ab982d 100644 --- a/src/harfbuzz-gdef-private.h +++ b/src/harfbuzz-gdef-private.h @@ -170,6 +170,9 @@ struct CaretValue { DEFINE_ACCESSOR0( , Type, name, Name) struct GDEFHeader { + static const hb_tag_t GDEFTag = HB_TAG ('G','D','E','F'); + + STATIC_DEFINE_GET_FOR_DATA (GDEFHeader); DEFINE_ACCESSOR (ClassDef, get_glyph_class_def, glyphClassDef); DEFINE_ACCESSOR (AttachList, get_attach_list, attachList); diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h index 57f1bd332..4633ef145 100644 --- a/src/harfbuzz-open-private.h +++ b/src/harfbuzz-open-private.h @@ -49,10 +49,6 @@ DEFINE_LEN(Type, array, num) \ DEFINE_SIZE(Type, array, num) -#define DEFINE_NON_INSTANTIABLE(Type) \ - private: inline Type() {} /* cannot be instantiated */ \ - public: - /* An array type is one that contains a variable number of objects * as its last item. An array object is extended with len() and size() * methods, as well as overloaded [] operator. */ @@ -98,6 +94,30 @@ + +/* + * Class features + */ + +/* makes class uninstantiable. should be used for union classes that don't + * contain any complete type */ +#define DEFINE_NON_INSTANTIABLE(Type) \ + private: inline Type() {} /* cannot be instantiated */ \ + public: + +/* get_for_data() is a static class method returning a reference to an + * instance of Type located at the input data location. It's just a + * fancy cast! */ +#define STATIC_DEFINE_GET_FOR_DATA0(const, Type) \ + static inline const Type& get_for_data (const char *data) { \ + return *(const Type*)data; \ + } +#define STATIC_DEFINE_GET_FOR_DATA(Type) \ + STATIC_DEFINE_GET_FOR_DATA0(const, Type) \ + STATIC_DEFINE_GET_FOR_DATA0( , Type) + + + /* * * The OpenType Font File @@ -293,15 +313,7 @@ struct OpenTypeFontFile { static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O'); static const hb_tag_t TTCTag = HB_TAG ('t','t','c','f'); - /* Factory: ::get(font_data) - * This is how you get a handle to one of these - */ - static inline const OpenTypeFontFile& get (const char *font_data) { - return (const OpenTypeFontFile&)*font_data; - } - static inline OpenTypeFontFile& get (char *font_data) { - return (OpenTypeFontFile&)*font_data; - } + STATIC_DEFINE_GET_FOR_DATA (OpenTypeFontFile); /* This is how you get a table */ inline const char* get_table (const OpenTypeTable& table) const { @@ -753,6 +765,10 @@ ASSERT_SIZE (Device, 6); DEFINE_LIST_ACCESSOR0( , Type, name) struct GSUBGPOSHeader { + static const hb_tag_t GSUBTag = HB_TAG ('G','S','U','B'); + static const hb_tag_t GPOSTag = HB_TAG ('G','P','O','S'); + + STATIC_DEFINE_GET_FOR_DATA (GSUBGPOSHeader); DEFINE_LIST_ACCESSOR(Script, script); /* get_script_list, get_script(i) */ DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list, get_feature(i) */ diff --git a/src/main.cc b/src/main.cc index 62e7cf05f..313723e9b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -18,7 +18,7 @@ main (int argc, char **argv) printf ("Opened font file %s: %d bytes long\n", argv[1], len); - const OpenTypeFontFile &ot = OpenTypeFontFile::get (font_data); + const OpenTypeFontFile &ot = OpenTypeFontFile::get_for_data (font_data); switch (ot.get_tag()) { case OpenTypeFontFile::TrueTypeTag: @@ -49,7 +49,7 @@ main (int argc, char **argv) (const char *)table.get_tag(), table.get_offset(), table.get_length()); if (table.get_tag() == "GSUB" || table.get_tag() == "GPOS") { - const GSUBGPOSHeader &g = (const GSUBGPOSHeader&)*ot[table]; + const GSUBGPOSHeader &g = GSUBGPOSHeader::get_for_data (ot[table]); const ScriptList &scripts = *g.get_script_list(); int num_scripts = scripts.get_len (); @@ -92,15 +92,13 @@ main (int argc, char **argv) lookup.get_type(), lookup.get_flag()); } } else if (table.get_tag() == "GDEF") { - const GDEFHeader &gdef = (const GDEFHeader&)*ot[table]; + const GDEFHeader &gdef = GDEFHeader::get_for_data (ot[table]); - /* - for (int glyph = 0; glyph < 1000; glyph++) + for (int glyph = 0; glyph < 1; glyph++) printf (" glyph %d has class %d and mark attachment type %d\n", glyph, gdef.get_glyph_class (glyph), gdef.get_mark_attachment_type (glyph)); - */ } } } From 1f437e6f47fb6c15761021bd2078f31778f2179c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 04:36:40 -0500 Subject: [PATCH 36/56] Make all code NULL-free and assert-free --- src/harfbuzz-gdef-private.h | 125 +++++++-------- src/harfbuzz-open-private.h | 309 +++++++++++++++++++----------------- src/main.cc | 8 +- 3 files changed, 226 insertions(+), 216 deletions(-) diff --git a/src/harfbuzz-gdef-private.h b/src/harfbuzz-gdef-private.h index db3ab982d..6e0f4e31d 100644 --- a/src/harfbuzz-gdef-private.h +++ b/src/harfbuzz-gdef-private.h @@ -10,22 +10,34 @@ struct GlyphClassDef : ClassDef { static const uint16_t ComponentGlyph = 0x0004u; }; -struct AttachPoint; +/* + * Attachment List Table + */ + +struct AttachPoint { + /* countour point indices, in increasing numerical order */ + DEFINE_ARRAY_TYPE (USHORT, pointIndex, pointCount); + + private: + USHORT pointCount; /* Number of attachment points on + * this glyph */ + USHORT pointIndex[]; /* Array of contour point indices--in + * increasing numerical order */ +}; +DEFINE_NULL_ASSERT_SIZE (AttachPoint, 2); struct AttachList { - /* AttachPoint tables, in Coverage Index order */ - /* TODO get attach lists */ -/* DEFINE_INDIRECT_OFFSET_ARRAY_TYPE (AttachPoint, attachPoint, glyphCount, get_coverage); -// get_coverage - - inline Coverage* get_default_language_system (void) { - if (!defaultLangSys) - return NULL; - return (LangSys *)((char*)this + defaultLangSys); + inline const AttachPoint* get_attach_points (uint16_t glyph_id) { + const Coverage &c = get_coverage (); + int c_index = c.get_coverage (glyph_id); + return &(*this)[c_index]; } -*/ + private: + /* AttachPoint tables, in Coverage Index order */ + DEFINE_OFFSET_ARRAY_TYPE (AttachPoint, attachPoint, glyphCount); + DEFINE_ACCESSOR (Coverage, get_coverage, coverage); private: Offset coverage; /* Offset to Coverage table -- from @@ -36,18 +48,7 @@ struct AttachList { * tables--from beginning of AttachList * table--in Coverage Index order */ }; -ASSERT_SIZE (AttachList, 4); - -struct AttachPoint { - /* TODO */ - - private: - USHORT pointCount; /* Number of attachment points on - * this glyph */ - USHORT pointIndex[]; /* Array of contour point indices--in - * increasing numerical order */ -}; -ASSERT_SIZE (AttachPoint, 2); +DEFINE_NULL_ASSERT_SIZE (AttachList, 4); /* * Ligature Caret Table @@ -67,22 +68,7 @@ struct LigCaretList { * LigCaretList table--in Coverage * Index order */ }; -ASSERT_SIZE (LigCaretList, 4); - -struct LigGlyph { - /* Caret value tables, in increasing coordinate order */ - DEFINE_OFFSET_ARRAY_TYPE (CaretValue, caretValue, caretCount); - /* TODO */ - - private: - USHORT caretCount; /* Number of CaretValues for this - * ligature (components - 1) */ - Offset caretValue[]; /* Array of offsets to CaretValue - * tables--from beginning of LigGlyph - * table--in increasing coordinate - * order */ -}; -ASSERT_SIZE (LigGlyph, 2); +DEFINE_NULL_ASSERT_SIZE (LigCaretList, 4); struct CaretValueFormat1 { @@ -94,7 +80,7 @@ struct CaretValueFormat1 { USHORT caretValueFormat; /* Format identifier--format = 1 */ SHORT coordinate; /* X or Y value, in design units */ }; -ASSERT_SIZE (CaretValueFormat1, 4); +DEFINE_NULL_ASSERT_SIZE (CaretValueFormat1, 4); struct CaretValueFormat2 { @@ -106,16 +92,17 @@ struct CaretValueFormat2 { USHORT caretValueFormat; /* Format identifier--format = 2 */ USHORT caretValuePoint; /* Contour point index on glyph */ }; -ASSERT_SIZE (CaretValueFormat2, 4); +DEFINE_NULL_ASSERT_SIZE (CaretValueFormat2, 4); struct CaretValueFormat3 { - inline const Device* get_device (void) const { - return (const Device*)((const char*)this + deviceTable); + inline const Device& get_device (void) const { + if (!deviceTable) return NullDevice; + return *(const Device*)((const char*)this + deviceTable); } inline int get_caret_value (int ppem) const { - return /* TODO garbage */ (coordinate + get_device()->get_delta (ppem)) / ppem; + return /* TODO garbage */ (coordinate + get_device().get_delta (ppem)) / ppem; } private: @@ -125,7 +112,7 @@ struct CaretValueFormat3 { * value--from beginning of CaretValue * table */ }; -ASSERT_SIZE (CaretValueFormat3, 6); +DEFINE_NULL_ASSERT_SIZE (CaretValueFormat3, 6); struct CaretValue { DEFINE_NON_INSTANTIABLE(CaretValue); @@ -158,16 +145,26 @@ struct CaretValue { /* FIXME old HarfBuzz code has a format 4 here! */ } u; }; +DEFINE_NULL (CaretValue, 2); +struct LigGlyph { + /* Caret value tables, in increasing coordinate order */ + DEFINE_OFFSET_ARRAY_TYPE (CaretValue, caretValue, caretCount); + /* TODO */ -#define DEFINE_ACCESSOR0(const, Type, name, Name) \ - inline const Type* name (void) const { \ - if (!Name) return NULL; \ - return (const Type *)((const char*)this + Name); \ - } -#define DEFINE_ACCESSOR(Type, name, Name) \ - DEFINE_ACCESSOR0(const, Type, name, Name) \ - DEFINE_ACCESSOR0( , Type, name, Name) + private: + USHORT caretCount; /* Number of CaretValues for this + * ligature (components - 1) */ + Offset caretValue[]; /* Array of offsets to CaretValue + * tables--from beginning of LigGlyph + * table--in increasing coordinate + * order */ +}; +DEFINE_NULL_ASSERT_SIZE (LigGlyph, 2); + +/* + * GDEF Header + */ struct GDEFHeader { static const hb_tag_t GDEFTag = HB_TAG ('G','D','E','F'); @@ -181,18 +178,18 @@ struct GDEFHeader { /* Returns 0 if not found. */ inline int get_glyph_class (uint16_t glyph_id) const { - const ClassDef *class_def = get_glyph_class_def (); - if (!class_def) return 0; - return class_def->get_class (glyph_id); + const ClassDef &class_def = get_glyph_class_def (); + return class_def.get_class (glyph_id); } /* Returns 0 if not found. */ inline int get_mark_attachment_type (uint16_t glyph_id) const { - const ClassDef *class_def = get_mark_attach_class_def (); - if (!class_def) return 0; - return class_def->get_class (glyph_id); + const ClassDef &class_def = get_mark_attach_class_def (); + return class_def.get_class (glyph_id); } + /* TODO get_glyph_property */ + /* TODO get_attach and get_lig_caret */ private: @@ -200,17 +197,17 @@ struct GDEFHeader { * 0x00010000 */ Offset glyphClassDef; /* Offset to class definition table * for glyph type--from beginning of - * GDEF header (may be NULL) */ + * GDEF header (may be Null) */ Offset attachList; /* Offset to list of glyphs with * attachment points--from beginning - * of GDEF header (may be NULL) */ + * of GDEF header (may be Null) */ Offset ligCaretList; /* Offset to list of positioning points * for ligature carets--from beginning - * of GDEF header (may be NULL) */ + * of GDEF header (may be Null) */ Offset markAttachClassDef; /* Offset to class definition table for * mark attachment type--from beginning - * of GDEF header (may be NULL) */ + * of GDEF header (may be Null) */ }; -ASSERT_SIZE (GDEFHeader, 12); +DEFINE_NULL_ASSERT_SIZE (GDEFHeader, 12); #endif /* HARFBUZZ_GDEF_PRIVATE_H */ diff --git a/src/harfbuzz-open-private.h b/src/harfbuzz-open-private.h index 4633ef145..9db304474 100644 --- a/src/harfbuzz-open-private.h +++ b/src/harfbuzz-open-private.h @@ -53,12 +53,11 @@ * as its last item. An array object is extended with len() and size() * methods, as well as overloaded [] operator. */ #define DEFINE_ARRAY_TYPE(Type, array, num) \ - DEFINE_INDEX_OPERATOR(const, Type, array, num) \ - DEFINE_INDEX_OPERATOR( , Type, array, num) \ + DEFINE_INDEX_OPERATOR(Type, array, num) \ DEFINE_LEN_AND_SIZE(Type, array, num) -#define DEFINE_INDEX_OPERATOR(const, Type, array, num) \ +#define DEFINE_INDEX_OPERATOR(Type, array, num) \ inline const Type& operator[] (unsigned int i) const { \ - assert (i < num); \ + if (i >= num) return Null##Type; \ return array[i]; \ } @@ -66,34 +65,42 @@ * of offsets to the objects, relative to the beginning of the current * object. */ #define DEFINE_OFFSET_ARRAY_TYPE(Type, array, num) \ - DEFINE_OFFSET_INDEX_OPERATOR(const, Type, array, num) \ - DEFINE_OFFSET_INDEX_OPERATOR( , Type, array, num) \ + DEFINE_OFFSET_INDEX_OPERATOR(Type, array, num) \ DEFINE_LEN_AND_SIZE(Offset, array, num) -#define DEFINE_OFFSET_INDEX_OPERATOR(const, Type, array, num) \ +#define DEFINE_OFFSET_INDEX_OPERATOR(Type, array, num) \ inline const Type& operator[] (unsigned int i) const { \ - assert (i < num); \ - assert (array[i]); /* TODO: should just skip them */ \ + if (i >= num) return Null##Type; \ + if (!array[i]) return Null##Type; \ return *(const Type *)((const char*)this + array[i]); \ } #define DEFINE_RECORD_ARRAY_TYPE(Type, array, num) \ - DEFINE_RECORD_ACCESSOR(const, Type, array, num) \ - DEFINE_RECORD_ACCESSOR( , Type, array, num) \ + DEFINE_RECORD_ACCESSOR(Type, array, num) \ DEFINE_LEN_AND_SIZE(Record, array, num) -#define DEFINE_RECORD_ACCESSOR(const, Type, array, num) \ +#define DEFINE_RECORD_ACCESSOR(Type, array, num) \ inline const Type& operator[] (unsigned int i) const { \ - assert (i < num); \ - assert (array[i].offset); /* TODO: should just skip them */ \ + if (i >= num) return Null##Type; \ + if (!array[i].offset) return Null##Type; \ return *(const Type *)((const char*)this + array[i].offset); \ } \ inline const Tag& get_tag (unsigned int i) const { \ - assert (i < num); \ + if (i >= num) return NullTag; \ return array[i].tag; \ } \ /* TODO: implement find_tag() */ +/* + * List types + */ - +#define DEFINE_LIST_ACCESSOR(Type, name) \ + inline const Type##List& get_##name##_list (void) const { \ + if (!name##List) return Null##Type##List; \ + return *(const Type##List *)((const char*)this + name##List); \ + } \ + inline const Type& get_##name (unsigned int i) const { \ + return get_##name##_list()[i]; \ + } /* * Class features @@ -105,6 +112,20 @@ private: inline Type() {} /* cannot be instantiated */ \ public: +/* defines Null##Type as a safe nil instance of Type */ +#define DEFINE_NULL_DATA(Type, size, data) \ + static const unsigned char Null##Type##Data[size] = data; \ + DEFINE_NULL_ALIAS (Type, Type) +#define DEFINE_NULL(Type, size) \ + DEFINE_NULL_DATA(Type, size, "") +#define DEFINE_NULL_ASSERT_SIZE(Type, size) \ + DEFINE_NULL_ASSERT_SIZE_DATA(Type, size, "") +#define DEFINE_NULL_ASSERT_SIZE_DATA(Type, size, data) \ + ASSERT_SIZE (Type, size); \ + DEFINE_NULL_DATA (Type, size, data) +#define DEFINE_NULL_ALIAS(NewType, OldType) \ + static const NewType &Null##NewType = *(NewType *)Null##OldType##Data + /* get_for_data() is a static class method returning a reference to an * instance of Type located at the input data location. It's just a * fancy cast! */ @@ -117,6 +138,13 @@ STATIC_DEFINE_GET_FOR_DATA0( , Type) +#define DEFINE_ACCESSOR(Type, name, Name) \ + inline const Type& name (void) const { \ + if (!Name) return Null##Type; \ + return *(const Type*)((const char*)this + Name); \ + } + + /* * @@ -136,17 +164,17 @@ DEFINE_INT_TYPE_STRUCT (BYTE, u, 8); /* 8-bit unsigned integer. */ -ASSERT_SIZE (BYTE, 1); +DEFINE_NULL_ASSERT_SIZE (BYTE, 1); DEFINE_INT_TYPE_STRUCT (CHAR, , 8); /* 8-bit signed integer. */ -ASSERT_SIZE (CHAR, 1); +DEFINE_NULL_ASSERT_SIZE (CHAR, 1); DEFINE_INT_TYPE_STRUCT (USHORT, u, 16); /* 16-bit unsigned integer. */ -ASSERT_SIZE (USHORT, 2); +DEFINE_NULL_ASSERT_SIZE (USHORT, 2); DEFINE_INT_TYPE_STRUCT (SHORT, , 16); /* 16-bit signed integer. */ -ASSERT_SIZE (SHORT, 2); +DEFINE_NULL_ASSERT_SIZE (SHORT, 2); DEFINE_INT_TYPE_STRUCT (ULONG, u, 32); /* 32-bit unsigned integer. */ -ASSERT_SIZE (ULONG, 4); +DEFINE_NULL_ASSERT_SIZE (ULONG, 4); DEFINE_INT_TYPE_STRUCT (LONG, , 32); /* 32-bit signed integer. */ -ASSERT_SIZE (LONG, 4); +DEFINE_NULL_ASSERT_SIZE (LONG, 4); /* Date represented in number of seconds since 12:00 midnight, January 1, * 1904. The value is represented as a signed 64-bit integer. */ @@ -166,7 +194,7 @@ struct Fixed { SHORT i; USHORT f; }; -ASSERT_SIZE (Fixed, 4); +DEFINE_NULL_ASSERT_SIZE (Fixed, 4); /* Smallest measurable distance in the em space. */ struct FUNIT; @@ -174,18 +202,18 @@ struct FUNIT; /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ struct FWORD : SHORT { }; -ASSERT_SIZE (FWORD, 2); +DEFINE_NULL_ASSERT_SIZE (FWORD, 2); /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ struct UFWORD : USHORT { }; -ASSERT_SIZE (UFWORD, 2); +DEFINE_NULL_ASSERT_SIZE (UFWORD, 2); /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ struct F2DOT14 : SHORT { inline operator double() const { return (uint32_t) this / 16384.; } }; -ASSERT_SIZE (F2DOT14, 2); +DEFINE_NULL_ASSERT_SIZE (F2DOT14, 2); /* Array of four uint8s (length = 32 bits) used to identify a script, language * system, feature, or baseline */ @@ -205,14 +233,15 @@ struct Tag { char v[4]; }; ASSERT_SIZE (Tag, 4); +DEFINE_NULL_DATA (Tag, 5, " "); /* Glyph index number, same as uint16 (length = 16 bits) */ DEFINE_INT_TYPE_STRUCT (GlyphID, u, 16); -ASSERT_SIZE (GlyphID, 2); +DEFINE_NULL_ASSERT_SIZE (GlyphID, 2); -/* Offset to a table, same as uint16 (length = 16 bits), NULL offset = 0x0000 */ +/* Offset to a table, same as uint16 (length = 16 bits), Null offset = 0x0000 */ DEFINE_INT_TYPE_STRUCT (Offset, u, 16); -ASSERT_SIZE (Offset, 2); +DEFINE_NULL_ASSERT_SIZE (Offset, 2); /* CheckSum */ struct CheckSum : ULONG { @@ -225,7 +254,7 @@ struct CheckSum : ULONG { return Sum; } }; -ASSERT_SIZE (CheckSum, 4); +DEFINE_NULL_ASSERT_SIZE (CheckSum, 4); /* @@ -234,13 +263,13 @@ ASSERT_SIZE (CheckSum, 4); struct USHORT_Version : USHORT { }; -ASSERT_SIZE (USHORT_Version, 2); +DEFINE_NULL_ASSERT_SIZE (USHORT_Version, 2); struct Fixed_Version : Fixed { inline int16_t major (void) const { return this->int_part(); } inline int16_t minor (void) const { return this->frac_part(); } }; -ASSERT_SIZE (Fixed_Version, 4); +DEFINE_NULL_ASSERT_SIZE (Fixed_Version, 4); /* @@ -267,7 +296,7 @@ typedef struct TableDirectory { * file. */ ULONG length; /* Length of this table. */ } OpenTypeTable; -ASSERT_SIZE (TableDirectory, 16); +DEFINE_NULL_ASSERT_SIZE (TableDirectory, 16); typedef struct OffsetTable { /* OpenTypeTables, in no particular order */ @@ -282,7 +311,8 @@ typedef struct OffsetTable { USHORT rangeShift; /* NumTables x 16-searchRange. */ TableDirectory tableDir[]; /* TableDirectory entries. numTables items */ } OpenTypeFontFace; -ASSERT_SIZE (OffsetTable, 12); +DEFINE_NULL_ASSERT_SIZE (OffsetTable, 12); +DEFINE_NULL_ALIAS (OpenTypeFontFace, OffsetTable); /* * TrueType Collections @@ -300,7 +330,7 @@ struct TTCHeader { ULONG offsetTable[]; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ }; -ASSERT_SIZE (TTCHeader, 12); +DEFINE_NULL_ASSERT_SIZE (TTCHeader, 12); /* @@ -338,25 +368,18 @@ struct OpenTypeFontFile { } } inline const OpenTypeFontFace& operator[] (unsigned int i) const { - assert (i < get_len ()); + if (i >= get_len ()) return NullOpenTypeFontFace; switch (tag) { default: case TrueTypeTag: case CFFTag: return (const OffsetTable&)*this; case TTCTag: return ((const TTCHeader&)*this)[i]; } } - inline OpenTypeFontFace& operator[] (unsigned int i) { - assert (i < get_len ()); - switch (tag) { - default: case TrueTypeTag: case CFFTag: return (OffsetTable&)*this; - case TTCTag: return ((TTCHeader&)*this)[i]; - } - } inline const Tag& get_tag (void) const { return tag; } private: Tag tag; /* 4-byte identifier. */ }; -ASSERT_SIZE (OpenTypeFontFile, 4); +DEFINE_NULL_ASSERT_SIZE (OpenTypeFontFile, 4); @@ -370,59 +393,12 @@ ASSERT_SIZE (OpenTypeFontFile, 4); * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList */ -struct Script; -struct ScriptList; -struct LangSys; -struct Feature; -struct FeatureList; -struct Lookup; -struct LookupList; - typedef struct Record { Tag tag; /* 4-byte Tag identifier */ Offset offset; /* Offset from beginning of object holding * the Record */ } ScriptRecord, LangSysRecord, FeatureRecord; -ASSERT_SIZE (Record, 6); - -struct ScriptList { - /* Scripts, in sorted alphabetical tag order */ - DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); - - private: - USHORT scriptCount; /* Number of ScriptRecords */ - ScriptRecord scriptRecord[]; /* Array of ScriptRecords--listed alphabetically - * by ScriptTag */ -}; -ASSERT_SIZE (ScriptList, 2); - -struct Script { - /* LangSys', in sorted alphabetical tag order */ - DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); - - /* Return NULL if none */ - inline const LangSys* get_default_language_system (void) const { - if (!defaultLangSys) - return NULL; - return (const LangSys *)((const char*)this + defaultLangSys); - } - inline LangSys* get_default_language_system (void) { - if (!defaultLangSys) - return NULL; - return (LangSys *)((char*)this + defaultLangSys); - } - - /* TODO implement find_language_system based on find_tag */ - - private: - Offset defaultLangSys; /* Offset to DefaultLangSys table--from - * beginning of Script table--may be NULL */ - USHORT langSysCount; /* Number of LangSysRecords for this script-- - * excluding the DefaultLangSys */ - LangSysRecord langSysRecord[];/* Array of LangSysRecords--listed - * alphabetically by LangSysTag */ -}; -ASSERT_SIZE (Script, 4); +DEFINE_NULL_ASSERT_SIZE (Record, 6); struct LangSys { /* Feature indices, in no particular order */ @@ -438,7 +414,7 @@ struct LangSys { /* TODO implement find_feature */ private: - Offset lookupOrder; /* = NULL (reserved for an offset to a + Offset lookupOrder; /* = Null (reserved for an offset to a * reordering table) */ USHORT reqFeatureIndex;/* Index of a feature required for this * language system--if no required features @@ -449,7 +425,60 @@ struct LangSys { USHORT featureIndex[]; /* Array of indices into the FeatureList--in * arbitrary order. featureCount entires long */ }; -ASSERT_SIZE (LangSys, 6); +DEFINE_NULL_ASSERT_SIZE_DATA (LangSys, 6, "\0\0\xFF\xFF"); + +struct Script { + /* LangSys', in sorted alphabetical tag order */ + DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); + + inline const bool has_default_language_system (void) const { + return defaultLangSys != 0; + } + inline const LangSys& get_default_language_system (void) const { + if (!defaultLangSys) + return NullLangSys; + return *(LangSys*)((const char*)this + defaultLangSys); + } + + /* TODO implement find_language_system based on find_tag */ + + private: + Offset defaultLangSys; /* Offset to DefaultLangSys table--from + * beginning of Script table--may be Null */ + USHORT langSysCount; /* Number of LangSysRecords for this script-- + * excluding the DefaultLangSys */ + LangSysRecord langSysRecord[];/* Array of LangSysRecords--listed + * alphabetically by LangSysTag */ +}; +DEFINE_NULL_ASSERT_SIZE (Script, 4); + +struct ScriptList { + /* Scripts, in sorted alphabetical tag order */ + DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); + +private: + USHORT scriptCount; /* Number of ScriptRecords */ + ScriptRecord scriptRecord[]; /* Array of ScriptRecords--listed alphabetically + * by ScriptTag */ +}; +DEFINE_NULL_ASSERT_SIZE (ScriptList, 2); + +struct Feature { + /* LookupList indices, in no particular order */ + DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount); + + private: + Offset featureParams; /* Offset to Feature Parameters table (if one + * has been defined for the feature), relative + * to the beginning of the Feature Table; = Null + * if not required */ + USHORT lookupCount; /* Number of LookupList indices for this + * feature */ + USHORT lookupIndex[]; /* Array of LookupList indices for this + * feature--zero-based (first lookup is + * LookupListIndex = 0) */ +}; +DEFINE_NULL_ASSERT_SIZE (Feature, 4); struct FeatureList { /* Feature indices, in sorted alphabetical tag order */ @@ -461,38 +490,7 @@ struct FeatureList { * feature has FeatureIndex = 0)--listed * alphabetically by FeatureTag */ }; -ASSERT_SIZE (FeatureList, 2); - -struct Feature { - /* LookupList indices, in no particular order */ - DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount); - - // TODO: implement get_feature_params() - - private: - Offset featureParams; /* Offset to Feature Parameters table (if one - * has been defined for the feature), relative - * to the beginning of the Feature Table; = NULL - * if not required */ - USHORT lookupCount; /* Number of LookupList indices for this - * feature */ - USHORT lookupIndex[]; /* Array of LookupList indices for this - * feature--zero-based (first lookup is - * LookupListIndex = 0) */ -}; -ASSERT_SIZE (Feature, 4); - -struct LookupList { - /* Lookup indices, in sorted alphabetical tag order */ - DEFINE_OFFSET_ARRAY_TYPE (Lookup, lookupOffset, lookupCount); - - private: - USHORT lookupCount; /* Number of lookups in this table */ - Offset lookupOffset[]; /* Array of offsets to Lookup tables--from - * beginning of LookupList--zero based (first - * lookup is Lookup index = 0) */ -}; -ASSERT_SIZE (LookupList, 2); +DEFINE_NULL_ASSERT_SIZE (FeatureList, 2); struct LookupFlag : USHORT { static const uint16_t RightToLeft = 0x0001u; @@ -502,11 +500,20 @@ struct LookupFlag : USHORT { static const uint16_t Reserved = 0x00F0u; static const uint16_t MarkAttachmentType = 0xFF00u; }; -ASSERT_SIZE (LookupFlag, 2); +DEFINE_NULL_ASSERT_SIZE (LookupFlag, 2); + +struct LookupSubTable { + DEFINE_NON_INSTANTIABLE(LookupSubTable); + + private: + USHORT format; /* Subtable format. Different for GSUB and GPOS */ +}; +DEFINE_NULL_ASSERT_SIZE (LookupSubTable, 2); + struct Lookup { /* SubTables, in the desired order */ - DEFINE_OFFSET_ARRAY_TYPE (char*, subTableOffset, subTableCount); + DEFINE_OFFSET_ARRAY_TYPE (LookupSubTable, subTableOffset, subTableCount); inline bool is_right_to_left (void) const { return lookupFlag & LookupFlag::RightToLeft; } inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; } @@ -524,7 +531,19 @@ struct Lookup { Offset subTableOffset[];/* Array of offsets to SubTables-from * beginning of Lookup table */ }; -ASSERT_SIZE (Lookup, 6); +DEFINE_NULL_ASSERT_SIZE (Lookup, 6); + +struct LookupList { + /* Lookup indices, in sorted alphabetical tag order */ + DEFINE_OFFSET_ARRAY_TYPE (Lookup, lookupOffset, lookupCount); + + private: + USHORT lookupCount; /* Number of lookups in this table */ + Offset lookupOffset[]; /* Array of offsets to Lookup tables--from + * beginning of LookupList--zero based (first + * lookup is Lookup index = 0) */ +}; +DEFINE_NULL_ASSERT_SIZE (LookupList, 2); /* * Coverage Table @@ -565,7 +584,7 @@ struct CoverageRangeRecord { USHORT startCoverageIndex; /* Coverage Index of first GlyphID in * range */ }; -ASSERT_SIZE (CoverageRangeRecord, 6); +DEFINE_NULL_ASSERT_SIZE_DATA (CoverageRangeRecord, 6, "\001"); struct CoverageFormat2 { /* CoverageRangeRecords, in sorted numerical start order */ @@ -617,6 +636,7 @@ struct Coverage { CoverageFormat2 format2; } u; }; +DEFINE_NULL (Coverage, 2); /* * Class Definition Table @@ -653,7 +673,7 @@ struct ClassRangeRecord { GlyphID end; /* Last GlyphID in the range */ USHORT classValue; /* Applied to all glyphs in the range */ }; -ASSERT_SIZE (ClassRangeRecord, 6); +DEFINE_NULL_ASSERT_SIZE_DATA (ClassRangeRecord, 6, "\001"); struct ClassDefFormat2 { /* ClassRangeRecords, in sorted numerical start order */ @@ -704,6 +724,7 @@ struct ClassDef { ClassDefFormat2 format2; } u; }; +DEFINE_NULL (ClassDef, 2); /* * Device Tables @@ -748,23 +769,13 @@ struct Device { USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 */ USHORT deltaValue[]; /* Array of compressed data */ }; -ASSERT_SIZE (Device, 6); +DEFINE_NULL_ASSERT_SIZE (Device, 6); +/* + * GSUB/GPOS Header + */ - -#define DEFINE_LIST_ACCESSOR0(const, Type, name) \ - inline const Type##List* get_##name##_list (void) const { \ - assert (name##List); \ - return (const Type##List *)((const char*)this + name##List); \ - } \ - inline const Type& get_##name (unsigned int i) const { \ - return (*get_##name##_list())[i]; \ - } -#define DEFINE_LIST_ACCESSOR(Type, name) \ - DEFINE_LIST_ACCESSOR0(const, Type, name) \ - DEFINE_LIST_ACCESSOR0( , Type, name) - -struct GSUBGPOSHeader { +typedef struct GSUBGPOSHeader { static const hb_tag_t GSUBTag = HB_TAG ('G','S','U','B'); static const hb_tag_t GPOSTag = HB_TAG ('G','P','O','S'); @@ -785,7 +796,9 @@ struct GSUBGPOSHeader { * GSUB/GPOS table */ Offset lookupList; /* Offset to LookupList table--from beginning of * GSUB/GPOS table */ -}; -ASSERT_SIZE (GSUBGPOSHeader, 10); +} GSUBHeader, GPOSHeader; +DEFINE_NULL_ASSERT_SIZE (GSUBGPOSHeader, 10); +DEFINE_NULL_ALIAS (GSUBHeader, GSUBGPOSHeader); +DEFINE_NULL_ALIAS (GPOSHeader, GSUBGPOSHeader); #endif /* HARFBUZZ_OPEN_PRIVATE_H */ diff --git a/src/main.cc b/src/main.cc index 313723e9b..3654e5e6e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -51,7 +51,7 @@ main (int argc, char **argv) if (table.get_tag() == "GSUB" || table.get_tag() == "GPOS") { const GSUBGPOSHeader &g = GSUBGPOSHeader::get_for_data (ot[table]); - const ScriptList &scripts = *g.get_script_list(); + const ScriptList &scripts = g.get_script_list(); int num_scripts = scripts.get_len (); printf (" %d script(s) found in table\n", num_scripts); for (int n_script = 0; n_script < num_scripts; n_script++) { @@ -59,7 +59,7 @@ main (int argc, char **argv) printf (" Script %2d of %2d: %.4s\n", n_script+1, num_scripts, (const char *)scripts.get_tag(n_script)); - if (script.get_default_language_system () == NULL) + if (!script.has_default_language_system()) printf (" No default language system\n"); int num_langsys = script.get_len (); printf (" %d language system(s) found in script\n", num_langsys); @@ -73,7 +73,7 @@ main (int argc, char **argv) } } - const FeatureList &features = *g.get_feature_list(); + const FeatureList &features = g.get_feature_list(); int num_features = features.get_len (); printf (" %d feature(s) found in table\n", num_features); for (int n_feature = 0; n_feature < num_features; n_feature++) { @@ -83,7 +83,7 @@ main (int argc, char **argv) feature.get_len()); } - const LookupList &lookups = *g.get_lookup_list(); + const LookupList &lookups = g.get_lookup_list(); int num_lookups = lookups.get_len (); printf (" %d lookup(s) found in table\n", num_lookups); for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { From 8dd1c8b8d6797d899d0f5b0a8015886bf6520ca2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 05:00:30 -0500 Subject: [PATCH 37/56] Clean up file names, add namespace --- src/harfbuzz-common.h | 14 -------------- src/harfbuzz-gdef.h | 11 ----------- src/hb-common.h | 14 ++++++++++++++ ...-gdef-private.h => hb-ot-layout-gdef-private.h} | 8 ++++---- ...-open-private.h => hb-ot-layout-open-private.h} | 10 +++++----- src/{harfbuzz-open.h => hb-ot-layout.h} | 12 ++++++------ src/{harfbuzz-private.h => hb-private.h} | 6 +++--- src/main.cc | 4 ++-- 8 files changed, 34 insertions(+), 45 deletions(-) delete mode 100644 src/harfbuzz-common.h delete mode 100644 src/harfbuzz-gdef.h create mode 100644 src/hb-common.h rename src/{harfbuzz-gdef-private.h => hb-ot-layout-gdef-private.h} (97%) rename src/{harfbuzz-open-private.h => hb-ot-layout-open-private.h} (99%) rename src/{harfbuzz-open.h => hb-ot-layout.h} (64%) rename src/{harfbuzz-private.h => hb-private.h} (79%) diff --git a/src/harfbuzz-common.h b/src/harfbuzz-common.h deleted file mode 100644 index b11539fd6..000000000 --- a/src/harfbuzz-common.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef HARFBUZZ_COMMON_H -#define HARFBUZZ_COMMON_H - -#include - -# ifdef __cplusplus -# define HARFBUZZ_BEGIN_DECLS() extern "C" { extern int harfbuzz_dummy_prototype (int) -# define HARFBUZZ_END_DECLS() } extern "C" int harfbuzz_dummy_prototype (int) -# else /* !__cplusplus */ -# define HARFBUZZ_BEGIN_DECLS() extern int harfbuzz_dummy_prototype (int) -# define HARFBUZZ_END_DECLS() extern int harfbuzz_dummy_prototype (int) -# endif /* !__cplusplus */ - -#endif /* HARFBUZZ_COMMON_H */ diff --git a/src/harfbuzz-gdef.h b/src/harfbuzz-gdef.h deleted file mode 100644 index 35647df7f..000000000 --- a/src/harfbuzz-gdef.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef HARFBUZZ_GDEF_H -#define HARFBUZZ_GDEF_H - -#include "harfbuzz-common.h" - -HARFBUZZ_BEGIN_DECLS(); - - -HARFBUZZ_END_DECLS(); - -#endif /* HARFBUZZ_GDEF_H */ diff --git a/src/hb-common.h b/src/hb-common.h new file mode 100644 index 000000000..4ad3bd102 --- /dev/null +++ b/src/hb-common.h @@ -0,0 +1,14 @@ +#ifndef HB_COMMON_H +#define HB_COMMON_H + +#include + +# ifdef __cplusplus +# define HB_BEGIN_DECLS() extern "C" { extern int hb_dummy_prototype (int) +# define HB_END_DECLS() } extern "C" int hb_dummy_prototype (int) +# else /* !__cplusplus */ +# define HB_BEGIN_DECLS() extern int hb_dummy_prototype (int) +# define HB_END_DECLS() extern int hb_dummy_prototype (int) +# endif /* !__cplusplus */ + +#endif /* HB_COMMON_H */ diff --git a/src/harfbuzz-gdef-private.h b/src/hb-ot-layout-gdef-private.h similarity index 97% rename from src/harfbuzz-gdef-private.h rename to src/hb-ot-layout-gdef-private.h index 6e0f4e31d..779b2b430 100644 --- a/src/harfbuzz-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -1,7 +1,7 @@ -#ifndef HARFBUZZ_GDEF_PRIVATE_H -#define HARFBUZZ_GDEF_PRIVATE_H +#ifndef HB_OT_LAYOUT_GDEF_PRIVATE_H +#define HB_OT_LAYOUT_GDEF_PRIVATE_H -#include "harfbuzz-open-private.h" +#include "hb-ot-layout-open-private.h" struct GlyphClassDef : ClassDef { static const uint16_t BaseGlyph = 0x0001u; @@ -210,4 +210,4 @@ struct GDEFHeader { }; DEFINE_NULL_ASSERT_SIZE (GDEFHeader, 12); -#endif /* HARFBUZZ_GDEF_PRIVATE_H */ +#endif /* HB_OT_LAYOUT_GDEF_PRIVATE_H */ diff --git a/src/harfbuzz-open-private.h b/src/hb-ot-layout-open-private.h similarity index 99% rename from src/harfbuzz-open-private.h rename to src/hb-ot-layout-open-private.h index 9db304474..6ee3b943a 100644 --- a/src/harfbuzz-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -1,8 +1,8 @@ -#ifndef HARFBUZZ_OPEN_PRIVATE_H -#define HARFBUZZ_OPEN_PRIVATE_H +#ifndef HB_OT_LAYOUT_OPEN_PRIVATE_H +#define HB_OT_LAYOUT_OPEN_PRIVATE_H -#include "harfbuzz-private.h" -#include "harfbuzz-open.h" +#include "hb-private.h" +#include "hb-ot-layout.h" #include @@ -801,4 +801,4 @@ DEFINE_NULL_ASSERT_SIZE (GSUBGPOSHeader, 10); DEFINE_NULL_ALIAS (GSUBHeader, GSUBGPOSHeader); DEFINE_NULL_ALIAS (GPOSHeader, GSUBGPOSHeader); -#endif /* HARFBUZZ_OPEN_PRIVATE_H */ +#endif /* HB_OT_LAYOUT_OPEN_PRIVATE_H */ diff --git a/src/harfbuzz-open.h b/src/hb-ot-layout.h similarity index 64% rename from src/harfbuzz-open.h rename to src/hb-ot-layout.h index 370bbdf32..fb3da3dc7 100644 --- a/src/harfbuzz-open.h +++ b/src/hb-ot-layout.h @@ -1,9 +1,9 @@ -#ifndef HARFBUZZ_OPEN_H -#define HARFBUZZ_OPEN_H +#ifndef HB_OT_LAYOUT_OPEN_H +#define HB_OT_LAYOUT_OPEN_H -#include "harfbuzz-common.h" +#include "hb-common.h" -HARFBUZZ_BEGIN_DECLS(); +HB_BEGIN_DECLS(); typedef uint32_t hb_tag_t; #define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d)) @@ -12,6 +12,6 @@ typedef uint32_t hb_tag_t; ((const char *) s)[2], \ ((const char *) s)[3])) -HARFBUZZ_END_DECLS(); +HB_END_DECLS(); -#endif /* HARFBUZZ_OPEN_H */ +#endif /* HB_OT_LAYOUT_OPEN_H */ diff --git a/src/harfbuzz-private.h b/src/hb-private.h similarity index 79% rename from src/harfbuzz-private.h rename to src/hb-private.h index 05b7ccc33..ab9a7c814 100644 --- a/src/harfbuzz-private.h +++ b/src/hb-private.h @@ -1,5 +1,5 @@ -#ifndef HARFBUZZ_PRIVATE_H -#define HARFBUZZ_PRIVATE_H +#ifndef HB_PRIVATE_H +#define HB_PRIVATE_H #include @@ -9,4 +9,4 @@ #define ASSERT_SIZE(_type, _size) ASSERT_STATIC (sizeof (_type) == (_size)) -#endif /* HARFBUZZ_PRIVATE_H */ +#endif /* HB_PRIVATE_H */ diff --git a/src/main.cc b/src/main.cc index 3654e5e6e..4e6f9adab 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,5 +1,5 @@ -#include "harfbuzz-open-private.h" -#include "harfbuzz-gdef-private.h" +#include "hb-ot-layout-open-private.h" +#include "hb-ot-layout-gdef-private.h" #include #include From 12360f7c159826ae72271b34486dee59d96aa8ca Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 15:50:38 -0500 Subject: [PATCH 38/56] Minor cleanup, add LIKELY and UNLIKELY annotations --- src/hb-ot-layout-gdef-private.h | 63 +++++++++++++++++++-------------- src/hb-ot-layout-open-private.h | 36 +++++++------------ src/hb-private.h | 15 ++++++++ 3 files changed, 63 insertions(+), 51 deletions(-) diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index 779b2b430..19df5f1e2 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -3,6 +3,15 @@ #include "hb-ot-layout-open-private.h" + +#define DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP(Type, name) \ + inline const Type& name (uint16_t glyph_id) { \ + const Coverage &c = get_coverage (); \ + int c_index = c.get_coverage (glyph_id); \ + return (*this)[c_index]; \ + } + + struct GlyphClassDef : ClassDef { static const uint16_t BaseGlyph = 0x0001u; static const uint16_t LigatureGlyph = 0x0002u; @@ -27,19 +36,15 @@ struct AttachPoint { DEFINE_NULL_ASSERT_SIZE (AttachPoint, 2); struct AttachList { - - inline const AttachPoint* get_attach_points (uint16_t glyph_id) { - const Coverage &c = get_coverage (); - int c_index = c.get_coverage (glyph_id); - return &(*this)[c_index]; - } + /* const AttachPoint& get_attach_points (uint16_t glyph_id); */ + DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (AttachPoint, get_attach_points); private: /* AttachPoint tables, in Coverage Index order */ DEFINE_OFFSET_ARRAY_TYPE (AttachPoint, attachPoint, glyphCount); DEFINE_ACCESSOR (Coverage, get_coverage, coverage); - private: + private: Offset coverage; /* Offset to Coverage table -- from * beginning of AttachList table */ USHORT glyphCount; /* Number of glyphs with attachment @@ -54,22 +59,6 @@ DEFINE_NULL_ASSERT_SIZE (AttachList, 4); * Ligature Caret Table */ -struct CaretValue; - -struct LigCaretList { - /* TODO */ - - private: - Offset coverage; /* Offset to Coverage table--from - * beginning of LigCaretList table */ - USHORT ligGlyphCount; /* Number of ligature glyphs */ - Offset ligGlyph[]; /* Array of offsets to LigGlyph - * tables--from beginning of - * LigCaretList table--in Coverage - * Index order */ -}; -DEFINE_NULL_ASSERT_SIZE (LigCaretList, 4); - struct CaretValueFormat1 { inline int get_caret_value (int ppem) const { @@ -80,7 +69,7 @@ struct CaretValueFormat1 { USHORT caretValueFormat; /* Format identifier--format = 1 */ SHORT coordinate; /* X or Y value, in design units */ }; -DEFINE_NULL_ASSERT_SIZE (CaretValueFormat1, 4); +ASSERT_SIZE (CaretValueFormat1, 4); struct CaretValueFormat2 { @@ -92,12 +81,12 @@ struct CaretValueFormat2 { USHORT caretValueFormat; /* Format identifier--format = 2 */ USHORT caretValuePoint; /* Contour point index on glyph */ }; -DEFINE_NULL_ASSERT_SIZE (CaretValueFormat2, 4); +ASSERT_SIZE (CaretValueFormat2, 4); struct CaretValueFormat3 { inline const Device& get_device (void) const { - if (!deviceTable) return NullDevice; + if (HB_UNLIKELY (!deviceTable)) return NullDevice; return *(const Device*)((const char*)this + deviceTable); } @@ -112,7 +101,7 @@ struct CaretValueFormat3 { * value--from beginning of CaretValue * table */ }; -DEFINE_NULL_ASSERT_SIZE (CaretValueFormat3, 6); +ASSERT_SIZE (CaretValueFormat3, 6); struct CaretValue { DEFINE_NON_INSTANTIABLE(CaretValue); @@ -162,6 +151,26 @@ struct LigGlyph { }; DEFINE_NULL_ASSERT_SIZE (LigGlyph, 2); +struct LigCaretList { + /* const LigGlyph& get_lig_glyph (uint16_t glyph_id); */ + DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph); + + private: + /* AttachPoint tables, in Coverage Index order */ + DEFINE_OFFSET_ARRAY_TYPE (LigGlyph, ligGlyph, ligGlyphCount); + DEFINE_ACCESSOR (Coverage, get_coverage, coverage); + + private: + Offset coverage; /* Offset to Coverage table--from + * beginning of LigCaretList table */ + USHORT ligGlyphCount; /* Number of ligature glyphs */ + Offset ligGlyph[]; /* Array of offsets to LigGlyph + * tables--from beginning of + * LigCaretList table--in Coverage + * Index order */ +}; +DEFINE_NULL_ASSERT_SIZE (LigCaretList, 4); + /* * GDEF Header */ diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 6ee3b943a..fa12daa93 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -4,18 +4,6 @@ #include "hb-private.h" #include "hb-ot-layout.h" -#include - -/* Macros to convert to/from BigEndian */ -#define hb_be_uint8_t -#define hb_be_int8_t -#define hb_be_uint16_t GUINT16_TO_BE -#define hb_be_int16_t GINT16_TO_BE -#define hb_be_uint32_t GUINT32_TO_BE -#define hb_be_int32_t GINT32_TO_BE -#define hb_be_uint64_t GUINT64_TO_BE -#define hb_be_int64_t GINT64_TO_BE - /* * Int types */ @@ -57,7 +45,7 @@ DEFINE_LEN_AND_SIZE(Type, array, num) #define DEFINE_INDEX_OPERATOR(Type, array, num) \ inline const Type& operator[] (unsigned int i) const { \ - if (i >= num) return Null##Type; \ + if (HB_UNLIKELY (i >= num)) return Null##Type; \ return array[i]; \ } @@ -69,8 +57,8 @@ DEFINE_LEN_AND_SIZE(Offset, array, num) #define DEFINE_OFFSET_INDEX_OPERATOR(Type, array, num) \ inline const Type& operator[] (unsigned int i) const { \ - if (i >= num) return Null##Type; \ - if (!array[i]) return Null##Type; \ + if (HB_UNLIKELY (i >= num)) return Null##Type; \ + if (HB_UNLIKELY (!array[i])) return Null##Type; \ return *(const Type *)((const char*)this + array[i]); \ } @@ -79,12 +67,12 @@ DEFINE_LEN_AND_SIZE(Record, array, num) #define DEFINE_RECORD_ACCESSOR(Type, array, num) \ inline const Type& operator[] (unsigned int i) const { \ - if (i >= num) return Null##Type; \ - if (!array[i].offset) return Null##Type; \ + if (HB_UNLIKELY (i >= num)) return Null##Type; \ + if (HB_UNLIKELY (!array[i].offset)) return Null##Type; \ return *(const Type *)((const char*)this + array[i].offset); \ } \ inline const Tag& get_tag (unsigned int i) const { \ - if (i >= num) return NullTag; \ + if (HB_UNLIKELY (i >= num)) return NullTag; \ return array[i].tag; \ } \ /* TODO: implement find_tag() */ @@ -95,7 +83,7 @@ #define DEFINE_LIST_ACCESSOR(Type, name) \ inline const Type##List& get_##name##_list (void) const { \ - if (!name##List) return Null##Type##List; \ + if (HB_UNLIKELY (!name##List)) return Null##Type##List; \ return *(const Type##List *)((const char*)this + name##List); \ } \ inline const Type& get_##name (unsigned int i) const { \ @@ -140,7 +128,7 @@ #define DEFINE_ACCESSOR(Type, name, Name) \ inline const Type& name (void) const { \ - if (!Name) return Null##Type; \ + if (HB_UNLIKELY (!Name)) return Null##Type; \ return *(const Type*)((const char*)this + Name); \ } @@ -368,7 +356,7 @@ struct OpenTypeFontFile { } } inline const OpenTypeFontFace& operator[] (unsigned int i) const { - if (i >= get_len ()) return NullOpenTypeFontFace; + if (HB_UNLIKELY (i >= get_len ())) return NullOpenTypeFontFace; switch (tag) { default: case TrueTypeTag: case CFFTag: return (const OffsetTable&)*this; case TTCTag: return ((const TTCHeader&)*this)[i]; @@ -435,7 +423,7 @@ struct Script { return defaultLangSys != 0; } inline const LangSys& get_default_language_system (void) const { - if (!defaultLangSys) + if (HB_UNLIKELY (!defaultLangSys)) return NullLangSys; return *(LangSys*)((const char*)this + defaultLangSys); } @@ -557,7 +545,7 @@ struct CoverageFormat1 { GlyphID gid; gid = glyph_id; // TODO: bsearch - for (int i = 0; i < glyphCount; i++) + for (unsigned int i = 0; i < glyphCount; i++) if (gid == glyphArray[i]) return i; return -1; @@ -592,7 +580,7 @@ struct CoverageFormat2 { inline int get_coverage (uint16_t glyph_id) const { // TODO: bsearch - for (int i = 0; i < rangeCount; i++) { + for (unsigned int i = 0; i < rangeCount; i++) { int coverage = rangeRecord[i].get_coverage (glyph_id); if (coverage >= 0) return coverage; diff --git a/src/hb-private.h b/src/hb-private.h index ab9a7c814..d2835064c 100644 --- a/src/hb-private.h +++ b/src/hb-private.h @@ -1,6 +1,21 @@ #ifndef HB_PRIVATE_H #define HB_PRIVATE_H +#include + +/* Macros to convert to/from BigEndian */ +#define hb_be_uint8_t +#define hb_be_int8_t +#define hb_be_uint16_t GUINT16_TO_BE +#define hb_be_int16_t GINT16_TO_BE +#define hb_be_uint32_t GUINT32_TO_BE +#define hb_be_int32_t GINT32_TO_BE +#define hb_be_uint64_t GUINT64_TO_BE +#define hb_be_int64_t GINT64_TO_BE + +#define HB_LIKELY G_LIKEYLY +#define HB_UNLIKELY G_UNLIKELY + #include #define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] From 64aef3a54999496fd1de4f5aa5b019e4c03b3836 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 16:14:38 -0500 Subject: [PATCH 39/56] Add copyright notices. --- src/hb-common.h | 26 ++++++++++++++++++++++++++ src/hb-ot-layout-gdef-private.h | 26 ++++++++++++++++++++++++++ src/hb-ot-layout-open-private.h | 26 ++++++++++++++++++++++++++ src/hb-ot-layout.h | 26 ++++++++++++++++++++++++++ src/hb-private.h | 26 ++++++++++++++++++++++++++ src/main.cc | 26 ++++++++++++++++++++++++++ 6 files changed, 156 insertions(+) diff --git a/src/hb-common.h b/src/hb-common.h index 4ad3bd102..9899a705d 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -1,3 +1,29 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + #ifndef HB_COMMON_H #define HB_COMMON_H diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index 19df5f1e2..e05ea38f3 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -1,3 +1,29 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + #ifndef HB_OT_LAYOUT_GDEF_PRIVATE_H #define HB_OT_LAYOUT_GDEF_PRIVATE_H diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index fa12daa93..bcd50e7f6 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -1,3 +1,29 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + #ifndef HB_OT_LAYOUT_OPEN_PRIVATE_H #define HB_OT_LAYOUT_OPEN_PRIVATE_H diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index fb3da3dc7..554be08a5 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -1,3 +1,29 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + #ifndef HB_OT_LAYOUT_OPEN_H #define HB_OT_LAYOUT_OPEN_H diff --git a/src/hb-private.h b/src/hb-private.h index d2835064c..eb5a26a4d 100644 --- a/src/hb-private.h +++ b/src/hb-private.h @@ -1,3 +1,29 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + #ifndef HB_PRIVATE_H #define HB_PRIVATE_H diff --git a/src/main.cc b/src/main.cc index 4e6f9adab..1efca5d26 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,3 +1,29 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + #include "hb-ot-layout-open-private.h" #include "hb-ot-layout-gdef-private.h" From a16ecbf0564a6e2576da22c12827f3c0719da549 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 17:01:55 -0500 Subject: [PATCH 40/56] Initial gsub stub --- src/hb-ot-layout-gdef-private.h | 4 + src/hb-ot-layout-gsub-private.h | 453 ++++++++++++++++++++++++++++++++ src/hb-ot-layout-open-private.h | 3 + src/main.cc | 1 + 4 files changed, 461 insertions(+) create mode 100644 src/hb-ot-layout-gsub-private.h diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index e05ea38f3..ce8b32e66 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -27,6 +27,9 @@ #ifndef HB_OT_LAYOUT_GDEF_PRIVATE_H #define HB_OT_LAYOUT_GDEF_PRIVATE_H +#include "hb-private.h" +#include "hb-ot-layout.h" + #include "hb-ot-layout-open-private.h" @@ -205,6 +208,7 @@ struct GDEFHeader { static const hb_tag_t GDEFTag = HB_TAG ('G','D','E','F'); STATIC_DEFINE_GET_FOR_DATA (GDEFHeader); + /* XXX check version here */ DEFINE_ACCESSOR (ClassDef, get_glyph_class_def, glyphClassDef); DEFINE_ACCESSOR (AttachList, get_attach_list, attachList); diff --git a/src/hb-ot-layout-gsub-private.h b/src/hb-ot-layout-gsub-private.h new file mode 100644 index 000000000..c8a19006e --- /dev/null +++ b/src/hb-ot-layout-gsub-private.h @@ -0,0 +1,453 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_LAYOUT_GSUB_PRIVATE_H +#define HB_OT_LAYOUT_GSUB_PRIVATE_H + +#include "hb-private.h" +#include "hb-ot-layout.h" + +#include "hb-ot-layout-open-private.h" +#include "hb-ot-layout-gdef-private.h" + + +struct SingleSubstFormat1 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 1 */ + Offset coverage; /* Offset to Coverage table--from + * beginning of Substitution table */ + SHORT deltaGlyphID; /* Add to original GlyphID to get + * substitute GlyphID */ +}; +ASSERT_SIZE (SingleSubstFormat1, 6); + +struct SingleSubstFormat2 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 2 */ + Offset coverage; /* Offset to Coverage table--from + * beginning of Substitution table */ + USHORT glyphCount; /* Number of GlyphIDs in the Substitute + * array */ + GlyphID substitute[]; /* Array of substitute + * GlyphIDs--ordered by Coverage Index */ +}; +ASSERT_SIZE (SingleSubstFormat2, 6); + +struct MultipleSubstFormat1 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 1 */ + Offset coverage; /* Offset to Coverage table--from + * beginning of Substitution table */ + USHORT sequenceCount; /* Number of Sequence table offsets in + * the Sequence array */ + Offset sequence[]; /* Array of offsets to Sequence + * tables--from beginning of + * Substitution table--ordered by + * Coverage Index */ +}; +ASSERT_SIZE (MultipleSubstFormat1, 6); + +struct Sequence { + /* TODO */ + + private: + USHORT glyphCount; /* Number of GlyphIDs in the Substitute + * array. This should always be + * greater than 0. */ + GlyphID substitute[]; /* String of GlyphIDs to substitute */ +}; +DEFINE_NULL_ASSERT_SIZE (Sequence, 2); + +struct AlternateSubstFormat1 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 1 */ + Offset coverage; /* Offset to Coverage table--from + * beginning of Substitution table */ + USHORT alternateSetCount; /* Number of AlternateSet tables */ + Offset alternateSet[]; /* Array of offsets to AlternateSet + * tables--from beginning of + * Substitution table--ordered by + * Coverage Index */ +}; +ASSERT_SIZE (AlternateSubstFormat1, 6); + +struct AlternateSet { + /* TODO */ + + private: + USHORT glyphCount; /* Number of GlyphIDs in the Alternate + * array */ + GlyphID alternate[]; /* Array of alternate GlyphIDs--in + * arbitrary order */ +}; +DEFINE_NULL_ASSERT_SIZE (AlternateSet, 2); + +struct LigatureSubstFormat1 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 1 */ + Offset coverage; /* Offset to Coverage table--from + * beginning of Substitution table */ + USHORT ligSetCount; /* Number of LigatureSet tables */ + Offset ligatureSet[]; /* Array of offsets to LigatureSet + * tables--from beginning of + * Substitution table--ordered by + * Coverage Index */ +}; +ASSERT_SIZE (LigatureSubstFormat1, 6); + +struct LigatureSet { + /* TODO */ + + private: + USHORT ligatureCount; /* Number of Ligature tables */ + Offset ligature[]; /* Array of offsets to Ligature + * tables--from beginning of + * LigatureSet table--ordered by + * preference */ +}; +DEFINE_NULL_ASSERT_SIZE (LigatureSet, 2); + +struct Ligature { + /* TODO */ + + private: + GlyphID ligGlyph; /* GlyphID of ligature to substitute */ + USHORT compCount; /* Number of components in the ligature */ + GlyphID component[]; /* Array of component GlyphIDs--start + * with the second component--ordered + * in writing direction */ +}; +DEFINE_NULL_ASSERT_SIZE (Ligature, 4); + +struct SubstLookupRecord { + /* TODO */ + + private: + USHORT sequenceIndex; /* Index into current glyph + * sequence--first glyph = 0 */ + USHORT lookupListIndex; /* Lookup to apply to that + * position--zero--based */ +}; +DEFINE_NULL_ASSERT_SIZE (SubstLookupRecord, 4); + +struct ContextSubstFormat1 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 1 */ + Offset coverage; /* Offset to Coverage table--from + * beginning of Substitution table */ + USHORT subRuleSetCount; /* Number of SubRuleSet tables--must + * equal GlyphCount in Coverage table */ + Offset subRuleSet[]; /* Array of offsets to SubRuleSet + * tables--from beginning of + * Substitution table--ordered by + * Coverage Index */ +}; +ASSERT_SIZE (ContextSubstFormat1, 6); + +struct SubRuleSet { + /* TODO */ + + private: + USHORT subRuleCount; /* Number of SubRule tables */ + Offset subRule[]; /* Array of offsets to SubRule + * tables--from beginning of SubRuleSet + * table--ordered by preference */ +}; +DEFINE_NULL_ASSERT_SIZE (SubRuleSet, 2); + +struct SubRule { + /* TODO */ + + private: + USHORT glyphCount; /* Total number of glyphs in input + * glyph sequence--includes the first + * glyph */ + USHORT substCount; /* Number of SubstLookupRecords */ + GlyphID input[]; /* Array of input GlyphIDs--start with + * second glyph */ + SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in + * design order */ +}; +DEFINE_NULL_ASSERT_SIZE (SubRule, 4); + +struct ContextSubstFormat2 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 2 */ + Offset coverage; /* Offset to Coverage table--from + * beginning of Substitution table */ + Offset classDef; /* Offset to glyph ClassDef table--from + * beginning of Substitution table */ + USHORT subClassSetCnt; /* Number of SubClassSet tables */ + Offset subClassSet[]; /* Array of offsets to SubClassSet + * tables--from beginning of + * Substitution table--ordered by + * class--may be NULL */ +}; +ASSERT_SIZE (ContextSubstFormat2, 8); + +struct SubClassSet { + /* TODO */ + + private: + USHORT subClassRuleCnt; /* Number of SubClassRule tables */ + Offset subClassRule[]; /* Array of offsets to SubClassRule + * tables--from beginning of + * SubClassSet--ordered by preference */ +}; +DEFINE_NULL_ASSERT_SIZE (SubClassSet, 2); + +struct SubClassRule { + /* TODO */ + + private: + USHORT glyphCount; /* Total number of classes + * specified for the context in the + * rule--includes the first class */ + USHORT substCount; /* Number of SubstLookupRecords */ + USHORT klass[]; /* Array of classes--beginning with the + * second class--to be matched to the + * input glyph class sequence */ + SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in + * design order */ +}; +DEFINE_NULL_ASSERT_SIZE (SubClassRule, 4); + +struct ContextSubstFormat3 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 3 */ + USHORT glyphCount; /* Number of glyphs in the input glyph + * sequence */ + USHORT substCount; /* Number of SubstLookupRecords */ + Offset coverage[]; /* Array of offsets to Coverage + * table--from beginning of + * Substitution table--in glyph + * sequence order */ + SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in + * design order */ +}; +ASSERT_SIZE (ContextSubstFormat3, 6); + +struct ChainContextSubstFormat1 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 1 */ + Offset coverage; /* Offset to Coverage table--from + * beginning of Substitution table */ + USHORT chainSubRuleSetCount; /* Number of ChainSubRuleSet + * tables--must equal GlyphCount in + * Coverage table */ + Offset chainSubRuleSet[]; /* Array of offsets to ChainSubRuleSet + * tables--from beginning of + * Substitution table--ordered by + * Coverage Index */ +}; +ASSERT_SIZE (ChainContextSubstFormat1, 6); + +struct ChainSubRuleSet { + /* TODO */ + + private: + USHORT chainSubRuleCount; /* Number of ChainSubRule tables */ + Offset chainSubRule[]; /* Array of offsets to ChainSubRule + * tables--from beginning of + * ChainSubRuleSet table--ordered + * by preference */ +}; +DEFINE_NULL_ASSERT_SIZE (ChainSubRuleSet, 2); + +struct ChainSubRule { + /* TODO */ + + private: + USHORT backtrackGlyphCount; /* Total number of glyphs in the + * backtrack sequence (number of + * glyphs to be matched before the + * first glyph) */ + GlyphID backtrack[]; /* Array of backtracking GlyphID's + * (to be matched before the input + * sequence) */ + USHORT inputGlyphCount; /* Total number of glyphs in the input + * sequence (includes the first glyph) */ + GlyphID input[]; /* Array of input GlyphIDs (start with + * second glyph) */ + USHORT lookaheadGlyphCount; /* Total number of glyphs in the look + * ahead sequence (number of glyphs to + * be matched after the input sequence) */ + GlyphID lookAhead[]; /* Array of lookahead GlyphID's (to be + * matched after the input sequence) */ + USHORT substCount; /* Number of SubstLookupRecords */ + SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in + * design order) */ +}; +DEFINE_NULL_ASSERT_SIZE (ChainSubRule, 8); + +struct ChainContextSubstFormat2 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 2 */ + Offset coverage; /* Offset to Coverage table--from + * beginning of Substitution table */ + Offset backtrackClassDef; /* Offset to glyph ClassDef table + * containing backtrack sequence + * data--from beginning of Substitution + * table */ + Offset inputClassDef; /* Offset to glyph ClassDef + * table containing input sequence + * data--from beginning of Substitution + * table */ + Offset lookaheadClassDef; /* Offset to glyph ClassDef table + * containing lookahead sequence + * data--from beginning of Substitution + * table */ + USHORT chainSubClassSetCnt; /* Number of ChainSubClassSet tables */ + Offset chainSubClassSet[]; /* Array of offsets to ChainSubClassSet + * tables--from beginning of + * Substitution table--ordered by input + * class--may be NULL */ +}; +ASSERT_SIZE (ChainContextSubstFormat2, 12); + +struct ChainSubClassSet { + /* TODO */ + + private: + USHORT chainSubClassRuleCnt; /* Number of ChainSubClassRule tables */ + Offset chainSubClassRule[]; /* Array of offsets + * to ChainSubClassRule + * tables--from beginning of + * ChainSubClassSet--ordered by + * preference */ +}; +DEFINE_NULL_ASSERT_SIZE (ChainSubClassSet, 2); + +struct ChainSubClassRule { + /* TODO */ + + private: + USHORT backtrackGlyphCount; /* Total number of glyphs in the + * backtrack sequence (number of + * glyphs to be matched before the + * first glyph) */ + USHORT backtrack[]; /* Array of backtracking classes(to be + * matched before the input sequence) */ + USHORT inputGlyphCount; /* Total number of classes in the input + * sequence (includes the first class) */ + USHORT input[]; /* Array of input classes(start with + * second class; to be matched with + * the input glyph sequence) */ + USHORT lookaheadGlyphCount; /* Total number of classes in the + * look ahead sequence (number of + * classes to be matched after the + * input sequence) */ + USHORT lookAhead[]; /* Array of lookahead classes(to be + * matched after the input sequence) */ + USHORT substCount; /* Number of SubstLookupRecords */ + SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in + * design order) */ +}; +DEFINE_NULL_ASSERT_SIZE (ChainSubClassRule, 8); + +struct ChainContextSubstFormat3 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 3 */ + USHORT backtrackGlyphCount; /* Number of glyphs in the backtracking + * sequence */ + Offset backtrackCoverage[]; /* Array of offsets to coverage tables + * in backtracking sequence, in glyph + * sequence order */ + USHORT inputGlyphCount; /* Number of glyphs in input sequence */ + Offset inputCoverage[]; /* Array of offsets to coverage + * tables in input sequence, in glyph + * sequence order */ + USHORT lookaheadGlyphCount; /* Number of glyphs in lookahead + * sequence */ + Offset lookaheadCoverage[]; /* Array of offsets to coverage tables + * in lookahead sequence, in glyph + * sequence order */ + USHORT substCount; /* Number of SubstLookupRecords */ + SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in + * design order */ +}; +ASSERT_SIZE (ChainContextSubstFormat3, 10); + +struct ExtensionSubstFormat1 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier. Set to 1. */ + USHORT extensionLookupType; /* Lookup type of subtable referenced + * by ExtensionOffset (i.e. the + * extension subtable). */ + ULONG extensionOffset; /* Offset to the extension subtable, + * of lookup type subtable. */ +}; +ASSERT_SIZE (ExtensionSubstFormat1, 8); + +struct ReverseChainSingleSubstFormat1 { + /* TODO */ + + private: + USHORT substFormat; /* Format identifier--format = 1 */ + Offset coverage; /* Offset to Coverage table -- from + * beginning of Substitution table */ + USHORT backtrackGlyphCount; /* Number of glyphs in the backtracking + * sequence */ + Offset backtrackCoverage[]; /* Array of offsets to coverage tables + * in backtracking sequence, in glyph + * sequence order */ + USHORT lookaheadGlyphCount; /* Number of glyphs in lookahead + * sequence */ + Offset lookaheadCoverage[]; /* Array of offsets to coverage tables + * in lookahead sequence, in glyph + * sequence order */ + USHORT glyphCount; /* Number of GlyphIDs in the Substitute + * array */ + GlyphID substitute[]; /* Array of substitute + * GlyphIDs--ordered by Coverage Index */ +}; +ASSERT_SIZE (ReverseChainSingleSubstFormat1, 10); + +#endif /* HB_OT_LAYOUT_GSUB_PRIVATE_H */ diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index bcd50e7f6..9cdb6e277 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -30,6 +30,7 @@ #include "hb-private.h" #include "hb-ot-layout.h" + /* * Int types */ @@ -335,6 +336,7 @@ DEFINE_NULL_ALIAS (OpenTypeFontFace, OffsetTable); struct TTCHeader { /* OpenTypeFontFaces, in no particular order */ DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); + /* XXX check version here */ private: Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ @@ -794,6 +796,7 @@ typedef struct GSUBGPOSHeader { static const hb_tag_t GPOSTag = HB_TAG ('G','P','O','S'); STATIC_DEFINE_GET_FOR_DATA (GSUBGPOSHeader); + /* XXX check version here */ DEFINE_LIST_ACCESSOR(Script, script); /* get_script_list, get_script(i) */ DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list, get_feature(i) */ diff --git a/src/main.cc b/src/main.cc index 1efca5d26..a670959ce 100644 --- a/src/main.cc +++ b/src/main.cc @@ -26,6 +26,7 @@ #include "hb-ot-layout-open-private.h" #include "hb-ot-layout-gdef-private.h" +#include "hb-ot-layout-gsub-private.h" #include #include From aefaafe5bc4fc6d37a412c135b1079c287be7045 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 17:25:29 -0500 Subject: [PATCH 41/56] Minor renaming --- src/hb-ot-layout-gdef-private.h | 10 +++++----- src/hb-ot-layout-open-private.h | 16 +++++++--------- src/main.cc | 4 ++-- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index ce8b32e66..8b20fd56e 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -201,14 +201,14 @@ struct LigCaretList { DEFINE_NULL_ASSERT_SIZE (LigCaretList, 4); /* - * GDEF Header + * GDEF */ -struct GDEFHeader { +struct GDEF { static const hb_tag_t GDEFTag = HB_TAG ('G','D','E','F'); - STATIC_DEFINE_GET_FOR_DATA (GDEFHeader); - /* XXX check version here */ + STATIC_DEFINE_GET_FOR_DATA (GDEF); + /* XXX check version here? */ DEFINE_ACCESSOR (ClassDef, get_glyph_class_def, glyphClassDef); DEFINE_ACCESSOR (AttachList, get_attach_list, attachList); @@ -247,6 +247,6 @@ struct GDEFHeader { * mark attachment type--from beginning * of GDEF header (may be Null) */ }; -DEFINE_NULL_ASSERT_SIZE (GDEFHeader, 12); +DEFINE_NULL_ASSERT_SIZE (GDEF, 12); #endif /* HB_OT_LAYOUT_GDEF_PRIVATE_H */ diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 9cdb6e277..a88808e75 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -336,7 +336,7 @@ DEFINE_NULL_ALIAS (OpenTypeFontFace, OffsetTable); struct TTCHeader { /* OpenTypeFontFaces, in no particular order */ DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); - /* XXX check version here */ + /* XXX check version here? */ private: Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ @@ -788,15 +788,15 @@ struct Device { DEFINE_NULL_ASSERT_SIZE (Device, 6); /* - * GSUB/GPOS Header + * GSUB/GPOS Common */ -typedef struct GSUBGPOSHeader { +typedef struct GSUBGPOS { static const hb_tag_t GSUBTag = HB_TAG ('G','S','U','B'); static const hb_tag_t GPOSTag = HB_TAG ('G','P','O','S'); - STATIC_DEFINE_GET_FOR_DATA (GSUBGPOSHeader); - /* XXX check version here */ + STATIC_DEFINE_GET_FOR_DATA (GSUBGPOS); + /* XXX check version here? */ DEFINE_LIST_ACCESSOR(Script, script); /* get_script_list, get_script(i) */ DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list, get_feature(i) */ @@ -813,9 +813,7 @@ typedef struct GSUBGPOSHeader { * GSUB/GPOS table */ Offset lookupList; /* Offset to LookupList table--from beginning of * GSUB/GPOS table */ -} GSUBHeader, GPOSHeader; -DEFINE_NULL_ASSERT_SIZE (GSUBGPOSHeader, 10); -DEFINE_NULL_ALIAS (GSUBHeader, GSUBGPOSHeader); -DEFINE_NULL_ALIAS (GPOSHeader, GSUBGPOSHeader); +}; +DEFINE_NULL_ASSERT_SIZE (GSUBGPOS, 10); #endif /* HB_OT_LAYOUT_OPEN_PRIVATE_H */ diff --git a/src/main.cc b/src/main.cc index a670959ce..edb805a1d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -76,7 +76,7 @@ main (int argc, char **argv) (const char *)table.get_tag(), table.get_offset(), table.get_length()); if (table.get_tag() == "GSUB" || table.get_tag() == "GPOS") { - const GSUBGPOSHeader &g = GSUBGPOSHeader::get_for_data (ot[table]); + const GSUBGPOS &g = GSUBGPOS::get_for_data (ot[table]); const ScriptList &scripts = g.get_script_list(); int num_scripts = scripts.get_len (); @@ -119,7 +119,7 @@ main (int argc, char **argv) lookup.get_type(), lookup.get_flag()); } } else if (table.get_tag() == "GDEF") { - const GDEFHeader &gdef = GDEFHeader::get_for_data (ot[table]); + const GDEF &gdef = GDEF::get_for_data (ot[table]); for (int glyph = 0; glyph < 1; glyph++) printf (" glyph %d has class %d and mark attachment type %d\n", From 7586089c6fa8185cad8387869d3703c637e5cbb1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 23 Jan 2008 18:02:28 -0500 Subject: [PATCH 42/56] Minor --- src/hb-ot-layout-gdef-private.h | 37 ++++++++++++++++++++----- src/hb-ot-layout-gsub-private.h | 13 +++++++++ src/hb-ot-layout-open-private.h | 49 +++++++++++++++++++++++++++------ src/hb-private.h | 2 ++ 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index 8b20fd56e..6442221c1 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -53,6 +53,10 @@ struct GlyphClassDef : ClassDef { */ struct AttachPoint { + + friend struct AttachList; + + private: /* countour point indices, in increasing numerical order */ DEFINE_ARRAY_TYPE (USHORT, pointIndex, pointCount); @@ -65,6 +69,10 @@ struct AttachPoint { DEFINE_NULL_ASSERT_SIZE (AttachPoint, 2); struct AttachList { + + friend struct GDEF; + + private: /* const AttachPoint& get_attach_points (uint16_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (AttachPoint, get_attach_points); @@ -90,6 +98,9 @@ DEFINE_NULL_ASSERT_SIZE (AttachList, 4); struct CaretValueFormat1 { + friend struct CaretValue; + + private: inline int get_caret_value (int ppem) const { return /* TODO garbage */ coordinate / ppem; } @@ -102,6 +113,9 @@ ASSERT_SIZE (CaretValueFormat1, 4); struct CaretValueFormat2 { + friend struct CaretValue; + + private: inline int get_caret_value (int ppem) const { return /* TODO garbage */ 0 / ppem; } @@ -114,6 +128,9 @@ ASSERT_SIZE (CaretValueFormat2, 4); struct CaretValueFormat3 { + friend struct CaretValue; + + private: inline const Device& get_device (void) const { if (HB_UNLIKELY (!deviceTable)) return NullDevice; return *(const Device*)((const char*)this + deviceTable); @@ -135,7 +152,7 @@ ASSERT_SIZE (CaretValueFormat3, 6); struct CaretValue { DEFINE_NON_INSTANTIABLE(CaretValue); - inline unsigned int get_size (void) const { + unsigned int get_size (void) const { switch (u.caretValueFormat) { case 1: return sizeof (u.format1); case 2: return sizeof (u.format2); @@ -145,7 +162,7 @@ struct CaretValue { } /* XXX we need access to a load-contour-point vfunc here */ - inline int get_caret_value (int ppem) const { + int get_caret_value (int ppem) const { switch (u.caretValueFormat) { case 1: return u.format1.get_caret_value(ppem); case 2: return u.format2.get_caret_value(ppem); @@ -166,6 +183,10 @@ struct CaretValue { DEFINE_NULL (CaretValue, 2); struct LigGlyph { + + friend struct LigCaretList; + + private: /* Caret value tables, in increasing coordinate order */ DEFINE_OFFSET_ARRAY_TYPE (CaretValue, caretValue, caretCount); /* TODO */ @@ -181,6 +202,10 @@ struct LigGlyph { DEFINE_NULL_ASSERT_SIZE (LigGlyph, 2); struct LigCaretList { + + friend struct GDEF; + + private: /* const LigGlyph& get_lig_glyph (uint16_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph); @@ -205,7 +230,7 @@ DEFINE_NULL_ASSERT_SIZE (LigCaretList, 4); */ struct GDEF { - static const hb_tag_t GDEFTag = HB_TAG ('G','D','E','F'); + static const hb_tag_t Tag = HB_TAG ('G','D','E','F'); STATIC_DEFINE_GET_FOR_DATA (GDEF); /* XXX check version here? */ @@ -217,14 +242,12 @@ struct GDEF { /* Returns 0 if not found. */ inline int get_glyph_class (uint16_t glyph_id) const { - const ClassDef &class_def = get_glyph_class_def (); - return class_def.get_class (glyph_id); + return get_glyph_class_def ().get_class (glyph_id); } /* Returns 0 if not found. */ inline int get_mark_attachment_type (uint16_t glyph_id) const { - const ClassDef &class_def = get_mark_attach_class_def (); - return class_def.get_class (glyph_id); + return get_mark_attach_class_def ().get_class (glyph_id); } /* TODO get_glyph_property */ diff --git a/src/hb-ot-layout-gsub-private.h b/src/hb-ot-layout-gsub-private.h index c8a19006e..46b538e0d 100644 --- a/src/hb-ot-layout-gsub-private.h +++ b/src/hb-ot-layout-gsub-private.h @@ -450,4 +450,17 @@ struct ReverseChainSingleSubstFormat1 { }; ASSERT_SIZE (ReverseChainSingleSubstFormat1, 10); +/* + * GSUB + */ + +struct GSUB : GSUBGPOS { + static const hb_tag_t Tag = HB_TAG ('G','S','U','B'); + + STATIC_DEFINE_GET_FOR_DATA (GSUB); + /* XXX check version here? */ +}; +DEFINE_NULL_ALIAS (GSUB, GSUBGPOS); + + #endif /* HB_OT_LAYOUT_GSUB_PRIVATE_H */ diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index a88808e75..04054df61 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -314,6 +314,12 @@ typedef struct TableDirectory { DEFINE_NULL_ASSERT_SIZE (TableDirectory, 16); typedef struct OffsetTable { + + friend struct OpenTypeFontFile; + friend struct TTCHeader; + + // XXX private: + // Add get_num_tables and get_table... /* OpenTypeTables, in no particular order */ DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables); // TODO: Implement find_table @@ -334,6 +340,10 @@ DEFINE_NULL_ALIAS (OpenTypeFontFace, OffsetTable); */ struct TTCHeader { + + friend struct OpenTypeFontFile; + + private: /* OpenTypeFontFaces, in no particular order */ DEFINE_OFFSET_ARRAY_TYPE (OffsetTable, offsetTable, numFonts); /* XXX check version here? */ @@ -376,14 +386,14 @@ struct OpenTypeFontFile { } /* Array interface sans get_size() */ - inline unsigned int get_len (void) const { + unsigned int get_len (void) const { switch (tag) { default: return 0; case TrueTypeTag: case CFFTag: return 1; case TTCTag: return ((const TTCHeader&)*this).get_len(); } } - inline const OpenTypeFontFace& operator[] (unsigned int i) const { + const OpenTypeFontFace& operator[] (unsigned int i) const { if (HB_UNLIKELY (i >= get_len ())) return NullOpenTypeFontFace; switch (tag) { default: case TrueTypeTag: case CFFTag: return (const OffsetTable&)*this; @@ -566,6 +576,10 @@ DEFINE_NULL_ASSERT_SIZE (LookupList, 2); */ struct CoverageFormat1 { + + friend struct Coverage; + + private: /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); @@ -588,6 +602,9 @@ ASSERT_SIZE (CoverageFormat1, 4); struct CoverageRangeRecord { + friend struct CoverageFormat2; + + private: inline int get_coverage (uint16_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return startCoverageIndex + (glyph_id - start); @@ -603,6 +620,10 @@ struct CoverageRangeRecord { DEFINE_NULL_ASSERT_SIZE_DATA (CoverageRangeRecord, 6, "\001"); struct CoverageFormat2 { + + friend struct Coverage; + + private: /* CoverageRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount); @@ -628,7 +649,7 @@ ASSERT_SIZE (CoverageFormat2, 4); struct Coverage { DEFINE_NON_INSTANTIABLE(Coverage); - inline unsigned int get_size (void) const { + unsigned int get_size (void) const { switch (u.coverageFormat) { case 1: return u.format1.get_size (); case 2: return u.format2.get_size (); @@ -637,7 +658,7 @@ struct Coverage { } /* Returns -1 if not covered. */ - inline int get_coverage (uint16_t glyph_id) const { + int get_coverage (uint16_t glyph_id) const { switch (u.coverageFormat) { case 1: return u.format1.get_coverage(glyph_id); case 2: return u.format2.get_coverage(glyph_id); @@ -659,6 +680,10 @@ DEFINE_NULL (Coverage, 2); */ struct ClassDefFormat1 { + + friend struct ClassDef; + + private: /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount); @@ -678,6 +703,9 @@ ASSERT_SIZE (ClassDefFormat1, 6); struct ClassRangeRecord { + friend struct ClassDefFormat2; + + private: inline int get_class (uint16_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return classValue; @@ -692,6 +720,10 @@ struct ClassRangeRecord { DEFINE_NULL_ASSERT_SIZE_DATA (ClassRangeRecord, 6, "\001"); struct ClassDefFormat2 { + + friend struct ClassDef; + + private: /* ClassRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (ClassRangeRecord, rangeRecord, rangeCount); @@ -716,7 +748,7 @@ ASSERT_SIZE (ClassDefFormat2, 4); struct ClassDef { DEFINE_NON_INSTANTIABLE(ClassDef); - inline unsigned int get_size (void) const { + unsigned int get_size (void) const { switch (u.classFormat) { case 1: return u.format1.get_size (); case 2: return u.format2.get_size (); @@ -725,7 +757,7 @@ struct ClassDef { } /* Returns 0 if not found. */ - inline int get_class (uint16_t glyph_id) const { + int get_class (uint16_t glyph_id) const { switch (u.classFormat) { case 1: return u.format1.get_class(glyph_id); case 2: return u.format2.get_class(glyph_id); @@ -747,8 +779,9 @@ DEFINE_NULL (ClassDef, 2); */ struct Device { + DEFINE_NON_INSTANTIABLE(Device); - inline unsigned int get_size (void) const { + unsigned int get_size (void) const { int count = endSize - startSize + 1; if (count < 0) count = 0; switch (deltaFormat) { @@ -759,7 +792,7 @@ struct Device { } } - inline int get_delta (int ppem_size) const { + int get_delta (int ppem_size) const { if (ppem_size >= startSize && ppem_size <= endSize && deltaFormat >= 1 && deltaFormat <= 3) { int s = ppem_size - startSize; diff --git a/src/hb-private.h b/src/hb-private.h index eb5a26a4d..f67bd5718 100644 --- a/src/hb-private.h +++ b/src/hb-private.h @@ -41,6 +41,8 @@ #define HB_LIKELY G_LIKEYLY #define HB_UNLIKELY G_UNLIKELY +#define HB_UNUSED(arg) ((arg) = (arg)) + #include From fd92a3dde32fd10df30c9eeb97641bc3c15b1e9b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 24 Jan 2008 03:11:09 -0500 Subject: [PATCH 43/56] Starting public interface --- src/{Makefile => Makefile.ng} | 0 src/hb-ot-layout-gdef-private.h | 17 +++--- src/hb-ot-layout-gsub-private.h | 3 +- src/hb-ot-layout-open-private.h | 96 +++++++++++++++++++++++---------- src/hb-ot-layout-private.h | 51 ++++++++++++++++++ src/hb-ot-layout.cc | 67 +++++++++++++++++++++++ src/hb-ot-layout.h | 35 ++++++++++-- src/main.cc | 1 + 8 files changed, 227 insertions(+), 43 deletions(-) rename src/{Makefile => Makefile.ng} (100%) create mode 100644 src/hb-ot-layout-private.h create mode 100644 src/hb-ot-layout.cc diff --git a/src/Makefile b/src/Makefile.ng similarity index 100% rename from src/Makefile rename to src/Makefile.ng diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index 6442221c1..39d2d8751 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -27,16 +27,15 @@ #ifndef HB_OT_LAYOUT_GDEF_PRIVATE_H #define HB_OT_LAYOUT_GDEF_PRIVATE_H -#include "hb-private.h" -#include "hb-ot-layout.h" +#include "hb-ot-layout-private.h" #include "hb-ot-layout-open-private.h" #define DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP(Type, name) \ - inline const Type& name (uint16_t glyph_id) { \ + inline const Type& name (hb_ot_layout_glyph_t glyph_id) { \ const Coverage &c = get_coverage (); \ - int c_index = c.get_coverage (glyph_id); \ + hb_ot_layout_coverage_t c_index = c.get_coverage (glyph_id); \ return (*this)[c_index]; \ } @@ -73,7 +72,7 @@ struct AttachList { friend struct GDEF; private: - /* const AttachPoint& get_attach_points (uint16_t glyph_id); */ + /* const AttachPoint& get_attach_points (hb_ot_layout_glyph_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (AttachPoint, get_attach_points); private: @@ -206,7 +205,7 @@ struct LigCaretList { friend struct GDEF; private: - /* const LigGlyph& get_lig_glyph (uint16_t glyph_id); */ + /* const LigGlyph& get_lig_glyph (hb_ot_layout_glyph_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph); private: @@ -241,17 +240,15 @@ struct GDEF { DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef); /* Returns 0 if not found. */ - inline int get_glyph_class (uint16_t glyph_id) const { + inline int get_glyph_class (hb_ot_layout_glyph_t glyph_id) const { return get_glyph_class_def ().get_class (glyph_id); } /* Returns 0 if not found. */ - inline int get_mark_attachment_type (uint16_t glyph_id) const { + inline int get_mark_attachment_type (hb_ot_layout_glyph_t glyph_id) const { return get_mark_attach_class_def ().get_class (glyph_id); } - /* TODO get_glyph_property */ - /* TODO get_attach and get_lig_caret */ private: diff --git a/src/hb-ot-layout-gsub-private.h b/src/hb-ot-layout-gsub-private.h index 46b538e0d..8ce77054f 100644 --- a/src/hb-ot-layout-gsub-private.h +++ b/src/hb-ot-layout-gsub-private.h @@ -27,8 +27,7 @@ #ifndef HB_OT_LAYOUT_GSUB_PRIVATE_H #define HB_OT_LAYOUT_GSUB_PRIVATE_H -#include "hb-private.h" -#include "hb-ot-layout.h" +#include "hb-ot-layout-private.h" #include "hb-ot-layout-open-private.h" #include "hb-ot-layout-gdef-private.h" diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 04054df61..a095c640a 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -27,8 +27,7 @@ #ifndef HB_OT_LAYOUT_OPEN_PRIVATE_H #define HB_OT_LAYOUT_OPEN_PRIVATE_H -#include "hb-private.h" -#include "hb-ot-layout.h" +#include "hb-ot-layout-private.h" /* @@ -89,6 +88,9 @@ return *(const Type *)((const char*)this + array[i]); \ } +/* A record array type is like an array type, but it contains a table + * of records to the objects. Each record has a tag, and an offset + * relative to the beginning of the current object. */ #define DEFINE_RECORD_ARRAY_TYPE(Type, array, num) \ DEFINE_RECORD_ACCESSOR(Type, array, num) \ DEFINE_LEN_AND_SIZE(Record, array, num) @@ -104,6 +106,37 @@ } \ /* TODO: implement find_tag() */ + +#define DEFINE_ARRAY_INTERFACE(Type, name) \ + inline const Type& get_##name (unsigned int i) const { \ + return (*this)[i]; \ + } \ + inline unsigned int get_##name##_count (void) const { \ + return this->get_len (); \ + } +#define DEFINE_INDEX_ARRAY_INTERFACE(name) \ + inline unsigned int get_##name##_index (unsigned int i) const { \ + return (*this)[i]; \ + } \ + inline unsigned int get_##name##_count (void) const { \ + return this->get_len (); \ + } + +#define DEFINE_FIND_TAG_INTERFACE(Type, name) \ + inline const Type* find_##name (hb_tag_t tag) const { \ + for (unsigned int i = 0; i < this->get_len (); i++) \ + if (tag == (*this)[i].tag) \ + return &(*this)[i]; \ + return NULL; \ + } \ + inline const Type& get_##name_by_tag (hb_tag_t tag) const { \ + for (unsigned int i = 0; i < this->get_len (); i++) \ + if (tag == (*this)[i].tag) \ + return (*this)[i]; \ + return Null##Type; \ + } + + /* * List types */ @@ -144,13 +177,15 @@ /* get_for_data() is a static class method returning a reference to an * instance of Type located at the input data location. It's just a * fancy cast! */ -#define STATIC_DEFINE_GET_FOR_DATA0(const, Type) \ - static inline const Type& get_for_data (const char *data) { \ - return *(const Type*)data; \ - } #define STATIC_DEFINE_GET_FOR_DATA(Type) \ - STATIC_DEFINE_GET_FOR_DATA0(const, Type) \ - STATIC_DEFINE_GET_FOR_DATA0( , Type) + static inline const Type& get_for_data (const char *data) { \ + extern const Type &Null##Type; \ + if (HB_UNLIKELY (data == NULL)) return Null##Type; \ + return *(const Type*)data; \ + } \ + static inline Type& get_for_data (char *data) { \ + return *(Type*)data; \ + } #define DEFINE_ACCESSOR(Type, name, Name) \ @@ -297,8 +332,9 @@ struct TTCHeader; typedef struct TableDirectory { - friend struct OpenTypeFontFile; + friend struct OffsetTable; + inline bool is_null (void) const { return length == 0; } inline const Tag& get_tag (void) const { return tag; } inline unsigned long get_checksum (void) const { return checkSum; } inline unsigned long get_offset (void) const { return offset; } @@ -312,17 +348,19 @@ typedef struct TableDirectory { ULONG length; /* Length of this table. */ } OpenTypeTable; DEFINE_NULL_ASSERT_SIZE (TableDirectory, 16); +DEFINE_NULL_ALIAS (OpenTypeTable, TableDirectory); typedef struct OffsetTable { friend struct OpenTypeFontFile; friend struct TTCHeader; - // XXX private: - // Add get_num_tables and get_table... + DEFINE_ARRAY_INTERFACE (OpenTypeTable, table); + DEFINE_FIND_TAG_INTERFACE (OpenTypeTable, table); + + private: /* OpenTypeTables, in no particular order */ DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables); - // TODO: Implement find_table private: Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */ @@ -427,9 +465,9 @@ typedef struct Record { DEFINE_NULL_ASSERT_SIZE (Record, 6); struct LangSys { - /* Feature indices, in no particular order */ - DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount); - + + DEFINE_INDEX_ARRAY_INTERFACE (feature); + /* Returns -1 if none */ inline int get_required_feature_index (void) const { if (reqFeatureIndex == 0xffff) @@ -437,7 +475,9 @@ struct LangSys { return reqFeatureIndex;; } - /* TODO implement find_feature */ + private: + /* Feature indices, in no particular order */ + DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount); private: Offset lookupOrder; /* = Null (reserved for an offset to a @@ -490,6 +530,10 @@ private: DEFINE_NULL_ASSERT_SIZE (ScriptList, 2); struct Feature { + + DEFINE_INDEX_ARRAY_INTERFACE (lookup); + + private: /* LookupList indices, in no particular order */ DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount); @@ -583,7 +627,7 @@ struct CoverageFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); - inline int get_coverage (uint16_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { GlyphID gid; gid = glyph_id; // TODO: bsearch @@ -605,7 +649,7 @@ struct CoverageRangeRecord { friend struct CoverageFormat2; private: - inline int get_coverage (uint16_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return startCoverageIndex + (glyph_id - start); return -1; @@ -627,7 +671,7 @@ struct CoverageFormat2 { /* CoverageRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount); - inline int get_coverage (uint16_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { // TODO: bsearch for (unsigned int i = 0; i < rangeCount; i++) { int coverage = rangeRecord[i].get_coverage (glyph_id); @@ -657,8 +701,7 @@ struct Coverage { } } - /* Returns -1 if not covered. */ - int get_coverage (uint16_t glyph_id) const { + hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { switch (u.coverageFormat) { case 1: return u.format1.get_coverage(glyph_id); case 2: return u.format2.get_coverage(glyph_id); @@ -687,7 +730,7 @@ struct ClassDefFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount); - inline int get_class (uint16_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { if (glyph_id >= startGlyph && glyph_id < startGlyph + glyphCount) return classValueArray[glyph_id - startGlyph]; return 0; @@ -706,7 +749,7 @@ struct ClassRangeRecord { friend struct ClassDefFormat2; private: - inline int get_class (uint16_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return classValue; return 0; @@ -727,7 +770,7 @@ struct ClassDefFormat2 { /* ClassRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (ClassRangeRecord, rangeRecord, rangeCount); - inline int get_class (uint16_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { // TODO: bsearch for (int i = 0; i < rangeCount; i++) { int classValue = rangeRecord[i].get_class (glyph_id); @@ -756,8 +799,7 @@ struct ClassDef { } } - /* Returns 0 if not found. */ - int get_class (uint16_t glyph_id) const { + hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { switch (u.classFormat) { case 1: return u.format1.get_class(glyph_id); case 2: return u.format2.get_class(glyph_id); @@ -835,8 +877,6 @@ typedef struct GSUBGPOS { DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list, get_feature(i) */ DEFINE_LIST_ACCESSOR(Lookup, lookup); /* get_lookup_list, get_lookup(i) */ - /* TODO implement find_script */ - private: Fixed_Version version; /* Version of the GSUB/GPOS table--initially set * to 0x00010000 */ diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h new file mode 100644 index 000000000..c364b2198 --- /dev/null +++ b/src/hb-ot-layout-private.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_LAYOUT_PRIVATE_H +#define HB_OT_LAYOUT_PRIVATE_H + +#ifndef HB_OT_LAYOUT_CC +#error "This file should only be included from hb-ot-layout.c" +#endif + +#include "hb-private.h" +#include "hb-ot-layout.h" + +struct GDEF; +struct GSUB; +struct GPOS; + +HB_BEGIN_DECLS(); + +struct _HB_OT_Layout { + GDEF *gdef; + GSUB *gsub; + GPOS *gpos; +}; + +HB_END_DECLS(); + +#endif /* HB_OT_LAYOUT_PRIVATE_H */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc new file mode 100644 index 000000000..ca3b951ac --- /dev/null +++ b/src/hb-ot-layout.cc @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + +#define HB_OT_LAYOUT_CC + +#include "hb-ot-layout.h" +#include "hb-ot-layout-private.h" + +#include "hb-ot-layout-open-private.h" +#include "hb-ot-layout-gdef-private.h" +#include "hb-ot-layout-gsub-private.h" + +#include + +HB_OT_Layout * +hb_ot_layout_create (const char *font_data, + int face_index) +{ + HB_OT_Layout *layout = (HB_OT_Layout *) calloc (1, sizeof (HB_OT_Layout)); + + const OpenTypeFontFile &ot = OpenTypeFontFile::get_for_data (font_data); + const OpenTypeFontFace &font = ot[face_index]; + + layout->gdef = font.find_table (GDEF::Tag); + layout->gsub = font.find_table (GSUB::Tag); + layout->gpos = font.find_table (GPOS::Tag); + + return layout; +} + +void +hb_ot_layout_destroy (HB_OT_Layout *layout) +{ + free (layout); +} + +hb_ot_layout_glyph_properties_t +hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph); + +void +hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph, + hb_ot_layout_glyph_properties_t properties); diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 554be08a5..786e4acff 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -24,8 +24,8 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_OT_LAYOUT_OPEN_H -#define HB_OT_LAYOUT_OPEN_H +#ifndef HB_OT_LAYOUT_H +#define HB_OT_LAYOUT_H #include "hb-common.h" @@ -38,6 +38,35 @@ typedef uint32_t hb_tag_t; ((const char *) s)[2], \ ((const char *) s)[3])) +typedef uint16_t hb_ot_layout_glyph_properties_t; +typedef uint16_t hb_ot_layout_glyph_t; +typedef uint16_t hb_ot_layout_class_t; +typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */ + +typedef struct _HB_OT_Layout HB_OT_Layout; + +HB_OT_Layout * +hb_ot_layout_create (const char *font_data, + int face_index); + +void +hb_ot_layout_destroy (HB_OT_Layout *layout); + +/* TODO +HB_OT_Layout * +hb_ot_layout_create_sanitize (char *data, + make_writable_func); +*/ + +hb_ot_layout_glyph_properties_t +hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph); + +void +hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph, + hb_ot_layout_glyph_properties_t properties); + HB_END_DECLS(); -#endif /* HB_OT_LAYOUT_OPEN_H */ +#endif /* HB_OT_LAYOUT_H */ diff --git a/src/main.cc b/src/main.cc index edb805a1d..41a70c739 100644 --- a/src/main.cc +++ b/src/main.cc @@ -24,6 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ +#define HB_OT_LAYOUT_CC #include "hb-ot-layout-open-private.h" #include "hb-ot-layout-gdef-private.h" #include "hb-ot-layout-gsub-private.h" From ead428d7a0bf4dc84340a99f3959e5cc58123e99 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 24 Jan 2008 03:54:09 -0500 Subject: [PATCH 44/56] More public api --- src/hb-ot-layout-open-private.h | 32 +++++++++++++++++++------------- src/hb-ot-layout-private.h | 9 ++++++--- src/hb-ot-layout.cc | 21 ++++++++++++++------- src/hb-ot-layout.h | 2 -- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index a095c640a..3d125d987 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -34,6 +34,8 @@ * Int types */ +/* XXX define these as structs of chars on machines that do not allow + * unaligned access */ #define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN) \ inline NAME& operator = (TYPE i) { v = BIG_ENDIAN(i); return *this; } \ inline operator TYPE(void) const { return BIG_ENDIAN(v); } \ @@ -100,11 +102,7 @@ if (HB_UNLIKELY (!array[i].offset)) return Null##Type; \ return *(const Type *)((const char*)this + array[i].offset); \ } \ - inline const Tag& get_tag (unsigned int i) const { \ - if (HB_UNLIKELY (i >= num)) return NullTag; \ - return array[i].tag; \ - } \ - /* TODO: implement find_tag() */ + /* TODO: implement find_tag() and get_tag() publicly */ #define DEFINE_ARRAY_INTERFACE(Type, name) \ @@ -332,10 +330,11 @@ struct TTCHeader; typedef struct TableDirectory { + friend struct OpenTypeFontFile; friend struct OffsetTable; inline bool is_null (void) const { return length == 0; } - inline const Tag& get_tag (void) const { return tag; } + inline hb_tag_t get_tag (void) const { return tag; } inline unsigned long get_checksum (void) const { return checkSum; } inline unsigned long get_offset (void) const { return offset; } inline unsigned long get_length (void) const { return length; } @@ -409,17 +408,25 @@ struct OpenTypeFontFile { STATIC_DEFINE_GET_FOR_DATA (OpenTypeFontFile); + DEFINE_ARRAY_INTERFACE (OpenTypeFontFace, face); + + inline hb_tag_t get_tag (void) const { return tag; } + /* This is how you get a table */ - inline const char* get_table (const OpenTypeTable& table) const { - return ((const char*)this) + table.offset; + inline const char* get_table_data (const OpenTypeTable& table) const { + return (*this)[table]; } - inline char* get_table (const OpenTypeTable& table) { - return ((char*)this) + table.offset; + inline char* get_table_data (const OpenTypeTable& table) { + return (*this)[table]; } + + private: inline const char* operator[] (const OpenTypeTable& table) const { + if (G_UNLIKELY (table.offset == 0)) return NULL; return ((const char*)this) + table.offset; } inline char* operator[] (const OpenTypeTable& table) { + if (G_UNLIKELY (table.offset == 0)) return NULL; return ((char*)this) + table.offset; } @@ -438,7 +445,6 @@ struct OpenTypeFontFile { case TTCTag: return ((const TTCHeader&)*this)[i]; } } - inline const Tag& get_tag (void) const { return tag; } private: Tag tag; /* 4-byte identifier. */ @@ -731,7 +737,7 @@ struct ClassDefFormat1 { DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount); inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { - if (glyph_id >= startGlyph && glyph_id < startGlyph + glyphCount) + if (glyph_id >= startGlyph && glyph_id - startGlyph < glyphCount) return classValueArray[glyph_id - startGlyph]; return 0; } @@ -799,7 +805,7 @@ struct ClassDef { } } - hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { switch (u.classFormat) { case 1: return u.format1.get_class(glyph_id); case 2: return u.format2.get_class(glyph_id); diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index c364b2198..8327197e4 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -34,6 +34,9 @@ #include "hb-private.h" #include "hb-ot-layout.h" +typedef uint16_t hb_ot_layout_class_t; +typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */ + struct GDEF; struct GSUB; struct GPOS; @@ -41,9 +44,9 @@ struct GPOS; HB_BEGIN_DECLS(); struct _HB_OT_Layout { - GDEF *gdef; - GSUB *gsub; - GPOS *gpos; + const GDEF *gdef; + const GSUB *gsub; + const GPOS *gpos; }; HB_END_DECLS(); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index ca3b951ac..827aa23ed 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -41,12 +41,12 @@ hb_ot_layout_create (const char *font_data, { HB_OT_Layout *layout = (HB_OT_Layout *) calloc (1, sizeof (HB_OT_Layout)); - const OpenTypeFontFile &ot = OpenTypeFontFile::get_for_data (font_data); - const OpenTypeFontFace &font = ot[face_index]; + const OpenTypeFontFile &font = OpenTypeFontFile::get_for_data (font_data); + const OpenTypeFontFace &face = font.get_face (face_index); - layout->gdef = font.find_table (GDEF::Tag); - layout->gsub = font.find_table (GSUB::Tag); - layout->gpos = font.find_table (GPOS::Tag); + layout->gdef = &GDEF::get_for_data (font.get_table_data (face.get_table (GDEF::Tag))); + layout->gsub = &GSUB::get_for_data (font.get_table_data (face.get_table (GSUB::Tag))); +//layout->gpos = &GPOS::get_for_data (font.get_table_data (face.get_table (GPOS::Tag))); return layout; } @@ -59,9 +59,16 @@ hb_ot_layout_destroy (HB_OT_Layout *layout) hb_ot_layout_glyph_properties_t hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph); + hb_ot_layout_glyph_t glyph) +{ + +} void hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout, hb_ot_layout_glyph_t glyph, - hb_ot_layout_glyph_properties_t properties); + hb_ot_layout_glyph_properties_t properties) +{ + +} + diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 786e4acff..8419d36b1 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -40,8 +40,6 @@ typedef uint32_t hb_tag_t; typedef uint16_t hb_ot_layout_glyph_properties_t; typedef uint16_t hb_ot_layout_glyph_t; -typedef uint16_t hb_ot_layout_class_t; -typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */ typedef struct _HB_OT_Layout HB_OT_Layout; From aff831ed6787abe8e24a977e34d97ff2e0b7dc21 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 24 Jan 2008 06:03:45 -0500 Subject: [PATCH 45/56] Implement glyph properties --- src/hb-ot-layout-gdef-private.h | 10 +++- src/hb-ot-layout-private.h | 16 ++++++- src/hb-ot-layout.cc | 84 ++++++++++++++++++++++++++++++--- src/hb-ot-layout.h | 25 +++++++--- 4 files changed, 117 insertions(+), 18 deletions(-) diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index 39d2d8751..5d4759f93 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -231,6 +231,12 @@ DEFINE_NULL_ASSERT_SIZE (LigCaretList, 4); struct GDEF { static const hb_tag_t Tag = HB_TAG ('G','D','E','F'); + static const hb_ot_layout_class_t UnclassifiedGlyph = 0; + static const hb_ot_layout_class_t BaseGlyph = 1; + static const hb_ot_layout_class_t LigatureGlyph = 2; + static const hb_ot_layout_class_t MarkGlyph = 3; + static const hb_ot_layout_class_t ComponentGlyph = 4; + STATIC_DEFINE_GET_FOR_DATA (GDEF); /* XXX check version here? */ @@ -240,12 +246,12 @@ struct GDEF { DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef); /* Returns 0 if not found. */ - inline int get_glyph_class (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_glyph_class (hb_ot_layout_glyph_t glyph_id) const { return get_glyph_class_def ().get_class (glyph_id); } /* Returns 0 if not found. */ - inline int get_mark_attachment_type (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_mark_attachment_type (hb_ot_layout_glyph_t glyph_id) const { return get_mark_attach_class_def ().get_class (glyph_id); } diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index 8327197e4..55f14f8ab 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -35,20 +35,32 @@ #include "hb-ot-layout.h" typedef uint16_t hb_ot_layout_class_t; +typedef uint16_t hb_ot_layout_glyph_properties_t; typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */ struct GDEF; struct GSUB; struct GPOS; -HB_BEGIN_DECLS(); - struct _HB_OT_Layout { const GDEF *gdef; const GSUB *gsub; const GPOS *gpos; + + struct { + uint8_t *klasses; + unsigned int len; + } new_gdef; + }; + +HB_BEGIN_DECLS(); + +static hb_ot_layout_glyph_properties_t +_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph); + HB_END_DECLS(); #endif /* HB_OT_LAYOUT_PRIVATE_H */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 827aa23ed..5fc9f8f57 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -34,6 +34,8 @@ #include "hb-ot-layout-gsub-private.h" #include +#include + HB_OT_Layout * hb_ot_layout_create (const char *font_data, @@ -57,18 +59,86 @@ hb_ot_layout_destroy (HB_OT_Layout *layout) free (layout); } -hb_ot_layout_glyph_properties_t -hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph) +static hb_ot_layout_glyph_properties_t +_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph) { + hb_ot_layout_class_t klass; + /* TODO old harfbuzz doesn't always parse mark attachments as it says it was + * introduced without a version bump, so it may not be safe */ + klass = layout->gdef->get_mark_attachment_type (glyph); + if (klass) + return klass << 8; + + klass = layout->gdef->get_glyph_class (glyph); + + if (!klass && glyph < layout->new_gdef.len) + klass = layout->new_gdef.klasses[glyph]; + + switch (klass) { + default: + case GDEF::UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED; + case GDEF::BaseGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH; + case GDEF::LigatureGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE; + case GDEF::MarkGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_MARK; + case GDEF::ComponentGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT; + } +} + +hb_ot_layout_glyph_class_t +hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph) +{ + hb_ot_layout_glyph_properties_t properties; + hb_ot_layout_class_t klass; + + properties = _hb_ot_layout_get_glyph_properties (layout, glyph); + + if (properties & 0xFF) + return HB_OT_LAYOUT_GLYPH_CLASS_MARK; + + return (hb_ot_layout_glyph_class_t) properties; } void -hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph, - hb_ot_layout_glyph_properties_t properties) +hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph, + hb_ot_layout_glyph_class_t klass) { + /* TODO optimize this, similar to old harfbuzz code for example */ + /* TODO our semantics are a bit different from old harfbuzz code too */ + hb_ot_layout_class_t gdef_klass; + int len = layout->new_gdef.len; + + if (glyph >= len) { + int new_len; + uint8_t *new_klasses; + + new_len = len == 0 ? 120 : 2 * len; + if (new_len > 65535) + new_len = 65535; + new_klasses = (uint8_t *) realloc (layout->new_gdef.klasses, new_len * sizeof (uint8_t)); + + if (G_UNLIKELY (!new_klasses)) + return; + + memset (new_klasses + len, 0, new_len - len); + + layout->new_gdef.klasses = new_klasses; + layout->new_gdef.len = new_len; + } + + switch (klass) { + default: + case HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED: gdef_klass = GDEF::UnclassifiedGlyph; break; + case HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH: gdef_klass = GDEF::BaseGlyph; break; + case HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE: gdef_klass = GDEF::LigatureGlyph; break; + case HB_OT_LAYOUT_GLYPH_CLASS_MARK: gdef_klass = GDEF::MarkGlyph; break; + case HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT: gdef_klass = GDEF::ComponentGlyph; break; + } + + layout->new_gdef.klasses[glyph] = gdef_klass; + return; } - diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 8419d36b1..e0eb054e7 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -38,9 +38,20 @@ typedef uint32_t hb_tag_t; ((const char *) s)[2], \ ((const char *) s)[3])) -typedef uint16_t hb_ot_layout_glyph_properties_t; +typedef enum { + HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0x0000, + HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 0x0002, + HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 0x0004, + HB_OT_LAYOUT_GLYPH_CLASS_MARK = 0x0008, + HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 0x0010 +} hb_ot_layout_glyph_class_t; + typedef uint16_t hb_ot_layout_glyph_t; +/* + * HB_OT_Layout + */ + typedef struct _HB_OT_Layout HB_OT_Layout; HB_OT_Layout * @@ -56,14 +67,14 @@ hb_ot_layout_create_sanitize (char *data, make_writable_func); */ -hb_ot_layout_glyph_properties_t -hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph); +hb_ot_layout_glyph_class_t +hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph); void -hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph, - hb_ot_layout_glyph_properties_t properties); +hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph, + hb_ot_layout_glyph_class_t klass); HB_END_DECLS(); From 590d55cbb9e21ef74dfd88eee51fd0a763958cd2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 24 Jan 2008 19:13:50 -0500 Subject: [PATCH 46/56] [GDEF] Finish public API --- src/hb-common.h | 11 +++ src/hb-ot-layout-gdef-private.h | 28 ++++---- src/hb-ot-layout-open-private.h | 25 ++++--- src/hb-ot-layout-private.h | 23 ++---- src/hb-ot-layout.cc | 123 +++++++++++++++++++++++++++++--- src/hb-ot-layout.h | 29 ++++---- 6 files changed, 176 insertions(+), 63 deletions(-) diff --git a/src/hb-common.h b/src/hb-common.h index 9899a705d..c60ad8404 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -37,4 +37,15 @@ # define HB_END_DECLS() extern int hb_dummy_prototype (int) # endif /* !__cplusplus */ +typedef int hb_bool_t; + +typedef uint32_t hb_tag_t; +#define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d)) +#define HB_TAG_STR(s) (HB_TAG(((const char *) s)[0], \ + ((const char *) s)[1], \ + ((const char *) s)[2], \ + ((const char *) s)[3])) + +typedef uint16_t hb_glyph_t; + #endif /* HB_COMMON_H */ diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index 5d4759f93..447ee0e4a 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -33,7 +33,7 @@ #define DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP(Type, name) \ - inline const Type& name (hb_ot_layout_glyph_t glyph_id) { \ + inline const Type& name (hb_glyph_t glyph_id) { \ const Coverage &c = get_coverage (); \ hb_ot_layout_coverage_t c_index = c.get_coverage (glyph_id); \ return (*this)[c_index]; \ @@ -72,13 +72,13 @@ struct AttachList { friend struct GDEF; private: - /* const AttachPoint& get_attach_points (hb_ot_layout_glyph_t glyph_id); */ + /* const AttachPoint& get_attach_points (hb_glyph_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (AttachPoint, get_attach_points); private: /* AttachPoint tables, in Coverage Index order */ DEFINE_OFFSET_ARRAY_TYPE (AttachPoint, attachPoint, glyphCount); - DEFINE_ACCESSOR (Coverage, get_coverage, coverage); + DEFINE_GET_ACCESSOR (Coverage, coverage, coverage); private: Offset coverage; /* Offset to Coverage table -- from @@ -205,13 +205,13 @@ struct LigCaretList { friend struct GDEF; private: - /* const LigGlyph& get_lig_glyph (hb_ot_layout_glyph_t glyph_id); */ + /* const LigGlyph& get_lig_glyph (hb_glyph_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph); private: /* AttachPoint tables, in Coverage Index order */ DEFINE_OFFSET_ARRAY_TYPE (LigGlyph, ligGlyph, ligGlyphCount); - DEFINE_ACCESSOR (Coverage, get_coverage, coverage); + DEFINE_GET_ACCESSOR (Coverage, coverage, coverage); private: Offset coverage; /* Offset to Coverage table--from @@ -240,19 +240,17 @@ struct GDEF { STATIC_DEFINE_GET_FOR_DATA (GDEF); /* XXX check version here? */ - DEFINE_ACCESSOR (ClassDef, get_glyph_class_def, glyphClassDef); - DEFINE_ACCESSOR (AttachList, get_attach_list, attachList); - DEFINE_ACCESSOR (LigCaretList, get_lig_caret_list, ligCaretList); - DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef); + DEFINE_GET_HAS_ACCESSOR (ClassDef, glyph_classes, glyphClassDef); + DEFINE_GET_HAS_ACCESSOR (AttachList, attach_list, attachList); + DEFINE_GET_HAS_ACCESSOR (LigCaretList, lig_caret_list, ligCaretList); + DEFINE_GET_HAS_ACCESSOR (ClassDef, mark_attachment_types, markAttachClassDef); - /* Returns 0 if not found. */ - inline hb_ot_layout_class_t get_glyph_class (hb_ot_layout_glyph_t glyph_id) const { - return get_glyph_class_def ().get_class (glyph_id); + inline hb_ot_layout_class_t get_glyph_class (hb_glyph_t glyph_id) const { + return get_glyph_classes ().get_class (glyph_id); } - /* Returns 0 if not found. */ - inline hb_ot_layout_class_t get_mark_attachment_type (hb_ot_layout_glyph_t glyph_id) const { - return get_mark_attach_class_def ().get_class (glyph_id); + inline hb_ot_layout_class_t get_mark_attachment_type (hb_glyph_t glyph_id) const { + return get_mark_attachment_types ().get_class (glyph_id); } /* TODO get_attach and get_lig_caret */ diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 3d125d987..94ff209bf 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -186,11 +186,16 @@ } -#define DEFINE_ACCESSOR(Type, name, Name) \ - inline const Type& name (void) const { \ +#define DEFINE_GET_ACCESSOR(Type, name, Name) \ + inline const Type& get_##name (void) const { \ if (HB_UNLIKELY (!Name)) return Null##Type; \ return *(const Type*)((const char*)this + Name); \ } +#define DEFINE_GET_HAS_ACCESSOR(Type, name, Name) \ + DEFINE_GET_ACCESSOR (Type, name, Name); \ + inline bool has_##name (void) const { \ + return Name != 0; \ + } @@ -633,7 +638,7 @@ struct CoverageFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); - inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { GlyphID gid; gid = glyph_id; // TODO: bsearch @@ -655,7 +660,7 @@ struct CoverageRangeRecord { friend struct CoverageFormat2; private: - inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return startCoverageIndex + (glyph_id - start); return -1; @@ -677,7 +682,7 @@ struct CoverageFormat2 { /* CoverageRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount); - inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { // TODO: bsearch for (unsigned int i = 0; i < rangeCount; i++) { int coverage = rangeRecord[i].get_coverage (glyph_id); @@ -707,7 +712,7 @@ struct Coverage { } } - hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { + hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { switch (u.coverageFormat) { case 1: return u.format1.get_coverage(glyph_id); case 2: return u.format2.get_coverage(glyph_id); @@ -736,7 +741,7 @@ struct ClassDefFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount); - inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { if (glyph_id >= startGlyph && glyph_id - startGlyph < glyphCount) return classValueArray[glyph_id - startGlyph]; return 0; @@ -755,7 +760,7 @@ struct ClassRangeRecord { friend struct ClassDefFormat2; private: - inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return classValue; return 0; @@ -776,7 +781,7 @@ struct ClassDefFormat2 { /* ClassRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (ClassRangeRecord, rangeRecord, rangeCount); - inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { // TODO: bsearch for (int i = 0; i < rangeCount; i++) { int classValue = rangeRecord[i].get_class (glyph_id); @@ -805,7 +810,7 @@ struct ClassDef { } } - inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { + hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { switch (u.classFormat) { case 1: return u.format1.get_class(glyph_id); case 2: return u.format2.get_class(glyph_id); diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index 55f14f8ab..f5fc30e14 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -38,28 +38,15 @@ typedef uint16_t hb_ot_layout_class_t; typedef uint16_t hb_ot_layout_glyph_properties_t; typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */ -struct GDEF; -struct GSUB; -struct GPOS; - -struct _HB_OT_Layout { - const GDEF *gdef; - const GSUB *gsub; - const GPOS *gpos; - - struct { - uint8_t *klasses; - unsigned int len; - } new_gdef; - -}; - HB_BEGIN_DECLS(); static hb_ot_layout_glyph_properties_t -_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph); +_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, + hb_glyph_t glyph); + +static hb_bool_t +_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout); HB_END_DECLS(); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 5fc9f8f57..8b9b90541 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -37,6 +37,18 @@ #include +struct _HB_OT_Layout { + const GDEF *gdef; + const GSUB *gsub; +//const GPOS *gpos; + + struct { + unsigned char *klasses; + unsigned int len; + } new_gdef; + +}; + HB_OT_Layout * hb_ot_layout_create (const char *font_data, int face_index) @@ -59,9 +71,25 @@ hb_ot_layout_destroy (HB_OT_Layout *layout) free (layout); } +/* + * GDEF + */ + +hb_bool_t +hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout) +{ + return layout->gdef->has_glyph_classes (); +} + +static hb_bool_t +_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout) +{ + return layout->new_gdef.len > 0; +} + static hb_ot_layout_glyph_properties_t -_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph) +_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, + hb_glyph_t glyph) { hb_ot_layout_class_t klass; @@ -86,9 +114,68 @@ _hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, } } +#if 0 +static bool +_hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, + HB_GlyphItem gitem, + HB_UShort flags, + HB_UShort* property) +{ + HB_Error error; + + if ( gdef ) + { + HB_UShort basic_glyph_class; + HB_UShort desired_attachment_class; + + if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN ) + { + error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties ); + if ( error ) + return error; + } + + *property = gitem->gproperties; + + /* If the glyph was found in the MarkAttachmentClass table, + * then that class value is the high byte of the result, + * otherwise the low byte contains the basic type of the glyph + * as defined by the GlyphClassDef table. + */ + if ( *property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) + basic_glyph_class = HB_GDEF_MARK; + else + basic_glyph_class = *property; + + /* Return Not_Covered, if, for example, basic_glyph_class + * is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES + */ + if ( flags & basic_glyph_class ) + return HB_Err_Not_Covered; + + /* The high byte of LookupFlags has the meaning + * "ignore marks of attachment type different than + * the attachment type specified." + */ + desired_attachment_class = flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS; + if ( desired_attachment_class ) + { + if ( basic_glyph_class == HB_GDEF_MARK && + *property != desired_attachment_class ) + return HB_Err_Not_Covered; + } + } else { + *property = 0; + } + + return HB_Err_Ok; +} +#endif + + hb_ot_layout_glyph_class_t -hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph) +hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, + hb_glyph_t glyph) { hb_ot_layout_glyph_properties_t properties; hb_ot_layout_class_t klass; @@ -103,23 +190,22 @@ hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, void hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph, + hb_glyph_t glyph, hb_ot_layout_glyph_class_t klass) { /* TODO optimize this, similar to old harfbuzz code for example */ - /* TODO our semantics are a bit different from old harfbuzz code too */ hb_ot_layout_class_t gdef_klass; int len = layout->new_gdef.len; if (glyph >= len) { int new_len; - uint8_t *new_klasses; + unsigned char *new_klasses; new_len = len == 0 ? 120 : 2 * len; if (new_len > 65535) new_len = 65535; - new_klasses = (uint8_t *) realloc (layout->new_gdef.klasses, new_len * sizeof (uint8_t)); + new_klasses = (unsigned char *) realloc (layout->new_gdef.klasses, new_len * sizeof (unsigned char)); if (G_UNLIKELY (!new_klasses)) return; @@ -142,3 +228,24 @@ hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, layout->new_gdef.klasses[glyph] = gdef_klass; return; } + +void +hb_ot_layout_build_glyph_classes (HB_OT_Layout *layout, + uint16_t num_total_glyphs, + hb_glyph_t *glyphs, + unsigned char *klasses, + uint16_t count) +{ + int i; + + if (G_UNLIKELY (!count || !glyphs || !klasses)) + return; + + if (layout->new_gdef.len == 0) { + layout->new_gdef.klasses = (unsigned char *) calloc (num_total_glyphs, sizeof (unsigned char)); + layout->new_gdef.len = count; + } + + for (i = 0; i < count; i++) + hb_ot_layout_set_glyph_class (layout, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]); +} diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index e0eb054e7..4ac6e380f 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -31,13 +31,6 @@ HB_BEGIN_DECLS(); -typedef uint32_t hb_tag_t; -#define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d)) -#define HB_TAG_STR(s) (HB_TAG(((const char *) s)[0], \ - ((const char *) s)[1], \ - ((const char *) s)[2], \ - ((const char *) s)[3])) - typedef enum { HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0x0000, HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 0x0002, @@ -46,8 +39,6 @@ typedef enum { HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 0x0010 } hb_ot_layout_glyph_class_t; -typedef uint16_t hb_ot_layout_glyph_t; - /* * HB_OT_Layout */ @@ -67,15 +58,29 @@ hb_ot_layout_create_sanitize (char *data, make_writable_func); */ +/* + * GDEF + */ + +hb_bool_t +hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout); + hb_ot_layout_glyph_class_t -hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph); +hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, + hb_glyph_t glyph); void hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph, + hb_glyph_t glyph, hb_ot_layout_glyph_class_t klass); +void +hb_ot_layout_build_glyph_classes (HB_OT_Layout *layout, + uint16_t num_total_glyphs, + hb_glyph_t *glyphs, + unsigned char *klasses, + uint16_t count); + HB_END_DECLS(); #endif /* HB_OT_LAYOUT_H */ From 6f425b11799aa20dab553085f05744191b7318e2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 24 Jan 2008 19:38:56 -0500 Subject: [PATCH 47/56] [GDEF] Finish internal API --- src/hb-ot-layout-private.h | 15 +++++- src/hb-ot-layout.cc | 95 ++++++++++++++++++-------------------- src/hb-ot-layout.h | 16 +++---- 3 files changed, 66 insertions(+), 60 deletions(-) diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index f5fc30e14..e0b7be03c 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -34,19 +34,30 @@ #include "hb-private.h" #include "hb-ot-layout.h" +/* XXX */ +#include "harfbuzz-buffer.h" + + typedef uint16_t hb_ot_layout_class_t; typedef uint16_t hb_ot_layout_glyph_properties_t; +typedef uint16_t hb_ot_layout_lookup_flags_t; typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */ HB_BEGIN_DECLS(); +static hb_bool_t +_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout); + static hb_ot_layout_glyph_properties_t _hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, hb_glyph_t glyph); -static hb_bool_t -_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout); +static bool +_hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, + HB_GlyphItem gitem, + hb_ot_layout_lookup_flags_t lookup_flags, + hb_ot_layout_glyph_properties_t *property); HB_END_DECLS(); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 8b9b90541..faad280db 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1,4 +1,6 @@ /* + * Copyright (C) 1998-2004 David Turner and Werner Lemberg + * Copyright (C) 2006 Behdad Esfahbod * Copyright (C) 2007,2008 Red Hat, Inc. * * This is part of HarfBuzz, an OpenType Layout engine library. @@ -33,6 +35,7 @@ #include "hb-ot-layout-gdef-private.h" #include "hb-ot-layout-gsub-private.h" + #include #include @@ -114,63 +117,55 @@ _hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, } } -#if 0 static bool -_hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, - HB_GlyphItem gitem, - HB_UShort flags, - HB_UShort* property) +_hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, + HB_GlyphItem gitem, + hb_ot_layout_lookup_flags_t lookup_flags, + hb_ot_layout_glyph_properties_t *property) { - HB_Error error; + /* TODO ugh, clean this mess up */ + hb_ot_layout_glyph_class_t basic_glyph_class; + hb_ot_layout_glyph_properties_t desired_attachment_class; - if ( gdef ) + if (gitem->gproperties == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED) { - HB_UShort basic_glyph_class; - HB_UShort desired_attachment_class; - - if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN ) - { - error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties ); - if ( error ) - return error; - } - - *property = gitem->gproperties; - - /* If the glyph was found in the MarkAttachmentClass table, - * then that class value is the high byte of the result, - * otherwise the low byte contains the basic type of the glyph - * as defined by the GlyphClassDef table. - */ - if ( *property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) - basic_glyph_class = HB_GDEF_MARK; - else - basic_glyph_class = *property; - - /* Return Not_Covered, if, for example, basic_glyph_class - * is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES - */ - if ( flags & basic_glyph_class ) - return HB_Err_Not_Covered; - - /* The high byte of LookupFlags has the meaning - * "ignore marks of attachment type different than - * the attachment type specified." - */ - desired_attachment_class = flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS; - if ( desired_attachment_class ) - { - if ( basic_glyph_class == HB_GDEF_MARK && - *property != desired_attachment_class ) - return HB_Err_Not_Covered; - } - } else { - *property = 0; + gitem->gproperties = _hb_ot_layout_get_glyph_properties (layout, gitem->gindex); + if (gitem->gproperties == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED) + return false; } - return HB_Err_Ok; + *property = gitem->gproperties; + + /* If the glyph was found in the MarkAttachmentClass table, + * then that class value is the high byte of the result, + * otherwise the low byte contains the basic type of the glyph + * as defined by the GlyphClassDef table. + */ + if (*property & LookupFlag::MarkAttachmentType) + basic_glyph_class = HB_OT_LAYOUT_GLYPH_CLASS_MARK; + else + basic_glyph_class = (hb_ot_layout_glyph_class_t) *property; + + /* Not covered, if, for example, basic_glyph_class + * is HB_GDEF_LIGATURE and lookup_flags includes LookupFlags::IgnoreLigatures + */ + if (lookup_flags & basic_glyph_class) + return false; + + /* The high byte of lookup_flags has the meaning + * "ignore marks of attachment type different than + * the attachment type specified." + */ + desired_attachment_class = lookup_flags & LookupFlag::MarkAttachmentType; + if (desired_attachment_class) + { + if (basic_glyph_class == HB_OT_LAYOUT_GLYPH_CLASS_MARK && + *property != desired_attachment_class ) + return false; + } + + return true; } -#endif hb_ot_layout_glyph_class_t diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 4ac6e380f..fefe24f38 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -31,14 +31,6 @@ HB_BEGIN_DECLS(); -typedef enum { - HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0x0000, - HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 0x0002, - HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 0x0004, - HB_OT_LAYOUT_GLYPH_CLASS_MARK = 0x0008, - HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 0x0010 -} hb_ot_layout_glyph_class_t; - /* * HB_OT_Layout */ @@ -62,6 +54,14 @@ hb_ot_layout_create_sanitize (char *data, * GDEF */ +typedef enum { + HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0x0000, + HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 0x0002, + HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 0x0004, + HB_OT_LAYOUT_GLYPH_CLASS_MARK = 0x0008, + HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 0x0010 +} hb_ot_layout_glyph_class_t; + hb_bool_t hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout); From 54e5aac5e2947d4e2864c6f2987e4d275da73100 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 27 Jan 2008 21:19:51 -0500 Subject: [PATCH 48/56] GDEF completely working now --- src/hb-ot-layout-open-private.h | 11 ++++++++--- src/hb-ot-layout-private.h | 16 +++++++++------- src/hb-ot-layout.cc | 19 +++++++++---------- src/hb-private.h | 7 +++++++ src/main.cc | 12 ++++++------ 5 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 94ff209bf..482cf148a 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -27,6 +27,10 @@ #ifndef HB_OT_LAYOUT_OPEN_PRIVATE_H #define HB_OT_LAYOUT_OPEN_PRIVATE_H +#ifndef HB_OT_LAYOUT_CC +#error "This file should only be included from hb-ot-layout.c" +#endif + #include "hb-ot-layout-private.h" @@ -127,7 +131,7 @@ return &(*this)[i]; \ return NULL; \ } \ - inline const Type& get_##name_by_tag (hb_tag_t tag) const { \ + inline const Type& get_##name##_by_tag (hb_tag_t tag) const { \ for (unsigned int i = 0; i < this->get_len (); i++) \ if (tag == (*this)[i].tag) \ return (*this)[i]; \ @@ -158,6 +162,7 @@ private: inline Type() {} /* cannot be instantiated */ \ public: +/* TODO use a global nul-array for most Null's */ /* defines Null##Type as a safe nil instance of Type */ #define DEFINE_NULL_DATA(Type, size, data) \ static const unsigned char Null##Type##Data[size] = data; \ @@ -170,11 +175,11 @@ ASSERT_SIZE (Type, size); \ DEFINE_NULL_DATA (Type, size, data) #define DEFINE_NULL_ALIAS(NewType, OldType) \ - static const NewType &Null##NewType = *(NewType *)Null##OldType##Data + /* XXX static */ const NewType &Null##NewType = *(NewType *)Null##OldType##Data /* get_for_data() is a static class method returning a reference to an * instance of Type located at the input data location. It's just a - * fancy cast! */ + * fancy, NULL-safe, cast! */ #define STATIC_DEFINE_GET_FOR_DATA(Type) \ static inline const Type& get_for_data (const char *data) { \ extern const Type &Null##Type; \ diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index e0b7be03c..607ee2644 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -27,10 +27,6 @@ #ifndef HB_OT_LAYOUT_PRIVATE_H #define HB_OT_LAYOUT_PRIVATE_H -#ifndef HB_OT_LAYOUT_CC -#error "This file should only be included from hb-ot-layout.c" -#endif - #include "hb-private.h" #include "hb-ot-layout.h" @@ -43,17 +39,23 @@ typedef uint16_t hb_ot_layout_glyph_properties_t; typedef uint16_t hb_ot_layout_lookup_flags_t; typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */ +/* XXX #define HB_OT_LAYOUT_INTERNAL static */ +#define HB_OT_LAYOUT_INTERNAL HB_BEGIN_DECLS(); -static hb_bool_t +/* + * GDEF + */ + +HB_OT_LAYOUT_INTERNAL hb_bool_t _hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout); -static hb_ot_layout_glyph_properties_t +HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t _hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, hb_glyph_t glyph); -static bool +HB_OT_LAYOUT_INTERNAL hb_bool_t _hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, HB_GlyphItem gitem, hb_ot_layout_lookup_flags_t lookup_flags, diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index faad280db..ab3ac9324 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -61,9 +61,9 @@ hb_ot_layout_create (const char *font_data, const OpenTypeFontFile &font = OpenTypeFontFile::get_for_data (font_data); const OpenTypeFontFace &face = font.get_face (face_index); - layout->gdef = &GDEF::get_for_data (font.get_table_data (face.get_table (GDEF::Tag))); - layout->gsub = &GSUB::get_for_data (font.get_table_data (face.get_table (GSUB::Tag))); -//layout->gpos = &GPOS::get_for_data (font.get_table_data (face.get_table (GPOS::Tag))); + layout->gdef = &GDEF::get_for_data (font.get_table_data (face.get_table_by_tag (GDEF::Tag))); + layout->gsub = &GSUB::get_for_data (font.get_table_data (face.get_table_by_tag (GSUB::Tag))); +//layout->gpos = &GPOS::get_for_data (font.get_table_data (face.get_table_by_tag (GPOS::Tag))); return layout; } @@ -84,13 +84,13 @@ hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout) return layout->gdef->has_glyph_classes (); } -static hb_bool_t +HB_OT_LAYOUT_INTERNAL hb_bool_t _hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout) { return layout->new_gdef.len > 0; } -static hb_ot_layout_glyph_properties_t +HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t _hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, hb_glyph_t glyph) { @@ -117,19 +117,18 @@ _hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, } } -static bool +HB_OT_LAYOUT_INTERNAL hb_bool_t _hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, HB_GlyphItem gitem, hb_ot_layout_lookup_flags_t lookup_flags, hb_ot_layout_glyph_properties_t *property) { - /* TODO ugh, clean this mess up */ hb_ot_layout_glyph_class_t basic_glyph_class; hb_ot_layout_glyph_properties_t desired_attachment_class; - if (gitem->gproperties == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED) + if (gitem->gproperties == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN) { - gitem->gproperties = _hb_ot_layout_get_glyph_properties (layout, gitem->gindex); + gitem->gproperties = *property = _hb_ot_layout_get_glyph_properties (layout, gitem->gindex); if (gitem->gproperties == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED) return false; } @@ -177,7 +176,7 @@ hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, properties = _hb_ot_layout_get_glyph_properties (layout, glyph); - if (properties & 0xFF) + if (properties & 0xFF00) return HB_OT_LAYOUT_GLYPH_CLASS_MARK; return (hb_ot_layout_glyph_class_t) properties; diff --git a/src/hb-private.h b/src/hb-private.h index f67bd5718..3dca04907 100644 --- a/src/hb-private.h +++ b/src/hb-private.h @@ -52,4 +52,11 @@ #define ASSERT_SIZE(_type, _size) ASSERT_STATIC (sizeof (_type) == (_size)) +/* + * buffer + */ + +/* XXX */ +#define HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN 0xFFFF + #endif /* HB_PRIVATE_H */ diff --git a/src/main.cc b/src/main.cc index 41a70c739..5a3da5580 100644 --- a/src/main.cc +++ b/src/main.cc @@ -63,21 +63,21 @@ main (int argc, char **argv) break; } - int num_fonts = ot.get_len (); + int num_fonts = ot.get_face_count (); printf ("%d font(s) found in file\n", num_fonts); for (int n_font = 0; n_font < num_fonts; n_font++) { - const OpenTypeFontFace &font = ot[n_font]; + const OpenTypeFontFace &font = ot.get_face (n_font); printf ("Font %d of %d:\n", n_font+1, num_fonts); - int num_tables = font.get_len (); + int num_tables = font.get_table_count (); printf (" %d table(s) found in font\n", num_tables); for (int n_table = 0; n_table < num_tables; n_table++) { - const OpenTypeTable &table = font[n_table]; + const OpenTypeTable &table = font.get_table (n_table); printf (" Table %2d of %2d: %.4s (0x%08lx+0x%08lx)\n", n_table+1, num_tables, (const char *)table.get_tag(), table.get_offset(), table.get_length()); - if (table.get_tag() == "GSUB" || table.get_tag() == "GPOS") { - const GSUBGPOS &g = GSUBGPOS::get_for_data (ot[table]); + if (table.get_tag() == GSUBGPOS::GSUBTag || table.get_tag() == GSUBGPOS::GPOSTag) { + const GSUBGPOS &g = GSUBGPOS::get_for_data (ot.get_table_data (table)); const ScriptList &scripts = g.get_script_list(); int num_scripts = scripts.get_len (); From dfa811965133bc4d1696fa5a0166e17ed4142c98 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 28 Jan 2008 00:12:21 -0500 Subject: [PATCH 49/56] Rename hb_ot_layout_create() to hb_ot_layout_create_for_data() --- src/hb-ot-layout.cc | 4 ++-- src/hb-ot-layout.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index ab3ac9324..39328a999 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -53,8 +53,8 @@ struct _HB_OT_Layout { }; HB_OT_Layout * -hb_ot_layout_create (const char *font_data, - int face_index) +hb_ot_layout_create_for_data (const char *font_data, + int face_index) { HB_OT_Layout *layout = (HB_OT_Layout *) calloc (1, sizeof (HB_OT_Layout)); diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index fefe24f38..ceb364703 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -38,8 +38,8 @@ HB_BEGIN_DECLS(); typedef struct _HB_OT_Layout HB_OT_Layout; HB_OT_Layout * -hb_ot_layout_create (const char *font_data, - int face_index); +hb_ot_layout_create_for_data (const char *font_data, + int face_index); void hb_ot_layout_destroy (HB_OT_Layout *layout); From e50c3978d37b2c0d6ddd4ced6a6196f6857cd596 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 28 Jan 2008 00:16:49 -0500 Subject: [PATCH 50/56] Rename HB_OT_Layout to hb_ot_layout_t --- src/hb-ot-layout-private.h | 8 ++++---- src/hb-ot-layout.cc | 34 +++++++++++++++++----------------- src/hb-ot-layout.h | 33 +++++++++++++++------------------ 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index 607ee2644..8060e4f31 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -49,14 +49,14 @@ HB_BEGIN_DECLS(); */ HB_OT_LAYOUT_INTERNAL hb_bool_t -_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout); +_hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout); HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t -_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, - hb_glyph_t glyph); +_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout, + hb_glyph_t glyph); HB_OT_LAYOUT_INTERNAL hb_bool_t -_hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, +_hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout, HB_GlyphItem gitem, hb_ot_layout_lookup_flags_t lookup_flags, hb_ot_layout_glyph_properties_t *property); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 39328a999..4cd70def0 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -40,7 +40,7 @@ #include -struct _HB_OT_Layout { +struct _hb_ot_layout_t { const GDEF *gdef; const GSUB *gsub; //const GPOS *gpos; @@ -52,11 +52,11 @@ struct _HB_OT_Layout { }; -HB_OT_Layout * +hb_ot_layout_t * hb_ot_layout_create_for_data (const char *font_data, int face_index) { - HB_OT_Layout *layout = (HB_OT_Layout *) calloc (1, sizeof (HB_OT_Layout)); + hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t)); const OpenTypeFontFile &font = OpenTypeFontFile::get_for_data (font_data); const OpenTypeFontFace &face = font.get_face (face_index); @@ -69,7 +69,7 @@ hb_ot_layout_create_for_data (const char *font_data, } void -hb_ot_layout_destroy (HB_OT_Layout *layout) +hb_ot_layout_destroy (hb_ot_layout_t *layout) { free (layout); } @@ -79,20 +79,20 @@ hb_ot_layout_destroy (HB_OT_Layout *layout) */ hb_bool_t -hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout) +hb_ot_layout_has_font_glyph_classes (hb_ot_layout_t *layout) { return layout->gdef->has_glyph_classes (); } HB_OT_LAYOUT_INTERNAL hb_bool_t -_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout) +_hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout) { return layout->new_gdef.len > 0; } HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t -_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, - hb_glyph_t glyph) +_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout, + hb_glyph_t glyph) { hb_ot_layout_class_t klass; @@ -118,7 +118,7 @@ _hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, } HB_OT_LAYOUT_INTERNAL hb_bool_t -_hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, +_hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout, HB_GlyphItem gitem, hb_ot_layout_lookup_flags_t lookup_flags, hb_ot_layout_glyph_properties_t *property) @@ -168,8 +168,8 @@ _hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, hb_ot_layout_glyph_class_t -hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, - hb_glyph_t glyph) +hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout, + hb_glyph_t glyph) { hb_ot_layout_glyph_properties_t properties; hb_ot_layout_class_t klass; @@ -183,7 +183,7 @@ hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, } void -hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, +hb_ot_layout_set_glyph_class (hb_ot_layout_t *layout, hb_glyph_t glyph, hb_ot_layout_glyph_class_t klass) { @@ -224,11 +224,11 @@ hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, } void -hb_ot_layout_build_glyph_classes (HB_OT_Layout *layout, - uint16_t num_total_glyphs, - hb_glyph_t *glyphs, - unsigned char *klasses, - uint16_t count) +hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout, + uint16_t num_total_glyphs, + hb_glyph_t *glyphs, + unsigned char *klasses, + uint16_t count) { int i; diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index ceb364703..c515d5b9e 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -32,23 +32,20 @@ HB_BEGIN_DECLS(); /* - * HB_OT_Layout + * hb_ot_layout_t */ -typedef struct _HB_OT_Layout HB_OT_Layout; +typedef struct _hb_ot_layout_t hb_ot_layout_t; -HB_OT_Layout * +hb_ot_layout_t * hb_ot_layout_create_for_data (const char *font_data, int face_index); void -hb_ot_layout_destroy (HB_OT_Layout *layout); +hb_ot_layout_destroy (hb_ot_layout_t *layout); -/* TODO -HB_OT_Layout * -hb_ot_layout_create_sanitize (char *data, - make_writable_func); -*/ +/* TODO sanitizing API/constructor (make_wrieable_func_t) */ +/* TODO get_table_func_t constructor */ /* * GDEF @@ -63,23 +60,23 @@ typedef enum { } hb_ot_layout_glyph_class_t; hb_bool_t -hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout); +hb_ot_layout_has_font_glyph_classes (hb_ot_layout_t *layout); hb_ot_layout_glyph_class_t -hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, - hb_glyph_t glyph); +hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout, + hb_glyph_t glyph); void -hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, +hb_ot_layout_set_glyph_class (hb_ot_layout_t *layout, hb_glyph_t glyph, hb_ot_layout_glyph_class_t klass); void -hb_ot_layout_build_glyph_classes (HB_OT_Layout *layout, - uint16_t num_total_glyphs, - hb_glyph_t *glyphs, - unsigned char *klasses, - uint16_t count); +hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout, + uint16_t num_total_glyphs, + hb_glyph_t *glyphs, + unsigned char *klasses, + uint16_t count); HB_END_DECLS(); From 40a81314fa3eb7c701aea47b43f81bfad985f717 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 28 Jan 2008 02:30:48 -0500 Subject: [PATCH 51/56] Make main.cc compile again, which means finished getter API --- src/hb-ot-layout-open-private.h | 117 +++++++++++++++++++++++--------- src/main.cc | 99 +++++++++++++++++++-------- 2 files changed, 155 insertions(+), 61 deletions(-) diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 482cf148a..95adfa528 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -106,7 +106,11 @@ if (HB_UNLIKELY (!array[i].offset)) return Null##Type; \ return *(const Type *)((const char*)this + array[i].offset); \ } \ - /* TODO: implement find_tag() and get_tag() publicly */ + inline const Tag& get_tag (unsigned int i) const { \ + if (HB_UNLIKELY (i >= num)) return NullTag; \ + return array[i].tag; \ + } + /* TODO: implement bsearch find_tag() and use it */ #define DEFINE_ARRAY_INTERFACE(Type, name) \ @@ -124,32 +128,53 @@ return this->get_len (); \ } -#define DEFINE_FIND_TAG_INTERFACE(Type, name) \ - inline const Type* find_##name (hb_tag_t tag) const { \ - for (unsigned int i = 0; i < this->get_len (); i++) \ - if (tag == (*this)[i].tag) \ - return &(*this)[i]; \ - return NULL; \ - } \ - inline const Type& get_##name##_by_tag (hb_tag_t tag) const { \ - for (unsigned int i = 0; i < this->get_len (); i++) \ - if (tag == (*this)[i].tag) \ - return (*this)[i]; \ - return Null##Type; \ - } - /* * List types */ -#define DEFINE_LIST_ACCESSOR(Type, name) \ +#define DEFINE_LIST_ARRAY(Type, name) \ inline const Type##List& get_##name##_list (void) const { \ if (HB_UNLIKELY (!name##List)) return Null##Type##List; \ return *(const Type##List *)((const char*)this + name##List); \ - } \ + } + +#define DEFINE_LIST_INTERFACE(Type, name) \ inline const Type& get_##name (unsigned int i) const { \ - return get_##name##_list()[i]; \ + return get_##name##_list ()[i]; \ + } \ + inline unsigned int get_##name##_count (void) const { \ + return get_##name##_list ().get_len (); \ + } + +/* + * Tag types + */ + +#define DEFINE_TAG_ARRAY_INTERFACE(Type, name) \ + DEFINE_ARRAY_INTERFACE (Type, name); \ + inline hb_tag_t get_##name##_tag (unsigned int i) const { \ + return (*this)[i].tag; \ + } +#define DEFINE_TAG_LIST_INTERFACE(Type, name) \ + DEFINE_LIST_INTERFACE (Type, name); \ + inline const Tag& get_##name##_tag (unsigned int i) const { \ + return get_##name##_list ().get_tag (i); \ + } + +#define DEFINE_TAG_FIND_INTERFACE(Type, name) \ + inline const Type* find_##name (hb_tag_t tag) const { \ + for (unsigned int i = 0; i < get_##name##_count (); i++) \ + if (tag == get_##name##_tag (i)) \ + return &get_##name (i); \ + return NULL; \ + } \ + inline const Type& get_##name##_by_tag (hb_tag_t tag) const { \ + const Type* res = find_##name (tag); \ + if (res) \ + return *res; \ + else \ + return Null##Type; \ } /* @@ -344,7 +369,7 @@ typedef struct TableDirectory { friend struct OffsetTable; inline bool is_null (void) const { return length == 0; } - inline hb_tag_t get_tag (void) const { return tag; } + inline const Tag& get_tag (void) const { return tag; } inline unsigned long get_checksum (void) const { return checkSum; } inline unsigned long get_offset (void) const { return offset; } inline unsigned long get_length (void) const { return length; } @@ -364,8 +389,8 @@ typedef struct OffsetTable { friend struct OpenTypeFontFile; friend struct TTCHeader; - DEFINE_ARRAY_INTERFACE (OpenTypeTable, table); - DEFINE_FIND_TAG_INTERFACE (OpenTypeTable, table); + DEFINE_TAG_ARRAY_INTERFACE (OpenTypeTable, table); /* get_table_count(), get_table(i), get_table_tag(i) */ + DEFINE_TAG_FIND_INTERFACE (OpenTypeTable, table); /* find_table(tag), get_table_by_tag(tag) */ private: /* OpenTypeTables, in no particular order */ @@ -418,9 +443,9 @@ struct OpenTypeFontFile { STATIC_DEFINE_GET_FOR_DATA (OpenTypeFontFile); - DEFINE_ARRAY_INTERFACE (OpenTypeFontFace, face); + DEFINE_ARRAY_INTERFACE (OpenTypeFontFace, face); /* get_face_count(), get_face(i) */ - inline hb_tag_t get_tag (void) const { return tag; } + inline const Tag& get_tag (void) const { return tag; } /* This is how you get a table */ inline const char* get_table_data (const OpenTypeTable& table) const { @@ -510,19 +535,28 @@ struct LangSys { DEFINE_NULL_ASSERT_SIZE_DATA (LangSys, 6, "\0\0\xFF\xFF"); struct Script { - /* LangSys', in sorted alphabetical tag order */ - DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); - inline const bool has_default_language_system (void) const { + DEFINE_ARRAY_INTERFACE (LangSys, lang_sys); /* get_lang_sys_count(), get_lang_sys(i) */ + + inline const Tag& get_lang_sys_tag (unsigned int i) const { + return get_tag (i); + } + + /* TODO bsearch */ + DEFINE_TAG_FIND_INTERFACE (LangSys, lang_sys); /* find_lang_sys (), get_lang_sys_by_tag (tag) */ + + inline const bool has_default_lang_sys (void) const { return defaultLangSys != 0; } - inline const LangSys& get_default_language_system (void) const { + inline const LangSys& get_default_lang_sys (void) const { if (HB_UNLIKELY (!defaultLangSys)) return NullLangSys; return *(LangSys*)((const char*)this + defaultLangSys); } - /* TODO implement find_language_system based on find_tag */ + private: + /* LangSys', in sorted alphabetical tag order */ + DEFINE_RECORD_ARRAY_TYPE (LangSys, langSysRecord, langSysCount); private: Offset defaultLangSys; /* Offset to DefaultLangSys table--from @@ -535,6 +569,10 @@ struct Script { DEFINE_NULL_ASSERT_SIZE (Script, 4); struct ScriptList { + + friend struct GSUBGPOS; + +private: /* Scripts, in sorted alphabetical tag order */ DEFINE_RECORD_ARRAY_TYPE (Script, scriptRecord, scriptCount); @@ -567,6 +605,10 @@ struct Feature { DEFINE_NULL_ASSERT_SIZE (Feature, 4); struct FeatureList { + + friend struct GSUBGPOS; + + private: /* Feature indices, in sorted alphabetical tag order */ DEFINE_RECORD_ARRAY_TYPE (Feature, featureRecord, featureCount); @@ -620,6 +662,10 @@ struct Lookup { DEFINE_NULL_ASSERT_SIZE (Lookup, 6); struct LookupList { + + friend struct GSUBGPOS; + + private: /* Lookup indices, in sorted alphabetical tag order */ DEFINE_OFFSET_ARRAY_TYPE (Lookup, lookupOffset, lookupCount); @@ -889,9 +935,18 @@ typedef struct GSUBGPOS { STATIC_DEFINE_GET_FOR_DATA (GSUBGPOS); /* XXX check version here? */ - DEFINE_LIST_ACCESSOR(Script, script); /* get_script_list, get_script(i) */ - DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list, get_feature(i) */ - DEFINE_LIST_ACCESSOR(Lookup, lookup); /* get_lookup_list, get_lookup(i) */ + DEFINE_TAG_LIST_INTERFACE (Script, script ); /* get_script_count (), get_script (i), get_script_tag (i) */ + DEFINE_TAG_LIST_INTERFACE (Feature, feature); /* get_feature_count(), get_feature(i), get_feature_tag(i) */ + DEFINE_LIST_INTERFACE (Lookup, lookup ); /* get_lookup_count (), get_lookup (i) */ + + /* TODO bsearch */ + DEFINE_TAG_FIND_INTERFACE (Script, script ); /* find_script (), get_script_by_tag (tag) */ + DEFINE_TAG_FIND_INTERFACE (Feature, feature); /* find_feature(), get_feature_by_tag(tag) */ + + private: + DEFINE_LIST_ARRAY(Script, script); + DEFINE_LIST_ARRAY(Feature, feature); + DEFINE_LIST_ARRAY(Lookup, lookup); private: Fixed_Version version; /* Version of the GSUB/GPOS table--initially set diff --git a/src/main.cc b/src/main.cc index 5a3da5580..1a81ad180 100644 --- a/src/main.cc +++ b/src/main.cc @@ -67,66 +67,105 @@ main (int argc, char **argv) printf ("%d font(s) found in file\n", num_fonts); for (int n_font = 0; n_font < num_fonts; n_font++) { const OpenTypeFontFace &font = ot.get_face (n_font); - printf ("Font %d of %d:\n", n_font+1, num_fonts); + printf ("Font %d of %d:\n", n_font, num_fonts); int num_tables = font.get_table_count (); printf (" %d table(s) found in font\n", num_tables); for (int n_table = 0; n_table < num_tables; n_table++) { const OpenTypeTable &table = font.get_table (n_table); - printf (" Table %2d of %2d: %.4s (0x%08lx+0x%08lx)\n", n_table+1, num_tables, + printf (" Table %2d of %2d: %.4s (0x%08lx+0x%08lx)\n", n_table, num_tables, (const char *)table.get_tag(), table.get_offset(), table.get_length()); - if (table.get_tag() == GSUBGPOS::GSUBTag || table.get_tag() == GSUBGPOS::GPOSTag) { - const GSUBGPOS &g = GSUBGPOS::get_for_data (ot.get_table_data (table)); + switch (table.get_tag ()) { - const ScriptList &scripts = g.get_script_list(); - int num_scripts = scripts.get_len (); + case GSUBGPOS::GSUBTag: + case GSUBGPOS::GPOSTag: + { + + const GSUBGPOS &g = GSUBGPOS::get_for_data (ot.get_table_data (table)); + + int num_scripts = g.get_script_count (); printf (" %d script(s) found in table\n", num_scripts); for (int n_script = 0; n_script < num_scripts; n_script++) { - const Script &script = scripts[n_script]; - printf (" Script %2d of %2d: %.4s\n", n_script+1, num_scripts, - (const char *)scripts.get_tag(n_script)); + const Script &script = g.get_script (n_script); + printf (" Script %2d of %2d: %.4s\n", n_script, num_scripts, + (const char *)g.get_script_tag(n_script)); - if (!script.has_default_language_system()) + if (!script.has_default_lang_sys()) printf (" No default language system\n"); - int num_langsys = script.get_len (); + int num_langsys = script.get_lang_sys_count (); printf (" %d language system(s) found in script\n", num_langsys); - for (int n_langsys = 0; n_langsys < num_langsys; n_langsys++) { - const LangSys &langsys = script[n_langsys]; - printf (" Language System %2d of %2d: %.4s; %d features\n", n_langsys+1, num_langsys, - (const char *)script.get_tag(n_langsys), - langsys.get_len ()); + for (int n_langsys = script.has_default_lang_sys() ? -1 : 0; n_langsys < num_langsys; n_langsys++) { + const LangSys &langsys = n_langsys == -1 + ? script.get_default_lang_sys () + : script.get_lang_sys (n_langsys); + printf (n_langsys == -1 + ? " Default Language System\n" + : " Language System %2d of %2d: %.4s\n", n_langsys, num_langsys, + (const char *)script.get_lang_sys_tag (n_langsys)); if (!langsys.get_required_feature_index ()) printf (" No required feature\n"); + + int num_features = langsys.get_feature_count (); + printf (" %d feature(s) found in language system\n", num_features); + for (int n_feature = 0; n_feature < num_features; n_feature++) { + unsigned int feature_index = langsys.get_feature_index (n_feature); + printf (" Feature index %2d of %2d: %d\n", n_feature, num_features, + langsys.get_feature_index (n_feature)); + } } } - - const FeatureList &features = g.get_feature_list(); - int num_features = features.get_len (); + + int num_features = g.get_feature_count (); printf (" %d feature(s) found in table\n", num_features); for (int n_feature = 0; n_feature < num_features; n_feature++) { - const Feature &feature = features[n_feature]; - printf (" Feature %2d of %2d: %.4s; %d lookup(s)\n", n_feature+1, num_features, - (const char *)features.get_tag(n_feature), - feature.get_len()); + const Feature &feature = g.get_feature (n_feature); + printf (" Feature %2d of %2d: %.4s; %d lookup(s)\n", n_feature, num_features, + (const char *)g.get_feature_tag(n_feature), + feature.get_lookup_count()); + + int num_lookups = feature.get_lookup_count (); + printf (" %d lookup(s) found in language system\n", num_lookups); + for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { + unsigned int lookup_index = feature.get_lookup_index (n_lookup); + printf (" Feature index %2d of %2d: %d\n", n_lookup, num_lookups, + feature.get_lookup_index (n_lookup)); + } } - - const LookupList &lookups = g.get_lookup_list(); - int num_lookups = lookups.get_len (); + + int num_lookups = g.get_lookup_count (); printf (" %d lookup(s) found in table\n", num_lookups); for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { - const Lookup &lookup = lookups[n_lookup]; - printf (" Lookup %2d of %2d: type %d, flags %04x\n", n_lookup+1, num_lookups, + const Lookup &lookup = g.get_lookup (n_lookup); + printf (" Lookup %2d of %2d: type %d, flags 0x%04X\n", n_lookup, num_lookups, lookup.get_type(), lookup.get_flag()); } - } else if (table.get_tag() == "GDEF") { - const GDEF &gdef = GDEF::get_for_data (ot[table]); + + } + break; + + case GDEF::Tag: + { + + const GDEF &gdef = GDEF::get_for_data (ot.get_table_data (table)); + + printf (" Has %sglyph classes\n", + gdef.has_glyph_classes () ? "" : "no "); + printf (" Has %smark attachment types\n", + gdef.has_mark_attachment_types () ? "" : "no "); + printf (" Has %sattach list\n", + gdef.has_attach_list () ? "" : "no "); + printf (" Has %slig caret list\n", + gdef.has_lig_caret_list () ? "" : "no "); for (int glyph = 0; glyph < 1; glyph++) printf (" glyph %d has class %d and mark attachment type %d\n", glyph, gdef.get_glyph_class (glyph), gdef.get_mark_attachment_type (glyph)); + + } + break; } } } From 706ab25a4cb043d46e6088aa0a7184ee200276c9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 28 Jan 2008 05:58:50 -0500 Subject: [PATCH 52/56] Add script and language public getter API --- src/hb-ot-layout-open-private.h | 40 ++++++---- src/hb-ot-layout.cc | 127 +++++++++++++++++++++++++++++++- src/hb-ot-layout.h | 56 ++++++++++++++ src/main.cc | 2 +- 4 files changed, 207 insertions(+), 18 deletions(-) diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 95adfa528..3127c4dd2 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -34,6 +34,8 @@ #include "hb-ot-layout-private.h" +#define NO_INDEX ((unsigned int) 0xFFFF) + /* * Int types */ @@ -153,7 +155,7 @@ #define DEFINE_TAG_ARRAY_INTERFACE(Type, name) \ DEFINE_ARRAY_INTERFACE (Type, name); \ - inline hb_tag_t get_##name##_tag (unsigned int i) const { \ + inline const Tag& get_##name##_tag (unsigned int i) const { \ return (*this)[i].tag; \ } #define DEFINE_TAG_LIST_INTERFACE(Type, name) \ @@ -163,16 +165,21 @@ } #define DEFINE_TAG_FIND_INTERFACE(Type, name) \ - inline const Type* find_##name (hb_tag_t tag) const { \ - for (unsigned int i = 0; i < get_##name##_count (); i++) \ - if (tag == get_##name##_tag (i)) \ - return &get_##name (i); \ - return NULL; \ + inline bool find_##name##_index (hb_tag_t tag, unsigned int *name##_index) const { \ + const Tag t = tag; \ + for (unsigned int i = 0; i < get_##name##_count (); i++) { \ + if (t == get_##name##_tag (i)) { \ + if (name##_index) *name##_index = i; \ + return true; \ + } \ + } \ + if (name##_index) *name##_index = NO_INDEX; \ + return false; \ } \ inline const Type& get_##name##_by_tag (hb_tag_t tag) const { \ - const Type* res = find_##name (tag); \ - if (res) \ - return *res; \ + unsigned int i; \ + if (find_##name##_index (tag, &i)) \ + return get_##name (i); \ else \ return Null##Type; \ } @@ -390,7 +397,7 @@ typedef struct OffsetTable { friend struct TTCHeader; DEFINE_TAG_ARRAY_INTERFACE (OpenTypeTable, table); /* get_table_count(), get_table(i), get_table_tag(i) */ - DEFINE_TAG_FIND_INTERFACE (OpenTypeTable, table); /* find_table(tag), get_table_by_tag(tag) */ + DEFINE_TAG_FIND_INTERFACE (OpenTypeTable, table); /* find_table_index(tag), get_table_by_tag(tag) */ private: /* OpenTypeTables, in no particular order */ @@ -509,10 +516,13 @@ struct LangSys { DEFINE_INDEX_ARRAY_INTERFACE (feature); - /* Returns -1 if none */ + inline const bool has_required_feature (void) const { + return reqFeatureIndex != 0xffff; + } + /* Returns NO_INDEX if none */ inline int get_required_feature_index (void) const { if (reqFeatureIndex == 0xffff) - return -1; + return NO_INDEX; return reqFeatureIndex;; } @@ -543,7 +553,7 @@ struct Script { } /* TODO bsearch */ - DEFINE_TAG_FIND_INTERFACE (LangSys, lang_sys); /* find_lang_sys (), get_lang_sys_by_tag (tag) */ + DEFINE_TAG_FIND_INTERFACE (LangSys, lang_sys); /* find_lang_sys_index (), get_lang_sys_by_tag (tag) */ inline const bool has_default_lang_sys (void) const { return defaultLangSys != 0; @@ -940,8 +950,8 @@ typedef struct GSUBGPOS { DEFINE_LIST_INTERFACE (Lookup, lookup ); /* get_lookup_count (), get_lookup (i) */ /* TODO bsearch */ - DEFINE_TAG_FIND_INTERFACE (Script, script ); /* find_script (), get_script_by_tag (tag) */ - DEFINE_TAG_FIND_INTERFACE (Feature, feature); /* find_feature(), get_feature_by_tag(tag) */ + DEFINE_TAG_FIND_INTERFACE (Script, script ); /* find_script_index (), get_script_by_tag (tag) */ + DEFINE_TAG_FIND_INTERFACE (Feature, feature); /* find_feature_index(), get_feature_by_tag(tag) */ private: DEFINE_LIST_ARRAY(Script, script); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 4cd70def0..33bfe4209 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -43,7 +43,7 @@ struct _hb_ot_layout_t { const GDEF *gdef; const GSUB *gsub; -//const GPOS *gpos; + const /*XXX*/GSUBGPOS *gpos; struct { unsigned char *klasses; @@ -63,7 +63,7 @@ hb_ot_layout_create_for_data (const char *font_data, layout->gdef = &GDEF::get_for_data (font.get_table_data (face.get_table_by_tag (GDEF::Tag))); layout->gsub = &GSUB::get_for_data (font.get_table_data (face.get_table_by_tag (GSUB::Tag))); -//layout->gpos = &GPOS::get_for_data (font.get_table_data (face.get_table_by_tag (GPOS::Tag))); + layout->gpos = &/*XXX*/GSUBGPOS::get_for_data (font.get_table_data (face.get_table_by_tag (/*XXX*/GSUBGPOS::GPOSTag))); return layout; } @@ -243,3 +243,126 @@ hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout, for (i = 0; i < count; i++) hb_ot_layout_set_glyph_class (layout, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]); } + +/* + * GSUB/GPOS + */ + +static const GSUBGPOS& +get_gsubgpos_table (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type) +{ + switch (table_type) { + case HB_OT_LAYOUT_TABLE_TYPE_GSUB: return *(layout->gsub); + case HB_OT_LAYOUT_TABLE_TYPE_GPOS: return *(layout->gpos); + default: return NullGSUBGPOS; + } +} + + +unsigned int +hb_ot_layout_get_script_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type) +{ + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + + return g.get_script_count (); +} + +hb_tag_t +hb_ot_layout_get_script_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index) +{ + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + + return g.get_script_tag (script_index); +} + +hb_bool_t +hb_ot_layout_find_script (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + hb_tag_t script_tag, + unsigned int *script_index) +{ + unsigned int i; + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + + if (g.find_script_index (script_tag, script_index)) + return TRUE; + + /* try finding 'DFLT' */ + if (g.find_script_index (HB_OT_LAYOUT_TAG_DEFAULT_SCRIPT, script_index)) + return FALSE; + + /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ + if (g.find_script_index (HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE, script_index)) + return FALSE; + + if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; + return FALSE; +} + + +unsigned int +hb_ot_layout_get_language_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index) +{ + const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index); + + return s.get_lang_sys_count (); +} + +hb_tag_t +hb_ot_layout_get_language_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index) +{ + const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index); + + return s.get_lang_sys_tag (language_index); +} + +hb_bool_t +hb_ot_layout_find_language (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + hb_tag_t language_tag, + unsigned int *language_index, + unsigned int *required_features_index) +{ + unsigned int i; + const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index); + +#if 0 + if (s.find_script_index (script_tag, script_index)) + return TRUE; + + /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ + if (s.find_script_index (HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE, script_index)) + return FALSE; + + //////////////////////// + if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; + return FALSE; + + if (language_index) + *language_index = PANGO_OT_DEFAULT_LANGUAGE; + if (required_feature_index) + *required_feature_index = PANGO_OT_NO_FEATURE; + + if (script_index == PANGO_OT_NO_SCRIPT) + return FALSE; + + + /* DefaultLangSys */ + if (language_index) + *language_index = PANGO_OT_DEFAULT_LANGUAGE; + if (required_feature_index) + *required_feature_index = script->DefaultLangSys.ReqFeatureIndex; +#endif + + return FALSE; +} diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index c515d5b9e..abea248dd 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -78,6 +78,62 @@ hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout, unsigned char *klasses, uint16_t count); +/* + * GSUB/GPOS + */ + +typedef enum { + HB_OT_LAYOUT_TABLE_TYPE_GSUB, + HB_OT_LAYOUT_TABLE_TYPE_GPOS, + HB_OT_LAYOUT_TABLE_TYPE_NONE +} hb_ot_layout_table_type_t; + +#define HB_OT_LAYOUT_NO_SCRIPT_INDEX ((unsigned int) 0xFFFF) +#define HB_OT_LAYOUT_NO_FEATURE_INDEX ((unsigned int) 0xFFFF) +#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX ((unsigned int) 0xFFFF) +#define HB_OT_LAYOUT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T') +#define HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') + +unsigned int +hb_ot_layout_get_script_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type); + +hb_tag_t +hb_ot_layout_get_script_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index); + +hb_bool_t +hb_ot_layout_find_script (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + hb_tag_t script_tag, + unsigned int *script_index); + +unsigned int +hb_ot_layout_get_language_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index); + +hb_tag_t +hb_ot_layout_get_language_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index); + +hb_bool_t +hb_ot_layout_find_language (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + hb_tag_t language_tag, + unsigned int *language_index, + unsigned int *required_features_index); + + +/* +#define PANGO_OT_ALL_GLYPHS ((guint) 0xFFFF) + +*/ + HB_END_DECLS(); #endif /* HB_OT_LAYOUT_H */ diff --git a/src/main.cc b/src/main.cc index 1a81ad180..b149e1118 100644 --- a/src/main.cc +++ b/src/main.cc @@ -103,7 +103,7 @@ main (int argc, char **argv) ? " Default Language System\n" : " Language System %2d of %2d: %.4s\n", n_langsys, num_langsys, (const char *)script.get_lang_sys_tag (n_langsys)); - if (!langsys.get_required_feature_index ()) + if (langsys.get_required_feature_index () == NO_INDEX) printf (" No required feature\n"); int num_features = langsys.get_feature_count (); From 4a26ea408c87f0bb59deca9ff44008d138471aa3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 28 Jan 2008 07:40:10 -0500 Subject: [PATCH 53/56] Finish script, language, and feature public API --- src/hb-ot-layout-open-private.h | 22 ++++-- src/hb-ot-layout.cc | 119 ++++++++++++++++++++++++-------- src/hb-ot-layout.h | 34 ++++++++- 3 files changed, 138 insertions(+), 37 deletions(-) diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 3127c4dd2..ce629db02 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -112,7 +112,6 @@ if (HB_UNLIKELY (i >= num)) return NullTag; \ return array[i].tag; \ } - /* TODO: implement bsearch find_tag() and use it */ #define DEFINE_ARRAY_INTERFACE(Type, name) \ @@ -124,10 +123,11 @@ } #define DEFINE_INDEX_ARRAY_INTERFACE(name) \ inline unsigned int get_##name##_index (unsigned int i) const { \ + if (HB_UNLIKELY (i >= get_len ())) return NO_INDEX; \ return (*this)[i]; \ } \ inline unsigned int get_##name##_count (void) const { \ - return this->get_len (); \ + return get_len (); \ } @@ -194,7 +194,7 @@ private: inline Type() {} /* cannot be instantiated */ \ public: -/* TODO use a global nul-array for most Null's */ +// TODO use a global nul-array for most Null's /* defines Null##Type as a safe nil instance of Type */ #define DEFINE_NULL_DATA(Type, size, data) \ static const unsigned char Null##Type##Data[size] = data; \ @@ -546,13 +546,21 @@ DEFINE_NULL_ASSERT_SIZE_DATA (LangSys, 6, "\0\0\xFF\xFF"); struct Script { - DEFINE_ARRAY_INTERFACE (LangSys, lang_sys); /* get_lang_sys_count(), get_lang_sys(i) */ + /* DEFINE_ARRAY_INTERFACE (LangSys, lang_sys) but handling defaultLangSys */ + + inline const LangSys& get_lang_sys (unsigned int i) const { + if (i == NO_INDEX) return get_default_lang_sys (); + return (*this)[i]; + } + inline unsigned int get_lang_sys_count (void) const { + return this->get_len (); + } inline const Tag& get_lang_sys_tag (unsigned int i) const { return get_tag (i); } - /* TODO bsearch */ + // LONGTERMTODO bsearch DEFINE_TAG_FIND_INTERFACE (LangSys, lang_sys); /* find_lang_sys_index (), get_lang_sys_by_tag (tag) */ inline const bool has_default_lang_sys (void) const { @@ -595,7 +603,7 @@ DEFINE_NULL_ASSERT_SIZE (ScriptList, 2); struct Feature { - DEFINE_INDEX_ARRAY_INTERFACE (lookup); + DEFINE_INDEX_ARRAY_INTERFACE (lookup); /* get_feature_count(), get_feature_index(i) */ private: /* LookupList indices, in no particular order */ @@ -949,7 +957,7 @@ typedef struct GSUBGPOS { DEFINE_TAG_LIST_INTERFACE (Feature, feature); /* get_feature_count(), get_feature(i), get_feature_tag(i) */ DEFINE_LIST_INTERFACE (Lookup, lookup ); /* get_lookup_count (), get_lookup (i) */ - /* TODO bsearch */ + // LONGTERMTODO bsearch DEFINE_TAG_FIND_INTERFACE (Script, script ); /* find_script_index (), get_script_by_tag (tag) */ DEFINE_TAG_FIND_INTERFACE (Feature, feature); /* find_feature_index(), get_feature_by_tag(tag) */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 33bfe4209..22fa81c5a 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -52,11 +52,28 @@ struct _hb_ot_layout_t { }; +hb_ot_layout_t * +hb_ot_layout_create (void) +{ + hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t)); + + layout->gdef = &NullGDEF; + layout->gsub = &NullGSUB; + layout->gpos = &/*XXX*/NullGSUBGPOS; + + return layout; +} + hb_ot_layout_t * hb_ot_layout_create_for_data (const char *font_data, int face_index) { - hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t)); + hb_ot_layout_t *layout; + + if (HB_UNLIKELY (font_data == NULL)) + return hb_ot_layout_create (); + + layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t)); const OpenTypeFontFile &font = OpenTypeFontFile::get_for_data (font_data); const OpenTypeFontFace &face = font.get_face (face_index); @@ -285,7 +302,7 @@ hb_ot_layout_find_script (hb_ot_layout_t *layout, hb_tag_t script_tag, unsigned int *script_index) { - unsigned int i; + ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); if (g.find_script_index (script_tag, script_index)) @@ -330,39 +347,85 @@ hb_ot_layout_find_language (hb_ot_layout_t *layout, hb_ot_layout_table_type_t table_type, unsigned int script_index, hb_tag_t language_tag, - unsigned int *language_index, - unsigned int *required_features_index) + unsigned int *language_index) { - unsigned int i; + ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX); const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index); -#if 0 - if (s.find_script_index (script_tag, script_index)) + if (s.find_lang_sys_index (language_tag, language_index)) return TRUE; /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ - if (s.find_script_index (HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE, script_index)) + if (s.find_lang_sys_index (HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE, language_index)) return FALSE; - //////////////////////// - if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX; - return FALSE; - - if (language_index) - *language_index = PANGO_OT_DEFAULT_LANGUAGE; - if (required_feature_index) - *required_feature_index = PANGO_OT_NO_FEATURE; - - if (script_index == PANGO_OT_NO_SCRIPT) - return FALSE; - - - /* DefaultLangSys */ - if (language_index) - *language_index = PANGO_OT_DEFAULT_LANGUAGE; - if (required_feature_index) - *required_feature_index = script->DefaultLangSys.ReqFeatureIndex; -#endif - + if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; + return FALSE; +} + +hb_bool_t +hb_ot_layout_get_required_feature_index (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int *feature_index) +{ + const LangSys &l = get_gsubgpos_table (layout, table_type).get_script (script_index).get_lang_sys (language_index); + + if (feature_index) *feature_index = l.get_required_feature_index (); + + return l.has_required_feature (); +} + +unsigned int +hb_ot_layout_get_feature_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index) +{ + const LangSys &l = get_gsubgpos_table (layout, table_type).get_script (script_index).get_lang_sys (language_index); + + return l.get_feature_count (); +} + +hb_tag_t +hb_ot_layout_get_feature_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int feature_index) +{ + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); + + feature_index = l.get_feature_index (feature_index); + + return g.get_feature_tag (feature_index); +} + + +hb_bool_t +hb_ot_layout_find_feature (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + hb_tag_t feature_tag, + unsigned int *feature_index) +{ + ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); + unsigned int i; + + for (i = 0; i < l.get_feature_count (); i++) { + unsigned int f_index = l.get_feature_index (i); + + if (feature_tag == g.get_feature_tag (f_index)) { + if (feature_index) *feature_index = f_index; + return TRUE; + } + } + + if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; return FALSE; } diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index abea248dd..895cc44a8 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -37,6 +37,9 @@ HB_BEGIN_DECLS(); typedef struct _hb_ot_layout_t hb_ot_layout_t; +hb_ot_layout_t * +hb_ot_layout_create (void); + hb_ot_layout_t * hb_ot_layout_create_for_data (const char *font_data, int face_index); @@ -125,8 +128,35 @@ hb_ot_layout_find_language (hb_ot_layout_t *layout, hb_ot_layout_table_type_t table_type, unsigned int script_index, hb_tag_t language_tag, - unsigned int *language_index, - unsigned int *required_features_index); + unsigned int *language_index); + +hb_bool_t +hb_ot_layout_get_required_feature_index (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int *feature_index); + +unsigned int +hb_ot_layout_get_feature_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index); + +hb_tag_t +hb_ot_layout_get_feature_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int feature_index); + +hb_bool_t +hb_ot_layout_find_feature (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + hb_tag_t feature_tag, + unsigned int *feature_index); /* From 57225672098ebdafb0c06ae091a1b55635daca29 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 18 Feb 2008 20:58:39 -0500 Subject: [PATCH 54/56] Fix typo, add TODOs --- src/hb-ot-layout-open-private.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index ce629db02..9d45f7c85 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -603,12 +603,15 @@ DEFINE_NULL_ASSERT_SIZE (ScriptList, 2); struct Feature { - DEFINE_INDEX_ARRAY_INTERFACE (lookup); /* get_feature_count(), get_feature_index(i) */ + DEFINE_INDEX_ARRAY_INTERFACE (lookup); /* get_lookup_count(), get_lookup_index(i) */ private: /* LookupList indices, in no particular order */ DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount); + /* TODO: implement get_feature_parameters() */ + /* TODO: implement FeatureSize and other special features? */ + private: Offset featureParams; /* Offset to Feature Parameters table (if one * has been defined for the feature), relative From c44733596c6648e209c12349e18e35424edf3d59 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 18 Feb 2008 21:14:23 -0500 Subject: [PATCH 55/56] [hb-ot-layout] Add proper namespace to accessors --- src/hb-ot-layout.cc | 165 ++++++++++++++++++++++++++++++++------------ src/hb-ot-layout.h | 115 +++++++++++++++++++----------- 2 files changed, 198 insertions(+), 82 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 22fa81c5a..117224814 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -278,8 +278,8 @@ get_gsubgpos_table (hb_ot_layout_t *layout, unsigned int -hb_ot_layout_get_script_count (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type) +hb_ot_layout_table_get_script_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type) { const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); @@ -287,9 +287,9 @@ hb_ot_layout_get_script_count (hb_ot_layout_t *layout, } hb_tag_t -hb_ot_layout_get_script_tag (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index) +hb_ot_layout_table_get_script_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index) { const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); @@ -297,10 +297,10 @@ hb_ot_layout_get_script_tag (hb_ot_layout_t *layout, } hb_bool_t -hb_ot_layout_find_script (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - hb_tag_t script_tag, - unsigned int *script_index) +hb_ot_layout_table_find_script (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + hb_tag_t script_tag, + unsigned int *script_index) { ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX); const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); @@ -320,11 +320,55 @@ hb_ot_layout_find_script (hb_ot_layout_t *layout, return FALSE; } +unsigned int +hb_ot_layout_table_get_feature_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type) +{ + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + + return g.get_feature_count (); +} + +hb_tag_t +hb_ot_layout_table_get_feature_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int feature_index) +{ + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + + return g.get_feature_tag (feature_index); +} + +hb_bool_t +hb_ot_layout_table_find_feature (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + hb_tag_t feature_tag, + unsigned int *feature_index) +{ + ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + + if (g.find_feature_index (feature_tag, feature_index)) + return TRUE; + + if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; + return FALSE; +} unsigned int -hb_ot_layout_get_language_count (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index) +hb_ot_layout_table_get_lookup_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type) +{ + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + + return g.get_lookup_count (); +} + + +unsigned int +hb_ot_layout_script_get_language_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index) { const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index); @@ -332,10 +376,10 @@ hb_ot_layout_get_language_count (hb_ot_layout_t *layout, } hb_tag_t -hb_ot_layout_get_language_tag (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - unsigned int language_index) +hb_ot_layout_script_get_language_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index) { const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index); @@ -343,11 +387,11 @@ hb_ot_layout_get_language_tag (hb_ot_layout_t *layout, } hb_bool_t -hb_ot_layout_find_language (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - hb_tag_t language_tag, - unsigned int *language_index) +hb_ot_layout_script_find_language (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + hb_tag_t language_tag, + unsigned int *language_index) { ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX); const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index); @@ -364,11 +408,11 @@ hb_ot_layout_find_language (hb_ot_layout_t *layout, } hb_bool_t -hb_ot_layout_get_required_feature_index (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - unsigned int language_index, - unsigned int *feature_index) +hb_ot_layout_language_get_required_feature_index (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int *feature_index) { const LangSys &l = get_gsubgpos_table (layout, table_type).get_script (script_index).get_lang_sys (language_index); @@ -378,39 +422,51 @@ hb_ot_layout_get_required_feature_index (hb_ot_layout_t *layout, } unsigned int -hb_ot_layout_get_feature_count (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - unsigned int language_index) +hb_ot_layout_language_get_feature_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index) { const LangSys &l = get_gsubgpos_table (layout, table_type).get_script (script_index).get_lang_sys (language_index); return l.get_feature_count (); } -hb_tag_t -hb_ot_layout_get_feature_tag (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - unsigned int language_index, - unsigned int feature_index) +unsigned int +hb_ot_layout_language_get_feature_index (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int num_feature) { const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); - feature_index = l.get_feature_index (feature_index); + return l.get_feature_index (num_feature); +} + +hb_tag_t +hb_ot_layout_language_get_feature_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int num_feature) +{ + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + const LangSys &l = g.get_script (script_index).get_lang_sys (language_index); + unsigned int feature_index = l.get_feature_index (num_feature); return g.get_feature_tag (feature_index); } hb_bool_t -hb_ot_layout_find_feature (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - unsigned int language_index, - hb_tag_t feature_tag, - unsigned int *feature_index) +hb_ot_layout_language_find_feature (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + hb_tag_t feature_tag, + unsigned int *feature_index) { ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); @@ -429,3 +485,26 @@ hb_ot_layout_find_feature (hb_ot_layout_t *layout, if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; return FALSE; } + +unsigned int +hb_ot_layout_feature_get_lookup_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int feature_index) +{ + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + const Feature &f = g.get_feature (feature_index); + + return f.get_lookup_count (); +} + +unsigned int +hb_ot_layout_feature_get_lookup_index (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int feature_index, + unsigned int num_lookup) +{ + const GSUBGPOS &g = get_gsubgpos_table (layout, table_type); + const Feature &f = g.get_feature (feature_index); + + return f.get_lookup_index (num_lookup); +} diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 895cc44a8..447dac247 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -98,65 +98,102 @@ typedef enum { #define HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') unsigned int -hb_ot_layout_get_script_count (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type); +hb_ot_layout_table_get_script_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type); hb_tag_t -hb_ot_layout_get_script_tag (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index); +hb_ot_layout_table_get_script_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index); hb_bool_t -hb_ot_layout_find_script (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - hb_tag_t script_tag, - unsigned int *script_index); +hb_ot_layout_table_find_script (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + hb_tag_t script_tag, + unsigned int *script_index); unsigned int -hb_ot_layout_get_language_count (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index); +hb_ot_layout_table_get_feature_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type); hb_tag_t -hb_ot_layout_get_language_tag (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - unsigned int language_index); +hb_ot_layout_table_get_feature_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int feature_index); hb_bool_t -hb_ot_layout_find_language (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - hb_tag_t language_tag, - unsigned int *language_index); +hb_ot_layout_table_find_script (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + hb_tag_t feature_tag, + unsigned int *feature_index); + +unsigned int +hb_ot_layout_table_get_lookup_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type); + +unsigned int +hb_ot_layout_script_get_language_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index); + +hb_tag_t +hb_ot_layout_script_get_language_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index); hb_bool_t -hb_ot_layout_get_required_feature_index (hb_ot_layout_t *layout, +hb_ot_layout_script_find_language (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + hb_tag_t language_tag, + unsigned int *language_index); + +hb_bool_t +hb_ot_layout_language_get_required_feature_index (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int *feature_index); + +unsigned int +hb_ot_layout_language_get_feature_count (hb_ot_layout_t *layout, hb_ot_layout_table_type_t table_type, unsigned int script_index, - unsigned int language_index, - unsigned int *feature_index); + unsigned int language_index); unsigned int -hb_ot_layout_get_feature_count (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - unsigned int language_index); +hb_ot_layout_language_get_feature_index (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int num_feature); hb_tag_t -hb_ot_layout_get_feature_tag (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - unsigned int language_index, - unsigned int feature_index); +hb_ot_layout_language_get_feature_tag (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + unsigned int num_feature); hb_bool_t -hb_ot_layout_find_feature (hb_ot_layout_t *layout, - hb_ot_layout_table_type_t table_type, - unsigned int script_index, - unsigned int language_index, - hb_tag_t feature_tag, - unsigned int *feature_index); +hb_ot_layout_language_find_feature (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int script_index, + unsigned int language_index, + hb_tag_t feature_tag, + unsigned int *feature_index); + +unsigned int +hb_ot_layout_feature_get_lookup_count (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int feature_index); + +unsigned int +hb_ot_layout_feature_get_lookup_index (hb_ot_layout_t *layout, + hb_ot_layout_table_type_t table_type, + unsigned int feature_index, + unsigned int num_lookup); /* From 2d15e72c75931398db5e027e660f1320bb979117 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 15 Apr 2009 19:50:16 -0400 Subject: [PATCH 56/56] Give it a start at GSUB --- src/hb-common.h | 5 +- src/hb-ot-layout-gdef-private.h | 24 +++---- src/hb-ot-layout-gsub-private.h | 120 +++++++++++++++++++++++++++++++- src/hb-ot-layout-open-private.h | 51 ++++++++------ src/hb-ot-layout-private.h | 2 +- src/hb-ot-layout.cc | 63 +++++++++++++++-- src/hb-ot-layout.h | 29 +++++++- src/main.cc | 4 +- 8 files changed, 253 insertions(+), 45 deletions(-) diff --git a/src/hb-common.h b/src/hb-common.h index c60ad8404..d404353ce 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -46,6 +46,9 @@ typedef uint32_t hb_tag_t; ((const char *) s)[2], \ ((const char *) s)[3])) -typedef uint16_t hb_glyph_t; +typedef uint32_t hb_codepoint_t; + +/* XXX */ +typedef struct HB_BufferRec_ hb_buffer_t; #endif /* HB_COMMON_H */ diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index 447ee0e4a..5418d8b1a 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -33,18 +33,18 @@ #define DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP(Type, name) \ - inline const Type& name (hb_glyph_t glyph_id) { \ + inline const Type& name (hb_codepoint_t glyph) { \ const Coverage &c = get_coverage (); \ - hb_ot_layout_coverage_t c_index = c.get_coverage (glyph_id); \ + hb_ot_layout_coverage_t c_index = c.get_coverage (glyph); \ return (*this)[c_index]; \ } struct GlyphClassDef : ClassDef { - static const uint16_t BaseGlyph = 0x0001u; - static const uint16_t LigatureGlyph = 0x0002u; - static const uint16_t MarkGlyph = 0x0003u; - static const uint16_t ComponentGlyph = 0x0004u; + static const unsigned int BaseGlyph = 0x0001u; + static const unsigned int LigatureGlyph = 0x0002u; + static const unsigned int MarkGlyph = 0x0003u; + static const unsigned int ComponentGlyph = 0x0004u; }; /* @@ -72,7 +72,7 @@ struct AttachList { friend struct GDEF; private: - /* const AttachPoint& get_attach_points (hb_glyph_t glyph_id); */ + /* const AttachPoint& get_attach_points (hb_codepoint_t glyph); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (AttachPoint, get_attach_points); private: @@ -205,7 +205,7 @@ struct LigCaretList { friend struct GDEF; private: - /* const LigGlyph& get_lig_glyph (hb_glyph_t glyph_id); */ + /* const LigGlyph& get_lig_glyph (hb_codepoint_t glyph); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph); private: @@ -245,12 +245,12 @@ struct GDEF { DEFINE_GET_HAS_ACCESSOR (LigCaretList, lig_caret_list, ligCaretList); DEFINE_GET_HAS_ACCESSOR (ClassDef, mark_attachment_types, markAttachClassDef); - inline hb_ot_layout_class_t get_glyph_class (hb_glyph_t glyph_id) const { - return get_glyph_classes ().get_class (glyph_id); + inline hb_ot_layout_class_t get_glyph_class (hb_codepoint_t glyph) const { + return get_glyph_classes ().get_class (glyph); } - inline hb_ot_layout_class_t get_mark_attachment_type (hb_glyph_t glyph_id) const { - return get_mark_attachment_types ().get_class (glyph_id); + inline hb_ot_layout_class_t get_mark_attachment_type (hb_codepoint_t glyph) const { + return get_mark_attachment_types ().get_class (glyph); } /* TODO get_attach and get_lig_caret */ diff --git a/src/hb-ot-layout-gsub-private.h b/src/hb-ot-layout-gsub-private.h index 8ce77054f..ae410903c 100644 --- a/src/hb-ot-layout-gsub-private.h +++ b/src/hb-ot-layout-gsub-private.h @@ -34,7 +34,17 @@ struct SingleSubstFormat1 { - /* TODO */ + + friend struct SingleSubst; + + private: + inline bool substitute (hb_ot_layout_t *layout, + hb_buffer_t *buffer, + unsigned int context_length, + unsigned int nesting_level_left) const { +// if (get_coverage (IN_CURGLYPH())) +// return ; + } private: USHORT substFormat; /* Format identifier--format = 1 */ @@ -449,6 +459,108 @@ struct ReverseChainSingleSubstFormat1 { }; ASSERT_SIZE (ReverseChainSingleSubstFormat1, 10); +/* + * SubstLookup + */ + +struct SubstLookupSubTable { + DEFINE_NON_INSTANTIABLE(SubstLookupSubTable); + + friend struct SubstLookup; + + unsigned int get_size (unsigned int lookup_type) const { + switch (lookup_type) { +// case 1: return u.format1.get_size (); +// case 2: return u.format2.get_size (); + /* + case Single: + case Multiple: + case Alternate: + case Ligature: + case Context: + case ChainingContext: + case Extension: + case ReverseChainingContextSingle: + */ + default:return sizeof (LookupSubTable); + } + } + + inline bool substitute (hb_ot_layout_t *layout, + hb_buffer_t *buffer, + unsigned int context_length, + unsigned int nesting_level_left, + unsigned int lookup_type) const { + } + + private: + union { + USHORT substFormat; + CoverageFormat1 format1; + CoverageFormat2 format2; + } u; +}; + +struct SubstLookup : Lookup { + + DEFINE_NON_INSTANTIABLE(SubstLookup); + + static const unsigned int Single = 1; + static const unsigned int Multiple = 2; + static const unsigned int Alternate = 3; + static const unsigned int Ligature = 4; + static const unsigned int Context = 5; + static const unsigned int ChainingContext = 6; + static const unsigned int Extension = 7; + static const unsigned int ReverseChainingContextSingle = 8; + + inline const SubstLookupSubTable& get_subtable (unsigned int i) const { + return *(SubstLookupSubTable*)&(((Lookup *)this)->get_subtable (i)); + } + + /* Like get_type(), but looks through extension lookups. + * Never returns SubstLookup::Extension */ + inline unsigned int get_effective_type (void) const { + unsigned int type = get_type (); + + if (HB_UNLIKELY (type == Extension)) { + /* Return lookup type of first extension subtable. + * The spec says all of them should have the same type. + * XXX check for that somehow */ +//XXX type = get_subtable(0).v.extension.get_type (); + } + + return type; + } + + inline bool is_reverse (void) const { + switch (get_effective_type ()) { + case ReverseChainingContextSingle: return true; + default: return false; + } + } + + inline bool substitute (hb_ot_layout_t *layout, + hb_buffer_t *buffer, + unsigned int context_length, + unsigned int nesting_level_left) const { + unsigned int lookup_type = get_type (); + + if (HB_UNLIKELY (nesting_level_left == 0)) + return false; + nesting_level_left--; + + for (unsigned int i = 0; i < get_subtable_count (); i++) + if (get_subtable (i).substitute (layout, buffer, + context_length, nesting_level_left, + lookup_type)) + return true; + + return false; + } +}; +DEFINE_NULL_ALIAS (SubstLookup, Lookup); + /* * GSUB */ @@ -458,6 +570,12 @@ struct GSUB : GSUBGPOS { STATIC_DEFINE_GET_FOR_DATA (GSUB); /* XXX check version here? */ + + inline const SubstLookup& get_lookup (unsigned int i) const { + return *(SubstLookup*)&(((GSUBGPOS *)this)->get_lookup (i)); + } + + }; DEFINE_NULL_ALIAS (GSUB, GSUBGPOS); diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 9d45f7c85..66fd55eba 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -35,6 +35,7 @@ #define NO_INDEX ((unsigned int) 0xFFFF) +#define NO_CONTEXT ((unsigned int) -1) /* * Int types @@ -191,7 +192,7 @@ /* makes class uninstantiable. should be used for union classes that don't * contain any complete type */ #define DEFINE_NON_INSTANTIABLE(Type) \ - private: inline Type() {} /* cannot be instantiated */ \ + protected: inline Type() {} /* cannot be instantiated */ \ public: // TODO use a global nul-array for most Null's @@ -236,6 +237,7 @@ + /* * * The OpenType Font File @@ -642,12 +644,12 @@ struct FeatureList { DEFINE_NULL_ASSERT_SIZE (FeatureList, 2); struct LookupFlag : USHORT { - static const uint16_t RightToLeft = 0x0001u; - static const uint16_t IgnoreBaseGlyphs = 0x0002u; - static const uint16_t IgnoreLigatures = 0x0004u; - static const uint16_t IgnoreMarks = 0x0008u; - static const uint16_t Reserved = 0x00F0u; - static const uint16_t MarkAttachmentType = 0xFF00u; + static const unsigned int RightToLeft = 0x0001u; + static const unsigned int IgnoreBaseGlyphs = 0x0002u; + static const unsigned int IgnoreLigatures = 0x0004u; + static const unsigned int IgnoreMarks = 0x0008u; + static const unsigned int Reserved = 0x00F0u; + static const unsigned int MarkAttachmentType = 0xFF00u; }; DEFINE_NULL_ASSERT_SIZE (LookupFlag, 2); @@ -661,8 +663,9 @@ DEFINE_NULL_ASSERT_SIZE (LookupSubTable, 2); struct Lookup { - /* SubTables, in the desired order */ - DEFINE_OFFSET_ARRAY_TYPE (LookupSubTable, subTableOffset, subTableCount); + DEFINE_NON_INSTANTIABLE(Lookup); + + DEFINE_ARRAY_INTERFACE (LookupSubTable, subtable); /* get_subtable_count(), get_subtable(i) */ inline bool is_right_to_left (void) const { return lookupFlag & LookupFlag::RightToLeft; } inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; } @@ -670,10 +673,14 @@ struct Lookup { inline bool ignore_marks (void) const { return lookupFlag & LookupFlag::IgnoreMarks; } inline bool get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; } - inline uint16_t get_type (void) const { return lookupType; } - inline uint16_t get_flag (void) const { return lookupFlag; } + inline unsigned int get_type (void) const { return lookupType; } + inline unsigned int get_flag (void) const { return lookupFlag; } private: + /* SubTables, in the desired order */ + DEFINE_OFFSET_ARRAY_TYPE (LookupSubTable, subTableOffset, subTableCount); + + protected: USHORT lookupType; /* Different enumerations for GSUB and GPOS */ USHORT lookupFlag; /* Lookup qualifiers */ USHORT subTableCount; /* Number of SubTables for this lookup */ @@ -710,8 +717,10 @@ struct CoverageFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); - inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const { GlyphID gid; + if (HB_UNLIKELY (glyph_id > 65535)) + return -1; gid = glyph_id; // TODO: bsearch for (unsigned int i = 0; i < glyphCount; i++) @@ -732,7 +741,7 @@ struct CoverageRangeRecord { friend struct CoverageFormat2; private: - inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return startCoverageIndex + (glyph_id - start); return -1; @@ -754,7 +763,7 @@ struct CoverageFormat2 { /* CoverageRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount); - inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const { // TODO: bsearch for (unsigned int i = 0; i < rangeCount; i++) { int coverage = rangeRecord[i].get_coverage (glyph_id); @@ -784,7 +793,7 @@ struct Coverage { } } - hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { + hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const { switch (u.coverageFormat) { case 1: return u.format1.get_coverage(glyph_id); case 2: return u.format2.get_coverage(glyph_id); @@ -813,7 +822,7 @@ struct ClassDefFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount); - inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const { if (glyph_id >= startGlyph && glyph_id - startGlyph < glyphCount) return classValueArray[glyph_id - startGlyph]; return 0; @@ -832,7 +841,7 @@ struct ClassRangeRecord { friend struct ClassDefFormat2; private: - inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return classValue; return 0; @@ -853,9 +862,9 @@ struct ClassDefFormat2 { /* ClassRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (ClassRangeRecord, rangeRecord, rangeCount); - inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const { // TODO: bsearch - for (int i = 0; i < rangeCount; i++) { + for (unsigned int i = 0; i < rangeCount; i++) { int classValue = rangeRecord[i].get_class (glyph_id); if (classValue > 0) return classValue; @@ -882,7 +891,7 @@ struct ClassDef { } } - hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { + hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const { switch (u.classFormat) { case 1: return u.format1.get_class(glyph_id); case 2: return u.format2.get_class(glyph_id); @@ -949,7 +958,7 @@ DEFINE_NULL_ASSERT_SIZE (Device, 6); * GSUB/GPOS Common */ -typedef struct GSUBGPOS { +struct GSUBGPOS { static const hb_tag_t GSUBTag = HB_TAG ('G','S','U','B'); static const hb_tag_t GPOSTag = HB_TAG ('G','P','O','S'); diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index 8060e4f31..a1be8aaf2 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -53,7 +53,7 @@ _hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout); HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t _hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout, - hb_glyph_t glyph); + hb_codepoint_t glyph); HB_OT_LAYOUT_INTERNAL hb_bool_t _hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout, diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 117224814..68fd3e583 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -35,6 +35,8 @@ #include "hb-ot-layout-gdef-private.h" #include "hb-ot-layout-gsub-private.h" +/* XXX */ +#include "harfbuzz-buffer-private.h" #include #include @@ -50,6 +52,7 @@ struct _hb_ot_layout_t { unsigned int len; } new_gdef; + /* TODO add max-nesting-level here? */ }; hb_ot_layout_t * @@ -109,7 +112,7 @@ _hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout) HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t _hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout, - hb_glyph_t glyph) + hb_codepoint_t glyph) { hb_ot_layout_class_t klass; @@ -186,7 +189,7 @@ _hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout, hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout, - hb_glyph_t glyph) + hb_codepoint_t glyph) { hb_ot_layout_glyph_properties_t properties; hb_ot_layout_class_t klass; @@ -201,7 +204,7 @@ hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout, void hb_ot_layout_set_glyph_class (hb_ot_layout_t *layout, - hb_glyph_t glyph, + hb_codepoint_t glyph, hb_ot_layout_glyph_class_t klass) { /* TODO optimize this, similar to old harfbuzz code for example */ @@ -243,7 +246,7 @@ hb_ot_layout_set_glyph_class (hb_ot_layout_t *layout, void hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout, uint16_t num_total_glyphs, - hb_glyph_t *glyphs, + hb_codepoint_t *glyphs, unsigned char *klasses, uint16_t count) { @@ -508,3 +511,55 @@ hb_ot_layout_feature_get_lookup_index (hb_ot_layout_t *layout, return f.get_lookup_index (num_lookup); } + +/* + * GSUB + */ + +hb_bool_t +hb_ot_layout_substitute_lookup (hb_ot_layout_t *layout, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_ot_layout_feature_mask_t mask) +{ + const GSUB &gsub = *(layout->gsub); + const SubstLookup &l = gsub.get_lookup (lookup_index); + unsigned int lookup_type = l.get_type (); + unsigned int nesting_level_left = HB_OT_LAYOUT_MAX_NESTING_LEVEL; + unsigned int context_length = NO_CONTEXT; + bool handled, ret = false; + + if (!l.is_reverse ()) { + + /* in/out forward substitution */ + _hb_buffer_clear_output (buffer); + buffer->in_pos = 0; + while (buffer->in_pos < buffer->in_length) { + + if ((~IN_PROPERTIES (buffer->in_pos) & mask) && + l.substitute (layout, buffer, context_length, nesting_level_left)) + ret = true; + else + _hb_buffer_copy_output_glyph (buffer); + + } + _hb_buffer_swap (buffer); + + } else { + + /* in-place backward substitution */ + buffer->in_pos = buffer->in_length - 1; + do { + + if ((~IN_PROPERTIES (buffer->in_pos) & mask) && + l.substitute (layout, buffer, context_length, nesting_level_left)) + ret = true; + else + buffer->in_pos--; + + } while (buffer->in_pos); + + } + + return ret; +} diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 447dac247..c29485c02 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -67,17 +67,17 @@ hb_ot_layout_has_font_glyph_classes (hb_ot_layout_t *layout); hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout, - hb_glyph_t glyph); + hb_codepoint_t glyph); void hb_ot_layout_set_glyph_class (hb_ot_layout_t *layout, - hb_glyph_t glyph, + hb_codepoint_t glyph, hb_ot_layout_glyph_class_t klass); void hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout, uint16_t num_total_glyphs, - hb_glyph_t *glyphs, + hb_codepoint_t *glyphs, unsigned char *klasses, uint16_t count); @@ -91,6 +91,10 @@ typedef enum { HB_OT_LAYOUT_TABLE_TYPE_NONE } hb_ot_layout_table_type_t; +typedef uint16_t hb_ot_layout_feature_mask_t; + +#define HB_OT_LAYOUT_MAX_NESTING_LEVEL 100 + #define HB_OT_LAYOUT_NO_SCRIPT_INDEX ((unsigned int) 0xFFFF) #define HB_OT_LAYOUT_NO_FEATURE_INDEX ((unsigned int) 0xFFFF) #define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX ((unsigned int) 0xFFFF) @@ -195,6 +199,25 @@ hb_ot_layout_feature_get_lookup_index (hb_ot_layout_t *layout, unsigned int feature_index, unsigned int num_lookup); +/* + * GSUB + */ + +hb_bool_t +hb_ot_layout_substitute_lookup (hb_ot_layout_t *layout, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_ot_layout_feature_mask_t mask); + + + + + + + + + + /* #define PANGO_OT_ALL_GLYPHS ((guint) 0xFFFF) diff --git a/src/main.cc b/src/main.cc index b149e1118..4c24ff457 100644 --- a/src/main.cc +++ b/src/main.cc @@ -125,10 +125,10 @@ main (int argc, char **argv) feature.get_lookup_count()); int num_lookups = feature.get_lookup_count (); - printf (" %d lookup(s) found in language system\n", num_lookups); + printf (" %d lookup(s) found in feature\n", num_lookups); for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) { unsigned int lookup_index = feature.get_lookup_index (n_lookup); - printf (" Feature index %2d of %2d: %d\n", n_lookup, num_lookups, + printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups, feature.get_lookup_index (n_lookup)); } }