提交 331d66c7 编写于 作者: J Jonathan Kew 提交者: Behdad Esfahbod

Add function to compare two buffers

Based on patch from Jonathan Kew.

Needs more cleaning up and documentation.

New API:
hb_buffer_diff_flags_t
hb_buffer_diff()
上级 219af509
...@@ -50,6 +50,7 @@ ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)); ...@@ -50,6 +50,7 @@ ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
HB_MARK_AS_FLAG_T (hb_buffer_flags_t); HB_MARK_AS_FLAG_T (hb_buffer_flags_t);
HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t); HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t);
HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t);
enum hb_buffer_scratch_flags_t { enum hb_buffer_scratch_flags_t {
HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u,
......
...@@ -153,8 +153,8 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, ...@@ -153,8 +153,8 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
{ {
if (info[i].mask &HB_GLYPH_FLAG_DEFINED) if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask &HB_GLYPH_FLAG_DEFINED)); p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));
} }
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
......
...@@ -1860,6 +1860,88 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g ...@@ -1860,6 +1860,88 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g
} }
} }
/*
* Comparing buffers.
*/
hb_buffer_diff_flags_t
hb_buffer_diff (hb_buffer_t *buffer,
hb_buffer_t *reference,
hb_codepoint_t dottedcircle_glyph,
unsigned int position_fuzz)
{
if (buffer->content_type != reference->content_type)
return HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH;
hb_buffer_diff_flags_t result = HB_BUFFER_DIFF_FLAG_EQUAL;
unsigned int count = reference->len;
if (buffer->len != count)
{
/*
* we can't compare glyph-by-glyph, but we do want to know if there
* are .notdef or dottedcircle glyphs present in the reference buffer
*/
const hb_glyph_info_t *info = reference->info;
unsigned int i;
for (i = 0; i < count; i++)
{
if (info[i].codepoint == dottedcircle_glyph)
result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
else if (info[i].codepoint == 0)
result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
}
result |= HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH;
return hb_buffer_diff_flags_t (result);
}
if (!count)
return hb_buffer_diff_flags_t (result);
const hb_glyph_info_t *buf_info = buffer->info;
const hb_glyph_info_t *ref_info = reference->info;
for (unsigned int i = 0; i < count; i++)
{
if (buf_info->codepoint != ref_info->codepoint)
result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH;
if (buf_info->cluster != ref_info->cluster)
result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH;
if ((buf_info->mask & HB_GLYPH_FLAG_DEFINED) != (ref_info->mask & HB_GLYPH_FLAG_DEFINED))
result |= HB_BUFFER_DIFF_FLAG_MASK_MISMATCH;
if (ref_info->codepoint == dottedcircle_glyph)
result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
else if (ref_info->codepoint == 0)
result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
buf_info++;
ref_info++;
}
if (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS)
{
assert (buffer->have_positions);
const hb_glyph_position_t *buf_pos = buffer->pos;
const hb_glyph_position_t *ref_pos = reference->pos;
for (unsigned int i = 0; i < count; i++)
{
if (abs (buf_pos->x_advance - ref_pos->x_advance) > position_fuzz ||
abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz ||
abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz ||
abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz)
{
result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH;
break;
}
buf_pos++;
ref_pos++;
}
}
return result;
}
/* /*
* Debugging. * Debugging.
*/ */
......
...@@ -465,6 +465,45 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, ...@@ -465,6 +465,45 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
hb_buffer_serialize_format_t format); hb_buffer_serialize_format_t format);
/*
* Compare buffers
*/
typedef enum { /*< flags >*/
HB_BUFFER_DIFF_FLAG_EQUAL = 0x0000,
/* Buffers with different content_type cannot be meaningfully compared
* in any further detail. */
HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH = 0X0001,
/* For buffers with differing length, the per-glyph comparison is not
* attempted, though we do still scan reference for dottedcircle / .notdef
* glyphs. */
HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH = 0X0002,
/* We want to know if dottedcircle / .notdef glyphs are present in the
* reference, as we may not care so much about other differences in this
* case. */
HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT = 0x0004,
HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT = 0x0008,
/* If the buffers have the same length, we compare them glyph-by-glyph
* and report which aspect(s) of the glyph info/position are different. */
HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH = 0x0010,
HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH = 0x0010,
HB_BUFFER_DIFF_FLAG_MASK_MISMATCH = 0x0040,
HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH = 0x0080
} hb_buffer_diff_flags_t;
/* Compare the contents of two buffers, report types of differences. */
hb_buffer_diff_flags_t
hb_buffer_diff (hb_buffer_t *buffer,
hb_buffer_t *reference,
hb_codepoint_t dottedcircle_glyph,
unsigned int position_fuzz);
/* /*
* Debugging. * Debugging.
*/ */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册