From 808dbe283c1ad66091f2cb67380888b7cf265c01 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 25 Dec 2006 06:18:52 -0500 Subject: [PATCH] Make types not instantiable --- src/hb-types-private.cc | 104 ++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/src/hb-types-private.cc b/src/hb-types-private.cc index 947d64d..0d74e85 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,57 +254,46 @@ 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 { + /* 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; + } + + /* Array interface sans get_size() */ + inline 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 (); + default: return 0; + case truetype_tag: case cff_tag: return 1; + case ttc_tag: return ((const TTCHeader&)*this).get_len(); } } - - inline const OffsetTable& operator[] (unsigned int i) const { + inline const OpenTypeFont& 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]; + default: case truetype_tag: case cff_tag: return (const OffsetTable&)*this; + case ttc_tag: return ((const TTCHeader&)*this)[i]; } } - inline OffsetTable& operator[] (unsigned int i) { + inline OpenTypeFont& 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]; + default: case truetype_tag: case cff_tag: return (OffsetTable&)*this; + case ttc_tag: return ((TTCHeader&)*this)[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() {} + 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; -- 2.7.4