Imported Upstream version 2.6.7
[platform/upstream/harfbuzz.git] / src / hb-ot-post-table.hh
index 5f42751..8586331 100644 (file)
@@ -27,9 +27,7 @@
 #ifndef HB_OT_POST_TABLE_HH
 #define HB_OT_POST_TABLE_HH
 
-#include "hb-open-type-private.hh"
-#include "hb-dsalgs.hh"
-#include "hb-subset-plan.hh"
+#include "hb-open-type.hh"
 
 #define HB_STRING_ARRAY_NAME format1_names
 #define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh"
@@ -37,8 +35,6 @@
 #undef HB_STRING_ARRAY_LIST
 #undef HB_STRING_ARRAY_NAME
 
-#define NUM_FORMAT1_NAMES 258
-
 /*
  * post -- PostScript
  * https://docs.microsoft.com/en-us/typography/opentype/spec/post
@@ -51,119 +47,105 @@ namespace OT {
 
 struct postV2Tail
 {
-  inline bool sanitize (hb_sanitize_context_t *c) const
+  friend struct post;
+
+  bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (glyphNameIndex.sanitize (c));
   }
 
-  ArrayOf<HBUINT16>glyphNameIndex;     /* This is not an offset, but is the
+  protected:
+  ArrayOf<HBUINT16>    glyphNameIndex; /* This is not an offset, but is the
                                         * ordinal number of the glyph in 'post'
                                         * string tables. */
-  HBUINT8              namesX[VAR];            /* Glyph names with length bytes [variable]
+/*UnsizedArrayOf<HBUINT8>
+                       namesX;*/       /* Glyph names with length bytes [variable]
                                         * (a Pascal string). */
 
-  DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
+  public:
+  DEFINE_SIZE_ARRAY (2, glyphNameIndex);
 };
 
 struct post
 {
-  static const hb_tag_t tableTag = HB_OT_TAG_post;
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_post;
 
-  inline bool sanitize (hb_sanitize_context_t *c) const
+  void serialize (hb_serialize_context_t *c) const
   {
-    TRACE_SANITIZE (this);
-    if (unlikely (!c->check_struct (this)))
-      return_trace (false);
-    if (version.to_int () == 0x00020000)
-    {
-      const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
-      return_trace (v2.sanitize (c));
-    }
-    return_trace (true);
+    post *post_prime = c->allocate_min<post> ();
+    if (unlikely (!post_prime))  return;
+
+    memcpy (post_prime, this, post::min_size);
+    post_prime->version.major = 3; // Version 3 does not have any glyph names.
   }
 
-  inline bool subset (hb_subset_plan_t *plan) const
+  bool subset (hb_subset_context_t *c) const
   {
-    unsigned int post_prime_length;
-    hb_blob_t *post_blob = OT::Sanitizer<post>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_post));
-    hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::static_size);
-    post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length);
-    hb_blob_destroy (post_blob);
+    TRACE_SUBSET (this);
+    post *post_prime = c->serializer->start_embed<post> ();
+    if (unlikely (!post_prime)) return_trace (false);
 
-    if (unlikely (!post_prime || post_prime_length != post::static_size))
-    {
-      hb_blob_destroy (post_prime_blob);
-      DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length);
-      return false;
-    }
+    serialize (c->serializer);
+    if (c->serializer->in_error () || c->serializer->ran_out_of_room) return_trace (false);
 
-    post_prime->version.major.set (3); // Version 3 does not have any glyph names.
-    bool result = plan->add_table (HB_OT_TAG_post, post_prime_blob);
-    hb_blob_destroy (post_prime_blob);
-
-    return result;
+    return_trace (true);
   }
 
   struct accelerator_t
   {
-    inline void init (hb_face_t *face)
+    void init (hb_face_t *face)
     {
       index_to_offset.init ();
 
-      blob = Sanitizer<post>().sanitize (face->reference_table (HB_OT_TAG_post));
-      const post *table = blob->as<post> ();
-      unsigned int table_length = blob->length;
+      table = hb_sanitize_context_t ().reference_table<post> (face);
+      unsigned int table_length = table.get_length ();
 
       version = table->version.to_int ();
-      if (version != 0x00020000)
-        return;
+      if (version != 0x00020000) return;
 
-      const postV2Tail &v2 = StructAfter<postV2Tail> (*table);
+      const postV2Tail &v2 = table->v2X;
 
       glyphNameIndex = &v2.glyphNameIndex;
       pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
 
-      const uint8_t *end = (uint8_t *) table + table_length;
-      for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data)
+      const uint8_t *end = (const uint8_t *) (const void *) table + table_length;
+      for (const uint8_t *data = pool;
+          index_to_offset.length < 65535 && data < end && data + *data < end;
+          data += 1 + *data)
        index_to_offset.push (data - pool);
     }
-    inline void fini (void)
+    void fini ()
     {
       index_to_offset.fini ();
-      free (gids_sorted_by_name);
+      free (gids_sorted_by_name.get ());
+      table.destroy ();
     }
 
-    inline bool get_glyph_name (hb_codepoint_t glyph,
-                               char *buf, unsigned int buf_len) const
+    bool get_glyph_name (hb_codepoint_t glyph,
+                        char *buf, unsigned int buf_len) const
     {
       hb_bytes_t s = find_glyph_name (glyph);
-      if (!s.len)
-        return false;
-      if (!buf_len)
-       return true;
-      if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
-        return false;
-      strncpy (buf, s.bytes, s.len);
-      buf[s.len] = '\0';
+      if (!s.length) return false;
+      if (!buf_len) return true;
+      unsigned int len = hb_min (buf_len - 1, s.length);
+      strncpy (buf, s.arrayZ, len);
+      buf[len] = '\0';
       return true;
     }
 
-    inline bool get_glyph_from_name (const char *name, int len,
-                                    hb_codepoint_t *glyph) const
+    bool get_glyph_from_name (const char *name, int len,
+                             hb_codepoint_t *glyph) const
     {
       unsigned int count = get_glyph_count ();
-      if (unlikely (!count))
-        return false;
+      if (unlikely (!count)) return false;
 
-      if (len < 0)
-       len = strlen (name);
+      if (len < 0) len = strlen (name);
 
-      if (unlikely (!len))
-       return false;
+      if (unlikely (!len)) return false;
 
     retry:
-      uint16_t *gids = (uint16_t *) hb_atomic_ptr_get (&gids_sorted_by_name);
+      uint16_t *gids = gids_sorted_by_name.get ();
 
       if (unlikely (!gids))
       {
@@ -173,16 +155,17 @@ struct post
 
        for (unsigned int i = 0; i < count; i++)
          gids[i] = i;
-       hb_sort_r (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
+       hb_qsort (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
 
-       if (!hb_atomic_ptr_cmpexch (&gids_sorted_by_name, nullptr, gids)) {
+       if (unlikely (!gids_sorted_by_name.cmpexch (nullptr, gids)))
+       {
          free (gids);
          goto retry;
        }
       }
 
       hb_bytes_t st (name, len);
-      const uint16_t *gid = (const uint16_t *) hb_bsearch_r (&st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
+      auto* gid = hb_bsearch (st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
       if (gid)
       {
        *glyph = *gid;
@@ -192,20 +175,22 @@ struct post
       return false;
     }
 
+    hb_blob_ptr_t<post> table;
+
     protected:
 
-    inline unsigned int get_glyph_count (void) const
+    unsigned int get_glyph_count () const
     {
       if (version == 0x00010000)
-        return NUM_FORMAT1_NAMES;
+       return format1_names_length;
 
       if (version == 0x00020000)
-        return glyphNameIndex->len;
+       return glyphNameIndex->len;
 
       return 0;
     }
 
-    static inline int cmp_gids (const void *pa, const void *pb, void *arg)
+    static int cmp_gids (const void *pa, const void *pb, void *arg)
     {
       const accelerator_t *thiz = (const accelerator_t *) arg;
       uint16_t a = * (const uint16_t *) pa;
@@ -213,7 +198,7 @@ struct post
       return thiz->find_glyph_name (b).cmp (thiz->find_glyph_name (a));
     }
 
-    static inline int cmp_key (const void *pk, const void *po, void *arg)
+    static int cmp_key (const void *pk, const void *po, void *arg)
     {
       const accelerator_t *thiz = (const accelerator_t *) arg;
       const hb_bytes_t *key = (const hb_bytes_t *) pk;
@@ -221,11 +206,11 @@ struct post
       return thiz->find_glyph_name (o).cmp (*key);
     }
 
-    inline hb_bytes_t find_glyph_name (hb_codepoint_t glyph) const
+    hb_bytes_t find_glyph_name (hb_codepoint_t glyph) const
     {
       if (version == 0x00010000)
       {
-       if (glyph >= NUM_FORMAT1_NAMES)
+       if (glyph >= format1_names_length)
          return hb_bytes_t ();
 
        return format1_names (glyph);
@@ -235,13 +220,13 @@ struct post
        return hb_bytes_t ();
 
       unsigned int index = glyphNameIndex->arrayZ[glyph];
-      if (index < NUM_FORMAT1_NAMES)
+      if (index < format1_names_length)
        return format1_names (index);
-      index -= NUM_FORMAT1_NAMES;
+      index -= format1_names_length;
 
-      if (index >= index_to_offset.len)
+      if (index >= index_to_offset.length)
        return hb_bytes_t ();
-      unsigned int offset = index_to_offset.arrayZ[index];
+      unsigned int offset = index_to_offset[index];
 
       const uint8_t *data = pool + offset;
       unsigned int name_length = *data;
@@ -251,20 +236,30 @@ struct post
     }
 
     private:
-    hb_blob_t *blob;
     uint32_t version;
     const ArrayOf<HBUINT16> *glyphNameIndex;
-    hb_vector_t<uint32_t, 1> index_to_offset;
+    hb_vector_t<uint32_t> index_to_offset;
     const uint8_t *pool;
-    mutable uint16_t *gids_sorted_by_name;
+    hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
   };
 
+  bool has_data () const { return version.to_int (); }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+                         (version.to_int () == 0x00010000 ||
+                          (version.to_int () == 0x00020000 && v2X.sanitize (c)) ||
+                          version.to_int () == 0x00030000)));
+  }
+
   public:
   FixedVersion<>version;               /* 0x00010000 for version 1.0
                                         * 0x00020000 for version 2.0
                                         * 0x00025000 for version 2.5 (deprecated)
                                         * 0x00030000 for version 3.0 */
-  Fixed                italicAngle;            /* Italic angle in counter-clockwise degrees
+  HBFixed      italicAngle;            /* Italic angle in counter-clockwise degrees
                                         * from the vertical. Zero for upright text,
                                         * negative for text that leans to the right
                                         * (forward). */
@@ -291,10 +286,12 @@ struct post
                                         * is downloaded as a Type 1 font. */
   HBUINT32     maxMemType1;            /* Maximum memory usage when an OpenType font
                                         * is downloaded as a Type 1 font. */
-/*postV2Tail   v2[VAR];*/
-  DEFINE_SIZE_STATIC (32);
+  postV2Tail   v2X;
+  DEFINE_SIZE_MIN (32);
 };
 
+struct post_accelerator_t : post::accelerator_t {};
+
 } /* namespace OT */