| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2010,2012 Google, Inc. | 2 * Copyright © 2010,2012 Google, Inc. |
| 3 * | 3 * |
| 4 * This is part of HarfBuzz, a text shaping library. | 4 * This is part of HarfBuzz, a text shaping library. |
| 5 * | 5 * |
| 6 * Permission is hereby granted, without written agreement and without | 6 * Permission is hereby granted, without written agreement and without |
| 7 * license or royalty fees, to use, copy, modify, and distribute this | 7 * license or royalty fees, to use, copy, modify, and distribute this |
| 8 * software and its documentation for any purpose, provided that the | 8 * software and its documentation for any purpose, provided that the |
| 9 * above copyright notice and the following two paragraphs appear in | 9 * above copyright notice and the following two paragraphs appear in |
| 10 * all copies of this software. | 10 * all copies of this software. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 /* buffer var allocations */ | 31 /* buffer var allocations */ |
| 32 #define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ | 32 #define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ |
| 33 | 33 |
| 34 | 34 |
| 35 /* | 35 /* |
| 36 * Bits used in the joining tables | 36 * Bits used in the joining tables |
| 37 */ | 37 */ |
| 38 enum { | 38 enum { |
| 39 JOINING_TYPE_U = 0, | 39 JOINING_TYPE_U = 0, |
| 40 JOINING_TYPE_R» » = 1, | 40 JOINING_TYPE_L» » = 1, |
| 41 JOINING_TYPE_D» » = 2, | 41 JOINING_TYPE_R» » = 2, |
| 42 JOINING_TYPE_D» » = 3, |
| 42 JOINING_TYPE_C = JOINING_TYPE_D, | 43 JOINING_TYPE_C = JOINING_TYPE_D, |
| 43 JOINING_GROUP_ALAPH» » = 3, | 44 JOINING_GROUP_ALAPH» » = 4, |
| 44 JOINING_GROUP_DALATH_RISH» = 4, | 45 JOINING_GROUP_DALATH_RISH» = 5, |
| 45 NUM_STATE_MACHINE_COLS» = 5, | 46 NUM_STATE_MACHINE_COLS» = 6, |
| 46 | 47 |
| 47 /* We deliberately don't have a JOINING_TYPE_L since that's unused in Unicode.
*/ | 48 JOINING_TYPE_T = 7, |
| 48 | 49 JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. *
/ |
| 49 JOINING_TYPE_T = 6, | |
| 50 JOINING_TYPE_X = 7 /* means: use general-category to choose between U or T. *
/ | |
| 51 }; | 50 }; |
| 52 | 51 |
| 53 /* | 52 /* |
| 54 * Joining types: | 53 * Joining types: |
| 55 */ | 54 */ |
| 56 | 55 |
| 57 #include "hb-ot-shape-complex-arabic-table.hh" | 56 #include "hb-ot-shape-complex-arabic-table.hh" |
| 58 | 57 |
| 59 static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ
ory_t gen_cat) | 58 static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ
ory_t gen_cat) |
| 60 { | 59 { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 74 if ((FLAG(gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | | 73 if ((FLAG(gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | |
| 75 FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER))) | 74 FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER))) |
| 76 || u == 0x1807 || u == 0x180A) | 75 || u == 0x1807 || u == 0x180A) |
| 77 return JOINING_TYPE_D; | 76 return JOINING_TYPE_D; |
| 78 } | 77 } |
| 79 | 78 |
| 80 /* 'Phags-pa joining data is not in ArabicJoining.txt yet. */ | 79 /* 'Phags-pa joining data is not in ArabicJoining.txt yet. */ |
| 81 if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872))) | 80 if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872))) |
| 82 { | 81 { |
| 83 if (unlikely (u == 0xA872)) | 82 if (unlikely (u == 0xA872)) |
| 84 » /* XXX Looks like this should be TYPE_L, but we don't support that yet!
*/ | 83 » return JOINING_TYPE_L; |
| 85 » return JOINING_TYPE_R; | |
| 86 | 84 |
| 87 return JOINING_TYPE_D; | 85 return JOINING_TYPE_D; |
| 88 } | 86 } |
| 89 | 87 |
| 90 if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D))) | 88 if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D))) |
| 91 { | 89 { |
| 92 return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C; | 90 return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C; |
| 93 } | 91 } |
| 94 | 92 |
| 95 return (FLAG(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEG
ORY_FORMAT))) ? | 93 return (FLAG(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEG
ORY_FORMAT))) ? |
| (...skipping 30 matching lines...) Expand all Loading... |
| 126 | 124 |
| 127 ARABIC_NUM_FEATURES = NONE | 125 ARABIC_NUM_FEATURES = NONE |
| 128 }; | 126 }; |
| 129 | 127 |
| 130 static const struct arabic_state_table_entry { | 128 static const struct arabic_state_table_entry { |
| 131 uint8_t prev_action; | 129 uint8_t prev_action; |
| 132 uint8_t curr_action; | 130 uint8_t curr_action; |
| 133 uint16_t next_state; | 131 uint16_t next_state; |
| 134 } arabic_state_table[][NUM_STATE_MACHINE_COLS] = | 132 } arabic_state_table[][NUM_STATE_MACHINE_COLS] = |
| 135 { | 133 { |
| 136 /* jt_U, jt_R, jt_D, jg_ALAPH, jg_DALATH_RIS
H */ | 134 /* jt_U, jt_L, jt_R, jt_D, jg_ALAPH,
jg_DALATH_RISH */ |
| 137 | 135 |
| 138 /* State 0: prev was U, not willing to join. */ | 136 /* State 0: prev was U, not willing to join. */ |
| 139 { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, }
, | 137 { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {
NONE,ISOL,6}, }, |
| 140 | 138 |
| 141 /* State 1: prev was R or ISOL/ALAPH, not willing to join. */ | 139 /* State 1: prev was R or ISOL/ALAPH, not willing to join. */ |
| 142 { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, }
, | 140 { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {
NONE,ISOL,6}, }, |
| 143 | 141 |
| 144 /* State 2: prev was D/ISOL, willing to join. */ | 142 /* State 2: prev was D/L in ISOL form, willing to join. */ |
| 145 { {NONE,NONE,0}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, }
, | 143 { {NONE,NONE,0}, {NONE,ISOL,2}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {
INIT,FINA,6}, }, |
| 146 | 144 |
| 147 /* State 3: prev was D/FINA, willing to join. */ | 145 /* State 3: prev was D in FINA form, willing to join. */ |
| 148 { {NONE,NONE,0}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, }
, | 146 { {NONE,NONE,0}, {NONE,ISOL,2}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {
MEDI,FINA,6}, }, |
| 149 | 147 |
| 150 /* State 4: prev was FINA ALAPH, not willing to join. */ | 148 /* State 4: prev was FINA ALAPH, not willing to join. */ |
| 151 { {NONE,NONE,0}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, }
, | 149 { {NONE,NONE,0}, {NONE,ISOL,2}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {
MED2,ISOL,6}, }, |
| 152 | 150 |
| 153 /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */ | 151 /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */ |
| 154 { {NONE,NONE,0}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, }
, | 152 { {NONE,NONE,0}, {NONE,ISOL,2}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {
ISOL,ISOL,6}, }, |
| 155 | 153 |
| 156 /* State 6: prev was DALATH/RISH, not willing to join. */ | 154 /* State 6: prev was DALATH/RISH, not willing to join. */ |
| 157 { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, } | 155 { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {
NONE,ISOL,6}, } |
| 158 }; | 156 }; |
| 159 | 157 |
| 160 | 158 |
| 161 static void | 159 static void |
| 162 arabic_fallback_shape (const hb_ot_shape_plan_t *plan, | 160 arabic_fallback_shape (const hb_ot_shape_plan_t *plan, |
| 163 hb_font_t *font, | 161 hb_font_t *font, |
| 164 hb_buffer_t *buffer); | 162 hb_buffer_t *buffer); |
| 165 | 163 |
| 166 static void | 164 static void |
| 167 collect_features_arabic (hb_ot_shape_planner_t *plan) | 165 collect_features_arabic (hb_ot_shape_planner_t *plan) |
| 168 { | 166 { |
| 169 hb_ot_map_builder_t *map = &plan->map; | 167 hb_ot_map_builder_t *map = &plan->map; |
| 170 | 168 |
| 171 /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init togeth
er, | 169 /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init togeth
er, |
| 172 * then rlig and calt each in their own stage. This makes IranNastaliq's ALLA
H | 170 * then rlig and calt each in their own stage. This makes IranNastaliq's ALLA
H |
| 173 * ligature work correctly. It's unfortunate though... | 171 * ligature work correctly. It's unfortunate though... |
| 174 * | 172 * |
| 175 * This also makes Arial Bold in Windows7 work. See: | 173 * This also makes Arial Bold in Windows7 work. See: |
| 176 * https://bugzilla.mozilla.org/show_bug.cgi?id=644184 | 174 * https://bugzilla.mozilla.org/show_bug.cgi?id=644184 |
| 177 * | 175 * |
| 178 * TODO: Add test cases for these two. | 176 * TODO: Add test cases for these two. |
| 179 */ | 177 */ |
| 180 | 178 |
| 181 map->add_bool_feature (HB_TAG('c','c','m','p')); | 179 map->add_global_bool_feature (HB_TAG('c','c','m','p')); |
| 182 map->add_bool_feature (HB_TAG('l','o','c','l')); | 180 map->add_global_bool_feature (HB_TAG('l','o','c','l')); |
| 183 | 181 |
| 184 map->add_gsub_pause (NULL); | 182 map->add_gsub_pause (NULL); |
| 185 | 183 |
| 186 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) | 184 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) |
| 187 map->add_bool_feature (arabic_features[i], false, i < 4); /* The first four
features have fallback. */ | 185 map->add_feature (arabic_features[i], 1, i < 4 ? F_HAS_FALLBACK : F_NONE); /
* The first four features have fallback. */ |
| 188 | 186 |
| 189 map->add_gsub_pause (NULL); | 187 map->add_gsub_pause (NULL); |
| 190 | 188 |
| 191 map->add_bool_feature (HB_TAG('r','l','i','g'), true, true); | 189 map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK); |
| 192 map->add_gsub_pause (arabic_fallback_shape); | 190 map->add_gsub_pause (arabic_fallback_shape); |
| 193 | 191 |
| 194 map->add_bool_feature (HB_TAG('c','a','l','t')); | 192 map->add_global_bool_feature (HB_TAG('c','a','l','t')); |
| 195 map->add_gsub_pause (NULL); | 193 map->add_gsub_pause (NULL); |
| 196 | 194 |
| 197 map->add_bool_feature (HB_TAG('c','s','w','h')); | 195 map->add_global_bool_feature (HB_TAG('c','s','w','h')); |
| 198 map->add_bool_feature (HB_TAG('d','l','i','g')); | 196 map->add_global_bool_feature (HB_TAG('d','l','i','g')); |
| 199 map->add_bool_feature (HB_TAG('m','s','e','t')); | 197 map->add_global_bool_feature (HB_TAG('m','s','e','t')); |
| 200 } | 198 } |
| 201 | 199 |
| 202 #include "hb-ot-shape-complex-arabic-fallback.hh" | 200 #include "hb-ot-shape-complex-arabic-fallback.hh" |
| 203 | 201 |
| 204 struct arabic_shape_plan_t | 202 struct arabic_shape_plan_t |
| 205 { | 203 { |
| 206 ASSERT_POD (); | 204 ASSERT_POD (); |
| 207 | 205 |
| 208 /* The "+ 1" in the next array is to accommodate for the "NONE" command, | 206 /* The "+ 1" in the next array is to accommodate for the "NONE" command, |
| 209 * which is not an OpenType feature, but this simplifies the code by not | 207 * which is not an OpenType feature, but this simplifies the code by not |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 "arabic", | 345 "arabic", |
| 348 collect_features_arabic, | 346 collect_features_arabic, |
| 349 NULL, /* override_features */ | 347 NULL, /* override_features */ |
| 350 data_create_arabic, | 348 data_create_arabic, |
| 351 data_destroy_arabic, | 349 data_destroy_arabic, |
| 352 NULL, /* preprocess_text_arabic */ | 350 NULL, /* preprocess_text_arabic */ |
| 353 NULL, /* normalization_preference */ | 351 NULL, /* normalization_preference */ |
| 354 NULL, /* decompose */ | 352 NULL, /* decompose */ |
| 355 NULL, /* compose */ | 353 NULL, /* compose */ |
| 356 setup_masks_arabic, | 354 setup_masks_arabic, |
| 357 true, /* zero_width_attached_marks */ | 355 HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE, |
| 358 true, /* fallback_position */ | 356 true, /* fallback_position */ |
| 359 }; | 357 }; |
| OLD | NEW |