[Vertical] GPOS x/y advance adjustments only apply in hori/vert respectively
authorBehdad Esfahbod <behdad@behdad.org>
Fri, 20 May 2011 19:59:59 +0000 (15:59 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Fri, 20 May 2011 19:59:59 +0000 (15:59 -0400)
src/hb-ot-layout-gpos-private.hh

index 9ddc0f7..87e25ff 100644 (file)
@@ -95,20 +95,26 @@ struct ValueFormat : USHORT
   { 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 @@ struct ValueFormat : USHORT
       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 @@ struct SinglePosFormat1
     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 @@ struct SinglePosFormat2
     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 @@ struct PairSet
     {
       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 @@ struct PairPosFormat2
       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++;