178 { |
178 { |
179 hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t)); |
179 hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t)); |
180 if (unlikely (!plan)) |
180 if (unlikely (!plan)) |
181 return nullptr; |
181 return nullptr; |
182 |
182 |
|
183 plan->init (); |
|
184 |
183 hb_ot_shape_planner_t planner (shape_plan); |
185 hb_ot_shape_planner_t planner (shape_plan); |
184 |
186 |
185 planner.shaper = hb_ot_shape_complex_categorize (&planner); |
187 planner.shaper = hb_ot_shape_complex_categorize (&planner); |
186 |
188 |
187 hb_ot_shape_collect_features (&planner, &shape_plan->props, |
189 hb_ot_shape_collect_features (&planner, &shape_plan->props, |
266 buffer->idx = 0; |
268 buffer->idx = 0; |
267 hb_glyph_info_t info = dottedcircle; |
269 hb_glyph_info_t info = dottedcircle; |
268 info.cluster = buffer->cur().cluster; |
270 info.cluster = buffer->cur().cluster; |
269 info.mask = buffer->cur().mask; |
271 info.mask = buffer->cur().mask; |
270 buffer->output_info (info); |
272 buffer->output_info (info); |
271 while (buffer->idx < buffer->len && !buffer->in_error) |
273 while (buffer->idx < buffer->len && buffer->successful) |
272 buffer->next_glyph (); |
274 buffer->next_glyph (); |
273 |
275 |
274 buffer->swap_buffers (); |
276 buffer->swap_buffers (); |
275 } |
277 } |
276 |
278 |
304 |
306 |
305 static void |
307 static void |
306 hb_ensure_native_direction (hb_buffer_t *buffer) |
308 hb_ensure_native_direction (hb_buffer_t *buffer) |
307 { |
309 { |
308 hb_direction_t direction = buffer->props.direction; |
310 hb_direction_t direction = buffer->props.direction; |
|
311 hb_direction_t horiz_dir = hb_script_get_horizontal_direction (buffer->props.script); |
309 |
312 |
310 /* TODO vertical: |
313 /* TODO vertical: |
311 * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType |
314 * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType |
312 * Ogham fonts are supposed to be implemented BTT or not. Need to research that |
315 * Ogham fonts are supposed to be implemented BTT or not. Need to research that |
313 * first. */ |
316 * first. */ |
314 if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) || |
317 if ((HB_DIRECTION_IS_HORIZONTAL (direction) && |
315 (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) |
318 direction != horiz_dir && horiz_dir != HB_DIRECTION_INVALID) || |
|
319 (HB_DIRECTION_IS_VERTICAL (direction) && |
|
320 direction != HB_DIRECTION_TTB)) |
316 { |
321 { |
317 /* Same loop as hb_form_clusters(). |
322 /* Same loop as hb_form_clusters(). |
318 * Since form_clusters() merged clusters already, we don't merge. */ |
323 * Since form_clusters() merged clusters already, we don't merge. */ |
319 unsigned int base = 0; |
324 unsigned int base = 0; |
320 unsigned int count = buffer->len; |
325 unsigned int count = buffer->len; |
937 hb_buffer_t *buffer, |
942 hb_buffer_t *buffer, |
938 const hb_feature_t *features, |
943 const hb_feature_t *features, |
939 unsigned int num_features, |
944 unsigned int num_features, |
940 hb_set_t *glyphs) |
945 hb_set_t *glyphs) |
941 { |
946 { |
942 hb_ot_shape_plan_t plan; |
|
943 |
|
944 const char *shapers[] = {"ot", nullptr}; |
947 const char *shapers[] = {"ot", nullptr}; |
945 hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, |
948 hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, |
946 features, num_features, shapers); |
949 features, num_features, shapers); |
947 |
950 |
948 bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL; |
951 bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL; |
952 for (unsigned int i = 0; i < count; i++) |
955 for (unsigned int i = 0; i < count; i++) |
953 add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs); |
956 add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs); |
954 |
957 |
955 hb_set_t *lookups = hb_set_create (); |
958 hb_set_t *lookups = hb_set_create (); |
956 hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, lookups); |
959 hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, lookups); |
957 |
960 hb_ot_layout_lookups_substitute_closure (font->face, lookups, glyphs); |
958 /* And find transitive closure. */ |
|
959 hb_set_t *copy = hb_set_create (); |
|
960 do { |
|
961 copy->set (glyphs); |
|
962 for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);) |
|
963 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); |
|
964 } while (!copy->is_equal (glyphs)); |
|
965 hb_set_destroy (copy); |
|
966 |
961 |
967 hb_set_destroy (lookups); |
962 hb_set_destroy (lookups); |
968 |
963 |
969 hb_shape_plan_destroy (shape_plan); |
964 hb_shape_plan_destroy (shape_plan); |
970 } |
965 } |