batchwidth
diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index 4950e0b..81ae411 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -54,6 +54,7 @@
   HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
   HB_FONT_FUNC_IMPLEMENT (glyph_name) \
   HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_h_advances) \
   /* ^--- Add new callbacks here */
 
 struct hb_font_funcs_t
@@ -227,6 +228,18 @@
 					 klass->user_data.glyph_h_advance);
   }
 
+  inline void get_glyph_h_advances(unsigned count,
+                                   hb_codepoint_t* glyphs,
+                                   unsigned glyph_struct_size,
+                                   hb_position_t* advances,
+                                   unsigned advance_struct_size) {
+    return klass->get.f.glyph_h_advances (this, user_data,
+                                          count,
+                                          glyphs, glyph_struct_size,
+                                          advances, advance_struct_size,
+					  klass->user_data.glyph_h_advances);
+  }
+
   inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
   {
     return klass->get.f.glyph_v_advance (this, user_data,
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 7d8de6d..a3f4d1a 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -143,6 +143,43 @@
   return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
 }
 
+template <class T>
+T* advance_by_byte_size(T* p, unsigned byte_size) {
+  return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(p) + byte_size);
+}
+
+static void
+hb_font_get_glyph_h_advances_nil(hb_font_t *font,
+				 void *font_data HB_UNUSED,
+				 unsigned count,
+                                 hb_codepoint_t* glyphs,
+                                 unsigned glyph_struct_size,
+                                 hb_position_t* advances,
+                                 unsigned advance_struct_size,
+                                 void *user_data HB_UNUSED) {
+  for (; count--;
+       glyphs = advance_by_byte_size(glyphs, glyph_struct_size),
+       advances = advance_by_byte_size(advances, advance_struct_size)) {
+    *advances = hb_font_get_glyph_h_advance_nil(font, font_data, *glyphs, user_data);
+  }
+}
+
+static void
+hb_font_get_glyph_h_advances_parent(hb_font_t* font,
+                                    void* font_data HB_UNUSED,
+                                    unsigned count,
+                                    hb_codepoint_t* glyphs,
+                                    unsigned glyph_struct_size,
+                                    hb_position_t* advances,
+                                    unsigned advance_struct_size,
+                                    void* user_data HB_UNUSED) {
+  for (; count--;
+       glyphs = advance_by_byte_size(glyphs, glyph_struct_size),
+       advances = advance_by_byte_size(advances, advance_struct_size)) {
+    *advances = hb_font_get_glyph_h_advance_parent(font, font_data, *glyphs, user_data);
+  }
+}
+
 static hb_position_t
 hb_font_get_glyph_v_advance_nil (hb_font_t *font,
 				 void *font_data HB_UNUSED,
diff --git a/src/hb-font.h b/src/hb-font.h
index c95b61d..41e9b0b 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -132,6 +132,16 @@
 typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
 typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
 
+typedef void (*hb_font_get_glyph_h_advances_func_t)(
+    hb_font_t* font,
+    void* font_data,
+    unsigned count,
+    hb_codepoint_t* glyphs,
+    unsigned glyph_struct_size,
+    hb_position_t* advances,
+    unsigned advance_struct_size,
+    void* user_data);
+
 typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data,
 						      hb_codepoint_t glyph,
 						      hb_position_t *x, hb_position_t *y,
@@ -248,6 +258,11 @@
 					hb_font_get_glyph_h_advance_func_t func,
 					void *user_data, hb_destroy_func_t destroy);
 
+HB_EXTERN void
+hb_font_funcs_set_glyph_h_advances_func (hb_font_funcs_t *ffuncs,
+					hb_font_get_glyph_h_advances_func_t func,
+					void *user_data, hb_destroy_func_t destroy);
+
 /**
  * hb_font_funcs_set_glyph_v_advance_func:
  * @ffuncs: font functions.
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index d7f4afe..71b448c 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -680,8 +680,8 @@
 
   if (HB_DIRECTION_IS_HORIZONTAL (direction))
   {
-    for (unsigned int i = 0; i < count; i++)
-      pos[i].x_advance = c->font->get_glyph_h_advance (info[i].codepoint);
+    c->font->get_glyph_h_advances (count, &info[0].codepoint, sizeof(info[0]),
+                                   &pos[0].x_advance, sizeof(pos[0]));
     /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
     if (c->font->has_glyph_h_origin_func ())
       for (unsigned int i = 0; i < count; i++)