Skip to content

Commit 69f9fbc

Browse files
committed
Synthesize GDEF glyph class for any glyph that does not have one in GDEF
Previously we only synthesized GDEF glyph classes if the glyphClassDef array in GDEF was null. This worked well enough, and is indeed what OpenType requires: "If the font does not include a GlyphClassDef table, the client must define and maintain this information when using the GSUB and GPOS tables." That sentence does not quite make sense since one needs Unicode properties as well, but is close enough. However, looks like Arial Unicode as shipped on WinXP, does have GDEF glyph class array, but defines no classes for Hebrew. This results in Hebrew marks not getting their widths zeroed. So, with this change, we synthesize glyph class for any glyph that is not specified in the GDEF glyph class table. Since, from our point of view, a glyph not being listed in that table is a font bug, any unwanted consequence of this change is a font bug :). Note that we still don't get the same rendering as Uniscribe, since Uniscribe seems to do fallback positioning as well, even though the font does have a GPOS table (which does NOT cover Hebrew!). We are not going to try to match that though. Test string for Arial Unicode: U+05E9,U+05B8,U+05C1,U+05DC Before: [gid1166=3+991|gid1142=0+737|gid5798=0+1434] After: [gid1166=3+991|gid1142=0+0|gid5798=0+1434] Uniscribe: [gid1166=3+991|gid1142=0@348,0+0|gid5798=0+1434] Note that our new output matches what we were generating until July 2014, because the Hebrew shaper used to zero mark advances based on Unicode, NOT GDEF. That's 9e834e2. Reported by Greg Douglas.
1 parent fef5dd9 commit 69f9fbc

File tree

2 files changed

+20
-31
lines changed

2 files changed

+20
-31
lines changed

src/hb-ot-layout-gsub-table.hh

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,10 +1288,28 @@ GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
12881288

12891289
const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
12901290
unsigned int count = buffer->len;
1291+
hb_glyph_info_t *info = buffer->info;
12911292
for (unsigned int i = 0; i < count; i++)
12921293
{
1293-
_hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
1294-
_hb_glyph_info_clear_lig_props (&buffer->info[i]);
1294+
unsigned int props = gdef.get_glyph_props (info[i].codepoint);
1295+
if (!props)
1296+
{
1297+
/* Never mark default-ignorables as marks.
1298+
* They won't get in the way of lookups anyway,
1299+
* but having them as mark will cause them to be skipped
1300+
* over if the lookup-flag says so, but at least for the
1301+
* Mongolian variation selectors, looks like Uniscribe
1302+
* marks them as non-mark. Some Mongolian fonts without
1303+
* GDEF rely on this. Another notable character that
1304+
* this applies to is COMBINING GRAPHEME JOINER. */
1305+
props = (_hb_glyph_info_get_general_category (&info[i]) !=
1306+
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
1307+
_hb_glyph_info_is_default_ignorable (&info[i])) ?
1308+
HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
1309+
HB_OT_LAYOUT_GLYPH_PROPS_MARK;
1310+
}
1311+
_hb_glyph_info_set_glyph_props (&info[i], props);
1312+
_hb_glyph_info_clear_lig_props (&info[i]);
12951313
buffer->info[i].syllable() = 0;
12961314
}
12971315
}

src/hb-ot-shape.cc

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -523,32 +523,6 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
523523
buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
524524
}
525525

526-
static inline void
527-
hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
528-
{
529-
unsigned int count = c->buffer->len;
530-
hb_glyph_info_t *info = c->buffer->info;
531-
for (unsigned int i = 0; i < count; i++)
532-
{
533-
hb_ot_layout_glyph_props_flags_t klass;
534-
535-
/* Never mark default-ignorables as marks.
536-
* They won't get in the way of lookups anyway,
537-
* but having them as mark will cause them to be skipped
538-
* over if the lookup-flag says so, but at least for the
539-
* Mongolian variation selectors, looks like Uniscribe
540-
* marks them as non-mark. Some Mongolian fonts without
541-
* GDEF rely on this. Another notable character that
542-
* this applies to is COMBINING GRAPHEME JOINER. */
543-
klass = (_hb_glyph_info_get_general_category (&info[i]) !=
544-
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
545-
_hb_glyph_info_is_default_ignorable (&info[i])) ?
546-
HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
547-
HB_OT_LAYOUT_GLYPH_PROPS_MARK;
548-
_hb_glyph_info_set_glyph_props (&info[i], klass);
549-
}
550-
}
551-
552526
static inline void
553527
hb_ot_substitute_default (hb_ot_shape_context_t *c)
554528
{
@@ -580,9 +554,6 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
580554

581555
hb_ot_layout_substitute_start (c->font, buffer);
582556

583-
if (!hb_ot_layout_has_glyph_classes (c->face))
584-
hb_synthesize_glyph_classes (c);
585-
586557
c->plan->substitute (c->font, buffer);
587558

588559
return;

0 commit comments

Comments
 (0)