src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-colr-table.hh
changeset 50826 f5b95be8b6e2
parent 50352 25db2c8f3cf8
child 54232 7c11a7cc7c1d
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-colr-table.hh	Thu Jun 21 09:53:50 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-colr-table.hh	Thu Jun 21 12:54:30 2018 -0700
@@ -28,11 +28,11 @@
 #include "hb-open-type-private.hh"
 
 /*
- * Color Palette
- * http://www.microsoft.com/typography/otspec/colr.htm
+ * COLR -- Color
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
  */
+#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
 
-#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
 
 namespace OT {
 
@@ -48,8 +48,8 @@
   }
 
   protected:
-  GlyphID gID;                  /* Glyph ID of layer glyph */
-  HBUINT16 paletteIndex;        /* Index value to use with a selected color palette */
+  GlyphID       glyphid;        /* Glyph ID of layer glyph */
+  HBUINT16      colorIdx;       /* Index value to use with a selected color palette */
   public:
   DEFINE_SIZE_STATIC (4);
 };
@@ -61,17 +61,28 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  inline int cmp (hb_codepoint_t g) const {
+    return g < glyphid ? -1 : g > glyphid ? 1 : 0;
   }
 
   protected:
-  GlyphID gID;                  /* Glyph ID of reference glyph */
-  HBUINT16 firstLayerIndex;     /* Index to the layer record */
-  HBUINT16 numLayers;           /* Number of color layers associated with this glyph */
+  GlyphID       glyphid;        /* Glyph ID of reference glyph */
+  HBUINT16      firstLayerIdx;  /* Index to the layer record */
+  HBUINT16      numLayers;      /* Number of color layers associated with this glyph */
   public:
   DEFINE_SIZE_STATIC (6);
 };
 
+static int compare_bgr (const void *pa, const void *pb)
+{
+  const hb_codepoint_t *a = (const hb_codepoint_t *) pa;
+  const BaseGlyphRecord *b = (const BaseGlyphRecord *) pb;
+  return b->cmp (*a);
+}
+
 struct COLR
 {
   static const hb_tag_t tableTag = HB_OT_TAG_COLR;
@@ -79,59 +90,50 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!(c->check_struct (this) &&
-        c->check_array ((const void*) &layerRecordsOffsetZ, sizeof (LayerRecord), numLayerRecords) &&
-        c->check_array ((const void*) &baseGlyphRecordsZ, sizeof (BaseGlyphRecord), numBaseGlyphRecords)))
-      return_trace (false);
-
-    const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this);
-    for (unsigned int i = 0; i < numBaseGlyphRecords; ++i)
-      if (base_glyph_records[i].firstLayerIndex +
-          base_glyph_records[i].numLayers > numLayerRecords)
-        return_trace (false);
-
-    return_trace (true);
+    return_trace (likely (c->check_struct (this) &&
+                          (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
+                          (this+layersZ).sanitize (c, numLayers)));
   }
 
-  inline bool get_base_glyph_record (
-    hb_codepoint_t glyph_id, unsigned int &first_layer, unsigned int &num_layers) const
+  inline bool get_base_glyph_record (hb_codepoint_t glyph_id,
+                                     unsigned int *first_layer /* OUT */,
+                                     unsigned int *num_layers /* OUT */) const
   {
-    const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this);
-    unsigned int min = 0, max = numBaseGlyphRecords - 1;
-    while (min <= max)
-    {
-      unsigned int mid = (min + max) / 2;
-      hb_codepoint_t gID = base_glyph_records[mid].gID;
-      if (gID > glyph_id)
-        max = mid - 1;
-      else if (gID < glyph_id)
-        min = mid + 1;
-      else
-      {
-        first_layer = base_glyph_records[mid].firstLayerIndex;
-        num_layers = base_glyph_records[mid].numLayers;
-        return true;
-      }
-    }
-    return false;
+    const BaseGlyphRecord* record;
+    record = (BaseGlyphRecord *) bsearch (&glyph_id, &(this+baseGlyphsZ), numBaseGlyphs,
+                                          sizeof (BaseGlyphRecord), compare_bgr);
+    if (unlikely (!record))
+      return false;
+
+    *first_layer = record->firstLayerIdx;
+    *num_layers = record->numLayers;
+    return true;
   }
 
-  inline void get_layer_record (int layer,
-    hb_codepoint_t &glyph_id, unsigned int &palette_index) const
+  inline bool get_layer_record (unsigned int record,
+                                hb_codepoint_t *glyph_id /* OUT */,
+                                unsigned int *palette_index /* OUT */) const
   {
-    const LayerRecord* records = &layerRecordsOffsetZ (this);
-    glyph_id = records[layer].gID;
-    palette_index = records[layer].paletteIndex;
+    if (unlikely (record >= numLayers))
+    {
+      *glyph_id = 0;
+      *palette_index = 0xFFFF;
+      return false;
+    }
+    const LayerRecord &layer = (this+layersZ)[record];
+    *glyph_id = layer.glyphid;
+    *palette_index = layer.colorIdx;
+    return true;
   }
 
   protected:
-  HBUINT16      version;                /* Table version number */
-  HBUINT16      numBaseGlyphRecords;    /* Number of Base Glyph Records */
-  LOffsetTo<BaseGlyphRecord>
-                baseGlyphRecordsZ;      /* Offset to Base Glyph records. */
-  LOffsetTo<LayerRecord>
-                layerRecordsOffsetZ;    /* Offset to Layer Records */
-  HBUINT16      numLayerRecords;        /* Number of Layer Records */
+  HBUINT16      version;        /* Table version number */
+  HBUINT16      numBaseGlyphs;  /* Number of Base Glyph Records */
+  LOffsetTo<UnsizedArrayOf<BaseGlyphRecord> >
+                baseGlyphsZ;    /* Offset to Base Glyph records. */
+  LOffsetTo<UnsizedArrayOf<LayerRecord> >
+                layersZ;        /* Offset to Layer Records */
+  HBUINT16      numLayers;      /* Number of Layer Records */
   public:
   DEFINE_SIZE_STATIC (14);
 };