[HarfBuzz] harfbuzz: Branch 'master' - 2 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Sun Jul 1 10:10:54 UTC 2018


 .circleci/config.yml        |    2 
 src/hb-blob.cc              |   16 +--
 src/hb-open-file-private.hh |  196 ++++++++++++++++++++++++++++++++++++++++++++
 src/hb-open-type-private.hh |    1 
 src/main.cc                 |    3 
 5 files changed, 209 insertions(+), 9 deletions(-)

New commits:
commit 225b92b7d4437360f8779850ee0aae85966679b5
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Sun Jul 1 14:32:00 2018 +0430

    Support dfont font files (#949)

diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index 2965b462..f69d5f46 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -286,6 +286,197 @@ struct TTCHeader
   } u;
 };
 
+/*
+ * Mac Resource Fork
+ */
+
+struct ResourceRefItem
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    // actual data sanitization is done on ResourceForkHeader sanitizer
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  HBINT16	id;		/* Resource ID, is really should be signed? */
+  HBINT16	nameOffset;	/* Offset from beginning of resource name list
+				 * to resource name, minus means there is no */
+  HBUINT8	attr;		/* Resource attributes */
+  HBUINT24	dataOffset;	/* Offset from beginning of resource data to
+				 * data for this resource */
+  HBUINT32	reserved;	/* Reserved for handle to resource */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct ResourceTypeItem
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    // RefList sanitization is done on ResourceMap sanitizer
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  inline unsigned int get_resource_count () const
+  {
+    return numRes + 1;
+  }
+
+  inline bool is_sfnt () const
+  {
+    return type == HB_TAG ('s','f','n','t');
+  }
+
+  inline const ResourceRefItem& get_ref_item (const void *base,
+					      unsigned int i) const
+  {
+    return (base+refList)[i];
+  }
+
+  protected:
+  Tag		type;		/* Resource type */
+  HBUINT16	numRes;		/* Number of resource this type in map minus 1 */
+  OffsetTo<UnsizedArrayOf<ResourceRefItem> >
+		refList;	/* Offset from beginning of resource type list
+				 * to reference list for this type */
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct ResourceMap
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+    for (unsigned int i = 0; i < get_types_count (); ++i)
+    {
+      const ResourceTypeItem& type = get_type (i);
+      if (unlikely (!type.sanitize (c)))
+        return_trace (false);
+      for (unsigned int j = 0; j < type.get_resource_count (); ++j)
+	if (unlikely (!get_ref_item (type, j).sanitize (c)))
+	  return_trace (false);
+    }
+    return_trace (true);
+  }
+
+  inline const ResourceTypeItem& get_type (unsigned int i) const
+  {
+    // Why offset from the second byte of the object? I'm not sure
+    return ((&reserved[2])+typeList)[i];
+  }
+
+  inline unsigned int get_types_count () const
+  {
+    return nTypes + 1;
+  }
+
+  inline const ResourceRefItem &get_ref_item (const ResourceTypeItem &type,
+					      unsigned int i) const
+  {
+    return type.get_ref_item (&(this+typeList), i);
+  }
+
+  inline const PString& get_name (const ResourceRefItem &item,
+				  unsigned int i) const
+  {
+    if (item.nameOffset == -1)
+      return Null (PString);
+
+    return StructAtOffset<PString> (this, nameList + item.nameOffset);
+  }
+
+  protected:
+  HBUINT8	reserved[16];	/* Reserved for copy of resource header */
+  LOffsetTo<ResourceMap>
+		reserved1;	/* Reserved for handle to next resource map */
+  HBUINT16	reserved2;	/* Reserved for file reference number */
+  HBUINT16	attr;		/* Resource fork attribute */
+  OffsetTo<UnsizedArrayOf<ResourceTypeItem> >
+		typeList;	/* Offset from beginning of map to
+				 * resource type list */
+  HBUINT16	nameList;	/* Offset from beginning of map to
+				 * resource name list */
+  HBUINT16	nTypes;		/* Number of types in the map minus 1 */
+  public:
+  DEFINE_SIZE_STATIC (30);
+};
+
+struct ResourceForkHeader
+{
+  inline unsigned int get_face_count () const
+  {
+    const ResourceMap &resource_map = this+map;
+    for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
+    {
+      const ResourceTypeItem& type = resource_map.get_type (i);
+      if (type.is_sfnt ())
+	return type.get_resource_count ();
+    }
+    return 0;
+  }
+
+  inline const LArrayOf<HBUINT8>& get_data (const ResourceTypeItem& type,
+					    unsigned int idx) const
+  {
+    const ResourceMap &resource_map = this+map;
+    unsigned int offset = dataOffset;
+    offset += resource_map.get_ref_item (type, idx).dataOffset;
+    return StructAtOffset<LArrayOf<HBUINT8> > (this, offset);
+  }
+
+  inline const OpenTypeFontFace& get_face (unsigned int idx) const
+  {
+    const ResourceMap &resource_map = this+map;
+    for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
+    {
+      const ResourceTypeItem& type = resource_map.get_type (i);
+      if (type.is_sfnt () && idx < type.get_resource_count ())
+	return (OpenTypeFontFace&) get_data (type, idx).arrayZ;
+    }
+    return Null (OpenTypeFontFace);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+
+    const ResourceMap &resource_map = this+map;
+    if (unlikely (!resource_map.sanitize (c)))
+      return_trace (false);
+
+    for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
+    {
+      const ResourceTypeItem& type = resource_map.get_type (i);
+      for (unsigned int j = 0; j < type.get_resource_count (); ++j)
+      {
+        const LArrayOf<HBUINT8>& data = get_data (type, j);
+	if (unlikely (!(data.sanitize (c) &&
+			((OpenTypeFontFace&) data.arrayZ).sanitize (c))))
+	  return_trace (false);
+      }
+    }
+
+    return_trace (true);
+  }
+
+  protected:
+  HBUINT32	dataOffset;	/* Offset from beginning of resource fork
+				 * to resource data */
+  LOffsetTo<ResourceMap>
+		map;		/* Offset from beginning of resource fork
+				 * to resource map */
+  HBUINT32	dataLen;	/* Length of resource data */
+  HBUINT32	mapLen;		/* Length of resource map */
+  public:
+  DEFINE_SIZE_STATIC (16);
+};
 
 /*
  * OpenType Font File
@@ -299,6 +490,7 @@ struct OpenTypeFontFile
     CFFTag		= HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */
     TrueTypeTag	= HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */
     TTCTag		= HB_TAG ('t','t','c','f'), /* TrueType Collection */
