From 14f1f0480ffb7af9a33e224287428161a18e7cf2 Mon Sep 17 00:00:00 2001 From: Oleg Oshmyan Date: Wed, 1 Sep 2021 15:35:06 +0300 Subject: shaper: update invisible codepoint list to match HarfBuzz --- libass/ass_shaper.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c index 960dab1..dc47759 100644 --- a/libass/ass_shaper.c +++ b/libass/ass_shaper.c @@ -791,23 +791,37 @@ void ass_shaper_set_kerning(ASS_Shaper *shaper, bool kern) shaper->features[KERN].value = kern; } +/** + * \brief Determine whether HarfBuzz ignores any font-provided glyph + * for this Unicode codepoint and replaces it with a zero-width glyph. + * Matches hb_unicode_funcs_t::is_default_ignorable in hb-unicode.hh. + * The affected codepoints are a subset of Unicode's Default_Ignorable list. + */ +static inline bool is_harfbuzz_ignorable(unsigned symbol) { + switch (symbol >> 8) { + case 0x00: return symbol == 0x00AD; + case 0x03: return symbol == 0x034F; + case 0x06: return symbol == 0x061C; + case 0x17: return symbol >= 0x17B4 && symbol <= 0x17B5; + case 0x18: return symbol >= 0x180B && symbol <= 0x180E; + case 0x20: return (symbol >= 0x200B && symbol <= 0x200F) || + (symbol >= 0x202A && symbol <= 0x202E) || + (symbol >= 0x2060 && symbol <= 0x206F); + case 0xFE: return (symbol >= 0xFE00 && symbol <= 0xFE0F) || + symbol == 0xFEFF; + case 0xFF: return symbol >= 0xFFF0 && symbol <= 0xFFF8; + case 0x1D1: return symbol >= 0x1D173 && symbol <= 0x1D17A; + default: return symbol >= 0xE0000 && symbol <= 0xE0FFF; + } +} + /** * \brief Remove all zero-width invisible characters from the text. */ static void ass_shaper_skip_characters(GlyphInfo *glyphs, size_t len) { for (int i = 0; i < len; i++) { - // Skip direction override control characters - if ((glyphs[i].symbol <= 0x202e && glyphs[i].symbol >= 0x202a) - || (glyphs[i].symbol <= 0x200f && glyphs[i].symbol >= 0x200b) - || (glyphs[i].symbol <= 0x206f && glyphs[i].symbol >= 0x2060) - || (glyphs[i].symbol <= 0xfe0f && glyphs[i].symbol >= 0xfe00) - || (glyphs[i].symbol <= 0xe01ef && glyphs[i].symbol >= 0xe0100) - || (glyphs[i].symbol <= 0x180f && glyphs[i].symbol >= 0x180b) - || glyphs[i].symbol == 0x061c - || glyphs[i].symbol == 0xfeff - || glyphs[i].symbol == 0x00ad - || glyphs[i].symbol == 0x034f) { + if (is_harfbuzz_ignorable(glyphs[i].symbol)) { glyphs[i].skip = true; } } -- cgit v1.2.3