[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)
return false;
if (header.coverage & (header.CrossStream | header.Backwards))
if (header.coverage & header.Backwards)
return false;
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);
return_trace (true);
@ -427,11 +427,11 @@ struct KerxSubTableFormat2
if (!c->plan->requested_kerning)
return false;
if (header.coverage & (header.CrossStream | header.Backwards))
if (header.coverage & header.Backwards)
return false;
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);
return_trace (true);
@ -696,11 +696,11 @@ struct KerxSubTableFormat6
if (!c->plan->requested_kerning)
return false;
if (header.coverage & (header.CrossStream | header.Backwards))
if (header.coverage & header.Backwards)
return false;
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);
return_trace (true);

View File

@ -38,7 +38,10 @@ namespace OT {
template <typename Driver>
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
inline void kern (hb_font_t *font,
@ -81,26 +84,41 @@ struct hb_kern_machine_t
if (likely (!kern))
goto skip;
if (horizontal)
{
if (scale)
kern = font->em_scale_x (kern);
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;
if (crossStream)
{
pos[j].y_offset = kern;
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
}
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
{
if (scale)
kern = font->em_scale_y (kern);
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;
if (crossStream)
{
pos[j].x_offset = kern;
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
}
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);
@ -111,6 +129,7 @@ struct hb_kern_machine_t
}
const Driver &driver;
bool crossStream;
};

View File

@ -66,10 +66,10 @@ struct KernSubTableFormat3
if (!c->plan->requested_kerning)
return false;
if (header.coverage & (header.CrossStream | header.Backwards))
if (header.coverage & header.Backwards)
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);
return_trace (true);