< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.cc

Print this page

        

*** 67,76 **** --- 67,79 ---- const hb_feature_t *user_features, unsigned int num_user_features) { hb_ot_map_builder_t *map = &planner->map; + map->add_global_bool_feature (HB_TAG('r','v','r','n')); + map->add_gsub_pause (NULL); + switch (props->direction) { case HB_DIRECTION_LTR: map->add_global_bool_feature (HB_TAG ('l','t','r','a')); map->add_global_bool_feature (HB_TAG ('l','t','r','m')); break;
*** 161,183 **** */ hb_ot_shaper_shape_plan_data_t * _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, const hb_feature_t *user_features, ! unsigned int num_user_features) { hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t)); if (unlikely (!plan)) return NULL; hb_ot_shape_planner_t planner (shape_plan); planner.shaper = hb_ot_shape_complex_categorize (&planner); ! hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features); ! planner.compile (*plan); if (plan->shaper->data_create) { plan->data = plan->shaper->data_create (plan); if (unlikely (!plan->data)) return NULL; --- 164,189 ---- */ hb_ot_shaper_shape_plan_data_t * _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, const hb_feature_t *user_features, ! unsigned int num_user_features, ! const int *coords, ! unsigned int num_coords) { hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t)); if (unlikely (!plan)) return NULL; hb_ot_shape_planner_t planner (shape_plan); planner.shaper = hb_ot_shape_complex_categorize (&planner); ! hb_ot_shape_collect_features (&planner, &shape_plan->props, ! user_features, num_user_features); ! planner.compile (*plan, coords, num_coords); if (plan->shaper->data_create) { plan->data = plan->shaper->data_create (plan); if (unlikely (!plan->data)) return NULL;
*** 210,219 **** --- 216,227 ---- hb_buffer_t *buffer; const hb_feature_t *user_features; unsigned int num_user_features; /* Transient stuff */ + bool fallback_positioning; + bool fallback_glyph_classes; hb_direction_t target_direction; };
*** 522,531 **** --- 530,565 ---- buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; } static inline void + hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) + { + unsigned int count = c->buffer->len; + hb_glyph_info_t *info = c->buffer->info; + for (unsigned int i = 0; i < count; i++) + { + hb_ot_layout_glyph_props_flags_t klass; + + /* Never mark default-ignorables as marks. + * They won't get in the way of lookups anyway, + * but having them as mark will cause them to be skipped + * over if the lookup-flag says so, but at least for the + * Mongolian variation selectors, looks like Uniscribe + * marks them as non-mark. Some Mongolian fonts without + * GDEF rely on this. Another notable character that + * this applies to is COMBINING GRAPHEME JOINER. */ + klass = (_hb_glyph_info_get_general_category (&info[i]) != + HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK || + _hb_glyph_info_is_default_ignorable (&info[i])) ? + HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : + HB_OT_LAYOUT_GLYPH_PROPS_MARK; + _hb_glyph_info_set_glyph_props (&info[i], klass); + } + } + + static inline void hb_ot_substitute_default (hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; hb_ot_shape_initialize_masks (c);
*** 537,547 **** _hb_ot_shape_normalize (c->plan, buffer, c->font); hb_ot_shape_setup_masks (c); /* This is unfortunate to go here, but necessary... */ ! if (!hb_ot_layout_has_positioning (c->face)) _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer); hb_ot_map_glyphs_fast (buffer); HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); --- 571,581 ---- _hb_ot_shape_normalize (c->plan, buffer, c->font); hb_ot_shape_setup_masks (c); /* This is unfortunate to go here, but necessary... */ ! if (c->fallback_positioning) _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer); hb_ot_map_glyphs_fast (buffer); HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index);
*** 552,561 **** --- 586,598 ---- { hb_buffer_t *buffer = c->buffer; hb_ot_layout_substitute_start (c->font, buffer); + if (!hb_ot_layout_has_glyph_classes (c->face)) + hb_synthesize_glyph_classes (c); + c->plan->substitute (c->font, buffer); return; }
*** 630,659 **** } if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); } ! static inline bool hb_ot_position_complex (hb_ot_shape_context_t *c) { hb_ot_layout_position_start (c->font, c->buffer); - bool ret = false; unsigned int count = c->buffer->len; - bool has_positioning = (bool) hb_ot_layout_has_positioning (c->face); /* If the font has no GPOS, AND, no fallback positioning will * happen, AND, direction is forward, then when zeroing mark * widths, we shift the mark with it, such that the mark * is positioned hanging over the previous glyph. When * direction is backward we don't shift and it will end up * hanging over the next glyph after the final reordering. * If fallback positinoing happens or GPOS is present, we don't * care. */ ! bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallback_position || ! HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)); switch (c->plan->shaper->zero_width_marks) { case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); --- 667,695 ---- } if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); } ! static inline void hb_ot_position_complex (hb_ot_shape_context_t *c) { hb_ot_layout_position_start (c->font, c->buffer); unsigned int count = c->buffer->len; /* If the font has no GPOS, AND, no fallback positioning will * happen, AND, direction is forward, then when zeroing mark * widths, we shift the mark with it, such that the mark * is positioned hanging over the previous glyph. When * direction is backward we don't shift and it will end up * hanging over the next glyph after the final reordering. * If fallback positinoing happens or GPOS is present, we don't * care. */ ! bool adjust_offsets_when_zeroing = c->fallback_positioning && ! !c->plan->shaper->fallback_position && ! HB_DIRECTION_IS_FORWARD (c->buffer->props.direction); switch (c->plan->shaper->zero_width_marks) { case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
*** 663,673 **** case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: break; } ! if (has_positioning) { hb_glyph_info_t *info = c->buffer->info; hb_glyph_position_t *pos = c->buffer->pos; /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ --- 699,709 ---- case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: break; } ! if (likely (!c->fallback_positioning)) { hb_glyph_info_t *info = c->buffer->info; hb_glyph_position_t *pos = c->buffer->pos; /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
*** 686,696 **** for (unsigned int i = 0; i < count; i++) c->font->subtract_glyph_h_origin (info[i].codepoint, &pos[i].x_offset, &pos[i].y_offset); - ret = true; } switch (c->plan->shaper->zero_width_marks) { case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: --- 722,731 ----
*** 705,736 **** /* Finishing off GPOS has to follow a certain order. */ hb_ot_layout_position_finish_advances (c->font, c->buffer); hb_ot_zero_width_default_ignorables (c); hb_ot_layout_position_finish_offsets (c->font, c->buffer); - - return ret; } static inline void hb_ot_position (hb_ot_shape_context_t *c) { c->buffer->clear_positions (); hb_ot_position_default (c); ! hb_bool_t fallback = !hb_ot_position_complex (c); ! if (fallback && c->plan->shaper->fallback_position) _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) hb_buffer_reverse (c->buffer); /* Visual fallback goes here. */ ! if (fallback) _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); _hb_buffer_deallocate_gsubgpos_vars (c->buffer); } --- 740,769 ---- /* Finishing off GPOS has to follow a certain order. */ hb_ot_layout_position_finish_advances (c->font, c->buffer); hb_ot_zero_width_default_ignorables (c); hb_ot_layout_position_finish_offsets (c->font, c->buffer); } static inline void hb_ot_position (hb_ot_shape_context_t *c) { c->buffer->clear_positions (); hb_ot_position_default (c); ! hb_ot_position_complex (c); ! if (c->fallback_positioning && c->plan->shaper->fallback_position) _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) hb_buffer_reverse (c->buffer); /* Visual fallback goes here. */ ! if (c->fallback_positioning) _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); _hb_buffer_deallocate_gsubgpos_vars (c->buffer); }
*** 746,755 **** --- 779,793 ---- { c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_EXPANSION_FACTOR, (unsigned) HB_BUFFER_MAX_LEN_MIN); } + bool disable_otl = c->plan->shaper->disable_otl && c->plan->shaper->disable_otl (c->plan); + //c->fallback_substitute = disable_otl || !hb_ot_layout_has_substitution (c->face); + c->fallback_positioning = disable_otl || !hb_ot_layout_has_positioning (c->face); + c->fallback_glyph_classes = disable_otl || !hb_ot_layout_has_glyph_classes (c->face); + /* Save the original direction, we use it later. */ c->target_direction = c->buffer->props.direction; _hb_buffer_allocate_unicode_vars (c->buffer);
< prev index next >