+2011-11-18 Eli Zaretskii <eliz@gnu.org>
+
+ * dispnew.c (swap_glyph_pointers): Swap the used[] arrays and the
+ hash values of the two rows.
+ (copy_row_except_pointers): Preserve the used[] arrays and the
+ hash values of the two rows. (Bug#10035)
+
+ * xdisp.c (row_hash): New function, body extracted from
+ compute_line_metrics.
+ (compute_line_metrics): Call row_hash, instead of computing the
+ hash code inline.
+
+ * dispnew.c (verify_row_hash): Call row_hash for computing the
+ hash code of a row, instead of duplicating code from xdisp.c.
+
+ * dispextern.h (row_hash): Add prototype.
+
2011-11-18 Tassilo Horn <tassilo@member.fsf.org>
* frame.c (delete_frame): Don't delete the terminal when the last
int
verify_row_hash (struct glyph_row *row)
{
- int area, k;
- unsigned row_hash = 0;
-
- for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
- for (k = 0; k < row->used[area]; ++k)
- row_hash = ((((row_hash << 4) + (row_hash >> 24)) & 0x0fffffff)
- + row->glyphs[area][k].u.val
- + row->glyphs[area][k].face_id
- + row->glyphs[area][k].padding_p
- + (row->glyphs[area][k].type << 2));
-
- return row_hash == row->hash;
+ return row->hash == row_hash (row);
}
#endif
#endif /* 0 */
-/* Exchange pointers to glyph memory between glyph rows A and B. */
+/* Exchange pointers to glyph memory between glyph rows A and B. Also
+ exchange the used[] array and the hash values of the rows, because
+ these should all go together for the row's hash value to be
+ correct. */
static inline void
swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
{
int i;
+ unsigned hash_tem = a->hash;
+
for (i = 0; i < LAST_AREA + 1; ++i)
{
struct glyph *temp = a->glyphs[i];
+ short used_tem = a->used[i];
+
a->glyphs[i] = b->glyphs[i];
b->glyphs[i] = temp;
+ a->used[i] = b->used[i];
+ b->used[i] = used_tem;
}
+ a->hash = b->hash;
+ b->hash = hash_tem;
}
/* Copy glyph row structure FROM to glyph row structure TO, except
- that glyph pointers in the structures are left unchanged. */
+ that glyph pointers, the `used' counts, and the hash values in the
+ structures are left unchanged. */
static inline void
copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
{
struct glyph *pointers[1 + LAST_AREA];
+ short used[1 + LAST_AREA];
+ unsigned hashval;
/* Save glyph pointers of TO. */
memcpy (pointers, to->glyphs, sizeof to->glyphs);
+ memcpy (used, to->used, sizeof to->used);
+ hashval = to->hash;
/* Do a structure assignment. */
*to = *from;
/* Restore original pointers of TO. */
memcpy (to->glyphs, pointers, sizeof to->glyphs);
+ memcpy (to->used, used, sizeof to->used);
+ to->hash = hashval;
}
}
}
+/* Compute the hash code for ROW. */
+unsigned
+row_hash (struct glyph_row *row)
+{
+ int area, k;
+ unsigned hashval = 0;
+
+ for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+ for (k = 0; k < row->used[area]; ++k)
+ hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
+ + row->glyphs[area][k].u.val
+ + row->glyphs[area][k].face_id
+ + row->glyphs[area][k].padding_p
+ + (row->glyphs[area][k].type << 2));
+
+ return hashval;
+}
/* Compute the pixel height and width of IT->glyph_row.
}
/* Compute a hash code for this row. */
- {
- int area, i;
- row->hash = 0;
- for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
- for (i = 0; i < row->used[area]; ++i)
- row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
- + row->glyphs[area][i].u.val
- + row->glyphs[area][i].face_id
- + row->glyphs[area][i].padding_p
- + (row->glyphs[area][i].type << 2));
- }
+ row->hash = row_hash (row);
it->max_ascent = it->max_descent = 0;
it->max_phys_ascent = it->max_phys_descent = 0;