Give it a start at GSUB
[profile/ivi/org.tizen.video-player.git] / src / hb-ot-layout-gsub-private.h
1 /*
2  * Copyright (C) 2007,2008  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_GSUB_PRIVATE_H
28 #define HB_OT_LAYOUT_GSUB_PRIVATE_H
29
30 #include "hb-ot-layout-private.h"
31
32 #include "hb-ot-layout-open-private.h"
33 #include "hb-ot-layout-gdef-private.h"
34
35
36 struct SingleSubstFormat1 {
37
38   friend struct SingleSubst;
39
40   private:
41   inline bool substitute (hb_ot_layout_t *layout,
42                           hb_buffer_t    *buffer,
43                           unsigned int    context_length,
44                           unsigned int    nesting_level_left) const {
45 //    if (get_coverage (IN_CURGLYPH()))
46 //      return ;
47   }
48
49   private:
50   USHORT        substFormat;            /* Format identifier--format = 1 */
51   Offset        coverage;               /* Offset to Coverage table--from
52                                          * beginning of Substitution table */
53   SHORT         deltaGlyphID;           /* Add to original GlyphID to get
54                                          * substitute GlyphID */
55 };
56 ASSERT_SIZE (SingleSubstFormat1, 6);
57
58 struct SingleSubstFormat2 {
59   /* TODO */
60
61   private:
62   USHORT        substFormat;            /* Format identifier--format = 2 */
63   Offset        coverage;               /* Offset to Coverage table--from
64                                          * beginning of Substitution table */
65   USHORT        glyphCount;             /* Number of GlyphIDs in the Substitute
66                                          * array */
67   GlyphID       substitute[];           /* Array of substitute
68                                          * GlyphIDs--ordered by Coverage  Index */
69 };
70 ASSERT_SIZE (SingleSubstFormat2, 6);
71
72 struct MultipleSubstFormat1 {
73   /* TODO */
74
75   private:
76   USHORT        substFormat;            /* Format identifier--format = 1 */
77   Offset        coverage;               /* Offset to Coverage table--from
78                                          * beginning of Substitution table */
79   USHORT        sequenceCount;          /* Number of Sequence table offsets in
80                                          * the Sequence array */
81   Offset        sequence[];             /* Array of offsets to Sequence
82                                          * tables--from beginning of
83                                          * Substitution table--ordered by
84                                          * Coverage Index */
85 };
86 ASSERT_SIZE (MultipleSubstFormat1, 6);
87
88 struct Sequence {
89   /* TODO */
90
91   private:
92   USHORT        glyphCount;             /* Number of GlyphIDs in the Substitute
93                                          * array. This should always  be
94                                          * greater than 0. */
95   GlyphID       substitute[];           /* String of GlyphIDs to substitute */
96 };
97 DEFINE_NULL_ASSERT_SIZE (Sequence, 2);
98
99 struct AlternateSubstFormat1 {
100   /* TODO */
101
102   private:
103   USHORT        substFormat;            /* Format identifier--format = 1 */
104   Offset        coverage;               /* Offset to Coverage table--from
105                                          * beginning of Substitution table */
106   USHORT        alternateSetCount;      /* Number of AlternateSet tables */
107   Offset        alternateSet[];         /* Array of offsets to AlternateSet
108                                          * tables--from beginning of
109                                          * Substitution table--ordered by
110                                          * Coverage Index */
111 };
112 ASSERT_SIZE (AlternateSubstFormat1, 6);
113
114 struct AlternateSet {
115   /* TODO */
116
117   private:
118   USHORT        glyphCount;             /* Number of GlyphIDs in the Alternate
119                                          * array */
120   GlyphID       alternate[];            /* Array of alternate GlyphIDs--in
121                                          * arbitrary order */
122 };
123 DEFINE_NULL_ASSERT_SIZE (AlternateSet, 2);
124
125 struct LigatureSubstFormat1 {
126   /* TODO */
127
128   private:
129   USHORT        substFormat;            /* Format identifier--format = 1 */
130   Offset        coverage;               /* Offset to Coverage table--from
131                                          * beginning of Substitution table */
132   USHORT        ligSetCount;            /* Number of LigatureSet tables */
133   Offset        ligatureSet[];          /* Array of offsets to LigatureSet
134                                          * tables--from beginning of
135                                          * Substitution table--ordered by
136                                          * Coverage Index */
137 };
138 ASSERT_SIZE (LigatureSubstFormat1, 6);
139
140 struct LigatureSet {
141   /* TODO */
142
143   private:
144   USHORT        ligatureCount;          /* Number of Ligature tables */
145   Offset        ligature[];             /* Array of offsets to Ligature
146                                          * tables--from beginning of
147                                          * LigatureSet table--ordered by
148                                          * preference */
149 };
150 DEFINE_NULL_ASSERT_SIZE (LigatureSet, 2);
151
152 struct Ligature {
153   /* TODO */
154
155   private:
156   GlyphID       ligGlyph;               /* GlyphID of ligature to substitute */
157   USHORT        compCount;              /* Number of components in the ligature */
158   GlyphID       component[];            /* Array of component GlyphIDs--start
159                                          * with the second  component--ordered
160                                          * in writing direction */
161 };
162 DEFINE_NULL_ASSERT_SIZE (Ligature, 4);
163
164 struct SubstLookupRecord {
165   /* TODO */
166
167   private:
168   USHORT        sequenceIndex;          /* Index into current glyph
169                                          * sequence--first glyph = 0 */
170   USHORT        lookupListIndex;        /* Lookup to apply to that
171                                          * position--zero--based */
172 };
173 DEFINE_NULL_ASSERT_SIZE (SubstLookupRecord, 4);
174
175 struct ContextSubstFormat1 {
176   /* TODO */
177
178   private:
179   USHORT        substFormat;            /* Format identifier--format = 1 */
180   Offset        coverage;               /* Offset to Coverage table--from
181                                          * beginning of Substitution table */
182   USHORT        subRuleSetCount;        /* Number of SubRuleSet tables--must
183                                          * equal GlyphCount in Coverage  table */
184   Offset        subRuleSet[];           /* Array of offsets to SubRuleSet
185                                          * tables--from beginning of
186                                          * Substitution table--ordered by
187                                          * Coverage Index */
188 };
189 ASSERT_SIZE (ContextSubstFormat1, 6);
190
191 struct SubRuleSet {
192   /* TODO */
193
194   private:
195   USHORT        subRuleCount;           /* Number of SubRule tables */
196   Offset        subRule[];              /* Array of offsets to SubRule
197                                          * tables--from beginning of SubRuleSet
198                                          * table--ordered by preference */
199 };
200 DEFINE_NULL_ASSERT_SIZE (SubRuleSet, 2);
201
202 struct SubRule {
203   /* TODO */
204
205   private:
206   USHORT        glyphCount;             /* Total number of glyphs in input
207                                          * glyph sequence--includes the  first
208                                          * glyph */
209   USHORT        substCount;             /* Number of SubstLookupRecords */
210   GlyphID       input[];                /* Array of input GlyphIDs--start with
211                                          * second glyph */
212   SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in
213                                          * design order */
214 };
215 DEFINE_NULL_ASSERT_SIZE (SubRule, 4);
216
217 struct ContextSubstFormat2 {
218   /* TODO */
219
220   private:
221   USHORT        substFormat;            /* Format identifier--format = 2 */
222   Offset        coverage;               /* Offset to Coverage table--from
223                                          * beginning of Substitution table */
224   Offset        classDef;               /* Offset to glyph ClassDef table--from
225                                          * beginning of Substitution  table */
226   USHORT        subClassSetCnt;         /* Number of SubClassSet tables */
227   Offset        subClassSet[];          /* Array of offsets to SubClassSet
228                                          * tables--from beginning of
229                                          * Substitution table--ordered by
230                                          * class--may be NULL */
231 };
232 ASSERT_SIZE (ContextSubstFormat2, 8);
233
234 struct SubClassSet {
235   /* TODO */
236
237   private:
238   USHORT        subClassRuleCnt;        /* Number of SubClassRule tables */
239   Offset        subClassRule[];         /* Array of offsets to SubClassRule
240                                          * tables--from beginning of
241                                          * SubClassSet--ordered by preference */
242 };
243 DEFINE_NULL_ASSERT_SIZE (SubClassSet, 2);
244
245 struct SubClassRule {
246   /* TODO */
247
248   private:
249   USHORT        glyphCount;             /* Total number of classes
250                                          * specified for the context in the
251                                          * rule--includes the first class */
252   USHORT        substCount;             /* Number of SubstLookupRecords */
253   USHORT        klass[];                /* Array of classes--beginning with the
254                                          * second class--to be matched  to the
255                                          * input glyph class sequence */
256   SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in
257                                          * design order */
258 };
259 DEFINE_NULL_ASSERT_SIZE (SubClassRule, 4);
260
261 struct ContextSubstFormat3 {
262   /* TODO */
263
264   private:
265   USHORT        substFormat;            /* Format identifier--format = 3 */
266   USHORT        glyphCount;             /* Number of glyphs in the input glyph
267                                          * sequence */
268   USHORT        substCount;             /* Number of SubstLookupRecords */
269   Offset        coverage[];             /* Array of offsets to Coverage
270                                          * table--from beginning of
271                                          * Substitution table--in glyph
272                                          * sequence order */
273   SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in
274                                          * design order */
275 };
276 ASSERT_SIZE (ContextSubstFormat3, 6);
277
278 struct ChainContextSubstFormat1 {
279   /* TODO */
280
281   private:
282   USHORT        substFormat;            /* Format identifier--format = 1 */
283   Offset        coverage;               /* Offset to Coverage table--from
284                                          * beginning of Substitution table */
285   USHORT        chainSubRuleSetCount;   /* Number of ChainSubRuleSet
286                                          * tables--must equal GlyphCount in
287                                          * Coverage table */
288   Offset        chainSubRuleSet[];      /* Array of offsets to ChainSubRuleSet
289                                          * tables--from beginning of
290                                          * Substitution table--ordered by
291                                          * Coverage Index */
292 };
293 ASSERT_SIZE (ChainContextSubstFormat1, 6);
294
295 struct ChainSubRuleSet {
296   /* TODO */
297
298   private:
299   USHORT        chainSubRuleCount;      /* Number of ChainSubRule tables */
300   Offset        chainSubRule[];         /* Array of offsets to ChainSubRule
301                                          * tables--from beginning of
302                                          * ChainSubRuleSet table--ordered
303                                          * by preference */
304 };
305 DEFINE_NULL_ASSERT_SIZE (ChainSubRuleSet, 2);
306
307 struct ChainSubRule {
308   /* TODO */
309
310   private:
311   USHORT        backtrackGlyphCount;    /* Total number of glyphs in the
312                                          * backtrack sequence (number of
313                                          * glyphs to be matched before the
314                                          * first glyph) */
315   GlyphID       backtrack[];            /* Array of backtracking GlyphID's
316                                          * (to be matched before the input
317                                          * sequence) */
318   USHORT        inputGlyphCount;        /* Total number of glyphs in the input
319                                          * sequence (includes the first  glyph) */
320   GlyphID       input[];                /* Array of input GlyphIDs (start with
321                                          * second glyph) */
322   USHORT        lookaheadGlyphCount;    /* Total number of glyphs in the look
323                                          * ahead sequence (number of  glyphs to
324                                          * be matched after the input sequence) */
325   GlyphID       lookAhead[];            /* Array of lookahead GlyphID's (to be
326                                          * matched after  the input sequence) */
327   USHORT        substCount;             /* Number of SubstLookupRecords */
328   SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in
329                                          * design order) */
330 };
331 DEFINE_NULL_ASSERT_SIZE (ChainSubRule, 8);
332
333 struct ChainContextSubstFormat2 {
334   /* TODO */
335
336   private:
337   USHORT        substFormat;            /* Format identifier--format = 2 */
338   Offset        coverage;               /* Offset to Coverage table--from
339                                          * beginning of Substitution table */
340   Offset        backtrackClassDef;      /* Offset to glyph ClassDef table
341                                          * containing backtrack sequence
342                                          * data--from beginning of Substitution
343                                          * table */
344   Offset        inputClassDef;          /* Offset to glyph ClassDef
345                                          * table containing input sequence
346                                          * data--from beginning of Substitution
347                                          * table */
348   Offset        lookaheadClassDef;      /* Offset to glyph ClassDef table
349                                          * containing lookahead sequence
350                                          * data--from beginning of Substitution
351                                          * table */
352   USHORT        chainSubClassSetCnt;    /* Number of ChainSubClassSet tables */
353   Offset        chainSubClassSet[];     /* Array of offsets to ChainSubClassSet
354                                          * tables--from beginning of
355                                          * Substitution table--ordered by input
356                                          * class--may be NULL */
357 };
358 ASSERT_SIZE (ChainContextSubstFormat2, 12);
359
360 struct ChainSubClassSet {
361   /* TODO */
362
363   private:
364   USHORT        chainSubClassRuleCnt;   /* Number of ChainSubClassRule tables */
365   Offset        chainSubClassRule[];    /* Array of offsets
366                                          * to ChainSubClassRule
367                                          * tables--from beginning of
368                                          * ChainSubClassSet--ordered by
369                                          * preference */
370 };
371 DEFINE_NULL_ASSERT_SIZE (ChainSubClassSet, 2);
372
373 struct ChainSubClassRule {
374   /* TODO */
375
376   private:
377   USHORT        backtrackGlyphCount;    /* Total number of glyphs in the
378                                          * backtrack sequence (number of
379                                          * glyphs to be matched before the
380                                          * first glyph) */
381   USHORT        backtrack[];            /* Array of backtracking classes(to be
382                                          * matched before the input  sequence) */
383   USHORT        inputGlyphCount;        /* Total number of classes in the input
384                                          * sequence (includes the  first class) */
385   USHORT        input[];                /* Array of input classes(start with
386                                          * second class; to  be matched with
387                                          * the input glyph sequence) */
388   USHORT        lookaheadGlyphCount;    /* Total number of classes in the
389                                          * look ahead sequence (number of
390                                          * classes to be matched after the
391                                          * input sequence) */
392   USHORT        lookAhead[];            /* Array of lookahead classes(to be
393                                          * matched after the  input sequence) */
394   USHORT        substCount;             /* Number of SubstLookupRecords */
395   SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in
396                                          * design order) */
397 };
398 DEFINE_NULL_ASSERT_SIZE (ChainSubClassRule, 8);
399
400 struct ChainContextSubstFormat3 {
401   /* TODO */
402
403   private:
404   USHORT        substFormat;            /* Format identifier--format = 3 */
405   USHORT        backtrackGlyphCount;    /* Number of glyphs in the backtracking
406                                          * sequence */
407   Offset        backtrackCoverage[];    /* Array of offsets to coverage tables
408                                          * in backtracking sequence, in  glyph
409                                          * sequence order */
410   USHORT        inputGlyphCount;        /* Number of glyphs in input sequence */
411   Offset        inputCoverage[];        /* Array of offsets to coverage
412                                          * tables in input sequence, in glyph
413                                          * sequence order */
414   USHORT        lookaheadGlyphCount;    /* Number of glyphs in lookahead
415                                          * sequence */
416   Offset        lookaheadCoverage[];    /* Array of offsets to coverage tables
417                                          * in lookahead sequence, in  glyph
418                                          * sequence order */
419   USHORT        substCount;             /* Number of SubstLookupRecords */
420   SubstLookupRecord substLookupRecord[];/* Array of SubstLookupRecords--in
421                                          * design order */
422 };
423 ASSERT_SIZE (ChainContextSubstFormat3, 10);
424
425 struct ExtensionSubstFormat1 {
426   /* TODO */
427
428   private:
429   USHORT        substFormat;            /* Format identifier. Set to 1. */
430   USHORT        extensionLookupType;    /* Lookup type of subtable referenced
431                                          * by ExtensionOffset (i.e. the
432                                          * extension subtable). */
433   ULONG         extensionOffset;        /* Offset to the extension subtable,
434                                          * of lookup type  subtable. */
435 };
436 ASSERT_SIZE (ExtensionSubstFormat1, 8);
437
438 struct ReverseChainSingleSubstFormat1 {
439   /* TODO */
440
441   private:
442   USHORT        substFormat;            /* Format identifier--format = 1 */
443   Offset        coverage;               /* Offset to Coverage table -- from
444                                          * beginning of Substitution table */
445   USHORT        backtrackGlyphCount;    /* Number of glyphs in the backtracking
446                                          * sequence */
447   Offset        backtrackCoverage[];    /* Array of offsets to coverage tables
448                                          * in backtracking sequence, in  glyph
449                                          * sequence order */
450   USHORT        lookaheadGlyphCount;    /* Number of glyphs in lookahead
451                                          * sequence */
452   Offset        lookaheadCoverage[];    /* Array of offsets to coverage tables
453                                          * in lookahead sequence, in  glyph
454                                          * sequence order */
455   USHORT        glyphCount;             /* Number of GlyphIDs in the Substitute
456                                          * array */
457   GlyphID       substitute[];           /* Array of substitute
458                                          * GlyphIDs--ordered by Coverage  Index */
459 };
460 ASSERT_SIZE (ReverseChainSingleSubstFormat1, 10);
461
462 /*
463  * SubstLookup
464  */
465
466 struct SubstLookupSubTable {
467   DEFINE_NON_INSTANTIABLE(SubstLookupSubTable);
468
469   friend struct SubstLookup;
470
471   unsigned int get_size (unsigned int lookup_type) const {
472     switch (lookup_type) {
473 //    case 1: return u.format1.get_size ();
474 //    case 2: return u.format2.get_size ();
475     /*
476     case Single:
477     case Multiple:
478     case Alternate:
479     case Ligature:
480     case Context:
481     case ChainingContext:
482     case Extension:
483     case ReverseChainingContextSingle:
484     */
485     default:return sizeof (LookupSubTable);
486     }
487   }
488
489   inline bool substitute (hb_ot_layout_t *layout,
490                           hb_buffer_t    *buffer,
491                           unsigned int    context_length,
492                           unsigned int    nesting_level_left,
493                           unsigned int    lookup_type) const {
494   }
495
496   private:
497   union {
498   USHORT                substFormat;
499   CoverageFormat1       format1;
500   CoverageFormat2       format2;
501   } u;
502 };
503
504 struct SubstLookup : Lookup {
505
506   DEFINE_NON_INSTANTIABLE(SubstLookup);
507
508   static const unsigned int Single                              = 1;
509   static const unsigned int Multiple                            = 2;
510   static const unsigned int Alternate                           = 3;
511   static const unsigned int Ligature                            = 4;
512   static const unsigned int Context                             = 5;
513   static const unsigned int ChainingContext                     = 6;
514   static const unsigned int Extension                           = 7;
515   static const unsigned int ReverseChainingContextSingle        = 8;
516
517   inline const SubstLookupSubTable& get_subtable (unsigned int i) const {
518     return *(SubstLookupSubTable*)&(((Lookup *)this)->get_subtable (i));
519   }
520
521   /* Like get_type(), but looks through extension lookups.
522    * Never returns SubstLookup::Extension */
523   inline unsigned int get_effective_type (void) const {
524     unsigned int type = get_type ();
525
526     if (HB_UNLIKELY (type == Extension)) {
527       /* Return lookup type of first extension subtable.
528        * The spec says all of them should have the same type.
529        * XXX check for that somehow */
530 //XXX      type = get_subtable(0).v.extension.get_type ();
531     }
532
533     return type;
534   }
535
536   inline bool is_reverse (void) const {
537     switch (get_effective_type ()) {
538     case ReverseChainingContextSingle:  return true;
539     default:                            return false;
540     }
541   }
542
543   inline bool substitute (hb_ot_layout_t *layout,
544                           hb_buffer_t    *buffer,
545                           unsigned int    context_length,
546                           unsigned int    nesting_level_left) const {
547     unsigned int lookup_type = get_type ();
548
549     if (HB_UNLIKELY (nesting_level_left == 0))
550       return false;
551     nesting_level_left--;
552   
553     for (unsigned int i = 0; i < get_subtable_count (); i++)
554       if (get_subtable (i).substitute (layout, buffer,
555                                        context_length, nesting_level_left,
556                                        lookup_type))
557         return true;
558   
559     return false;
560   }
561 };
562 DEFINE_NULL_ALIAS (SubstLookup, Lookup);
563
564 /*
565  * GSUB
566  */
567
568 struct GSUB : GSUBGPOS {
569   static const hb_tag_t Tag             = HB_TAG ('G','S','U','B');
570
571   STATIC_DEFINE_GET_FOR_DATA (GSUB);
572   /* XXX check version here? */
573
574   inline const SubstLookup& get_lookup (unsigned int i) const {
575     return *(SubstLookup*)&(((GSUBGPOS *)this)->get_lookup (i));
576   }
577
578
579 };
580 DEFINE_NULL_ALIAS (GSUB, GSUBGPOS);
581
582
583 #endif /* HB_OT_LAYOUT_GSUB_PRIVATE_H */