[Vertical] GPOS x/y advance adjustments only apply in hori/vert respectively
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 9ddc0f7..87e25ff 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -95,20 +95,26 @@
   { return get_len () * Value::static_size; }
 
   void apply_value (hb_font_t            *font,
+		    hb_direction_t        direction,
 		    const void           *base,
 		    const Value          *values,
 		    hb_glyph_position_t  &glyph_pos) const
   {
     unsigned int x_ppem, y_ppem;
     unsigned int format = *this;
+    hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (direction);
 
     if (!format) return;
 
     if (format & xPlacement) glyph_pos.x_offset  += font->em_scale_x (get_short (values++));
     if (format & yPlacement) glyph_pos.y_offset  += font->em_scale_y (get_short (values++));
-    if (format & xAdvance)   glyph_pos.x_advance += font->em_scale_x (get_short (values++));
+    if (format & xAdvance) {
+      if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values++)); else values++;
+    }
     /* y_advance values grow downward but font-space grows upward, hence negation */
-    if (format & yAdvance)   glyph_pos.y_advance -= font->em_scale_y (get_short (values++));
+    if (format & yAdvance) {
+      if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values++)); else values++;
+    }
 
     if (!has_device ()) return;
 
@@ -125,11 +131,11 @@
       if (y_ppem) glyph_pos.y_offset  += (base + get_device (values++)).get_y_delta (font); else values++;
     }
     if (format & xAdvDevice) {
-      if (x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++;
+      if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++;
     }
     if (format & yAdvDevice) {
       /* y_advance values grow downward but font-space grows upward, hence negation */
-      if (y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++;
+      if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++;
     }
   }
 
@@ -436,7 +442,8 @@
     if (likely (index == NOT_COVERED))
       return false;
 
-    valueFormat.apply_value (c->font, this, values, c->buffer->pos[c->buffer->i]);
+    valueFormat.apply_value (c->font, c->direction, this,
+			     values, c->buffer->pos[c->buffer->i]);
 
     c->buffer->i++;
     return true;
@@ -478,7 +485,7 @@
     if (likely (index >= valueCount))
       return false;
 
-    valueFormat.apply_value (c->font, this,
+    valueFormat.apply_value (c->font, c->direction, this,
 			     &values[index * valueFormat.get_len ()],
 			     c->buffer->pos[c->buffer->i]);
 
@@ -574,8 +581,10 @@
     {
       if (c->buffer->info[pos].codepoint == record->secondGlyph)
       {
-	valueFormats[0].apply_value (c->font, this, &record->values[0], c->buffer->pos[c->buffer->i]);
-	valueFormats[1].apply_value (c->font, this, &record->values[len1], c->buffer->pos[pos]);
+	valueFormats[0].apply_value (c->font, c->direction, this,
+				     &record->values[0], c->buffer->pos[c->buffer->i]);
+	valueFormats[1].apply_value (c->font, c->direction, this,
+				     &record->values[len1], c->buffer->pos[pos]);
 	if (len2)
 	  pos++;
 	c->buffer->i = pos;
@@ -709,8 +718,10 @@
       return false;
 
     const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
-    valueFormat1.apply_value (c->font, this, v, c->buffer->pos[c->buffer->i]);
-    valueFormat2.apply_value (c->font, this, v + len1, c->buffer->pos[j]);
+    valueFormat1.apply_value (c->font, c->direction, this,
+			      v, c->buffer->pos[c->buffer->i]);
+    valueFormat2.apply_value (c->font, c->direction, this,
+			      v + len1, c->buffer->pos[j]);
 
     if (len2)
       j++;