Adjust mark advance-width zeroing logic for Myanmar
Before, we were zeroing advance width of attached marks for non-Indic scripts, and not doing it for Indic. We have now three different behaviors, which seem to better reflect what Uniscribe is doing: - For Indic, no explicit zeroing happens whatsoever, which is the same as before, - For Myanmar, zero advance width of glyphs marked as marks *in GDEF*, and do that *before* applying GPOS. This seems to be what the new Win8 Myanmar shaper does, - For everything else, zero advance width of glyphs that are from General_Category=Mn Unicode characters, and do so before applying GPOS. This seems to be what Uniscribe does for Latin at least. With these changes, positioning of all tests matches for Myanmar, except for the glitch in Uniscribe not applying 'mark'. See preivous commit.
This commit is contained in:
parent
99749ca8e0
commit
568000274c
|
@ -1528,7 +1528,7 @@ struct GPOS : GSUBGPOS
|
||||||
{ return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
|
{ return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
|
||||||
|
|
||||||
static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
|
static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
|
||||||
static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t zero_width_attahced_marks);
|
static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer);
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -1561,17 +1561,13 @@ fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, hb_bool_t zero_width_attached_marks)
|
fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction)
|
||||||
{
|
{
|
||||||
if (likely (!(pos[i].attach_lookback())))
|
if (likely (!(pos[i].attach_lookback())))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned int j = i - pos[i].attach_lookback();
|
unsigned int j = i - pos[i].attach_lookback();
|
||||||
|
|
||||||
if (zero_width_attached_marks) {
|
|
||||||
pos[i].x_advance = 0;
|
|
||||||
pos[i].y_advance = 0;
|
|
||||||
}
|
|
||||||
pos[i].x_offset += pos[j].x_offset;
|
pos[i].x_offset += pos[j].x_offset;
|
||||||
pos[i].y_offset += pos[j].y_offset;
|
pos[i].y_offset += pos[j].y_offset;
|
||||||
|
|
||||||
|
@ -1598,7 +1594,7 @@ GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t zero_width_attached_marks)
|
GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
|
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
|
||||||
|
@ -1610,7 +1606,7 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t
|
||||||
|
|
||||||
/* Handle attachments */
|
/* Handle attachments */
|
||||||
for (unsigned int i = 0; i < len; i++)
|
for (unsigned int i = 0; i < len; i++)
|
||||||
fix_mark_attachment (pos, i, direction, zero_width_attached_marks);
|
fix_mark_attachment (pos, i, direction);
|
||||||
|
|
||||||
HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
|
HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
|
||||||
HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
|
HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
|
||||||
|
|
|
@ -176,8 +176,7 @@ hb_ot_layout_position_lookup (hb_font_t *font,
|
||||||
/* Should be called after all the position_lookup's are done */
|
/* Should be called after all the position_lookup's are done */
|
||||||
HB_INTERNAL void
|
HB_INTERNAL void
|
||||||
hb_ot_layout_position_finish (hb_font_t *font,
|
hb_ot_layout_position_finish (hb_font_t *font,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer);
|
||||||
hb_bool_t zero_width_attached_marks);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -727,9 +727,9 @@ hb_ot_layout_position_lookup (hb_font_t *font,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t zero_width_attached_marks)
|
hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
OT::GPOS::position_finish (font, buffer, zero_width_attached_marks);
|
OT::GPOS::position_finish (font, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_bool_t
|
hb_bool_t
|
||||||
|
|
|
@ -354,6 +354,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
|
||||||
NULL, /* decompose */
|
NULL, /* decompose */
|
||||||
NULL, /* compose */
|
NULL, /* compose */
|
||||||
setup_masks_arabic,
|
setup_masks_arabic,
|
||||||
true, /* zero_width_attached_marks */
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE,
|
||||||
true, /* fallback_position */
|
true, /* fallback_position */
|
||||||
};
|
};
|
||||||
|
|
|
@ -221,6 +221,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
|
||||||
NULL, /* decompose */
|
NULL, /* decompose */
|
||||||
compose_default,
|
compose_default,
|
||||||
NULL, /* setup_masks */
|
NULL, /* setup_masks */
|
||||||
true, /* zero_width_attached_marks */
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE,
|
||||||
true, /* fallback_position */
|
true, /* fallback_position */
|
||||||
};
|
};
|
||||||
|
|
|
@ -1404,6 +1404,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
|
||||||
decompose_indic,
|
decompose_indic,
|
||||||
compose_indic,
|
compose_indic,
|
||||||
setup_masks_indic,
|
setup_masks_indic,
|
||||||
false, /* zero_width_attached_marks */
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
|
||||||
false, /* fallback_position */
|
false, /* fallback_position */
|
||||||
};
|
};
|
||||||
|
|
|
@ -635,6 +635,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
|
||||||
NULL, /* decompose */
|
NULL, /* decompose */
|
||||||
NULL, /* compose */
|
NULL, /* compose */
|
||||||
setup_masks_myanmar,
|
setup_masks_myanmar,
|
||||||
false, /* zero_width_attached_marks */
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF,
|
||||||
false, /* fallback_position */
|
false, /* fallback_position */
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,6 +39,12 @@
|
||||||
#define complex_var_u8_1() var2.u8[3]
|
#define complex_var_u8_1() var2.u8[3]
|
||||||
|
|
||||||
|
|
||||||
|
enum hb_ot_shape_zero_width_marks_type_t {
|
||||||
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
|
||||||
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE,
|
||||||
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Master OT shaper list */
|
/* Master OT shaper list */
|
||||||
#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
|
#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
|
||||||
|
@ -131,7 +137,8 @@ struct hb_ot_complex_shaper_t
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
hb_font_t *font);
|
hb_font_t *font);
|
||||||
|
|
||||||
bool zero_width_attached_marks;
|
hb_ot_shape_zero_width_marks_type_t zero_width_marks;
|
||||||
|
|
||||||
bool fallback_position;
|
bool fallback_position;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -373,6 +373,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
|
||||||
NULL, /* decompose */
|
NULL, /* decompose */
|
||||||
NULL, /* compose */
|
NULL, /* compose */
|
||||||
NULL, /* setup_masks */
|
NULL, /* setup_masks */
|
||||||
true, /* zero_width_attached_marks */
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE,
|
||||||
false,/* fallback_position */
|
false,/* fallback_position */
|
||||||
};
|
};
|
||||||
|
|
|
@ -405,7 +405,8 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
|
||||||
hb_ot_layout_position_start (c->font, c->buffer);
|
hb_ot_layout_position_start (c->font, c->buffer);
|
||||||
|
|
||||||
unsigned int count = c->buffer->len;
|
unsigned int count = c->buffer->len;
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
|
c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
|
||||||
c->buffer->props.direction,
|
c->buffer->props.direction,
|
||||||
&c->buffer->pos[i].x_advance,
|
&c->buffer->pos[i].x_advance,
|
||||||
|
@ -414,6 +415,32 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
|
||||||
c->buffer->props.direction,
|
c->buffer->props.direction,
|
||||||
&c->buffer->pos[i].x_offset,
|
&c->buffer->pos[i].x_offset,
|
||||||
&c->buffer->pos[i].y_offset);
|
&c->buffer->pos[i].y_offset);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (c->plan->shaper->zero_width_marks)
|
||||||
|
{
|
||||||
|
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE:
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (_hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
||||||
|
{
|
||||||
|
c->buffer->pos[i].x_advance = 0;
|
||||||
|
c->buffer->pos[i].y_advance = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF:
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if ((c->buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
|
||||||
|
{
|
||||||
|
c->buffer->pos[i].x_advance = 0;
|
||||||
|
c->buffer->pos[i].y_advance = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +473,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_ot_layout_position_finish (c->font, c->buffer, c->plan->shaper->zero_width_attached_marks);
|
hb_ot_layout_position_finish (c->font, c->buffer);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue