hb-ot-shape-complex-private.hh revision 851784f8372004e0a40b698c0cdc2d7db8629aa2
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
52struct 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  hb_bool_t (*decompose) (hb_unicode_funcs_t *unicode,
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  hb_bool_t (*compose) (hb_unicode_funcs_t *unicode,
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;
138HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
139#undef HB_COMPLEX_SHAPER_IMPLEMENT
140
141
142static inline const hb_ot_complex_shaper_t *
143hb_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      /* If the font has 'liga', let the generic shaper do it. */
288      if (!planner->map.found_script[0] ||
289	  hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB,
290					      planner->map.script_index[0],
291					      planner->map.language_index[0],
292					      HB_TAG ('l','i','g','a'), NULL))
293	return &_hb_ot_complex_shaper_default;
294      else
295	return &_hb_ot_complex_shaper_indic;
296
297
298    case HB_SCRIPT_MYANMAR:
299      /* For Myanmar, we only want to use the Indic shaper if the "new" script
300       * tag is found.  For "old" script tag we want to use the default shaper. */
301      if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
302	return &_hb_ot_complex_shaper_indic;
303      else
304	return &_hb_ot_complex_shaper_default;
305  }
306}
307
308
309#endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */
310