26871c2fc09d614490cf1de8e55008b8d261c4d0
[platform/upstream/harfbuzz.git] / src / hb-ot-shape-complex-private.hh
1 /*
2  * Copyright © 2010,2011,2012  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_SHAPE_COMPLEX_PRIVATE_HH
28 #define HB_OT_SHAPE_COMPLEX_PRIVATE_HH
29
30 #include "hb-private.hh"
31
32 #include "hb-ot-shape-private.hh"
33 #include "hb-ot-shape-normalize-private.hh"
34
35
36
37 /* buffer var allocations, used by complex shapers */
38 #define complex_var_u8_0()      var2.u8[2]
39 #define complex_var_u8_1()      var2.u8[3]
40
41
42
43 /* Master OT shaper list */
44 #define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
45   HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
46   HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
47   HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
48   HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
49   /* ^--- Add new shapers here */
50
51
52 struct hb_ot_complex_shaper_t
53 {
54   char name[8];
55
56   /* collect_features()
57    * Called during shape_plan().
58    * Shapers should use plan->map to add their features and callbacks.
59    * May be NULL.
60    */
61   void (*collect_features) (hb_ot_shape_planner_t *plan);
62
63   /* override_features()
64    * Called during shape_plan().
65    * Shapers should use plan->map to override features and add callbacks after
66    * common features are added.
67    * May be NULL.
68    */
69   void (*override_features) (hb_ot_shape_planner_t *plan);
70
71
72   /* data_create()
73    * Called at the end of shape_plan().
74    * Whatever shapers return will be accessible through plan->data later.
75    * If NULL is returned, means a plan failure.
76    */
77   void *(*data_create) (const hb_ot_shape_plan_t *plan);
78
79   /* data_destroy()
80    * Called when the shape_plan is being destroyed.
81    * plan->data is passed here for destruction.
82    * If NULL is returned, means a plan failure.
83    * May be NULL.
84    */
85   void (*data_destroy) (void *data);
86
87
88   /* preprocess_text()
89    * Called during shape().
90    * Shapers can use to modify text before shaping starts.
91    * May be NULL.
92    */
93   void (*preprocess_text) (const hb_ot_shape_plan_t *plan,
94                            hb_buffer_t              *buffer,
95                            hb_font_t                *font);
96
97
98   /* normalization_preference()
99    * Called during shape().
100    * May be NULL.
101    */
102   hb_ot_shape_normalization_mode_t
103   (*normalization_preference) (const hb_segment_properties_t *props);
104
105   /* decompose()
106    * Called during shape()'s normalization.
107    * May be NULL.
108    */
109   bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
110                      hb_codepoint_t  ab,
111                      hb_codepoint_t *a,
112                      hb_codepoint_t *b);
113
114   /* compose()
115    * Called during shape()'s normalization.
116    * May be NULL.
117    */
118   bool (*compose) (const hb_ot_shape_normalize_context_t *c,
119                    hb_codepoint_t  a,
120                    hb_codepoint_t  b,
121                    hb_codepoint_t *ab);
122
123   /* setup_masks()
124    * Called during shape().
125    * Shapers should use map to get feature masks and set on buffer.
126    * Shapers may NOT modify characters.
127    * May be NULL.
128    */
129   void (*setup_masks) (const hb_ot_shape_plan_t *plan,
130                        hb_buffer_t              *buffer,
131                        hb_font_t                *font);
132
133   bool zero_width_attached_marks;
134   bool fallback_position;
135 };
136
137 #define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
138 HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
139 #undef HB_COMPLEX_SHAPER_IMPLEMENT
140
141
142 static inline const hb_ot_complex_shaper_t *
143 hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
144 {
145   switch ((hb_tag_t) planner->props.script)
146   {
147     default:
148       return &_hb_ot_complex_shaper_default;
149
150
151     /* Unicode-1.1 additions */
152     case HB_SCRIPT_ARABIC:
153     case HB_SCRIPT_MONGOLIAN:
154     case HB_SCRIPT_SYRIAC:
155
156     /* Unicode-5.0 additions */
157     case HB_SCRIPT_NKO:
158     case HB_SCRIPT_PHAGS_PA:
159
160     /* Unicode-6.0 additions */
161     case HB_SCRIPT_MANDAIC:
162
163       /* For Arabic script, use the Arabic shaper even if no OT script tag was found.
164        * This is because we do fallback shaping for Arabic script (and not others). */
165       if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
166           planner->props.script == HB_SCRIPT_ARABIC)
167         return &_hb_ot_complex_shaper_arabic;
168       else
169         return &_hb_ot_complex_shaper_default;
170
171
172     /* Unicode-1.1 additions */
173     case HB_SCRIPT_THAI:
174     case HB_SCRIPT_LAO:
175
176       return &_hb_ot_complex_shaper_thai;
177
178
179
180     /* ^--- Add new shapers here */
181
182
183 #if 0
184     /* Note:
185      *
186      * These disabled scripts are listed in ucd/IndicSyllabicCategory.txt, but according
187      * to Martin Hosken and Jonathan Kew do not require complex shaping.
188      *
189      * TODO We should automate figuring out which scripts do not need complex shaping
190      *
191      * TODO We currently keep data for these scripts in our indic table.  Need to fix the
192      * generator to not do that.
193      */
194
195
196     /* Simple? */
197
198     /* Unicode-3.2 additions */
199     case HB_SCRIPT_BUHID:
200     case HB_SCRIPT_HANUNOO:
201
202     /* Unicode-5.1 additions */
203     case HB_SCRIPT_SAURASHTRA:
204
205     /* Unicode-6.0 additions */
206     case HB_SCRIPT_BATAK:
207     case HB_SCRIPT_BRAHMI:
208
209
210     /* Simple */
211
212     /* Unicode-1.1 additions */
213     /* These have their own shaper now. */
214     case HB_SCRIPT_LAO:
215     case HB_SCRIPT_THAI:
216
217     /* Unicode-2.0 additions */
218     case HB_SCRIPT_TIBETAN:
219
220     /* Unicode-3.2 additions */
221     case HB_SCRIPT_TAGALOG:
222     case HB_SCRIPT_TAGBANWA:
223
224     /* Unicode-4.0 additions */
225     case HB_SCRIPT_LIMBU:
226     case HB_SCRIPT_TAI_LE:
227
228     /* Unicode-4.1 additions */
229     case HB_SCRIPT_KHAROSHTHI:
230     case HB_SCRIPT_SYLOTI_NAGRI:
231
232     /* Unicode-5.1 additions */
233     case HB_SCRIPT_KAYAH_LI:
234
235     /* Unicode-5.2 additions */
236     case HB_SCRIPT_TAI_VIET:
237
238
239 #endif
240
241     /* Unicode-1.1 additions */
242     case HB_SCRIPT_BENGALI:
243     case HB_SCRIPT_DEVANAGARI:
244     case HB_SCRIPT_GUJARATI:
245     case HB_SCRIPT_GURMUKHI:
246     case HB_SCRIPT_KANNADA:
247     case HB_SCRIPT_MALAYALAM:
248     case HB_SCRIPT_ORIYA:
249     case HB_SCRIPT_TAMIL:
250     case HB_SCRIPT_TELUGU:
251
252     /* Unicode-3.0 additions */
253     case HB_SCRIPT_SINHALA:
254
255     /* Unicode-4.1 additions */
256     case HB_SCRIPT_BUGINESE:
257     case HB_SCRIPT_NEW_TAI_LUE:
258
259     /* Unicode-5.0 additions */
260     case HB_SCRIPT_BALINESE:
261
262     /* Unicode-5.1 additions */
263     case HB_SCRIPT_CHAM:
264     case HB_SCRIPT_LEPCHA:
265     case HB_SCRIPT_REJANG:
266     case HB_SCRIPT_SUNDANESE:
267
268     /* Unicode-5.2 additions */
269     case HB_SCRIPT_JAVANESE:
270     case HB_SCRIPT_KAITHI:
271     case HB_SCRIPT_MEETEI_MAYEK:
272     case HB_SCRIPT_TAI_THAM:
273
274
275     /* Unicode-6.1 additions */
276     case HB_SCRIPT_CHAKMA:
277     case HB_SCRIPT_SHARADA:
278     case HB_SCRIPT_TAKRI:
279
280       /* Only use Indic shaper if the font has Indic tables. */
281       if (planner->map.found_script[0])
282         return &_hb_ot_complex_shaper_indic;
283       else
284         return &_hb_ot_complex_shaper_default;
285
286     case HB_SCRIPT_KHMER:
287       /* A number of Khmer fonts in the wild don't have a 'pref' feature,
288        * and as such won't shape properly via the Indic shaper;
289        * however, they typically have 'liga' / 'clig' features that implement
290        * the necessary "reordering" by means of ligature substitutions.
291        * So we send such pref-less fonts through the generic shaper instead. */
292       if (planner->map.found_script[0] &&
293           hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB,
294                                               planner->map.script_index[0],
295                                               planner->map.language_index[0],
296                                               HB_TAG ('p','r','e','f'),
297                                               NULL))
298         return &_hb_ot_complex_shaper_indic;
299       else
300         return &_hb_ot_complex_shaper_default;
301
302     case HB_SCRIPT_MYANMAR:
303       /* For Myanmar, we only want to use the Indic shaper if the "new" script
304        * tag is found.  For "old" script tag we want to use the default shaper. */
305       if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
306         return &_hb_ot_complex_shaper_indic;
307       else
308         return &_hb_ot_complex_shaper_default;
309   }
310 }
311
312
313 #endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */