Normalize various spaces to space if font doesn't support
This resurrects the space fallback feature, after I disabled the compatibility decomposition. Now I can release HarfBuzz again without breaking Pango! It also remembers which space character it was, such that later on we can approximate the width of this particular space character. That part is not implemented yet. We normalize all GC=Zs chars except for U+1680 OGHA SPACE MARK, which is better left alone.
This commit is contained in:
parent
8b3c7f9ede
commit
7793aad946
|
@ -237,23 +237,6 @@ enum {
|
||||||
UPROPS_MASK_GEN_CAT = 0x1Fu
|
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
|
static inline void
|
||||||
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
|
_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;
|
HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR;
|
||||||
}
|
}
|
||||||
static inline void
|
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)))
|
if (unlikely (!_hb_glyph_info_is_unicode_space (info)))
|
||||||
return;
|
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);
|
info->unicode_props() = (((unsigned int) s)<<8) | (info->unicode_props() & 0xFF);
|
||||||
}
|
}
|
||||||
static inline space_t
|
static inline hb_unicode_funcs_t::space_t
|
||||||
_hb_glyph_info_get_unicode_space (const hb_glyph_info_t *info)
|
_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);
|
static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info);
|
||||||
|
|
|
@ -98,7 +98,7 @@ static inline void
|
||||||
output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
|
output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
|
||||||
{
|
{
|
||||||
buffer->cur().glyph_index() = 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);
|
_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_buffer_t * const buffer = c->buffer;
|
||||||
hb_codepoint_t u = buffer->cur().codepoint;
|
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... */
|
/* Kind of a cute waterfall here... */
|
||||||
if (shortest && c->font->get_glyph (u, 0, &glyph))
|
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);
|
skip_char (buffer);
|
||||||
else if (!shortest && c->font->get_glyph (u, 0, &glyph))
|
else if (!shortest && c->font->get_glyph (u, 0, &glyph))
|
||||||
next_char (buffer, 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
|
else
|
||||||
next_char (buffer, glyph); /* glyph is initialized in earlier branches. */
|
next_char (buffer, glyph); /* glyph is initialized in earlier branches. */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
struct {
|
||||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name;
|
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name;
|
||||||
|
|
|
@ -52,6 +52,7 @@ TESTS = \
|
||||||
tests/indic-old-spec.tests \
|
tests/indic-old-spec.tests \
|
||||||
tests/indic-pref-blocking.tests \
|
tests/indic-pref-blocking.tests \
|
||||||
tests/mongolian-variation-selector.tests \
|
tests/mongolian-variation-selector.tests \
|
||||||
|
tests/spaces.tests \
|
||||||
tests/vertical.tests \
|
tests/vertical.tests \
|
||||||
tests/zero-width-marks.tests \
|
tests/zero-width-marks.tests \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
Binary file not shown.
|
@ -2,6 +2,7 @@
|
||||||
051d92f8bc6ff724511b296c27623f824de256e9.ttf
|
051d92f8bc6ff724511b296c27623f824de256e9.ttf
|
||||||
191826b9643e3f124d865d617ae609db6a2ce203.ttf
|
191826b9643e3f124d865d617ae609db6a2ce203.ttf
|
||||||
1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf
|
1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf
|
||||||
|
1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf
|
||||||
226bc2deab3846f1a682085f70c67d0421014144.ttf
|
226bc2deab3846f1a682085f70c67d0421014144.ttf
|
||||||
270b89df543a7e48e206a2d830c0e10e5265c630.ttf
|
270b89df543a7e48e206a2d830c0e10e5265c630.ttf
|
||||||
298c9e1d955f10f6f72c6915c3c6ff9bf9695cec.ttf
|
298c9e1d955f10f6f72c6915c3c6ff9bf9695cec.ttf
|
||||||
|
|
|
@ -10,5 +10,6 @@ indic-joiner-candrabindu.tests
|
||||||
indic-old-spec.tests
|
indic-old-spec.tests
|
||||||
indic-pref-blocking.tests
|
indic-pref-blocking.tests
|
||||||
mongolian-variation-selector.tests
|
mongolian-variation-selector.tests
|
||||||
|
spaces.tests
|
||||||
vertical.tests
|
vertical.tests
|
||||||
zero-width-marks.tests
|
zero-width-marks.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]
|
Loading…
Reference in New Issue