Imported Upstream version 2.6.7
[platform/upstream/harfbuzz.git] / src / hb-ot-kern-table.hh
1 /*
2  * Copyright © 2017  Google, 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  * Google Author(s): Behdad Esfahbod
25  */
26
27 #ifndef HB_OT_KERN_TABLE_HH
28 #define HB_OT_KERN_TABLE_HH
29
30 #include "hb-aat-layout-kerx-table.hh"
31
32
33 /*
34  * kern -- Kerning
35  * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
36  * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
37  */
38 #define HB_OT_TAG_kern HB_TAG('k','e','r','n')
39
40
41 namespace OT {
42
43
44 template <typename KernSubTableHeader>
45 struct KernSubTableFormat3
46 {
47   int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
48   {
49     hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
50     hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (kernValue).as_array (glyphCount);
51     hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (leftClass).as_array (glyphCount);
52     hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8>> (rightClass).as_array (leftClassCount * rightClassCount);
53
54     unsigned int leftC = leftClass[left];
55     unsigned int rightC = rightClass[right];
56     if (unlikely (leftC >= leftClassCount || rightC >= rightClassCount))
57       return 0;
58     unsigned int i = leftC * rightClassCount + rightC;
59     return kernValue[kernIndex[i]];
60   }
61
62   bool apply (AAT::hb_aat_apply_context_t *c) const
63   {
64     TRACE_APPLY (this);
65
66     if (!c->plan->requested_kerning)
67       return false;
68
69     if (header.coverage & header.Backwards)
70       return false;
71
72     hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream);
73     machine.kern (c->font, c->buffer, c->plan->kern_mask);
74
75     return_trace (true);
76   }
77
78   bool sanitize (hb_sanitize_context_t *c) const
79   {
80     TRACE_SANITIZE (this);
81     return_trace (c->check_struct (this) &&
82                   c->check_range (kernValueZ,
83                                   kernValueCount * sizeof (FWORD) +
84                                   glyphCount * 2 +
85                                   leftClassCount * rightClassCount));
86   }
87
88   protected:
89   KernSubTableHeader
90                 header;
91   HBUINT16      glyphCount;     /* The number of glyphs in this font. */
92   HBUINT8       kernValueCount; /* The number of kerning values. */
93   HBUINT8       leftClassCount; /* The number of left-hand classes. */
94   HBUINT8       rightClassCount;/* The number of right-hand classes. */
95   HBUINT8       flags;          /* Set to zero (reserved for future use). */
96   UnsizedArrayOf<FWORD>
97                 kernValueZ;     /* The kerning values.
98                                  * Length kernValueCount. */
99 #if 0
100   UnsizedArrayOf<HBUINT8>
101                 leftClass;      /* The left-hand classes.
102                                  * Length glyphCount. */
103   UnsizedArrayOf<HBUINT8>
104                 rightClass;     /* The right-hand classes.
105                                  * Length glyphCount. */
106   UnsizedArrayOf<HBUINT8>kernIndex;
107                                 /* The indices into the kernValue array.
108                                  * Length leftClassCount * rightClassCount */
109 #endif
110   public:
111   DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
112 };
113
114 template <typename KernSubTableHeader>
115 struct KernSubTable
116 {
117   unsigned int get_size () const { return u.header.length; }
118   unsigned int get_type () const { return u.header.format; }
119
120   int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
121   {
122     switch (get_type ()) {
123     /* This method hooks up to hb_font_t's get_h_kerning.  Only support Format0. */
124     case 0: return u.format0.get_kerning (left, right);
125     default:return 0;
126     }
127   }
128
129   template <typename context_t, typename ...Ts>
130   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
131   {
132     unsigned int subtable_type = get_type ();
133     TRACE_DISPATCH (this, subtable_type);
134     switch (subtable_type) {
135     case 0:     return_trace (c->dispatch (u.format0));
136 #ifndef HB_NO_AAT_SHAPE
137     case 1:     return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward<Ts> (ds)...) : c->default_return_value ());
138 #endif
139     case 2:     return_trace (c->dispatch (u.format2));
140 #ifndef HB_NO_AAT_SHAPE
141     case 3:     return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward<Ts> (ds)...) : c->default_return_value ());
142 #endif
143     default:    return_trace (c->default_return_value ());
144     }
145   }
146
147   bool sanitize (hb_sanitize_context_t *c) const
148   {
149     TRACE_SANITIZE (this);
150     if (unlikely (!u.header.sanitize (c) ||
151                   u.header.length < u.header.min_size ||
152                   !c->check_range (this, u.header.length))) return_trace (false);
153
154     return_trace (dispatch (c));
155   }
156
157   public:
158   union {
159   KernSubTableHeader                            header;
160   AAT::KerxSubTableFormat0<KernSubTableHeader>  format0;
161   AAT::KerxSubTableFormat1<KernSubTableHeader>  format1;
162   AAT::KerxSubTableFormat2<KernSubTableHeader>  format2;
163   KernSubTableFormat3<KernSubTableHeader>       format3;
164   } u;
165   public:
166   DEFINE_SIZE_MIN (KernSubTableHeader::static_size);
167 };
168
169
170 struct KernOTSubTableHeader
171 {
172   static constexpr bool apple = false;
173   typedef AAT::ObsoleteTypes Types;
174
175   unsigned   tuple_count () const { return 0; }
176   bool     is_horizontal () const { return (coverage & Horizontal); }
177
178   enum Coverage
179   {
180     Horizontal  = 0x01u,
181     Minimum     = 0x02u,
182     CrossStream = 0x04u,
183     Override    = 0x08u,
184
185     /* Not supported: */
186     Backwards   = 0x00u,
187     Variation   = 0x00u,
188   };
189
190   bool sanitize (hb_sanitize_context_t *c) const
191   {
192     TRACE_SANITIZE (this);
193     return_trace (c->check_struct (this));
194   }
195
196   public:
197   HBUINT16      versionZ;       /* Unused. */
198   HBUINT16      length;         /* Length of the subtable (including this header). */
199   HBUINT8       format;         /* Subtable format. */
200   HBUINT8       coverage;       /* Coverage bits. */
201   public:
202   DEFINE_SIZE_STATIC (6);
203 };
204
205 struct KernOT : AAT::KerxTable<KernOT>
206 {
207   friend struct AAT::KerxTable<KernOT>;
208
209   static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
210   static constexpr unsigned minVersion = 0u;
211
212   typedef KernOTSubTableHeader SubTableHeader;
213   typedef SubTableHeader::Types Types;
214   typedef KernSubTable<SubTableHeader> SubTable;
215
216   protected:
217   HBUINT16      version;        /* Version--0x0000u */
218   HBUINT16      tableCount;     /* Number of subtables in the kerning table. */
219   SubTable      firstSubTable;  /* Subtables. */
220   public:
221   DEFINE_SIZE_MIN (4);
222 };
223
224
225 struct KernAATSubTableHeader
226 {
227   static constexpr bool apple = true;
228   typedef AAT::ObsoleteTypes Types;
229
230   unsigned   tuple_count () const { return 0; }
231   bool     is_horizontal () const { return !(coverage & Vertical); }
232
233   enum Coverage
234   {
235     Vertical    = 0x80u,
236     CrossStream = 0x40u,
237     Variation   = 0x20u,
238
239     /* Not supported: */
240     Backwards   = 0x00u,
241   };
242
243   bool sanitize (hb_sanitize_context_t *c) const
244   {
245     TRACE_SANITIZE (this);
246     return_trace (c->check_struct (this));
247   }
248
249   public:
250   HBUINT32      length;         /* Length of the subtable (including this header). */
251   HBUINT8       coverage;       /* Coverage bits. */
252   HBUINT8       format;         /* Subtable format. */
253   HBUINT16      tupleIndex;     /* The tuple index (used for variations fonts).
254                                  * This value specifies which tuple this subtable covers.
255                                  * Note: We don't implement. */
256   public:
257   DEFINE_SIZE_STATIC (8);
258 };
259
260 struct KernAAT : AAT::KerxTable<KernAAT>
261 {
262   friend struct AAT::KerxTable<KernAAT>;
263
264   static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
265   static constexpr unsigned minVersion = 0x00010000u;
266
267   typedef KernAATSubTableHeader SubTableHeader;
268   typedef SubTableHeader::Types Types;
269   typedef KernSubTable<SubTableHeader> SubTable;
270
271   protected:
272   HBUINT32      version;        /* Version--0x00010000u */
273   HBUINT32      tableCount;     /* Number of subtables in the kerning table. */
274   SubTable      firstSubTable;  /* Subtables. */
275   public:
276   DEFINE_SIZE_MIN (8);
277 };
278
279 struct kern
280 {
281   static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
282
283   bool     has_data () const { return u.version32; }
284   unsigned get_type () const { return u.major; }
285
286   bool has_state_machine () const
287   {
288     switch (get_type ()) {
289     case 0: return u.ot.has_state_machine ();
290 #ifndef HB_NO_AAT_SHAPE
291     case 1: return u.aat.has_state_machine ();
292 #endif
293     default:return false;
294     }
295   }
296
297   bool has_cross_stream () const
298   {
299     switch (get_type ()) {
300     case 0: return u.ot.has_cross_stream ();
301 #ifndef HB_NO_AAT_SHAPE
302     case 1: return u.aat.has_cross_stream ();
303 #endif
304     default:return false;
305     }
306   }
307
308   int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
309   {
310     switch (get_type ()) {
311     case 0: return u.ot.get_h_kerning (left, right);
312 #ifndef HB_NO_AAT_SHAPE
313     case 1: return u.aat.get_h_kerning (left, right);
314 #endif
315     default:return 0;
316     }
317   }
318
319   bool apply (AAT::hb_aat_apply_context_t *c) const
320   { return dispatch (c); }
321
322   template <typename context_t, typename ...Ts>
323   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
324   {
325     unsigned int subtable_type = get_type ();
326     TRACE_DISPATCH (this, subtable_type);
327     switch (subtable_type) {
328     case 0:     return_trace (c->dispatch (u.ot, hb_forward<Ts> (ds)...));
329 #ifndef HB_NO_AAT_SHAPE
330     case 1:     return_trace (c->dispatch (u.aat, hb_forward<Ts> (ds)...));
331 #endif
332     default:    return_trace (c->default_return_value ());
333     }
334   }
335
336   bool sanitize (hb_sanitize_context_t *c) const
337   {
338     TRACE_SANITIZE (this);
339     if (!u.version32.sanitize (c)) return_trace (false);
340     return_trace (dispatch (c));
341   }
342
343   protected:
344   union {
345   HBUINT32              version32;
346   HBUINT16              major;
347   KernOT                ot;
348 #ifndef HB_NO_AAT_SHAPE
349   KernAAT               aat;
350 #endif
351   } u;
352   public:
353   DEFINE_SIZE_UNION (4, version32);
354 };
355
356 } /* namespace OT */
357
358
359 #endif /* HB_OT_KERN_TABLE_HH */