[GSUB/GPOS] Move glyph props matching around

This commit is contained in:
Behdad Esfahbod 2012-07-30 19:30:01 -04:00
parent 2fca1426ca
commit 05bd1b6342
7 changed files with 127 additions and 139 deletions

View File

@ -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);

View File

@ -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)
{
}

View File

@ -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;
}
};

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}