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()
This commit is contained in:
parent
219af509ef
commit
331d66c7fe
|
@ -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_serialize_flags_t);
|
||||
HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t);
|
||||
|
||||
enum hb_buffer_scratch_flags_t {
|
||||
HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u,
|
||||
|
|
|
@ -153,8 +153,8 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
|
|||
|
||||
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
|
||||
{
|
||||
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));
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
|
|
@ -465,6 +465,45 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
|
|||
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.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue