[dfont] Solve the mystery +2 offset thing!

Previously, ResourceForkHeader was defined as 30 bytes, having the typeCountM1 as last member.
There was a mysterious offset-by-2 in the code, derived from FontTools and JDK code this was
ported from.

In testing, I observed that typeListZ offset is actually 28.  Suggesting that the typeCountM1
does NOT actually belong to ResourceForkHeader, but belongs to the array itself.  Adjusting for
that resolves the mystery +2 offset hack, so everything is clean and good now.

This, concludes my dfont hacking.  The code looks great now, and I'm happy to leave it.
Fuzzers might disagree though, we will see!
diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh
index 5c653fe..cd7d78a 100644
--- a/src/hb-open-file.hh
+++ b/src/hb-open-file.hh
@@ -357,13 +357,6 @@
 
 struct ResourceMap
 {
-  inline const ResourceTypeRecord& get_type_record (unsigned int i) const
-  {
-    // Why offset from the third byte of the object? I'm not sure
-    return hb_array_t<ResourceTypeRecord> (((2 + (const char *) this )+typeListZ).arrayZ,
-					   get_type_count ()) [i];
-  }
-
   inline unsigned int get_face_count (void) const
   {
     unsigned int count = get_type_count ();
@@ -386,7 +379,7 @@
       /* The check for idx < count is here because ResourceRecord is NOT null-safe.
        * Because an offset of 0 there does NOT mean null. */
       if (type.is_sfnt () && idx < type.get_resource_count ())
-	return type.get_resource_record (idx, &(this+typeListZ)).get_face (data_base);
+	return type.get_resource_record (idx, &(this+typeList)).get_face (data_base);
     }
     return Null (OpenTypeFontFace);
   }
@@ -394,30 +387,31 @@
   inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const
   {
     TRACE_SANITIZE (this);
-    const void *type_base = &(this+typeListZ);
+    const void *type_base = &(this+typeList);
     return_trace (c->check_struct (this) &&
-		  typeListZ.sanitize (c, 2 + (const char *) this,
-				      get_type_count (),
-				      type_base,
-				      data_base));
+		  typeList.sanitize (c, this,
+				     type_base,
+				     data_base));
   }
 
   private:
-  inline unsigned int get_type_count (void) const { return typeCountM1 + 1; }
+  inline unsigned int get_type_count (void) const { return (this+typeList).lenM1 + 1; }
+
+  inline const ResourceTypeRecord& get_type_record (unsigned int i) const
+  { return (this+typeList)[i]; }
 
   protected:
   HBUINT8	reserved0[16];	/* Reserved for copy of resource header */
   HBUINT32	reserved1;	/* Reserved for handle to next resource map */
   HBUINT16	resreved2;	/* Reserved for file reference number */
   HBUINT16	attrs;		/* Resource fork attribute */
-  OffsetTo<UnsizedArrayOf<ResourceTypeRecord> >
-		typeListZ;	/* Offset from beginning of map to
+  OffsetTo<ArrayOfM1<ResourceTypeRecord> >
+		typeList;	/* Offset from beginning of map to
 				 * resource type list */
   Offset16	nameList;	/* Offset from beginning of map to
 				 * resource name list */
-  HBUINT16	typeCountM1;	/* Number of types in the map minus 1 */
   public:
-  DEFINE_SIZE_STATIC (30);
+  DEFINE_SIZE_STATIC (28);
 };
 
 struct ResourceForkHeader
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index 6807973..4f16c7d 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -628,6 +628,50 @@
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
 
+/* An array storing length-1. */
+template <typename Type, typename LenType=HBUINT16>
+struct ArrayOfM1
+{
+  inline const Type& operator [] (unsigned int i) const
+  {
+    if (unlikely (i > lenM1)) return Null(Type);
+    return arrayZ[i];
+  }
+  inline Type& operator [] (unsigned int i)
+  {
+    if (unlikely (i > lenM1)) return Crap(Type);
+    return arrayZ[i];
+  }
+  inline unsigned int get_size (void) const
+  { return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
+
+  template <typename T>
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    unsigned int count = lenM1 + 1;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
+        return_trace (false);
+    return_trace (true);
+  }
+
+  private:
+  inline bool sanitize_shallow (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (lenM1.sanitize (c) &&
+		  (c->check_array (arrayZ, lenM1 + 1)));
+  }
+
+  public:
+  LenType	lenM1;
+  Type		arrayZ[VAR];
+  public:
+  DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
+};
+
 /* An array with sorted elements.  Supports binary searching. */
 template <typename Type, typename LenType=HBUINT16>
 struct SortedArrayOf : ArrayOf<Type, LenType>