< prev index next >
src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.cc
Print this page
@@ -67,10 +67,13 @@
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,23 +164,26 @@
*/
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)
+ 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);
+ hb_ot_shape_collect_features (&planner, &shape_plan->props,
+ user_features, num_user_features);
- planner.compile (*plan);
+ 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,10 +216,12 @@
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,10 +530,36 @@
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,11 +571,11 @@
_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))
+ 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,10 +586,13 @@
{
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,30 +667,29 @@
}
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
+static inline void
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));
+ 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,11 +699,11 @@
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
break;
}
- if (has_positioning)
+ 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,11 +722,10 @@
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:
@@ -705,32 +740,30 @@
/* 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);
+ hb_ot_position_complex (c);
- if (fallback && c->plan->shaper->fallback_position)
+ 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 (fallback)
+ if (c->fallback_positioning)
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);
}
@@ -746,10 +779,15 @@
{
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 >