[>64k:layout:SingleSubst] Implement format 3/4
Implements https://github.com/be-fonts/boring-expansion-spec/issues/31
This commit is contained in:
parent
e3caf8d50a
commit
8775e9b4a4
|
@ -16,6 +16,10 @@ struct SingleSubst
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
SingleSubstFormat1_3<SmallTypes> format1;
|
SingleSubstFormat1_3<SmallTypes> format1;
|
||||||
SingleSubstFormat2_4<SmallTypes> format2;
|
SingleSubstFormat2_4<SmallTypes> format2;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
SingleSubstFormat1_3<MediumTypes> format3;
|
||||||
|
SingleSubstFormat2_4<MediumTypes> format4;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -28,6 +32,10 @@ struct SingleSubst
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
|
||||||
|
case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
|
||||||
|
#endif
|
||||||
default:return_trace (c->default_return_value ());
|
default:return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,11 +53,24 @@ struct SingleSubst
|
||||||
if (glyphs)
|
if (glyphs)
|
||||||
{
|
{
|
||||||
format = 1;
|
format = 1;
|
||||||
|
hb_codepoint_t mask = 0xFFFFu;
|
||||||
|
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
if (+ glyphs
|
||||||
|
| hb_map_retains_sorting (hb_first)
|
||||||
|
| hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; }))
|
||||||
|
{
|
||||||
|
format += 2;
|
||||||
|
mask = 0xFFFFFFu;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
auto get_delta = [=] (hb_codepoint_pair_t _)
|
auto get_delta = [=] (hb_codepoint_pair_t _)
|
||||||
{ return (unsigned) (_.second - _.first) & 0xFFFF; };
|
{ return (unsigned) (_.second - _.first) & mask; };
|
||||||
delta = get_delta (*glyphs);
|
delta = get_delta (*glyphs);
|
||||||
if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
|
if (!hb_all (++(+glyphs), delta, get_delta)) format += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u.format = format;
|
u.format = format;
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (u.format1.serialize (c,
|
case 1: return_trace (u.format1.serialize (c,
|
||||||
|
@ -57,6 +78,13 @@ struct SingleSubst
|
||||||
| hb_map_retains_sorting (hb_first),
|
| hb_map_retains_sorting (hb_first),
|
||||||
delta));
|
delta));
|
||||||
case 2: return_trace (u.format2.serialize (c, glyphs));
|
case 2: return_trace (u.format2.serialize (c, glyphs));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (u.format3.serialize (c,
|
||||||
|
+ glyphs
|
||||||
|
| hb_map_retains_sorting (hb_first),
|
||||||
|
delta));
|
||||||
|
case 4: return_trace (u.format4.serialize (c, glyphs));
|
||||||
|
#endif
|
||||||
default:return_trace (false);
|
default:return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ struct SingleSubstFormat2_4
|
||||||
+ hb_zip (this+coverage, substitute)
|
+ hb_zip (this+coverage, substitute)
|
||||||
| hb_filter (glyphset, hb_first)
|
| hb_filter (glyphset, hb_first)
|
||||||
| hb_filter (glyphset, hb_second)
|
| hb_filter (glyphset, hb_second)
|
||||||
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t
|
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const typename Types::HBGlyphID &> p) -> hb_codepoint_pair_t
|
||||||
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
|
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue