Remove use of flexible arrays
[framework/uifw/harfbuzz.git] / src / hb-open-file-private.hh
1 /*
2  * Copyright (C) 2007,2008,2009  Red Hat, Inc.
3  *
4  *  This is part of HarfBuzz, a text shaping library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Red Hat Author(s): Behdad Esfahbod
25  */
26
27 #ifndef HB_OPEN_FILE_PRIVATE_HH
28 #define HB_OPEN_FILE_PRIVATE_HH
29
30 #include "hb-open-type-private.hh"
31
32
33 /*
34  *
35  * The OpenType Font File
36  *
37  */
38
39
40 /*
41  * Organization of an OpenType Font
42  */
43
44 struct OpenTypeFontFile;
45 struct OffsetTable;
46 struct TTCHeader;
47
48 typedef struct TableDirectory
49 {
50   static inline unsigned int get_size () { return sizeof (TableDirectory); }
51
52   inline bool sanitize (SANITIZE_ARG_DEF) {
53     TRACE_SANITIZE ();
54     return SANITIZE_SELF ();
55   }
56
57   Tag           tag;            /* 4-byte identifier. */
58   CheckSum      checkSum;       /* CheckSum for this table. */
59   ULONG         offset;         /* Offset from beginning of TrueType font
60                                  * file. */
61   ULONG         length;         /* Length of this table. */
62 } OpenTypeTable;
63 ASSERT_SIZE (TableDirectory, 16);
64
65 typedef struct OffsetTable
66 {
67   friend struct OpenTypeFontFile;
68
69   inline unsigned int get_table_count (void) const
70   { return numTables; }
71   inline const Tag& get_table_tag (unsigned int i) const
72   {
73     if (HB_UNLIKELY (i >= numTables)) return Null(Tag);
74     return tableDir[i].tag;
75   }
76   inline const TableDirectory& get_table (unsigned int i) const
77   {
78     if (HB_UNLIKELY (i >= numTables)) return Null(TableDirectory);
79     return tableDir[i];
80   }
81   inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
82   {
83     Tag t;
84     t.set (tag);
85     /* TODO: bsearch (need to sort in sanitize) */
86     unsigned int count = numTables;
87     for (unsigned int i = 0; i < count; i++)
88     {
89       if (t == tableDir[i].tag)
90       {
91         if (table_index) *table_index = i;
92         return true;
93       }
94     }
95     if (table_index) *table_index = NO_INDEX;
96     return false;
97   }
98   inline const TableDirectory& get_table_by_tag (hb_tag_t tag) const
99   {
100     unsigned int table_index;
101     find_table_index (tag, &table_index);
102     return get_table (table_index);
103   }
104
105   public:
106   inline bool sanitize (SANITIZE_ARG_DEF) {
107     TRACE_SANITIZE ();
108     return SANITIZE_SELF () && SANITIZE_ARRAY (tableDir, TableDirectory::get_size (), numTables);
109   }
110
111   private:
112   Tag           sfnt_version;   /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
113   USHORT        numTables;      /* Number of tables. */
114   USHORT        searchRange;    /* (Maximum power of 2 <= numTables) x 16 */
115   USHORT        entrySelector;  /* Log2(maximum power of 2 <= numTables). */
116   USHORT        rangeShift;     /* NumTables x 16-searchRange. */
117   TableDirectory tableDir[VAR]; /* TableDirectory entries. numTables items */
118 } OpenTypeFontFace;
119 ASSERT_SIZE_VAR (OffsetTable, 12, TableDirectory);
120
121 /*
122  * TrueType Collections
123  */
124
125 struct TTCHeaderVersion1
126 {
127   friend struct TTCHeader;
128
129   inline unsigned int get_face_count (void) const { return table.len; }
130   inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
131
132   inline bool sanitize (SANITIZE_ARG_DEF) {
133     TRACE_SANITIZE ();
134     return SANITIZE_THIS (table);
135   }
136
137   private:
138   Tag           ttcTag;         /* TrueType Collection ID string: 'ttcf' */
139   FixedVersion  version;        /* Version of the TTC Header (1.0),
140                                  * 0x00010000 */
141   LongOffsetLongArrayOf<OffsetTable>
142                 table;          /* Array of offsets to the OffsetTable for each font
143                                  * from the beginning of the file */
144 };
145 ASSERT_SIZE (TTCHeaderVersion1, 12);
146
147 struct TTCHeader
148 {
149   friend struct OpenTypeFontFile;
150
151   private:
152
153   inline unsigned int get_face_count (void) const
154   {
155     switch (u.header.version) {
156     case 2: /* version 2 is compatible with version 1 */
157     case 1: return u.version1->get_face_count ();
158     default:return 0;
159     }
160   }
161   inline const OpenTypeFontFace& get_face (unsigned int i) const
162   {
163     switch (u.header.version) {
164     case 2: /* version 2 is compatible with version 1 */
165     case 1: return u.version1->get_face (i);
166     default:return Null(OpenTypeFontFace);
167     }
168   }
169
170   inline bool sanitize (SANITIZE_ARG_DEF) {
171     TRACE_SANITIZE ();
172     if (!SANITIZE (u.header.version)) return false;
173     switch (u.header.version) {
174     case 2: /* version 2 is compatible with version 1 */
175     case 1: return u.version1->sanitize (SANITIZE_ARG);
176     default:return true;
177     }
178   }
179
180   private:
181   union {
182   struct {
183   Tag           ttcTag;         /* TrueType Collection ID string: 'ttcf' */
184   FixedVersion  version;        /* Version of the TTC Header (1.0 or 2.0),
185                                  * 0x00010000 or 0x00020000 */
186   }                     header;
187   TTCHeaderVersion1     version1[VAR];
188   } u;
189 };
190
191
192 /*
193  * OpenType Font File
194  */
195
196 struct OpenTypeFontFile
197 {
198   static const hb_tag_t CFFTag          = HB_TAG ('O','T','T','O');
199   static const hb_tag_t TrueTypeTag     = HB_TAG ( 0 , 1 , 0 , 0 );
200   static const hb_tag_t TTCTag          = HB_TAG ('t','t','c','f');
201
202   inline hb_tag_t get_tag (void) const { return u.tag; }
203
204   inline unsigned int get_face_count (void) const
205   {
206     switch (u.tag) {
207     case CFFTag:        /* All the non-collection tags */
208     case TrueTypeTag:   return 1;
209     case TTCTag:        return u.ttcHeader->get_face_count ();
210     default:            return 0;
211     }
212   }
213   inline const OpenTypeFontFace& get_face (unsigned int i) const
214   {
215     switch (u.tag) {
216     /* Note: for non-collection SFNT data we ignore index.  This is because
217      * Apple dfont container is a container of SFNT's.  So each SFNT is a
218      * non-TTC, but the index is more than zero. */
219     case CFFTag:        /* All the non-collection tags */
220     case TrueTypeTag:   return u.fontFace[0];
221     case TTCTag:        return u.ttcHeader->get_face (i);
222     default:            return Null(OpenTypeFontFace);
223     }
224   }
225
226   inline bool sanitize (SANITIZE_ARG_DEF) {
227     TRACE_SANITIZE ();
228     if (!SANITIZE (u.tag)) return false;
229     switch (u.tag) {
230     case CFFTag:        /* All the non-collection tags */
231     case TrueTypeTag:   return u.fontFace->sanitize (SANITIZE_ARG);
232     case TTCTag:        return u.ttcHeader->sanitize (SANITIZE_ARG);
233     default:            return true;
234     }
235   }
236
237   private:
238   union {
239   Tag                   tag;            /* 4-byte identifier. */
240   OpenTypeFontFace      fontFace[VAR];
241   TTCHeader             ttcHeader[VAR];
242   } u;
243 };
244
245
246 #endif /* HB_OPEN_FILE_PRIVATE_HH */