+    DFontTag		= HB_TAG ( 0 , 0 , 1 , 0 ), /* DFont Mac Resource Fork */
     TrueTag		= HB_TAG ('t','r','u','e'), /* Obsolete Apple TrueType */
     Typ1Tag		= HB_TAG ('t','y','p','1')  /* Obsolete Apple Type1 font in SFNT container */
   };
@@ -313,6 +505,7 @@ struct OpenTypeFontFile
     case Typ1Tag:
     case TrueTypeTag:	return 1;
     case TTCTag:	return u.ttcHeader.get_face_count ();
+    case DFontTag:	return u.rfHeader.get_face_count ();
     default:		return 0;
     }
   }
@@ -327,6 +520,7 @@ struct OpenTypeFontFile
     case Typ1Tag:
     case TrueTypeTag:	return u.fontFace;
     case TTCTag:	return u.ttcHeader.get_face (i);
+    case DFontTag:	return u.rfHeader.get_face (i);
     default:		return Null(OpenTypeFontFace);
     }
   }
@@ -353,6 +547,7 @@ struct OpenTypeFontFile
     case Typ1Tag:
     case TrueTypeTag:	return_trace (u.fontFace.sanitize (c));
     case TTCTag:	return_trace (u.ttcHeader.sanitize (c));
+    case DFontTag:	return_trace (u.rfHeader.sanitize (c));
     default:		return_trace (true);
     }
   }
@@ -362,6 +557,7 @@ struct OpenTypeFontFile
   Tag			tag;		/* 4-byte identifier. */
   OpenTypeFontFace	fontFace;
   TTCHeader		ttcHeader;
