diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 222285d46..dc3ecc582 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -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 machine (accel); + hb_kern_machine_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 machine (accel); + hb_kern_machine_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 machine (accel); + hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); return_trace (true); diff --git a/src/hb-kern.hh b/src/hb-kern.hh index 60e625c4b..aa01b470f 100644 --- a/src/hb-kern.hh +++ b/src/hb-kern.hh @@ -38,7 +38,10 @@ namespace OT { template 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; }; diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index b2c29e303..95306ece3 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -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 machine (*this); + hb_kern_machine_t machine (*this, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); return_trace (true);