Imported Upstream version 3.4.0
[platform/upstream/harfbuzz.git] / src / hb-ot-color-cpal-table.hh
index ce9f76e..a9deeba 100644 (file)
@@ -39,7 +39,6 @@
  */
 #define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
 
-
 namespace OT {
 
 
@@ -74,6 +73,44 @@ struct CPALV1Tail
   }
 
   public:
+  bool serialize (hb_serialize_context_t *c,
+                  unsigned palette_count,
+                  unsigned color_count,
+                  const void *base,
+                  const hb_map_t *color_index_map) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->allocate_size<CPALV1Tail> (static_size);
+    if (unlikely (!out)) return_trace (false);
+
+    out->paletteFlagsZ = 0;
+    if (paletteFlagsZ)
+      out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count);
+
+    out->paletteLabelsZ = 0;
+    if (paletteLabelsZ)
+      out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count);
+
+    const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
+    if (colorLabelsZ)
+    {
+      c->push ();
+      for (const auto _ : colorLabels)
+      {
+        if (!color_index_map->has (_)) continue;
+        NameID new_color_idx;
+        new_color_idx = color_index_map->get (_);
+        if (!c->copy<NameID> (new_color_idx))
+        {
+          c->pop_discard ();
+          return_trace (false);
+        }
+      }
+      c->add_link (out->colorLabelsZ, c->pop_pack ());
+    }
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c,
                 const void *base,
                 unsigned int palette_count,
@@ -87,15 +124,17 @@ struct CPALV1Tail
   }
 
   protected:
-  LNNOffsetTo<UnsizedArrayOf<HBUINT32>>
+  // TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets
+  //                     here. Currently they are needed since UnsizedArrayOf doesn't define null_size
+  NNOffset32To<UnsizedArrayOf<HBUINT32>>
                paletteFlagsZ;          /* Offset from the beginning of CPAL table to
                                         * the Palette Type Array. Set to 0 if no array
                                         * is provided. */
-  LNNOffsetTo<UnsizedArrayOf<NameID>>
+  NNOffset32To<UnsizedArrayOf<NameID>>
                paletteLabelsZ;         /* Offset from the beginning of CPAL table to
                                         * the palette labels array. Set to 0 if no
                                         * array is provided. */
-  LNNOffsetTo<UnsizedArrayOf<NameID>>
+  NNOffset32To<UnsizedArrayOf<NameID>>
                colorLabelsZ;           /* Offset from the beginning of CPAL table to
                                         * the color labels array. Set to 0
                                         * if no array is provided. */
@@ -142,12 +181,9 @@ struct CPAL
                                                                       numColors);
     if (color_count)
     {
-      hb_array_t<const BGRAColor> segment_colors = palette_colors.sub_array (start_offset, *color_count);
-      /* Always return numColors colors per palette even if it has out-of-bounds start index. */
-      unsigned int count = hb_min ((unsigned) hb_max ((int) (numColors - start_offset), 0), *color_count);
-      *color_count = count;
-      for (unsigned int i = 0; i < count; i++)
-       colors[i] = segment_colors[i]; /* Bound-checked read. */
+      + palette_colors.sub_array (start_offset, color_count)
+      | hb_sink (hb_array (colors, *color_count))
+      ;
     }
     return numColors;
   }
@@ -160,6 +196,84 @@ struct CPAL
   }
 
   public:
+  bool serialize (hb_serialize_context_t *c,
+                  const hb_array_t<const BGRAColor> &color_records,
+                  const hb_array_t<const HBUINT16> &color_record_indices,
+                  const hb_map_t &color_record_index_map,
+                  const hb_set_t &retained_color_record_indices) const
+  {
+    TRACE_SERIALIZE (this);
+
+    for (const auto idx : color_record_indices)
+    {
+      HBUINT16 new_idx;
+      if (idx == 0) new_idx = 0;
+      else new_idx = color_record_index_map.get (idx);
+      if (!c->copy<HBUINT16> (new_idx)) return_trace (false);
+    }
+
+    c->push ();
+    for (const auto _ : retained_color_record_indices.iter ())
+    {
+      if (!c->copy<BGRAColor> (color_records[_]))
+      {
+        c->pop_discard ();
+        return_trace (false);
+      }
+    }
+    c->add_link (colorRecordsZ, c->pop_pack ());
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_map_t *color_index_map = c->plan->colr_palettes;
+    if (color_index_map->is_empty ()) return_trace (false);
+
+    hb_set_t retained_color_indices;
+    for (const auto _ : color_index_map->keys ())
+    {
+      if (_ == 0xFFFF) continue;
+      retained_color_indices.add (_);
+    }
+    if (retained_color_indices.is_empty ()) return_trace (false);
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    out->version = version;
+    out->numColors = retained_color_indices.get_population ();
+    out->numPalettes = numPalettes;
+
+    const hb_array_t<const HBUINT16> colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes);
+    hb_map_t color_record_index_map;
+    hb_set_t retained_color_record_indices;
+
+    unsigned record_count = 0;
+    for (const auto first_color_record_idx : colorRecordIndices)
+    {
+      for (unsigned retained_color_idx : retained_color_indices.iter ())
+      {
+        unsigned color_record_idx = first_color_record_idx + retained_color_idx;
+        if (color_record_index_map.has (color_record_idx)) continue;
+        color_record_index_map.set (color_record_idx, record_count);
+        retained_color_record_indices.add (color_record_idx);
+        record_count++;
+      }
+    }
+
+    out->numColorRecords = record_count;
+    const hb_array_t<const BGRAColor> color_records = (this+colorRecordsZ).as_array (numColorRecords);
+    if (!out->serialize (c->serializer, color_records, colorRecordIndices, color_record_index_map, retained_color_record_indices))
+      return_trace (false);
+
+    if (version == 1)
+      return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map));
+
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -176,7 +290,7 @@ struct CPAL
   HBUINT16     numPalettes;            /* Number of palettes in the table. */
   HBUINT16     numColorRecords;        /* Total number of color records, combined for
                                         * all palettes. */
-  LNNOffsetTo<UnsizedArrayOf<BGRAColor>>
+  NNOffset32To<UnsizedArrayOf<BGRAColor>>
                colorRecordsZ;          /* Offset from the beginning of CPAL table to
                                         * the first ColorRecord. */
   UnsizedArrayOf<HBUINT16>