[kerx] Implement CrossStream kerning for non-state-machine subtables

Untested.
This commit is contained in:
Behdad Esfahbod 2018-11-07 14:52:36 -05:00
parent 0eb4157011
commit 7a9629f2f1
3 changed files with 39 additions and 20 deletions

View File

@ -118,11 +118,11 @@ struct KerxSubTableFormat0
if (!c->plan->requested_kerning) if (!c->plan->requested_kerning)
return false; return false;
if (header.coverage & (header.CrossStream | header.Backwards)) if (header.coverage & header.Backwards)
return false; return false;
accelerator_t accel (*this, c); accelerator_t accel (*this, c);
hb_kern_machine_t<accelerator_t> machine (accel); hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
machine.kern (c->font, c->buffer, c->plan->kern_mask); machine.kern (c->font, c->buffer, c->plan->kern_mask);
return_trace (true); return_trace (true);
@ -427,11 +427,11 @@ struct KerxSubTableFormat2
if (!c->plan->requested_kerning) if (!c->plan->requested_kerning)
return false; return false;
if (header.coverage & (header.CrossStream | header.Backwards)) if (header.coverage & header.Backwards)
return false; return false;
accelerator_t accel (*this, c); accelerator_t accel (*this, c);
hb_kern_machine_t<accelerator_t> machine (accel); hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
machine.kern (c->font, c->buffer, c->plan->kern_mask); machine.kern (c->font, c->buffer, c->plan->kern_mask);
return_trace (true); return_trace (true);
@ -696,11 +696,11 @@ struct KerxSubTableFormat6
if (!c->plan->requested_kerning) if (!c->plan->requested_kerning)
return false; return false;
if (header.coverage & (header.CrossStream | header.Backwards)) if (header.coverage & header.Backwards)
return false; return false;
accelerator_t accel (*this, c); accelerator_t accel (*this, c);
hb_kern_machine_t<accelerator_t> machine (accel); hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream);
machine.kern (c->font, c->buffer, c->plan->kern_mask); machine.kern (c->font, c->buffer, c->plan->kern_mask);
return_trace (true); return_trace (true);

View File

@ -38,7 +38,10 @@ namespace OT {
template <typename Driver> template <typename Driver>
struct hb_kern_machine_t struct hb_kern_machine_t
{ {
hb_kern_machine_t (const Driver &driver_) : driver (driver_) {} hb_kern_machine_t (const Driver &driver_,
bool crossStream_ = false) :
driver (driver_),
crossStream (crossStream_) {}
HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
inline void kern (hb_font_t *font, inline void kern (hb_font_t *font,
@ -81,26 +84,41 @@ struct hb_kern_machine_t
if (likely (!kern)) if (likely (!kern))
goto skip; goto skip;
if (horizontal) if (horizontal)
{ {
if (scale) if (scale)
kern = font->em_scale_x (kern); kern = font->em_scale_x (kern);
hb_position_t kern1 = kern >> 1; if (crossStream)
hb_position_t kern2 = kern - kern1; {
pos[i].x_advance += kern1; pos[j].y_offset = kern;
pos[j].x_advance += kern2; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
pos[j].x_offset += kern2; }
else
{
hb_position_t kern1 = kern >> 1;
hb_position_t kern2 = kern - kern1;
pos[i].x_advance += kern1;
pos[j].x_advance += kern2;
pos[j].x_offset += kern2;
}
} }
else else
{ {
if (scale) if (scale)
kern = font->em_scale_y (kern); kern = font->em_scale_y (kern);
hb_position_t kern1 = kern >> 1; if (crossStream)
hb_position_t kern2 = kern - kern1; {
pos[i].y_advance += kern1; pos[j].x_offset = kern;
pos[j].y_advance += kern2; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
pos[j].y_offset += kern2; }
else
{
hb_position_t kern1 = kern >> 1;
hb_position_t kern2 = kern - kern1;
pos[i].y_advance += kern1;
pos[j].y_advance += kern2;
pos[j].y_offset += kern2;
}
} }
buffer->unsafe_to_break (i, j + 1); buffer->unsafe_to_break (i, j + 1);
@ -111,6 +129,7 @@ struct hb_kern_machine_t
} }
const Driver &driver; const Driver &driver;
bool crossStream;
}; };

View File

@ -66,10 +66,10 @@ struct KernSubTableFormat3
if (!c->plan->requested_kerning) if (!c->plan->requested_kerning)
return false; return false;
if (header.coverage & (header.CrossStream | header.Backwards)) if (header.coverage & header.Backwards)
return false; return false;
hb_kern_machine_t<KernSubTableFormat3> machine (*this); hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream);
machine.kern (c->font, c->buffer, c->plan->kern_mask); machine.kern (c->font, c->buffer, c->plan->kern_mask);
return_trace (true); return_trace (true);