[GSUB/GPOS] Move glyph props matching around
This commit is contained in:
parent
2fca1426ca
commit
05bd1b6342
|
@ -1552,7 +1552,8 @@ struct PosLookup : Lookup
|
|||
else
|
||||
while (c->buffer->idx < c->buffer->len)
|
||||
{
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c))
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) &&
|
||||
apply_once (c))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->idx++;
|
||||
|
@ -1585,8 +1586,8 @@ struct GPOS : GSUBGPOS
|
|||
inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index) const
|
||||
{ return get_lookup (lookup_index).apply_string (c); }
|
||||
|
||||
static inline void position_start (hb_buffer_t *buffer);
|
||||
static inline void position_finish (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);
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE ();
|
||||
|
@ -1644,7 +1645,7 @@ fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di
|
|||
}
|
||||
|
||||
void
|
||||
GPOS::position_start (hb_buffer_t *buffer)
|
||||
GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
||||
{
|
||||
buffer->clear_positions ();
|
||||
|
||||
|
@ -1654,7 +1655,7 @@ GPOS::position_start (hb_buffer_t *buffer)
|
|||
}
|
||||
|
||||
void
|
||||
GPOS::position_finish (hb_buffer_t *buffer)
|
||||
GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int len;
|
||||
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
|
||||
|
|
|
@ -1220,7 +1220,8 @@ struct SubstLookup : Lookup
|
|||
else
|
||||
while (c->buffer->idx < c->buffer->len)
|
||||
{
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c))
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) &&
|
||||
apply_once (c))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->next_glyph ();
|
||||
|
@ -1289,8 +1290,8 @@ struct GSUB : GSUBGPOS
|
|||
inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index) const
|
||||
{ return get_lookup (lookup_index).apply_string (c); }
|
||||
|
||||
static inline void substitute_start (hb_buffer_t *buffer);
|
||||
static inline void substitute_finish (hb_buffer_t *buffer);
|
||||
static inline void substitute_start (hb_face_t *face, hb_buffer_t *buffer);
|
||||
static inline void substitute_finish (hb_face_t *face, hb_buffer_t *buffer);
|
||||
|
||||
inline void closure_lookup (hb_closure_context_t *c,
|
||||
unsigned int lookup_index) const
|
||||
|
@ -1308,19 +1309,22 @@ struct GSUB : GSUBGPOS
|
|||
|
||||
|
||||
void
|
||||
GSUB::substitute_start (hb_buffer_t *buffer)
|
||||
GSUB::substitute_start (hb_face_t *face, hb_buffer_t *buffer)
|
||||
{
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, props_cache);
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
|
||||
|
||||
const GDEF &gdef = *hb_ot_layout_from_face (face)->gdef;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
buffer->info[i].props_cache() = buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
|
||||
buffer->info[i].props_cache() = gdef.get_glyph_props (buffer->info[i].codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GSUB::substitute_finish (hb_buffer_t *buffer HB_UNUSED)
|
||||
GSUB::substitute_finish (hb_face_t *face HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,81 @@ struct hb_would_apply_context_t
|
|||
|
||||
|
||||
|
||||
static inline hb_bool_t
|
||||
_hb_ot_layout_match_properties_mark (hb_face_t *face,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int glyph_props,
|
||||
unsigned int lookup_props)
|
||||
{
|
||||
/* If using mark filtering sets, the high short of
|
||||
* lookup_props has the set index.
|
||||
*/
|
||||
if (lookup_props & LookupFlag::UseMarkFilteringSet)
|
||||
return hb_ot_layout_from_face (face)->gdef->mark_set_covers (lookup_props >> 16, glyph);
|
||||
|
||||
/* The second byte of lookup_props has the meaning
|
||||
* "ignore marks of attachment type different than
|
||||
* the attachment type specified."
|
||||
*/
|
||||
if (lookup_props & LookupFlag::MarkAttachmentType)
|
||||
return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline hb_bool_t
|
||||
_hb_ot_layout_match_properties (hb_face_t *face,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int glyph_props,
|
||||
unsigned int lookup_props)
|
||||
{
|
||||
/* Not covered, if, for example, glyph class is ligature and
|
||||
* lookup_props includes LookupFlags::IgnoreLigatures
|
||||
*/
|
||||
if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
|
||||
return false;
|
||||
|
||||
if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
|
||||
return _hb_ot_layout_match_properties_mark (face, glyph, glyph_props, lookup_props);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline hb_bool_t
|
||||
_hb_ot_layout_check_glyph_property (hb_face_t *face,
|
||||
hb_glyph_info_t *ginfo,
|
||||
unsigned int lookup_props,
|
||||
unsigned int *property_out)
|
||||
{
|
||||
unsigned int property;
|
||||
|
||||
property = ginfo->props_cache();
|
||||
*property_out = property;
|
||||
|
||||
return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
|
||||
}
|
||||
|
||||
static inline hb_bool_t
|
||||
_hb_ot_layout_skip_mark (hb_face_t *face,
|
||||
hb_glyph_info_t *ginfo,
|
||||
unsigned int lookup_props,
|
||||
unsigned int *property_out)
|
||||
{
|
||||
unsigned int property;
|
||||
|
||||
property = ginfo->props_cache();
|
||||
if (property_out)
|
||||
*property_out = property;
|
||||
|
||||
/* If it's a mark, skip it if we don't accept it. */
|
||||
if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
|
||||
return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
|
||||
|
||||
/* If not a mark, don't skip. */
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
struct hb_apply_context_t
|
||||
{
|
||||
hb_font_t *font;
|
||||
|
@ -109,6 +184,7 @@ struct hb_apply_context_t
|
|||
unsigned int property; /* propety of first glyph */
|
||||
unsigned int debug_depth;
|
||||
bool has_glyph_classes;
|
||||
const GDEF &gdef;
|
||||
|
||||
|
||||
hb_apply_context_t (hb_font_t *font_,
|
||||
|
@ -120,7 +196,8 @@ struct hb_apply_context_t
|
|||
lookup_mask (lookup_mask_),
|
||||
nesting_level_left (MAX_NESTING_LEVEL),
|
||||
lookup_props (0), property (0), debug_depth (0),
|
||||
has_glyph_classes (hb_ot_layout_has_glyph_classes (face_)) {}
|
||||
has_glyph_classes (hb_ot_layout_has_glyph_classes (face_)),
|
||||
gdef (*hb_ot_layout_from_face (face_)->gdef /* XXX Unsafe dereference */) {}
|
||||
|
||||
void set_lookup (const Lookup &l) {
|
||||
lookup_props = l.get_props ();
|
||||
|
@ -229,30 +306,30 @@ struct hb_apply_context_t
|
|||
return _hb_ot_layout_skip_mark (face, &buffer->cur(), lookup_props, &property);
|
||||
}
|
||||
|
||||
inline void set_klass_guess (unsigned int klass_guess) const
|
||||
inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
|
||||
{
|
||||
if (likely (has_glyph_classes))
|
||||
buffer->cur().props_cache() = 0;
|
||||
else if (klass_guess)
|
||||
buffer->cur().props_cache() = klass_guess;
|
||||
buffer->cur().props_cache() = gdef.get_glyph_props (glyph_index);
|
||||
else if (class_guess)
|
||||
buffer->cur().props_cache() = class_guess;
|
||||
}
|
||||
|
||||
inline void output_glyph (hb_codepoint_t glyph_index,
|
||||
unsigned int klass_guess = 0) const
|
||||
unsigned int class_guess = 0) const
|
||||
{
|
||||
set_klass_guess (klass_guess);
|
||||
set_class (glyph_index, class_guess);
|
||||
buffer->output_glyph (glyph_index);
|
||||
}
|
||||
inline void replace_glyph (hb_codepoint_t glyph_index,
|
||||
unsigned int klass_guess = 0) const
|
||||
unsigned int class_guess = 0) const
|
||||
{
|
||||
set_klass_guess (klass_guess);
|
||||
set_class (glyph_index, class_guess);
|
||||
buffer->replace_glyph (glyph_index);
|
||||
}
|
||||
inline void replace_glyph_inplace (hb_codepoint_t glyph_index,
|
||||
unsigned int klass_guess = 0) const
|
||||
unsigned int class_guess = 0) const
|
||||
{
|
||||
set_klass_guess (klass_guess);
|
||||
set_class (glyph_index, class_guess);
|
||||
buffer->cur().codepoint = glyph_index;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -57,18 +57,6 @@ typedef enum {
|
|||
} hb_ot_layout_glyph_class_t;
|
||||
|
||||
|
||||
HB_INTERNAL hb_bool_t
|
||||
_hb_ot_layout_check_glyph_property (hb_face_t *face,
|
||||
hb_glyph_info_t *ginfo,
|
||||
unsigned int lookup_props,
|
||||
unsigned int *property_out);
|
||||
|
||||
HB_INTERNAL hb_bool_t
|
||||
_hb_ot_layout_skip_mark (hb_face_t *face,
|
||||
hb_glyph_info_t *ginfo,
|
||||
unsigned int lookup_props,
|
||||
unsigned int *property_out);
|
||||
|
||||
|
||||
/*
|
||||
* GSUB/GPOS
|
||||
|
|
|
@ -106,93 +106,6 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face)
|
|||
return _get_gdef (face).has_glyph_classes ();
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
_hb_ot_layout_get_glyph_property (hb_face_t *face,
|
||||
hb_glyph_info_t *info)
|
||||
{
|
||||
if (!info->props_cache())
|
||||
{
|
||||
info->props_cache() = hb_ot_layout_from_face (face)->gdef->get_glyph_props (info->codepoint);
|
||||
}
|
||||
|
||||
return info->props_cache();
|
||||
}
|
||||
|
||||
static inline hb_bool_t
|
||||
_hb_ot_layout_match_properties_mark (hb_face_t *face,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int glyph_props,
|
||||
unsigned int lookup_props)
|
||||
{
|
||||
/* If using mark filtering sets, the high short of
|
||||
* lookup_props has the set index.
|
||||
*/
|
||||
if (lookup_props & LookupFlag::UseMarkFilteringSet)
|
||||
return hb_ot_layout_from_face (face)->gdef->mark_set_covers (lookup_props >> 16, glyph);
|
||||
|
||||
/* The second byte of lookup_props has the meaning
|
||||
* "ignore marks of attachment type different than
|
||||
* the attachment type specified."
|
||||
*/
|
||||
if (lookup_props & LookupFlag::MarkAttachmentType)
|
||||
return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline hb_bool_t
|
||||
_hb_ot_layout_match_properties (hb_face_t *face,
|
||||
hb_codepoint_t glyph,
|
||||
unsigned int glyph_props,
|
||||
unsigned int lookup_props)
|
||||
{
|
||||
/* Not covered, if, for example, glyph class is ligature and
|
||||
* lookup_props includes LookupFlags::IgnoreLigatures
|
||||
*/
|
||||
if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
|
||||
return false;
|
||||
|
||||
if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
|
||||
return _hb_ot_layout_match_properties_mark (face, glyph, glyph_props, lookup_props);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
_hb_ot_layout_check_glyph_property (hb_face_t *face,
|
||||
hb_glyph_info_t *ginfo,
|
||||
unsigned int lookup_props,
|
||||
unsigned int *property_out)
|
||||
{
|
||||
unsigned int property;
|
||||
|
||||
property = _hb_ot_layout_get_glyph_property (face, ginfo);
|
||||
*property_out = property;
|
||||
|
||||
return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
_hb_ot_layout_skip_mark (hb_face_t *face,
|
||||
hb_glyph_info_t *ginfo,
|
||||
unsigned int lookup_props,
|
||||
unsigned int *property_out)
|
||||
{
|
||||
unsigned int property;
|
||||
|
||||
property = _hb_ot_layout_get_glyph_property (face, ginfo);
|
||||
if (property_out)
|
||||
*property_out = property;
|
||||
|
||||
/* If it's a mark, skip it if we don't accept it. */
|
||||
if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
|
||||
return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
|
||||
|
||||
/* If not a mark, don't skip. */
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_get_attach_points (hb_face_t *face,
|
||||
|
@ -215,6 +128,7 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
|
|||
return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GSUB/GPOS
|
||||
*/
|
||||
|
@ -492,9 +406,9 @@ hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face,
|
|||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_substitute_start (hb_buffer_t *buffer)
|
||||
hb_ot_layout_substitute_start (hb_face_t *face, hb_buffer_t *buffer)
|
||||
{
|
||||
GSUB::substitute_start (buffer);
|
||||
GSUB::substitute_start (face, buffer);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
|
@ -518,9 +432,9 @@ hb_ot_layout_substitute_lookup_fast (hb_face_t *face,
|
|||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED)
|
||||
hb_ot_layout_substitute_finish (hb_face_t *face, hb_buffer_t *buffer)
|
||||
{
|
||||
GSUB::substitute_finish (buffer);
|
||||
GSUB::substitute_finish (face, buffer);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -543,9 +457,9 @@ hb_ot_layout_has_positioning (hb_face_t *face)
|
|||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_position_start (hb_buffer_t *buffer)
|
||||
hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
GPOS::position_start (buffer);
|
||||
GPOS::position_start (font, buffer);
|
||||
}
|
||||
|
||||
hb_bool_t
|
||||
|
@ -569,9 +483,9 @@ hb_ot_layout_position_lookup_fast (hb_font_t *font,
|
|||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_position_finish (hb_buffer_t *buffer)
|
||||
hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
GPOS::position_finish (buffer);
|
||||
GPOS::position_finish (font, buffer);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -178,7 +178,8 @@ hb_ot_layout_would_substitute_lookup (hb_face_t *face,
|
|||
|
||||
/* Should be called before all the substitute_lookup's are done. */
|
||||
void
|
||||
hb_ot_layout_substitute_start (hb_buffer_t *buffer);
|
||||
hb_ot_layout_substitute_start (hb_face_t *face,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_substitute_lookup (hb_face_t *face,
|
||||
|
@ -188,7 +189,8 @@ hb_ot_layout_substitute_lookup (hb_face_t *face,
|
|||
|
||||
/* Should be called after all the substitute_lookup's are done */
|
||||
void
|
||||
hb_ot_layout_substitute_finish (hb_buffer_t *buffer);
|
||||
hb_ot_layout_substitute_finish (hb_face_t *face,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
void
|
||||
|
@ -205,7 +207,8 @@ hb_ot_layout_has_positioning (hb_face_t *face);
|
|||
|
||||
/* Should be called before all the position_lookup's are done. Resets positions to zero. */
|
||||
void
|
||||
hb_ot_layout_position_start (hb_buffer_t *buffer);
|
||||
hb_ot_layout_position_start (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_position_lookup (hb_font_t *font,
|
||||
|
@ -215,7 +218,8 @@ hb_ot_layout_position_lookup (hb_font_t *font,
|
|||
|
||||
/* Should be called after all the position_lookup's are done */
|
||||
void
|
||||
hb_ot_layout_position_finish (hb_buffer_t *buffer);
|
||||
hb_ot_layout_position_finish (hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
|
|
@ -342,8 +342,6 @@ hb_map_glyphs (hb_font_t *font,
|
|||
static void
|
||||
hb_substitute_default (hb_ot_shape_context_t *c)
|
||||
{
|
||||
hb_ot_layout_substitute_start (c->buffer);
|
||||
|
||||
hb_mirror_chars (c);
|
||||
|
||||
hb_map_glyphs (c->font, c->buffer);
|
||||
|
@ -352,11 +350,13 @@ hb_substitute_default (hb_ot_shape_context_t *c)
|
|||
static void
|
||||
hb_ot_substitute_complex (hb_ot_shape_context_t *c)
|
||||
{
|
||||
hb_ot_layout_substitute_start (c->face, c->buffer);
|
||||
|
||||
if (hb_ot_layout_has_substitution (c->face)) {
|
||||
c->plan->map.substitute (c->face, c->buffer);
|
||||
}
|
||||
|
||||
hb_ot_layout_substitute_finish (c->buffer);
|
||||
hb_ot_layout_substitute_finish (c->face, c->buffer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
|
|||
static void
|
||||
hb_position_default (hb_ot_shape_context_t *c)
|
||||
{
|
||||
hb_ot_layout_position_start (c->buffer);
|
||||
hb_ot_layout_position_start (c->font, c->buffer);
|
||||
|
||||
unsigned int count = c->buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
|
@ -410,7 +410,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
|||
c->applied_position_complex = true;
|
||||
}
|
||||
|
||||
hb_ot_layout_position_finish (c->buffer);
|
||||
hb_ot_layout_position_finish (c->font, c->buffer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue