[HB] When looking back/forward, skip marks only

pull/1/head
Behdad Esfahbod 16 years ago
parent 1246e41021
commit 4189b92aaa
  1. 1
      src/TODO
  2. 13
      src/hb-ot-layout-gpos-private.h
  3. 38
      src/hb-ot-layout-gsub-private.h
  4. 14
      src/hb-ot-layout-gsubgpos-private.h
  5. 6
      src/hb-ot-layout-private.h
  6. 69
      src/hb-ot-layout.cc

@ -5,7 +5,6 @@
- Face index > 0 and dfont fonts - Face index > 0 and dfont fonts
- HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH vs LookupType::... mess - HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH vs LookupType::... mess
- Rename LookupFlag::MarkAttachmentType to LookupFlag:IgnoreSpecialMarks - Rename LookupFlag::MarkAttachmentType to LookupFlag:IgnoreSpecialMarks
- Skip forward/backward should only skip marks, not whatever lookupflags say!
- layout vs font split - layout vs font split
- gpi again - gpi again

@ -379,7 +379,7 @@ struct PairPosFormat1
return false; return false;
unsigned int j = buffer->in_pos + 1; unsigned int j = buffer->in_pos + 1;
while (!_hb_ot_layout_check_glyph_property (layout, IN_INFO (j), lookup_flag, &property)) while (_hb_ot_layout_skip_mark (layout, IN_INFO (j), lookup_flag, NULL))
{ {
if (HB_UNLIKELY (j == end)) if (HB_UNLIKELY (j == end))
return false; return false;
@ -444,7 +444,7 @@ struct PairPosFormat2
return false; return false;
unsigned int j = buffer->in_pos + 1; unsigned int j = buffer->in_pos + 1;
while (!_hb_ot_layout_check_glyph_property (layout, IN_INFO (j), lookup_flag, &property)) while (_hb_ot_layout_skip_mark (layout, IN_INFO (j), lookup_flag, NULL))
{ {
if (HB_UNLIKELY (j == end)) if (HB_UNLIKELY (j == end))
return false; return false;
@ -771,9 +771,6 @@ struct MarkBasePosFormat1
private: private:
inline bool apply (APPLY_ARG_DEF) const inline bool apply (APPLY_ARG_DEF) const
{ {
if (lookup_flag & LookupFlag::IgnoreBaseGlyphs)
return false;
unsigned int mark_index = (this+markCoverage) (IN_CURGLYPH ()); unsigned int mark_index = (this+markCoverage) (IN_CURGLYPH ());
if (HB_LIKELY (mark_index == NOT_COVERED)) if (HB_LIKELY (mark_index == NOT_COVERED))
return false; return false;
@ -896,9 +893,6 @@ struct MarkLigPosFormat1
private: private:
inline bool apply (APPLY_ARG_DEF) const inline bool apply (APPLY_ARG_DEF) const
{ {
if (lookup_flag & LookupFlag::IgnoreLigatures)
return false;
unsigned int mark_index = (this+markCoverage) (IN_CURGLYPH ()); unsigned int mark_index = (this+markCoverage) (IN_CURGLYPH ());
if (HB_LIKELY (mark_index == NOT_COVERED)) if (HB_LIKELY (mark_index == NOT_COVERED))
return false; return false;
@ -1034,9 +1028,6 @@ struct MarkMarkPosFormat1
private: private:
inline bool apply (APPLY_ARG_DEF) const inline bool apply (APPLY_ARG_DEF) const
{ {
if (lookup_flag & LookupFlag::IgnoreMarks)
return false;
unsigned int mark1_index = (this+mark1Coverage) (IN_CURGLYPH ()); unsigned int mark1_index = (this+mark1Coverage) (IN_CURGLYPH ());
if (HB_LIKELY (mark1_index == NOT_COVERED)) if (HB_LIKELY (mark1_index == NOT_COVERED))
return false; return false;

@ -45,11 +45,9 @@ struct SingleSubstFormat1
glyph_id += deltaGlyphID; glyph_id += deltaGlyphID;
_hb_buffer_replace_glyph (buffer, glyph_id); _hb_buffer_replace_glyph (buffer, glyph_id);
if ( _hb_ot_layout_has_new_glyph_classes (layout) ) /* We inherit the old glyph class to the substituted glyph */
{ if (_hb_ot_layout_has_new_glyph_classes (layout))
/* we inherit the old glyph class to the substituted glyph */
_hb_ot_layout_set_glyph_property (layout, glyph_id, property); _hb_ot_layout_set_glyph_property (layout, glyph_id, property);
}
return true; return true;
} }
@ -82,11 +80,9 @@ struct SingleSubstFormat2
glyph_id = substitute[index]; glyph_id = substitute[index];
_hb_buffer_replace_glyph (buffer, glyph_id); _hb_buffer_replace_glyph (buffer, glyph_id);
if ( _hb_ot_layout_has_new_glyph_classes (layout) ) /* We inherit the old glyph class to the substituted glyph */
{ if (_hb_ot_layout_has_new_glyph_classes (layout))
/* we inherit the old glyph class to the substituted glyph */
_hb_ot_layout_set_glyph_property (layout, glyph_id, property); _hb_ot_layout_set_glyph_property (layout, glyph_id, property);
}
return true; return true;
} }
@ -140,10 +136,10 @@ struct Sequence
substitute.len, (const uint16_t *) substitute.array, substitute.len, (const uint16_t *) substitute.array,
0xFFFF, 0xFFFF); 0xFFFF, 0xFFFF);
if ( _hb_ot_layout_has_new_glyph_classes (layout) ) /* This is a guess only ... */
if (_hb_ot_layout_has_new_glyph_classes (layout))
{ {
/* this is a guess only ... */ if (property == HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)
if ( property == HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE )
property = HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH; property = HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
unsigned int count = substitute.len; unsigned int count = substitute.len;
@ -246,11 +242,9 @@ struct AlternateSubstFormat1
_hb_buffer_replace_glyph (buffer, glyph_id); _hb_buffer_replace_glyph (buffer, glyph_id);
if ( _hb_ot_layout_has_new_glyph_classes (layout) ) /* We inherit the old glyph class to the substituted glyph */
{ if (_hb_ot_layout_has_new_glyph_classes (layout))
/* we inherit the old glyph class to the substituted glyph */
_hb_ot_layout_set_glyph_property (layout, glyph_id, property); _hb_ot_layout_set_glyph_property (layout, glyph_id, property);
}
return true; return true;
} }
@ -303,7 +297,7 @@ struct Ligature
for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++) for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++)
{ {
while (!_hb_ot_layout_check_glyph_property (layout, IN_INFO (j), lookup_flag, &property)) while (_hb_ot_layout_skip_mark (layout, IN_INFO (j), lookup_flag, &property))
{ {
if (HB_UNLIKELY (j + count - i == end)) if (HB_UNLIKELY (j + count - i == end))
return false; return false;
@ -313,11 +307,11 @@ struct Ligature
if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
is_mark = FALSE; is_mark = FALSE;
if (HB_LIKELY (IN_GLYPH(j) != component[i])) if (HB_LIKELY (IN_GLYPH (j) != component[i]))
return false; return false;
} }
if ( _hb_ot_layout_has_new_glyph_classes (layout) ) /* This is just a guess ... */
/* this is just a guess ... */ if (_hb_ot_layout_has_new_glyph_classes (layout))
hb_ot_layout_set_glyph_class (layout, ligGlyph, hb_ot_layout_set_glyph_class (layout, ligGlyph,
is_mark ? HB_OT_LAYOUT_GLYPH_CLASS_MARK is_mark ? HB_OT_LAYOUT_GLYPH_CLASS_MARK
: HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE); : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
@ -344,8 +338,8 @@ struct Ligature
for ( i = 1; i < count; i++ ) for ( i = 1; i < count; i++ )
{ {
while (!_hb_ot_layout_check_glyph_property (layout, IN_CURINFO(), lookup_flag, &property)) while (_hb_ot_layout_skip_mark (layout, IN_CURINFO (), lookup_flag, NULL))
_hb_buffer_add_output_glyph (buffer, IN_CURGLYPH(), i - 1, lig_id); _hb_buffer_add_output_glyph (buffer, IN_CURGLYPH (), i - 1, lig_id);
(buffer->in_pos)++; (buffer->in_pos)++;
} }
@ -505,7 +499,7 @@ struct ReverseChainSingleSubstFormat1
match_coverage, (char *) this, match_coverage, (char *) this,
1)) 1))
{ {
IN_CURGLYPH() = substitute[index]; IN_CURGLYPH () = substitute[index];
buffer->in_pos--; /* Reverse! */ buffer->in_pos--; /* Reverse! */
return true; return true;
} }

@ -89,14 +89,14 @@ static inline bool match_input (APPLY_ARG_DEF,
for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++) for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++)
{ {
while (!_hb_ot_layout_check_glyph_property (layout, IN_INFO (j), lookup_flag, &property)) while (_hb_ot_layout_skip_mark (layout, IN_INFO (j), lookup_flag, NULL))
{ {
if (HB_UNLIKELY (j + count - i == end)) if (HB_UNLIKELY (j + count - i == end))
return false; return false;
j++; j++;
} }
if (HB_LIKELY (!match_func (IN_GLYPH(j), input[i - 1], match_data))) if (HB_LIKELY (!match_func (IN_GLYPH (j), input[i - 1], match_data)))
return false; return false;
} }
@ -116,14 +116,14 @@ static inline bool match_backtrack (APPLY_ARG_DEF,
for (unsigned int i = 0, j = buffer->out_pos - 1; i < count; i++, j--) for (unsigned int i = 0, j = buffer->out_pos - 1; i < count; i++, j--)
{ {
while (!_hb_ot_layout_check_glyph_property (layout, OUT_INFO (j), lookup_flag, &property)) while (_hb_ot_layout_skip_mark (layout, OUT_INFO (j), lookup_flag, NULL))
{ {
if (HB_UNLIKELY (j + 1 == count - i)) if (HB_UNLIKELY (j + 1 == count - i))
return false; return false;
j--; j--;
} }
if (HB_LIKELY (!match_func (OUT_GLYPH(j), backtrack[i], match_data))) if (HB_LIKELY (!match_func (OUT_GLYPH (j), backtrack[i], match_data)))
return false; return false;
} }
@ -144,14 +144,14 @@ static inline bool match_lookahead (APPLY_ARG_DEF,
for (i = 0, j = buffer->in_pos + offset; i < count; i++, j++) for (i = 0, j = buffer->in_pos + offset; i < count; i++, j++)
{ {
while (!_hb_ot_layout_check_glyph_property (layout, OUT_INFO (j), lookup_flag, &property)) while (_hb_ot_layout_skip_mark (layout, OUT_INFO (j), lookup_flag, NULL))
{ {
if (HB_UNLIKELY (j + count - i == end)) if (HB_UNLIKELY (j + count - i == end))
return false; return false;
j++; j++;
} }
if (HB_LIKELY (!match_func (IN_GLYPH(j), lookahead[i], match_data))) if (HB_LIKELY (!match_func (IN_GLYPH (j), lookahead[i], match_data)))
return false; return false;
} }
@ -182,7 +182,7 @@ static inline bool apply_lookup (APPLY_ARG_DEF,
* Should be easy for in_place ones at least. */ * Should be easy for in_place ones at least. */
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
while (!_hb_ot_layout_check_glyph_property (layout, IN_CURINFO (), lookup_flag, &property)) while (_hb_ot_layout_skip_mark (layout, IN_CURINFO (), lookup_flag, NULL))
{ {
if (HB_UNLIKELY (buffer->in_pos == end)) if (HB_UNLIKELY (buffer->in_pos == end))
return true; return true;

@ -88,6 +88,12 @@ _hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout,
unsigned int lookup_flags, unsigned int lookup_flags,
unsigned int *property); unsigned int *property);
HB_INTERNAL hb_bool_t
_hb_ot_layout_skip_mark (hb_ot_layout_t *layout,
hb_glyph_info_t *ginfo,
unsigned int lookup_flags,
unsigned int *property);
HB_END_DECLS HB_END_DECLS
#endif /* HB_OT_LAYOUT_PRIVATE_H */ #endif /* HB_OT_LAYOUT_PRIVATE_H */

@ -161,37 +161,26 @@ HB_INTERNAL hb_bool_t
_hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout, _hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout,
hb_glyph_info_t *ginfo, hb_glyph_info_t *ginfo,
unsigned int lookup_flags, unsigned int lookup_flags,
unsigned int *property) unsigned int *property_out)
{ {
hb_ot_layout_glyph_class_t glyph_class; unsigned int property;
unsigned int desired_attachment_class;
if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN) if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
{ ginfo->gproperty = _hb_ot_layout_get_glyph_property (layout, ginfo->gindex);
ginfo->gproperty = *property = _hb_ot_layout_get_glyph_property (layout, ginfo->gindex); property = ginfo->gproperty;
if (ginfo->gproperty == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED) if (property_out)
return false; *property_out = property;
}
*property = ginfo->gproperty;
/* If the glyph was found in the MarkAttachmentClass table,
* then that class value is stored in the high byte of the result.
* The low byte contains the basic type of the glyph as defined by
* the GlyphClassDef table.
*/
glyph_class = (hb_ot_layout_glyph_class_t) *property;
/* Not covered, if, for example, glyph_class is HB_GDEF_LIGATURE and /* Not covered, if, for example, glyph class is ligature and
* lookup_flags includes LookupFlags::IgnoreLigatures * lookup_flags includes LookupFlags::IgnoreLigatures
*/ */
if (lookup_flags & glyph_class) if (property & lookup_flags)
return false; return false;
if (glyph_class & HB_OT_LAYOUT_GLYPH_CLASS_MARK) if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
{ {
/* If using mark filtering sets, the high short of /* If using mark filtering sets, the high short of
* lookup_flags hsa the set index. * lookup_flags has the set index.
*/ */
if (lookup_flags & LookupFlag::UseMarkFilteringSet) if (lookup_flags & LookupFlag::UseMarkFilteringSet)
return layout->gdef->mark_set_covers (lookup_flags >> 16, ginfo->gindex); return layout->gdef->mark_set_covers (lookup_flags >> 16, ginfo->gindex);
@ -200,14 +189,46 @@ _hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout,
* "ignore marks of attachment type different than * "ignore marks of attachment type different than
* the attachment type specified." * the attachment type specified."
*/ */
if (lookup_flags & LookupFlag::MarkAttachmentType && *property & LookupFlag::MarkAttachmentType) if (lookup_flags & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
return (lookup_flags & LookupFlag::MarkAttachmentType) == (*property & LookupFlag::MarkAttachmentType); return (lookup_flags & LookupFlag::MarkAttachmentType) == (property & LookupFlag::MarkAttachmentType);
} }
return true; return true;
} }
HB_INTERNAL hb_bool_t
_hb_ot_layout_skip_mark (hb_ot_layout_t *layout,
hb_glyph_info_t *ginfo,
unsigned int lookup_flags,
unsigned int *property_out)
{
unsigned int property;
if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
ginfo->gproperty = _hb_ot_layout_get_glyph_property (layout, ginfo->gindex);
property = ginfo->gproperty;
if (property_out)
*property_out = property;
if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
{
/* Skip mark if lookup_flags includes LookupFlags::IgnoreMarks */
if (lookup_flags & LookupFlag::IgnoreMarks)
return true;
/* If using mark filtering sets, the high short of lookup_flags has the set index. */
if (lookup_flags & LookupFlag::UseMarkFilteringSet)
return !layout->gdef->mark_set_covers (lookup_flags >> 16, ginfo->gindex);
/* The second byte of lookup_flags has the meaning "ignore marks of attachment type
* different than the attachment type specified." */
if (lookup_flags & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
return (lookup_flags & LookupFlag::MarkAttachmentType) != (property & LookupFlag::MarkAttachmentType);
}
return false;
}
HB_INTERNAL void HB_INTERNAL void
_hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout, _hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout,
hb_codepoint_t glyph, hb_codepoint_t glyph,

Loading…
Cancel
Save