.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 <ebra...@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 <ebra...@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; _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz