[HB] Remove unused methods
[framework/uifw/harfbuzz.git] / src / hb-ot-layout-common-private.h
1 /*
2  * Copyright (C) 2007,2008,2009  Red Hat, Inc.
3  *
4  *  This is part of HarfBuzz, an OpenType Layout engine 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_OT_LAYOUT_COMMON_PRIVATE_H
28 #define HB_OT_LAYOUT_COMMON_PRIVATE_H
29
30 #include "hb-ot-layout-open-private.h"
31
32
33 /*
34  *
35  * OpenType Layout Common Table Formats
36  *
37  */
38
39
40 /*
41  * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
42  */
43
44 template <typename Type>
45 struct Record {
46   Tag           tag;            /* 4-byte Tag identifier */
47   OffsetTo<Type>
48                 offset;         /* Offset from beginning of object holding
49                                  * the Record */
50 };
51
52 template <typename Type>
53 struct RecordListOf : ArrayOf<Record<Type> > {
54   inline const Type& operator [] (unsigned int i) const {
55     if (HB_UNLIKELY (i >= this->len)) return Null(Type);
56     return this+this->array[i].offset;
57   }
58   inline const Tag& get_tag (unsigned int i) const {
59     if (HB_UNLIKELY (i >= this->len)) return Null(Tag);
60     return this->array[i].tag;
61   }
62 };
63
64
65 struct Script;
66 typedef Record<Script> ScriptRecord;
67 ASSERT_SIZE (ScriptRecord, 6);
68 struct LangSys;
69 typedef Record<LangSys> LangSysRecord;
70 ASSERT_SIZE (LangSysRecord, 6);
71 struct Feature;
72 typedef Record<Feature> FeatureRecord;
73 ASSERT_SIZE (FeatureRecord, 6);
74
75
76 struct LangSys {
77
78   inline const unsigned int get_feature_index (unsigned int i) const {
79     return featureIndex[i];
80   }
81   inline unsigned int get_feature_count (void) const {
82     return featureIndex.len;
83   }
84
85   inline const bool has_required_feature (void) const {
86     return reqFeatureIndex != 0xffff;
87   }
88   /* Returns NO_INDEX if none */
89   inline int get_required_feature_index (void) const {
90     if (reqFeatureIndex == 0xffff)
91       return NO_INDEX;
92    return reqFeatureIndex;;
93   }
94
95   Offset        lookupOrder;    /* = Null (reserved for an offset to a
96                                  * reordering table) */
97   USHORT        reqFeatureIndex;/* Index of a feature required for this
98                                  * language system--if no required features
99                                  * = 0xFFFF */
100   ArrayOf<USHORT>
101                 featureIndex;   /* Array of indices into the FeatureList */
102 };
103 ASSERT_SIZE_DATA (LangSys, 6, "\0\0\xFF\xFF");
104
105
106 struct Script {
107
108   inline const LangSys& get_lang_sys (unsigned int i) const {
109     if (i == NO_INDEX) return get_default_lang_sys ();
110     return this+langSys[i].offset;
111   }
112   inline unsigned int get_lang_sys_count (void) const {
113     return langSys.len;
114   }
115   inline const Tag& get_lang_sys_tag (unsigned int i) const {
116     return langSys[i].tag;
117   }
118
119   // LONGTERMTODO bsearch
120   DEFINE_TAG_FIND_INTERFACE (LangSys, lang_sys);        /* find_lang_sys_index (), get_lang_sys_by_tag (tag) */
121
122   inline const bool has_default_lang_sys (void) const {
123     return defaultLangSys != 0;
124   }
125   inline const LangSys& get_default_lang_sys (void) const {
126     return this+defaultLangSys;
127   }
128
129   private:
130   OffsetTo<LangSys>
131                 defaultLangSys; /* Offset to DefaultLangSys table--from
132                                  * beginning of Script table--may be Null */
133   ArrayOf<LangSysRecord>
134                 langSys;        /* Array of LangSysRecords--listed
135                                  * alphabetically by LangSysTag */
136 };
137 ASSERT_SIZE (Script, 4);
138
139 typedef RecordListOf<Script> ScriptList;
140 ASSERT_SIZE (ScriptList, 2);
141
142
143 struct Feature {
144
145   inline const unsigned int get_lookup_index (unsigned int i) const {
146     return lookupIndex[i];
147   }
148   inline unsigned int get_lookup_count (void) const {
149     return lookupIndex.len;
150   }
151
152   /* TODO: implement get_feature_parameters() */
153   /* TODO: implement FeatureSize and other special features? */
154   Offset        featureParams;  /* Offset to Feature Parameters table (if one
155                                  * has been defined for the feature), relative
156                                  * to the beginning of the Feature Table; = Null
157                                  * if not required */
158   ArrayOf<USHORT>
159                 lookupIndex;    /* Array of LookupList indices */
160 };
161 ASSERT_SIZE (Feature, 4);
162
163 typedef RecordListOf<Feature> FeatureList;
164 ASSERT_SIZE (FeatureList, 2);
165
166
167 struct LookupFlag : USHORT {
168   enum {
169     RightToLeft         = 0x0001u,
170     IgnoreBaseGlyphs    = 0x0002u,
171     IgnoreLigatures     = 0x0004u,
172     IgnoreMarks         = 0x0008u,
173     Reserved            = 0x00F0u,
174     MarkAttachmentType  = 0xFF00u,
175   };
176 };
177 ASSERT_SIZE (LookupFlag, 2);
178
179 struct LookupSubTable {
180   private:
181   USHORT        format;         /* Subtable format.  Different for GSUB and GPOS */
182 };
183 ASSERT_SIZE (LookupSubTable, 2);
184
185 struct Lookup {
186
187   inline const LookupSubTable& get_subtable (unsigned int i) const {
188     return this+subTable[i];
189   }
190   inline unsigned int get_subtable_count (void) const {
191     return subTable.len;
192   }
193
194   inline unsigned int get_type (void) const { return lookupType; }
195   inline unsigned int get_flag (void) const { return lookupFlag; }
196
197   USHORT        lookupType;     /* Different enumerations for GSUB and GPOS */
198   USHORT        lookupFlag;     /* Lookup qualifiers */
199   OffsetArrayOf<LookupSubTable>
200                 subTable;       /* Array of SubTables */
201 };
202 ASSERT_SIZE (Lookup, 6);
203
204 template <typename Type>
205 struct OffsetListOf : OffsetArrayOf<Type> {
206   inline const Type& operator [] (unsigned int i) const {
207     if (HB_UNLIKELY (i >= this->len)) return Null(Type);
208     return this+this->array[i];
209   }
210 };
211
212 typedef OffsetListOf<Lookup> LookupList;
213 ASSERT_SIZE (LookupList, 2);
214
215
216 /*
217  * Coverage Table
218  */
219
220 struct CoverageFormat1 {
221
222   friend struct Coverage;
223
224   private:
225   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const {
226     if (HB_UNLIKELY (glyph_id > 0xFFFF))
227       return NOT_COVERED;
228     GlyphID gid;
229     gid = glyph_id;
230     // TODO: bsearch
231     unsigned int num_glyphs = glyphArray.len;
232     for (unsigned int i = 0; i < num_glyphs; i++)
233       if (gid == glyphArray[i])
234         return i;
235     return NOT_COVERED;
236   }
237
238   USHORT        coverageFormat; /* Format identifier--format = 1 */
239   ArrayOf<GlyphID>
240                 glyphArray;     /* Array of GlyphIDs--in numerical order */
241 };
242 ASSERT_SIZE (CoverageFormat1, 4);
243
244 struct CoverageRangeRecord {
245
246   friend struct CoverageFormat2;
247
248   private:
249   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const {
250     if (glyph_id >= start && glyph_id <= end)
251       return (unsigned int) startCoverageIndex + (glyph_id - start);
252     return NOT_COVERED;
253   }
254
255   private:
256   GlyphID       start;                  /* First GlyphID in the range */
257   GlyphID       end;                    /* Last GlyphID in the range */
258   USHORT        startCoverageIndex;     /* Coverage Index of first GlyphID in
259                                          * range */
260 };
261 ASSERT_SIZE_DATA (CoverageRangeRecord, 6, "\000\001");
262
263 struct CoverageFormat2 {
264
265   friend struct Coverage;
266
267   private:
268   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const {
269     // TODO: bsearch
270     unsigned int count = rangeRecord.len;
271     for (unsigned int i = 0; i < count; i++) {
272       unsigned int coverage = rangeRecord[i].get_coverage (glyph_id);
273       if (coverage != NOT_COVERED)
274         return coverage;
275     }
276     return NOT_COVERED;
277   }
278
279   USHORT        coverageFormat; /* Format identifier--format = 2 */
280   ArrayOf<CoverageRangeRecord>
281                 rangeRecord;    /* Array of glyph ranges--ordered by
282                                  * Start GlyphID. rangeCount entries
283                                  * long */
284 };
285 ASSERT_SIZE (CoverageFormat2, 4);
286
287 struct Coverage {
288   unsigned int get_coverage (hb_codepoint_t glyph_id) const {
289     switch (u.format) {
290     case 1: return u.format1->get_coverage(glyph_id);
291     case 2: return u.format2->get_coverage(glyph_id);
292     default:return NOT_COVERED;
293     }
294   }
295
296   inline unsigned int operator() (hb_codepoint_t glyph_id) const {
297     return get_coverage (glyph_id);
298   }
299
300   private:
301   union {
302   USHORT                format;         /* Format identifier */
303   CoverageFormat1       format1[];
304   CoverageFormat2       format2[];
305   } u;
306 };
307 ASSERT_SIZE (Coverage, 2);
308
309
310 /*
311  * Class Definition Table
312  */
313
314 struct ClassDefFormat1 {
315
316   friend struct ClassDef;
317
318   private:
319   inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
320     if ((unsigned int) (glyph_id - startGlyph) < classValue.len)
321       return classValue[glyph_id - startGlyph];
322     return 0;
323   }
324
325   USHORT        classFormat;            /* Format identifier--format = 1 */
326   GlyphID       startGlyph;             /* First GlyphID of the classValueArray */
327   ArrayOf<USHORT>
328                 classValue;             /* Array of Class Values--one per GlyphID */
329 };
330 ASSERT_SIZE (ClassDefFormat1, 6);
331
332 struct ClassRangeRecord {
333
334   friend struct ClassDefFormat2;
335
336   private:
337   inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
338     if (glyph_id >= start && glyph_id <= end)
339       return classValue;
340     return 0;
341   }
342
343   private:
344   GlyphID       start;          /* First GlyphID in the range */
345   GlyphID       end;            /* Last GlyphID in the range */
346   USHORT        classValue;     /* Applied to all glyphs in the range */
347 };
348 ASSERT_SIZE_DATA (ClassRangeRecord, 6, "\000\001");
349
350 struct ClassDefFormat2 {
351
352   friend struct ClassDef;
353
354   private:
355   inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
356     // TODO: bsearch
357     unsigned int count = rangeRecord.len;
358     for (unsigned int i = 0; i < count; i++) {
359       int classValue = rangeRecord[i].get_class (glyph_id);
360       if (classValue > 0)
361         return classValue;
362     }
363     return 0;
364   }
365
366   USHORT        classFormat;    /* Format identifier--format = 2 */
367   ArrayOf<ClassRangeRecord>
368                 rangeRecord;    /* Array of glyph ranges--ordered by
369                                  * Start GlyphID */
370 };
371 ASSERT_SIZE (ClassDefFormat2, 4);
372
373 struct ClassDef {
374   hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
375     switch (u.format) {
376     case 1: return u.format1->get_class(glyph_id);
377     case 2: return u.format2->get_class(glyph_id);
378     default:return 0;
379     }
380   }
381
382   inline unsigned int operator() (hb_codepoint_t glyph_id) const {
383     return get_class (glyph_id);
384   }
385
386   private:
387   union {
388   USHORT                format;         /* Format identifier */
389   ClassDefFormat1       format1[];
390   ClassDefFormat2       format2[];
391   } u;
392 };
393 ASSERT_SIZE (ClassDef, 2);
394
395
396 /*
397  * Device Tables
398  */
399
400 struct Device {
401   int get_delta (unsigned int ppem_size) const {
402
403     unsigned int f = deltaFormat;
404     if (HB_UNLIKELY (f < 1 || f > 3))
405       return 0;
406
407     if (ppem_size < startSize || ppem_size > endSize)
408       return 0;
409
410     unsigned int s = ppem_size - startSize;
411
412     unsigned int byte = deltaValue[s >> (4 - f)];
413     unsigned int bits = byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f));
414     unsigned int mask = 0xFFFF >> (16 - (1 << f));
415
416     int delta = bits & mask;
417
418     if (delta >= ((mask + 1) >> 1))
419       delta -= mask + 1;
420
421     return delta;
422   }
423
424   inline int operator() (unsigned int ppem_size) const {
425     return get_delta (ppem_size);
426   }
427
428   private:
429   USHORT        startSize;      /* Smallest size to correct--in ppem */
430   USHORT        endSize;        /* Largest size to correct--in ppem */
431   USHORT        deltaFormat;    /* Format of DeltaValue array data: 1, 2, or 3 */
432   USHORT        deltaValue[];   /* Array of compressed data */
433 };
434 ASSERT_SIZE (Device, 6);
435
436
437 #endif /* HB_OT_LAYOUT_COMMON_PRIVATE_H */