Adjust the width of various spaces if font does not cover them
See discussion here:
81ef4f407d
There's no way to disable this fallback, but I don't think it would
be needed. Let's hope for the best!
Fixes https://github.com/behdad/harfbuzz/issues/153
This commit is contained in:
parent
aa7044de0c
commit
49ef630936
|
@ -41,6 +41,12 @@ ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
|
|||
template <> class hb_mark_as_flags_t<hb_buffer_flags_t> {};
|
||||
template <> class hb_mark_as_flags_t<hb_buffer_serialize_flags_t> {};
|
||||
|
||||
enum hb_buffer_scratch_flags_t {
|
||||
HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000001u,
|
||||
};
|
||||
template <> class hb_mark_as_flags_t<hb_buffer_scratch_flags_t> {};
|
||||
|
||||
|
||||
/*
|
||||
* hb_buffer_t
|
||||
|
@ -55,6 +61,7 @@ struct hb_buffer_t {
|
|||
hb_buffer_flags_t flags; /* BOT / EOT / etc. */
|
||||
hb_buffer_cluster_level_t cluster_level;
|
||||
hb_codepoint_t replacement; /* U+FFFD or something else. */
|
||||
hb_buffer_scratch_flags_t scratch_flags; /* Have space-flallback, etc. */
|
||||
|
||||
/* Buffer contents */
|
||||
hb_buffer_content_type_t content_type;
|
||||
|
|
|
@ -198,6 +198,7 @@ hb_buffer_t::clear (void)
|
|||
|
||||
hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
|
||||
props = default_props;
|
||||
scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
|
||||
|
||||
content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
|
||||
in_error = false;
|
||||
|
@ -738,6 +739,7 @@ hb_buffer_get_empty (void)
|
|||
HB_BUFFER_FLAG_DEFAULT,
|
||||
HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
|
||||
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
|
||||
HB_BUFFER_SCRATCH_FLAG_DEFAULT,
|
||||
|
||||
HB_BUFFER_CONTENT_TYPE_INVALID,
|
||||
HB_SEGMENT_PROPERTIES_DEFAULT,
|
||||
|
|
|
@ -45,5 +45,9 @@ HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
|||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
HB_INTERNAL void _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
|
||||
#endif /* HB_OT_SHAPE_FALLBACK_PRIVATE_HH */
|
||||
|
|
|
@ -484,3 +484,70 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
|||
idx = skippy_iter.idx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Adjusts width of various spaces. */
|
||||
void
|
||||
_hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
|
||||
return;
|
||||
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (_hb_glyph_info_is_unicode_space (&info[i]) && !_hb_glyph_info_ligated (&info[i]))
|
||||
{
|
||||
hb_unicode_funcs_t::space_t space_type = _hb_glyph_info_get_unicode_space_fallback_type (&info[i]);
|
||||
hb_codepoint_t glyph;
|
||||
typedef hb_unicode_funcs_t t;
|
||||
switch (space_type)
|
||||
{
|
||||
case t::NOT_SPACE: /* Shouldn't happen. */
|
||||
case t::SPACE:
|
||||
break;
|
||||
|
||||
case t::SPACE_EM:
|
||||
case t::SPACE_EM_2:
|
||||
case t::SPACE_EM_3:
|
||||
case t::SPACE_EM_4:
|
||||
case t::SPACE_EM_5:
|
||||
case t::SPACE_EM_6:
|
||||
case t::SPACE_EM_16:
|
||||
pos[i].x_advance = (font->x_scale + ((int) space_type)/2) / (int) space_type;
|
||||
break;
|
||||
|
||||
case t::SPACE_4_EM_18:
|
||||
pos[i].x_advance = font->x_scale * 4 / 18;
|
||||
break;
|
||||
|
||||
case t::SPACE_FIGURE:
|
||||
for (char u = '0'; u <= '9'; u++)
|
||||
if (font->get_glyph (u, 0, &glyph))
|
||||
{
|
||||
pos[i].x_advance = font->get_glyph_h_advance (glyph);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case t::SPACE_PUNCTUATION:
|
||||
if (font->get_glyph ('.', 0, &glyph))
|
||||
pos[i].x_advance = font->get_glyph_h_advance (glyph);
|
||||
else if (font->get_glyph (',', 0, &glyph))
|
||||
pos[i].x_advance = font->get_glyph_h_advance (glyph);
|
||||
break;
|
||||
|
||||
case t::SPACE_NARROW:
|
||||
/* Half-space?
|
||||
* Unicode doc http://www.unicode.org/charts/PDF/U2000.pdf says ~1/4 or 1/5 of EM.
|
||||
* However, in my testing, many fonts have their regular space being about that
|
||||
* size. To me, a percentage of the space width makes more sense. Half is as
|
||||
* good as any. */
|
||||
pos[i].x_advance /= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,6 +180,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
|
|||
{
|
||||
_hb_glyph_info_set_unicode_space_fallback_type (&buffer->cur(), space_type);
|
||||
next_char (buffer, space_glyph);
|
||||
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK;
|
||||
}
|
||||
else
|
||||
next_char (buffer, glyph); /* glyph is initialized in earlier branches. */
|
||||
|
|
|
@ -659,6 +659,8 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
|
|||
&pos[i].y_offset);
|
||||
|
||||
}
|
||||
if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK)
|
||||
_hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -778,6 +780,7 @@ static void
|
|||
hb_ot_shape_internal (hb_ot_shape_context_t *c)
|
||||
{
|
||||
c->buffer->deallocate_var_all ();
|
||||
c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
|
||||
|
||||
/* Save the original direction, we use it later. */
|
||||
c->target_direction = c->buffer->props.direction;
|
||||
|
|
|
@ -199,21 +199,24 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
|
|||
}
|
||||
}
|
||||
|
||||
/* Space estimates based on:
|
||||
* http://www.unicode.org/charts/PDF/U2000.pdf
|
||||
* https://www.microsoft.com/typography/developers/fdsspec/spaces.aspx
|
||||
*/
|
||||
enum space_t {
|
||||
NOT_SPACE = 0,
|
||||
SPACE_NBSP,
|
||||
SPACE_EN,
|
||||
SPACE_EM,
|
||||
SPACE_EM_3,
|
||||
SPACE_EM_4,
|
||||
SPACE_EM_6,
|
||||
SPACE_EM = 1,
|
||||
SPACE_EM_2 = 2,
|
||||
SPACE_EM_3 = 3,
|
||||
SPACE_EM_4 = 4,
|
||||
SPACE_EM_5 = 5,
|
||||
SPACE_EM_6 = 6,
|
||||
SPACE_EM_16 = 16,
|
||||
SPACE_4_EM_18, /* 4/18th of an EM! */
|
||||
SPACE,
|
||||
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)
|
||||
|
@ -221,22 +224,23 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
|
|||
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;
|
||||
default: return NOT_SPACE; /* Shouldn't happen. */
|
||||
case 0x0020u: return SPACE; /* U+0020 SPACE */
|
||||
case 0x00A0u: return SPACE; /* U+00A0 NO-BREAK SPACE */
|
||||
case 0x2000u: return SPACE_EM_2; /* U+2000 EN QUAD */
|
||||
case 0x2001u: return SPACE_EM; /* U+2001 EM QUAD */
|
||||
case 0x2002u: return SPACE_EM_2; /* U+2002 EN SPACE */
|
||||
case 0x2003u: return SPACE_EM; /* U+2003 EM SPACE */
|
||||
case 0x2004u: return SPACE_EM_3; /* U+2004 THREE-PER-EM SPACE */
|
||||
case 0x2005u: return SPACE_EM_4; /* U+2005 FOUR-PER-EM SPACE */
|
||||
case 0x2006u: return SPACE_EM_6; /* U+2006 SIX-PER-EM SPACE */
|
||||
case 0x2007u: return SPACE_FIGURE; /* U+2007 FIGURE SPACE */
|
||||
case 0x2008u: return SPACE_PUNCTUATION; /* U+2008 PUNCTUATION SPACE */
|
||||
case 0x2009u: return SPACE_EM_5; /* U+2009 THIN SPACE */
|
||||
case 0x200Au: return SPACE_EM_16; /* U+200A HAIR SPACE */
|
||||
case 0x202Fu: return SPACE_NARROW; /* U+202F NARROW NO-BREAK SPACE */
|
||||
case 0x205Fu: return SPACE_4_EM_18; /* U+205F MEDIUM MATHEMATICAL SPACE */
|
||||
case 0x3000u: return SPACE_EM; /* U+3000 IDEOGRAPHIC SPACE */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +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+2000:[gid1=0+1024]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2001:[gid1=0+2048]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2002:[gid1=0+1024]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2003:[gid1=0+2048]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2004:[gid1=0+683]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2005:[gid1=0+512]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2006:[gid1=0+341]
|
||||
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]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+2009:[gid1=0+410]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+200A:[gid1=0+128]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+202F:[gid1=0+280]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+205F:[gid1=0+455]
|
||||
fonts/sha1sum/1c2c3fc37b2d4c3cb2ef726c6cdaaabd4b7f3eb9.ttf:--font-funcs=ot:U+3000:[gid1=0+2048]
|
||||
|
|
Loading…
Reference in New Issue