1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/harfbuzz/src/hb-ot-shape-complex-private.hh Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,357 @@ 1.4 +/* 1.5 + * Copyright © 2010,2011,2012 Google, Inc. 1.6 + * 1.7 + * This is part of HarfBuzz, a text shaping library. 1.8 + * 1.9 + * Permission is hereby granted, without written agreement and without 1.10 + * license or royalty fees, to use, copy, modify, and distribute this 1.11 + * software and its documentation for any purpose, provided that the 1.12 + * above copyright notice and the following two paragraphs appear in 1.13 + * all copies of this software. 1.14 + * 1.15 + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1.16 + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1.17 + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1.18 + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1.19 + * DAMAGE. 1.20 + * 1.21 + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 1.22 + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 1.23 + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 1.24 + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 1.25 + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 1.26 + * 1.27 + * Google Author(s): Behdad Esfahbod 1.28 + */ 1.29 + 1.30 +#ifndef HB_OT_SHAPE_COMPLEX_PRIVATE_HH 1.31 +#define HB_OT_SHAPE_COMPLEX_PRIVATE_HH 1.32 + 1.33 +#include "hb-private.hh" 1.34 + 1.35 +#include "hb-ot-shape-private.hh" 1.36 +#include "hb-ot-shape-normalize-private.hh" 1.37 + 1.38 + 1.39 + 1.40 +/* buffer var allocations, used by complex shapers */ 1.41 +#define complex_var_u8_0() var2.u8[2] 1.42 +#define complex_var_u8_1() var2.u8[3] 1.43 + 1.44 + 1.45 +enum hb_ot_shape_zero_width_marks_type_t { 1.46 + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, 1.47 +// HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY, 1.48 + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, 1.49 + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, 1.50 + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, 1.51 + 1.52 + HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT = HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE 1.53 +}; 1.54 + 1.55 + 1.56 +/* Master OT shaper list */ 1.57 +#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \ 1.58 + HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \ 1.59 + HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \ 1.60 + HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \ 1.61 + HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \ 1.62 + HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ 1.63 + HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ 1.64 + HB_COMPLEX_SHAPER_IMPLEMENT (sea) \ 1.65 + HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ 1.66 + HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \ 1.67 + /* ^--- Add new shapers here */ 1.68 + 1.69 + 1.70 +struct hb_ot_complex_shaper_t 1.71 +{ 1.72 + char name[8]; 1.73 + 1.74 + /* collect_features() 1.75 + * Called during shape_plan(). 1.76 + * Shapers should use plan->map to add their features and callbacks. 1.77 + * May be NULL. 1.78 + */ 1.79 + void (*collect_features) (hb_ot_shape_planner_t *plan); 1.80 + 1.81 + /* override_features() 1.82 + * Called during shape_plan(). 1.83 + * Shapers should use plan->map to override features and add callbacks after 1.84 + * common features are added. 1.85 + * May be NULL. 1.86 + */ 1.87 + void (*override_features) (hb_ot_shape_planner_t *plan); 1.88 + 1.89 + 1.90 + /* data_create() 1.91 + * Called at the end of shape_plan(). 1.92 + * Whatever shapers return will be accessible through plan->data later. 1.93 + * If NULL is returned, means a plan failure. 1.94 + */ 1.95 + void *(*data_create) (const hb_ot_shape_plan_t *plan); 1.96 + 1.97 + /* data_destroy() 1.98 + * Called when the shape_plan is being destroyed. 1.99 + * plan->data is passed here for destruction. 1.100 + * If NULL is returned, means a plan failure. 1.101 + * May be NULL. 1.102 + */ 1.103 + void (*data_destroy) (void *data); 1.104 + 1.105 + 1.106 + /* preprocess_text() 1.107 + * Called during shape(). 1.108 + * Shapers can use to modify text before shaping starts. 1.109 + * May be NULL. 1.110 + */ 1.111 + void (*preprocess_text) (const hb_ot_shape_plan_t *plan, 1.112 + hb_buffer_t *buffer, 1.113 + hb_font_t *font); 1.114 + 1.115 + 1.116 + hb_ot_shape_normalization_mode_t normalization_preference; 1.117 + 1.118 + /* decompose() 1.119 + * Called during shape()'s normalization. 1.120 + * May be NULL. 1.121 + */ 1.122 + bool (*decompose) (const hb_ot_shape_normalize_context_t *c, 1.123 + hb_codepoint_t ab, 1.124 + hb_codepoint_t *a, 1.125 + hb_codepoint_t *b); 1.126 + 1.127 + /* compose() 1.128 + * Called during shape()'s normalization. 1.129 + * May be NULL. 1.130 + */ 1.131 + bool (*compose) (const hb_ot_shape_normalize_context_t *c, 1.132 + hb_codepoint_t a, 1.133 + hb_codepoint_t b, 1.134 + hb_codepoint_t *ab); 1.135 + 1.136 + /* setup_masks() 1.137 + * Called during shape(). 1.138 + * Shapers should use map to get feature masks and set on buffer. 1.139 + * Shapers may NOT modify characters. 1.140 + * May be NULL. 1.141 + */ 1.142 + void (*setup_masks) (const hb_ot_shape_plan_t *plan, 1.143 + hb_buffer_t *buffer, 1.144 + hb_font_t *font); 1.145 + 1.146 + hb_ot_shape_zero_width_marks_type_t zero_width_marks; 1.147 + 1.148 + bool fallback_position; 1.149 +}; 1.150 + 1.151 +#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name; 1.152 +HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS 1.153 +#undef HB_COMPLEX_SHAPER_IMPLEMENT 1.154 + 1.155 + 1.156 +static inline const hb_ot_complex_shaper_t * 1.157 +hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) 1.158 +{ 1.159 + switch ((hb_tag_t) planner->props.script) 1.160 + { 1.161 + default: 1.162 + return &_hb_ot_complex_shaper_default; 1.163 + 1.164 + 1.165 + /* Unicode-1.1 additions */ 1.166 + case HB_SCRIPT_ARABIC: 1.167 + 1.168 + /* Unicode-3.0 additions */ 1.169 + case HB_SCRIPT_MONGOLIAN: 1.170 + case HB_SCRIPT_SYRIAC: 1.171 + 1.172 + /* Unicode-5.0 additions */ 1.173 + case HB_SCRIPT_NKO: 1.174 + case HB_SCRIPT_PHAGS_PA: 1.175 + 1.176 + /* Unicode-6.0 additions */ 1.177 + case HB_SCRIPT_MANDAIC: 1.178 + 1.179 + /* For Arabic script, use the Arabic shaper even if no OT script tag was found. 1.180 + * This is because we do fallback shaping for Arabic script (and not others). */ 1.181 + if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT || 1.182 + planner->props.script == HB_SCRIPT_ARABIC) 1.183 + return &_hb_ot_complex_shaper_arabic; 1.184 + else 1.185 + return &_hb_ot_complex_shaper_default; 1.186 + 1.187 + 1.188 + /* Unicode-1.1 additions */ 1.189 + case HB_SCRIPT_THAI: 1.190 + case HB_SCRIPT_LAO: 1.191 + 1.192 + return &_hb_ot_complex_shaper_thai; 1.193 + 1.194 + 1.195 + /* Unicode-1.1 additions */ 1.196 + case HB_SCRIPT_HANGUL: 1.197 + 1.198 + return &_hb_ot_complex_shaper_hangul; 1.199 + 1.200 + 1.201 + /* Unicode-2.0 additions */ 1.202 + case HB_SCRIPT_TIBETAN: 1.203 + 1.204 + return &_hb_ot_complex_shaper_tibetan; 1.205 + 1.206 + 1.207 + /* Unicode-1.1 additions */ 1.208 + case HB_SCRIPT_HEBREW: 1.209 + 1.210 + return &_hb_ot_complex_shaper_hebrew; 1.211 + 1.212 + 1.213 + /* ^--- Add new shapers here */ 1.214 + 1.215 + 1.216 +#if 0 1.217 + /* Note: 1.218 + * 1.219 + * These disabled scripts are listed in ucd/IndicSyllabicCategory.txt, but according 1.220 + * to Martin Hosken and Jonathan Kew do not require complex shaping. 1.221 + * 1.222 + * TODO We should automate figuring out which scripts do not need complex shaping 1.223 + * 1.224 + * TODO We currently keep data for these scripts in our indic table. Need to fix the 1.225 + * generator to not do that. 1.226 + */ 1.227 + 1.228 + 1.229 + /* Simple? */ 1.230 + 1.231 + /* Unicode-3.2 additions */ 1.232 + case HB_SCRIPT_BUHID: 1.233 + case HB_SCRIPT_HANUNOO: 1.234 + 1.235 + /* Unicode-5.1 additions */ 1.236 + case HB_SCRIPT_SAURASHTRA: 1.237 + 1.238 + /* Unicode-6.0 additions */ 1.239 + case HB_SCRIPT_BATAK: 1.240 + case HB_SCRIPT_BRAHMI: 1.241 + 1.242 + 1.243 + /* Simple */ 1.244 + 1.245 + /* Unicode-1.1 additions */ 1.246 + /* These have their own shaper now. */ 1.247 + case HB_SCRIPT_LAO: 1.248 + case HB_SCRIPT_THAI: 1.249 + 1.250 + /* Unicode-3.2 additions */ 1.251 + case HB_SCRIPT_TAGALOG: 1.252 + case HB_SCRIPT_TAGBANWA: 1.253 + 1.254 + /* Unicode-4.0 additions */ 1.255 + case HB_SCRIPT_LIMBU: 1.256 + case HB_SCRIPT_TAI_LE: 1.257 + 1.258 + /* Unicode-4.1 additions */ 1.259 + case HB_SCRIPT_KHAROSHTHI: 1.260 + case HB_SCRIPT_SYLOTI_NAGRI: 1.261 + 1.262 + /* Unicode-5.1 additions */ 1.263 + case HB_SCRIPT_KAYAH_LI: 1.264 + 1.265 + /* Unicode-5.2 additions */ 1.266 + case HB_SCRIPT_TAI_VIET: 1.267 + 1.268 + 1.269 +#endif 1.270 + 1.271 + /* Unicode-1.1 additions */ 1.272 + case HB_SCRIPT_BENGALI: 1.273 + case HB_SCRIPT_DEVANAGARI: 1.274 + case HB_SCRIPT_GUJARATI: 1.275 + case HB_SCRIPT_GURMUKHI: 1.276 + case HB_SCRIPT_KANNADA: 1.277 + case HB_SCRIPT_MALAYALAM: 1.278 + case HB_SCRIPT_ORIYA: 1.279 + case HB_SCRIPT_TAMIL: 1.280 + case HB_SCRIPT_TELUGU: 1.281 + 1.282 + /* Unicode-3.0 additions */ 1.283 + case HB_SCRIPT_SINHALA: 1.284 + 1.285 + /* Unicode-5.0 additions */ 1.286 + case HB_SCRIPT_BALINESE: 1.287 + 1.288 + /* Unicode-5.1 additions */ 1.289 + case HB_SCRIPT_LEPCHA: 1.290 + case HB_SCRIPT_REJANG: 1.291 + case HB_SCRIPT_SUNDANESE: 1.292 + 1.293 + /* Unicode-5.2 additions */ 1.294 + case HB_SCRIPT_JAVANESE: 1.295 + case HB_SCRIPT_KAITHI: 1.296 + case HB_SCRIPT_MEETEI_MAYEK: 1.297 + 1.298 + /* Unicode-6.0 additions */ 1.299 + 1.300 + /* Unicode-6.1 additions */ 1.301 + case HB_SCRIPT_CHAKMA: 1.302 + case HB_SCRIPT_SHARADA: 1.303 + case HB_SCRIPT_TAKRI: 1.304 + 1.305 + /* If the designer designed the font for the 'DFLT' script, 1.306 + * use the default shaper. Otherwise, use the Indic shaper. 1.307 + * Note that for some simple scripts, there may not be *any* 1.308 + * GSUB/GPOS needed, so there may be no scripts found! */ 1.309 + if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) 1.310 + return &_hb_ot_complex_shaper_default; 1.311 + else 1.312 + return &_hb_ot_complex_shaper_indic; 1.313 + 1.314 + case HB_SCRIPT_KHMER: 1.315 + /* A number of Khmer fonts in the wild don't have a 'pref' feature, 1.316 + * and as such won't shape properly via the Indic shaper; 1.317 + * however, they typically have 'liga' / 'clig' features that implement 1.318 + * the necessary "reordering" by means of ligature substitutions. 1.319 + * So we send such pref-less fonts through the generic shaper instead. */ 1.320 + if (planner->map.found_script[0] && 1.321 + hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB, 1.322 + planner->map.script_index[0], 1.323 + planner->map.language_index[0], 1.324 + HB_TAG ('p','r','e','f'), 1.325 + NULL)) 1.326 + return &_hb_ot_complex_shaper_indic; 1.327 + else 1.328 + return &_hb_ot_complex_shaper_default; 1.329 + 1.330 + case HB_SCRIPT_MYANMAR: 1.331 + /* For Myanmar, we only want to use the Myanmar shaper if the "new" script 1.332 + * tag is found. For "old" script tag we want to use the default shaper. */ 1.333 + if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2')) 1.334 + return &_hb_ot_complex_shaper_myanmar; 1.335 + else 1.336 + return &_hb_ot_complex_shaper_default; 1.337 + 1.338 + /* Unicode-4.1 additions */ 1.339 + case HB_SCRIPT_BUGINESE: 1.340 + case HB_SCRIPT_NEW_TAI_LUE: 1.341 + 1.342 + /* Unicode-5.1 additions */ 1.343 + case HB_SCRIPT_CHAM: 1.344 + 1.345 + /* Unicode-5.2 additions */ 1.346 + case HB_SCRIPT_TAI_THAM: 1.347 + 1.348 + /* If the designer designed the font for the 'DFLT' script, 1.349 + * use the default shaper. Otherwise, use the Indic shaper. 1.350 + * Note that for some simple scripts, there may not be *any* 1.351 + * GSUB/GPOS needed, so there may be no scripts found! */ 1.352 + if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) 1.353 + return &_hb_ot_complex_shaper_default; 1.354 + else 1.355 + return &_hb_ot_complex_shaper_sea; 1.356 + } 1.357 +} 1.358 + 1.359 + 1.360 +#endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */