Imported Upstream version 2.6.4
[platform/upstream/harfbuzz.git] / src / hb-ot-name-table.hh
index c8ababd..84be04c 100644 (file)
@@ -51,6 +51,7 @@ struct NameRecord
 {
   hb_language_t language (hb_face_t *face) const
   {
+#ifndef HB_NO_OT_NAME_LANGUAGE
     unsigned int p = platformID;
     unsigned int l = languageID;
 
@@ -60,9 +61,12 @@ struct NameRecord
     if (p == 1)
       return _hb_ot_name_language_for_mac_code (l);
 
+#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
     if (p == 0)
-      return _hb_aat_language_get (face, l);
+      return face->table.ltag->get_language (l);
+#endif
 
+#endif
     return HB_LANGUAGE_INVALID;
   }
 
@@ -93,11 +97,21 @@ struct NameRecord
     return UNSUPPORTED;
   }
 
+  NameRecord* copy (hb_serialize_context_t *c,
+                   const void *src_base,
+                   const void *dst_base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+    out->offset.serialize_copy (c, offset, src_base, dst_base, length);
+    return_trace (out);
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
-    /* We can check from base all the way up to the end of string... */
-    return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
+    return_trace (c->check_struct (this) && offset.sanitize (c, base, length));
   }
 
   HBUINT16     platformID;     /* Platform ID. */
@@ -105,7 +119,8 @@ struct NameRecord
   HBUINT16     languageID;     /* Language ID. */
   HBUINT16     nameID;         /* Name ID. */
   HBUINT16     length;         /* String length (in bytes). */
-  HBUINT16     offset;         /* String offset from start of storage area (in bytes). */
+  NNOffsetTo<UnsizedArrayOf<HBUINT8>>
+               offset;         /* String offset from start of storage area (in bytes). */
   public:
   DEFINE_SIZE_STATIC (12);
 };
@@ -156,15 +171,56 @@ struct name
   unsigned int get_size () const
   { return min_size + count * nameRecordZ.item_size; }
 
+  template <typename Iterator,
+           hb_requires (hb_is_source_of (Iterator, const NameRecord &))>
+  bool serialize (hb_serialize_context_t *c,
+                 Iterator it,
+                 const void *src_string_pool)
+  {
+    TRACE_SERIALIZE (this);
+
+    if (unlikely (!c->extend_min ((*this))))  return_trace (false);
+
+    this->format = 0;
+    this->count = it.len ();
+
+    auto snap = c->snapshot ();
+    this->nameRecordZ.serialize (c, this->count);
+    if (unlikely (!c->check_assign (this->stringOffset, c->length ()))) return_trace (false);
+    c->revert (snap);
+
+    const void *dst_string_pool = &(this + this->stringOffset);
+
+    for (const auto &_ : it) c->copy (_, src_string_pool, dst_string_pool);
+
+    if (unlikely (c->ran_out_of_room)) return_trace (false);
+
+    assert (this->stringOffset == c->length ());
+
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+
+    name *name_prime = c->serializer->start_embed<name> ();
+    if (unlikely (!name_prime)) return_trace (false);
+
+    auto it =
+    + nameRecordZ.as_array (count)
+    | hb_filter (c->plan->name_ids, &NameRecord::nameID)
+    ;
+
+    name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset));
+    return_trace (name_prime->count);
+  }
+
   bool sanitize_records (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     const void *string_pool = (this+stringOffset).arrayZ;
-    unsigned int _count = count;
-    /* Move to run-time?! */
-    for (unsigned int i = 0; i < _count; i++)
-      if (!nameRecordZ[i].sanitize (c, string_pool)) return_trace (false);
-    return_trace (true);
+    return_trace (nameRecordZ.sanitize (c, count, string_pool));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -173,7 +229,8 @@ struct name
     return_trace (c->check_struct (this) &&
                  likely (format == 0 || format == 1) &&
                  c->check_array (nameRecordZ.arrayZ, count) &&
-                 c->check_range (this, stringOffset));
+                 c->check_range (this, stringOffset) &&
+                 sanitize_records (c));
   }
 
   struct accelerator_t
@@ -206,10 +263,10 @@ struct name
       unsigned int j = 0;
       for (unsigned int i = 0; i < this->names.length; i++)
       {
-        if (this->names[i].entry_score == UNSUPPORTED ||
+       if (this->names[i].entry_score == UNSUPPORTED ||
            this->names[i].language == HB_LANGUAGE_INVALID)
          continue;
-        if (i &&
+       if (i &&
            this->names[i - 1].name_id  == this->names[i].name_id &&
            this->names[i - 1].language == this->names[i].language)
          continue;
@@ -236,10 +293,10 @@ struct name
                                                    sizeof (key),
                                                    _hb_ot_name_entry_cmp_key);
       if (!entry)
-        return -1;
+       return -1;
 
       if (width)
-        *width = entry->entry_score < 10 ? 2 : 1;
+       *width = entry->entry_score < 10 ? 2 : 1;
 
       return entry->entry_index;
     }
@@ -263,7 +320,7 @@ struct name
   /* We only implement format 0 for now. */
   HBUINT16     format;                 /* Format selector (=0/1). */
   HBUINT16     count;                  /* Number of name records. */
-  NNOffsetTo<UnsizedArrayOf<HBUINT8> >
+  NNOffsetTo<UnsizedArrayOf<HBUINT8>>
                stringOffset;           /* Offset to start of string storage (from start of table). */
   UnsizedArrayOf<NameRecord>
                nameRecordZ;            /* The name records where count is the number of records. */
@@ -271,6 +328,9 @@ struct name
   DEFINE_SIZE_ARRAY (6, nameRecordZ);
 };
 
+#undef entry_index
+#undef entry_score
+
 struct name_accelerator_t : name::accelerator_t {};
 
 } /* namespace OT */