diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 9020c895a..1759520fd 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -237,23 +237,6 @@ enum { UPROPS_MASK_GEN_CAT = 0x1Fu }; -enum space_t { - SPACE = 0, - SPACE_NBSP, - SPACE_EN, - SPACE_EM, - SPACE_EM_3, - SPACE_EM_4, - SPACE_EM_6, - SPACE_FIGURE, - SPACE_PUNCTUATION, - SPACE_THIN, - SPACE_HAIR, - SPACE_NARROW, - SPACE_MEDIUM, - SPACE_IDEOGRAPHIC, -}; - static inline void _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) { @@ -331,36 +314,18 @@ _hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info) HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR; } static inline void -_hb_glyph_info_set_unicode_space_for_char (hb_glyph_info_t *info, hb_codepoint_t u) +_hb_glyph_info_set_unicode_space_fallback_type (hb_glyph_info_t *info, hb_unicode_funcs_t::space_t s) { if (unlikely (!_hb_glyph_info_is_unicode_space (info))) return; - - space_t s; - switch (u) - { - default: s = SPACE; break; /* Shouldn't happen. */ - case 0x00A0u: s = SPACE_NBSP; break; - case 0x2002u: s = SPACE_EN; break; - case 0x2003u: s = SPACE_EM; break; - case 0x2004u: s = SPACE_EM_3; break; - case 0x2005u: s = SPACE_EM_4; break; - case 0x2006u: s = SPACE_EM_6; break; - case 0x2007u: s = SPACE_FIGURE; break; - case 0x2008u: s = SPACE_PUNCTUATION;break; - case 0x2009u: s = SPACE_THIN; break; - case 0x200Au: s = SPACE_HAIR; break; - case 0x202Fu: s = SPACE_NARROW; break; - case 0x205Fu: s = SPACE_MEDIUM; break; - case 0x3000u: s = SPACE_IDEOGRAPHIC;break; - } - info->unicode_props() = (((unsigned int) s)<<8) | (info->unicode_props() & 0xFF); } -static inline space_t -_hb_glyph_info_get_unicode_space (const hb_glyph_info_t *info) +static inline hb_unicode_funcs_t::space_t +_hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) { - return _hb_glyph_info_is_unicode_space (info) ? (space_t) (info->unicode_props()>>8) : SPACE; + return _hb_glyph_info_is_unicode_space (info) ? + (hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) : + hb_unicode_funcs_t::NOT_SPACE; } static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc index 0a4d40499..c86c634fb 100644 --- a/src/hb-ot-shape-normalize.cc +++ b/src/hb-ot-shape-normalize.cc @@ -98,7 +98,7 @@ static inline void output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) { buffer->cur().glyph_index() = glyph; - buffer->output_glyph (unichar); + buffer->output_glyph (unichar); /* This is very confusing indeed. */ _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer->unicode); } @@ -164,7 +164,8 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor { hb_buffer_t * const buffer = c->buffer; hb_codepoint_t u = buffer->cur().codepoint; - hb_codepoint_t glyph; + hb_codepoint_t glyph, space_glyph; + hb_unicode_funcs_t::space_t space_type; /* Kind of a cute waterfall here... */ if (shortest && c->font->get_glyph (u, 0, &glyph)) @@ -173,6 +174,13 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor skip_char (buffer); else if (!shortest && c->font->get_glyph (u, 0, &glyph)) next_char (buffer, glyph); + else if (_hb_glyph_info_is_unicode_space (&buffer->cur()) && + (space_type = buffer->unicode->space_fallback_type (u)) != hb_unicode_funcs_t::NOT_SPACE && + c->font->get_glyph (0x0020u, 0, &space_glyph)) + { + _hb_glyph_info_set_unicode_space_fallback_type (&buffer->cur(), space_type); + next_char (buffer, space_glyph); + } else next_char (buffer, glyph); /* glyph is initialized in earlier branches. */ } diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh index e729826bf..43bbed675 100644 --- a/src/hb-unicode-private.hh +++ b/src/hb-unicode-private.hh @@ -199,6 +199,46 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE } } + enum space_t { + NOT_SPACE = 0, + SPACE_NBSP, + SPACE_EN, + SPACE_EM, + SPACE_EM_3, + SPACE_EM_4, + SPACE_EM_6, + SPACE_FIGURE, + SPACE_PUNCTUATION, + SPACE_THIN, + SPACE_HAIR, + SPACE_NARROW, + SPACE_MEDIUM, + SPACE_IDEOGRAPHIC, + }; + static inline space_t + space_fallback_type (hb_codepoint_t u) + { + switch (u) + { + /* All GC=Zs chars that can use a fallback. */ + default: return NOT_SPACE; /* Shouldn't happen. */ + case 0x00A0u: return SPACE_NBSP; + case 0x2000u: return SPACE_EN; + case 0x2001u: return SPACE_EM; + case 0x2002u: return SPACE_EN; + case 0x2003u: return SPACE_EM; + case 0x2004u: return SPACE_EM_3; + case 0x2005u: return SPACE_EM_4; + case 0x2006u: return SPACE_EM_6; + case 0x2007u: return SPACE_FIGURE; + case 0x2008u: return SPACE_PUNCTUATION; + case 0x2009u: return SPACE_THIN; + case 0x200Au: return SPACE_HAIR; + case 0x202Fu: return SPACE_NARROW; + case 0x205Fu: return SPACE_MEDIUM; + case 0x3000u: return SPACE_IDEOGRAPHIC; + } + } struct { #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name; diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am index 5694572ab..607da6d04 100644 --- a/test/shaping/Makefile.am +++ b/test/shaping/Makefile.am @@ -52,6 +52,7 @@ TESTS = \ tests/indic-old-spec.tests \ tests/indic-pref-blocking.tests \ tests/mongolian-variation-selector.tests \ + tests/spaces.tests \ tests/vertical.tests \ tests/zero-width-marks.tests \ $(NULL) diff --git a/test/shaping/fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf b/test/shaping/fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf new file mode 100644 index 000000000..213e7cedb Binary files /dev/null and b/test/shaping/fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf differ diff --git a/test/shaping/fonts/sha1sum/MANIFEST b/test/shaping/fonts/sha1sum/MANIFEST index 785e6ef03..879d92971 100644 --- a/test/shaping/fonts/sha1sum/MANIFEST +++ b/test/shaping/fonts/sha1sum/MANIFEST @@ -2,6 +2,7 @@ 051d92f8bc6ff724511b296c27623f824de256e9.ttf 191826b9643e3f124d865d617ae609db6a2ce203.ttf 1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf +1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf 226bc2deab3846f1a682085f70c67d0421014144.ttf 270b89df543a7e48e206a2d830c0e10e5265c630.ttf 298c9e1d955f10f6f72c6915c3c6ff9bf9695cec.ttf diff --git a/test/shaping/tests/MANIFEST b/test/shaping/tests/MANIFEST index 6ae62dccb..457c2eb03 100644 --- a/test/shaping/tests/MANIFEST +++ b/test/shaping/tests/MANIFEST @@ -10,5 +10,6 @@ indic-joiner-candrabindu.tests indic-old-spec.tests indic-pref-blocking.tests mongolian-variation-selector.tests +spaces.tests vertical.tests zero-width-marks.tests diff --git a/test/shaping/tests/spaces.tests b/test/shaping/tests/spaces.tests new file mode 100644 index 000000000..d9e5d09c5 --- /dev/null +++ b/test/shaping/tests/spaces.tests @@ -0,0 +1,17 @@ +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+0020:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+00A0:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+1680:[gid0=0+692] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2000:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2001:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2002:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2003:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2004:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2005:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2006:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2007:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2008:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2009:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+200A:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+202F:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+205F:[gid1=0+560] +fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+3000:[gid1=0+560]