Fix regression that caused a few ligatures to not render correctly in rare circumstances

This was caused by cache corruption. is_special_glyph() and
is_empty_glyph() were treading over each other if called in
the right sequence. Fixes #303
This commit is contained in:
Kovid Goyal 2018-02-05 00:04:05 +05:30
parent 3f24e5b571
commit 240b1475c7
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 6 additions and 4 deletions

View File

@ -156,15 +156,16 @@ sprite_position_for(Font *font, glyph_index glyph, ExtraGlyphs *extra_glyphs, ui
}
static inline SpecialGlyphCache*
special_glyph_cache_for(Font *font, glyph_index glyph, uint8_t mask) {
special_glyph_cache_for(Font *font, glyph_index glyph, uint8_t filled_mask) {
SpecialGlyphCache *s = font->special_glyph_cache + (glyph & 0x3ff);
// Optimize for the common case of glyph under 1024 already in the cache
if (LIKELY(s->glyph == glyph && s->data & mask)) return s; // Cache hit
if (LIKELY(s->glyph == glyph && s->data & filled_mask)) return s; // Cache hit
while(true) {
if (s->data & mask) {
if (s->data & filled_mask) {
if (s->glyph == glyph) return s; // Cache hit
} else {
break;
if (!s->glyph) break; // Empty cache slot
else if (s->glyph == glyph) return s; // Cache slot that contains other data than the data indicated by filled_mask
}
if (!s->next) {
s->next = calloc(1, sizeof(SpecialGlyphCache));

View File

@ -78,6 +78,7 @@ class Rendering(BaseTest):
self.ae(groups('abcd'), [(1, 1) for i in range(4)])
self.ae(groups('A=>>B!=C', path='kitty_tests/FiraCode-Medium.otf'), [(1, 1), (3, 3), (1, 1), (2, 2), (1, 1)])
self.ae(groups('F--a--', path='kitty_tests/FiraCode-Medium.otf'), [(1, 1), (2, 2), (1, 1), (2, 2)])
self.ae(groups('==!=<>==<><><>', path='kitty_tests/FiraCode-Medium.otf'), [(2, 2), (2, 2), (2, 2), (2, 2), (2, 2), (2, 2), (2, 2)])
colon_glyph = shape_string('9:30', path='kitty_tests/FiraCode-Medium.otf')[1][2]
self.assertNotEqual(colon_glyph, shape_string(':', path='kitty_tests/FiraCode-Medium.otf')[0][2])