+  ResourceForkHeader	rfHeader;
   } u;
   public:
   DEFINE_SIZE_UNION (4, tag);
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 8180287d..9a4835b8 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -1033,6 +1033,7 @@ struct ArrayOf
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
 template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
+typedef ArrayOf<HBUINT8, HBUINT8> PString;
 
 /* Array of Offset's */
 template <typename Type, typename OffsetType=HBUINT16>
diff --git a/src/main.cc b/src/main.cc
index ca0fcc5b..873d240a 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -78,6 +78,9 @@ main (int argc, char **argv)
   case OpenTypeFontFile::Typ1Tag:
     printf ("Obsolete Apple Type1 font in SFNT container\n");
     break;
+  case OpenTypeFontFile::DFontTag:
+    printf ("DFont Mac Resource Fork\n");
+    break;
   default:
     printf ("Unknown font format\n");
     break;
commit 5d8cafcf6a47ce73afff06499f6be23c72ab6797
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Sun Jul 1 01:54:14 2018 +0430

    Improve nommap naming and use C style comments on create_from_file (#1084)

diff --git a/.circleci/config.yml b/.circleci/config.yml
index 012873e2..5ad1ae13 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -47,7 +47,7 @@ jobs:
       - checkout
       - run: apk update && apk add ragel make pkgconfig libtool autoconf automake gettext gcc g++ glib-dev freetype-dev cairo-dev
       # C??FLAGS are not needed for a regular build
-      - run: CFLAGS="-O3" CXXFLAGS="-O3 -DNOMMAPFILEREADER" ./autogen.sh
+      - run: CFLAGS="-O3" CXXFLAGS="-O3 -DHB_NO_MMAP" ./autogen.sh
       - run: make
       - run: make check || .ci/fail.sh
 
diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index 10db0978..98e9c65c 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -534,9 +534,9 @@ _hb_mapped_file_destroy (hb_mapped_file_t *file)
 hb_blob_t *
 hb_blob_create_from_file (const char *file_name)
 {
-  // Adopted from glib's gmappedfile.c with Matthias Clasen and
-  // Allison Lortie permission but changed a lot to suit our need.
-#if defined(HAVE_MMAP) && !defined(NOMMAPFILEREADER)
+  /* Adopted from glib's gmappedfile.c with Matthias Clasen and
+     Allison Lortie permission but changed a lot to suit our need. */
+#if defined(HAVE_MMAP) && !defined(HB_NO_MMAP)
   hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t));
   if (unlikely (!file)) return hb_blob_get_empty ();
 
@@ -563,7 +563,7 @@ fail:
 fail_without_close:
   free (file);
 
-#elif (defined(_WIN32) || defined(__CYGWIN__)) && !defined(NOMMAPFILEREADER)
+#elif (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP)
   hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t));
   if (unlikely (!file)) return hb_blob_get_empty ();
 
@@ -592,8 +592,8 @@ fail_without_close:
 
 #endif
 
-  // The following tries to read a file without knowing its size beforehand
-  // It's used as a fallback for systems without mmap or to read from pipes
+  /* The following tries to read a file without knowing its size beforehand
+     It's used as a fallback for systems without mmap or to read from pipes */
   unsigned long len = 0, allocated = BUFSIZ * 16;
   char *data = (char *) malloc (allocated);
   if (unlikely (data == nullptr)) return hb_blob_get_empty ();
@@ -606,8 +606,8 @@ fail_without_close:
     if (allocated - len < BUFSIZ)
     {
       allocated *= 2;
-      // Don't allocate and go more than ~536MB, our mmap reader still
-      // can cover files like that but lets limit our fallback reader
+      /* Don't allocate and go more than ~536MB, our mmap reader still
+	 can cover files like that but lets limit our fallback reader */
       if (unlikely (allocated > (2 << 28))) goto fread_fail;
       char *new_data = (char *) realloc (data, allocated);
       if (unlikely (new_data == nullptr)) goto fread_fail;


More information about the HarfBuzz mailing list