[color] Minimal API for COLR/CPAL
authorKhaled Hosny <khaledhosny@eglug.org>
Tue, 1 May 2018 15:16:46 +0000 (17:16 +0200)
committerKhaled Hosny <khaledhosny@eglug.org>
Mon, 22 Oct 2018 08:17:31 +0000 (10:17 +0200)
src/Makefile.sources
src/dump-emoji.cc
src/hb-ot-color-colr-table.hh
src/hb-ot-color-cpal-table.hh
src/hb-ot-color.cc
src/hb-ot-color.h [new file with mode: 0644]
src/hb-ot-face.hh
src/hb-ot.h
test/api/fonts/cpal-v0.ttf [moved from test/shaping/data/in-house/fonts/e90374e5e439e00725b4fe7a8d73db57c5a97f82.ttf with 100% similarity]
test/api/fonts/cpal-v1.ttf [moved from test/shaping/data/in-house/fonts/319f5d7ebffbefc5c5e6569f8cea73444d7a7268.ttf with 100% similarity]
test/api/test-ot-color.c

index 59cde6b..93965ac 100644 (file)
@@ -170,6 +170,7 @@ HB_OT_RAGEL_sources = \
 
 HB_OT_headers = \
        hb-ot.h \
+       hb-ot-color.h \
        hb-ot-font.h \
        hb-ot-layout.h \
        hb-ot-math.h \
index f45bc31..fe4dd4c 100644 (file)
@@ -83,13 +83,21 @@ static void svg_callback (const uint8_t* data, unsigned int length,
   fclose (f);
 }
 
-static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs,
-                                const OT::COLR *colr, const OT::CPAL *cpal)
+static void colr_cpal_rendering (hb_face_t *face, cairo_font_face_t *cairo_face)
 {
-  for (unsigned int i = 0; i < num_glyphs; ++i)
+  unsigned int upem = hb_face_get_upem (face);
+
+  for (hb_codepoint_t gid = 0; gid < hb_face_get_glyph_count (face); ++gid)
   {
-    unsigned int first_layer_index, num_layers;
-    if (colr->get_base_glyph_record (i, &first_layer_index, &num_layers))
+    unsigned int num_layers = hb_ot_color_get_color_layers (face, gid, 0, nullptr, nullptr, nullptr);
+    if (!num_layers)
+      continue;
+
+    hb_codepoint_t *layer_gids = (hb_codepoint_t*) calloc (num_layers, sizeof (hb_codepoint_t));
+    unsigned int *color_indices = (unsigned int*) calloc (num_layers, sizeof (unsigned int));
+
+    hb_ot_color_get_color_layers (face, gid, 0, &num_layers, layer_gids, color_indices);
+    if (num_layers)
     {
       // Measure
       cairo_text_extents_t extents;
@@ -101,12 +109,7 @@ static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upe
 
        cairo_glyph_t *glyphs = (cairo_glyph_t *) calloc (num_layers, sizeof (cairo_glyph_t));
        for (unsigned int j = 0; j < num_layers; ++j)
-       {
-         hb_codepoint_t glyph_id;
-         unsigned int color_index;
-         colr->get_layer_record (first_layer_index + j, &glyph_id, &color_index);
-         glyphs[j].index = glyph_id;
-       }
+         glyphs[j].index = layer_gids[j];
        cairo_glyph_extents (cr, glyphs, num_layers, &extents);
        free (glyphs);
        cairo_surface_destroy (surface);
@@ -120,45 +123,56 @@ static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upe
       extents.y_bearing -= extents.height / 20;
 
       // Render
-      unsigned int pallet_count = cpal->get_palette_count ();
+      unsigned int pallet_count = hb_ot_color_get_palette_count (face);
       for (unsigned int pallet = 0; pallet < pallet_count; ++pallet) {
        char output_path[255];
 
-       // If we have more than one pallet, use a better namin
-       if (pallet_count == 1)
-         sprintf (output_path, "out/colr-%d.svg", i);
-       else
-         sprintf (output_path, "out/colr-%d-%d.svg", i, pallet);
-
-       cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
-       cairo_t *cr = cairo_create (surface);
-       cairo_set_font_face (cr, cairo_face);
-       cairo_set_font_size (cr, upem);
-
-       for (unsigned int j = 0; j < num_layers; ++j)
-       {
-         hb_codepoint_t glyph_id;
-         unsigned int color_index;
-         colr->get_layer_record (first_layer_index + j, &glyph_id, &color_index);
-
-         uint32_t color = cpal->get_color_record_argb (color_index, pallet);
-         int alpha = color & 0xFF;
-         int r = (color >> 8) & 0xFF;
-         int g = (color >> 16) & 0xFF;
-         int b = (color >> 24) & 0xFF;
-         cairo_set_source_rgba (cr, r / 255., g / 255., b / 255., alpha);
-
-         cairo_glyph_t glyph;
-         glyph.index = glyph_id;
-         glyph.x = -extents.x_bearing;
-         glyph.y = -extents.y_bearing;
-         cairo_show_glyphs (cr, &glyph, 1);
-       }
-
-       cairo_surface_destroy (surface);
-       cairo_destroy (cr);
+        unsigned int num_colors = hb_ot_color_get_palette_colors (face, pallet, 0, nullptr, nullptr);
+        if (!num_colors)
+          continue;
+
+        hb_ot_color_t *colors = (hb_ot_color_t*) calloc (num_colors, sizeof (hb_ot_color_t));
+        hb_ot_color_get_palette_colors (face, pallet, 0, &num_colors, colors);
+        if (num_colors)
+        {
+         // If we have more than one pallet, use a better namin
+         if (pallet_count == 1)
+           sprintf (output_path, "out/colr-%d.svg", gid);
+         else
+           sprintf (output_path, "out/colr-%d-%d.svg", gid, pallet);
+
+         cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
+         cairo_t *cr = cairo_create (surface);
+         cairo_set_font_face (cr, cairo_face);
+         cairo_set_font_size (cr, upem);
+
+         for (unsigned int layer = 0; layer < num_layers; ++layer)
+         {
+           uint32_t color = 0xFF;
+            if (color_indices[layer] != 0xFFFF)
+             color = colors[color_indices[layer]];
+           int alpha = color & 0xFF;
+           int r = (color >> 8) & 0xFF;
+           int g = (color >> 16) & 0xFF;
+           int b = (color >> 24) & 0xFF;
+           cairo_set_source_rgba (cr, r / 255., g / 255., b / 255., alpha);
+
+           cairo_glyph_t glyph;
+           glyph.index = layer_gids[layer];
+           glyph.x = -extents.x_bearing;
+           glyph.y = -extents.y_bearing;
+           cairo_show_glyphs (cr, &glyph, 1);
+         }
+
+         cairo_surface_destroy (surface);
+         cairo_destroy (cr);
+        }
+        free (colors);
       }
     }
+
+    free (layer_gids);
+    free (color_indices);
   }
 }
 
@@ -228,7 +242,7 @@ int main (int argc, char **argv)
   font_name_file = fopen ("out/_font_name_file.txt", "w");
   if (font_name_file == nullptr)
   {
-    fprintf (stderr, "./out is not accessible, create it please\n");
+    fprintf (stderr, "./out is not accessible as a folder, create it please\n");
     exit (1);
   }
   fwrite (argv[1], 1, strlen (argv[1]), font_name_file);
@@ -253,12 +267,6 @@ int main (int argc, char **argv)
   svg.dump (svg_callback);
   svg.fini ();
 
-  hb_blob_t* colr_blob = hb_sanitize_context_t ().reference_table<OT::COLR> (face);
-  const OT::COLR *colr = colr_blob->as<OT::COLR> ();
-
-  hb_blob_t* cpal_blob = hb_sanitize_context_t ().reference_table<OT::CPAL> (face);
-  const OT::CPAL *cpal = cpal_blob->as<OT::CPAL> ();
-
   cairo_font_face_t *cairo_face;
   {
     FT_Library library;
@@ -269,7 +277,7 @@ int main (int argc, char **argv)
   }
   unsigned int num_glyphs = hb_face_get_glyph_count (face);
   unsigned int upem = hb_face_get_upem (face);
-  colr_cpal_rendering (cairo_face, upem, num_glyphs, colr, cpal);
+  colr_cpal_rendering (face, cairo_face);
   dump_glyphs (cairo_face, upem, num_glyphs);
 
 
index a59d2bf..b185968 100644 (file)
@@ -105,24 +105,24 @@ struct COLR
     if (unlikely (!record))
       return false;
 
-    *first_layer = record->firstLayerIdx;
-    *num_layers = record->numLayers;
+    if (first_layer) *first_layer = record->firstLayerIdx;
+    if (num_layers) *num_layers = record->numLayers;
     return true;
   }
 
   inline bool get_layer_record (unsigned int record,
                                hb_codepoint_t *glyph_id /* OUT */,
-                               unsigned int *palette_index /* OUT */) const
+                               unsigned int *color_index /* OUT */) const
   {
     if (unlikely (record >= numLayers))
     {
       *glyph_id = 0;
-      *palette_index = 0xFFFF;
+      *color_index = 0xFFFF;
       return false;
     }
     const LayerRecord &layer = (this+layersZ)[record];
-    *glyph_id = layer.glyphid;
-    *palette_index = layer.colorIdx;
+    if (glyph_id) *glyph_id = layer.glyphid;
+    if (color_index) *color_index = layer.colorIdx;
     return true;
   }
 
index e354ced..02b9336 100644 (file)
@@ -29,6 +29,7 @@
 #define HB_OT_COLOR_CPAL_TABLE_HH
 
 #include "hb-open-type.hh"
+#include "hb-ot-color.h"
 
 
 /*
  */
 
 /**
- * hb_ot_color_t:
- * ARGB data type for holding color values.
- *
- * Since: REPLACEME
- */
-typedef uint32_t hb_ot_color_t;
-
-
-/**
  * hb_ot_color_palette_flags_t:
  * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special to note about a color palette.
  * @HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND: flag indicating that the color palette is suitable for rendering text on light background.
@@ -58,32 +50,6 @@ typedef enum { /*< flags >*/
   HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u,
 } hb_ot_color_palette_flags_t;
 
-// HB_EXTERN unsigned int
-// hb_ot_color_get_palette_count (hb_face_t *face);
-
-// HB_EXTERN unsigned int
-// hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette);
-
-// HB_EXTERN hb_ot_color_palette_flags_t
-// hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette);
-
-// HB_EXTERN unsigned int
-// hb_ot_color_get_palette_colors (hb_face_t       *face,
-//                             unsigned int     palette, /* default=0 */
-//                             unsigned int     start_offset,
-//                             unsigned int    *color_count /* IN/OUT */,
-//                             hb_ot_color_t   *colors /* OUT */);
-
-
-
-
-
-/*
- * CPAL -- Color Palette
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
- */
-#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
-
 
 namespace OT {
 
@@ -189,15 +155,22 @@ struct CPAL
     return numPalettes;
   }
 
-  inline hb_ot_color_t
-  get_color_record_argb (unsigned int color_index, unsigned int palette) const
+  inline unsigned int get_palette_entries_count () const
+  {
+    return numPaletteEntries;
+  }
+
+  bool
+  get_color_record_argb (unsigned int color_index, unsigned int palette, hb_ot_color_t* color) const
   {
     if (unlikely (color_index >= numPaletteEntries || palette >= numPalettes))
-      return 0;
+      return false;
 
     // No need for more range check as it is already done on #sanitize
     const UnsizedArrayOf<BGRAColor>& color_records = this+colorRecordsZ;
-    return color_records[colorRecordIndicesZ[palette] + color_index];
+    if (color)
+      *color = color_records[colorRecordIndicesZ[palette] + color_index];
+    return true;
   }
 
   protected:
index 7cdff38..e2d502c 100644 (file)
 #include "hb-open-type.hh"
 #include "hb-ot-color-colr-table.hh"
 #include "hb-ot-color-cpal-table.hh"
+#include "hb-ot-face.hh"
 #include "hb-ot.h"
 
 #include <stdlib.h>
 #include <string.h>
 
 #include "hb-ot-layout.hh"
-#include "hb-shaper.hh"
 
 #if 0
 HB_MARK_AS_FLAG_T (hb_ot_color_palette_flags_t)
 //HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) Hmm?
+#endif
 
 
 static inline const OT::COLR&
 _get_colr (hb_face_t *face)
 {
   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::COLR);
-  return *(hb_ot_face_data (face)->colr.get ());
+  return *(hb_ot_face_data (face)->COLR.get ());
 }
 
 static inline const OT::CPAL&
 _get_cpal (hb_face_t *face)
 {
   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CPAL);
-  return *(hb_ot_face_data (face)->cpal.get ());
+  return *(hb_ot_face_data (face)->CPAL.get ());
 }
 
+HB_EXTERN hb_bool_t
+hb_ot_color_has_cpal_data (hb_face_t *face)
+{
+  return &_get_cpal (face) != &OT::Null(OT::CPAL);
+}
+
+HB_EXTERN hb_bool_t
+hb_ot_color_has_colr_data (hb_face_t *face)
+{
+  return &_get_colr (face) != &OT::Null(OT::COLR);
+}
 
 /**
  * hb_ot_color_get_palette_count:
@@ -72,7 +84,7 @@ hb_ot_color_get_palette_count (hb_face_t *face)
   return cpal.get_palette_count ();
 }
 
-
+#if 0
 /**
  * hb_ot_color_get_palette_name_id:
  * @face: a font face.
@@ -114,6 +126,7 @@ hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette)
   const OT::CPAL& cpal = _get_cpal(face);
   return cpal.get_palette_flags (palette);
 }
+#endif
 
 
 /**
@@ -125,7 +138,7 @@ hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette)
  * @color_count:  (inout) (optional): on input, how many colors
  *                can be maximally stored into the @colors array;
  *                on output, how many colors were actually stored.
- * @colors: (array length=color_count) (optional):
+ * @colors: (array length=color_count) (out) (optional):
  *                an array of #hb_ot_color_t records. After calling
  *                this function, @colors will be filled with
  *                the palette colors. If @colors is NULL, the function
@@ -144,38 +157,60 @@ hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette)
  * Since: REPLACEME
  */
 unsigned int
-hb_ot_color_get_palette_colors (hb_face_t       *face,
-                               unsigned int     palette, /* default=0 */
-                               unsigned int     start_offset,
-                               unsigned int    *color_count /* IN/OUT */,
-                               hb_ot_color_t   *colors /* OUT */)
+hb_ot_color_get_palette_colors (hb_face_t      *face,
+                               unsigned int    palette, /* default=0 */
+                               unsigned int    start_offset,
+                               unsigned int   *count /* IN/OUT */,
+                               hb_ot_color_t  *colors /* OUT */)
 {
   const OT::CPAL& cpal = _get_cpal(face);
-  if (unlikely (palette >= cpal.numPalettes))
+  if (unlikely (palette >= cpal.get_palette_count ()))
   {
-    if (color_count) *color_count = 0;
+    if (count) *count = 0;
     return 0;
   }
 
-  const OT::ColorRecord* crec = &cpal.offsetFirstColorRecord (&cpal);
-  crec += cpal.colorRecordIndices[palette];
+  unsigned int num_results = 0;
+  if (count)
+  {
+    unsigned int platte_count = MIN<unsigned int>(*count, cpal.get_palette_entries_count () - start_offset);
+    for (unsigned int i = 0; i < platte_count; i++)
+    {
+      if (cpal.get_color_record_argb(start_offset + i, palette, &colors[num_results]))
+        ++num_results;
+    }
+  }
 
+  if (likely (count)) *count = num_results;
+  return cpal.get_palette_entries_count ();
+}
+
+unsigned int
+hb_ot_color_get_color_layers (hb_face_t        *face,
+                             hb_codepoint_t    gid,
+                             unsigned int      start_offset,
+                             unsigned int     *count,        /* IN/OUT.  May be NULL. */
+                             hb_codepoint_t   *gids,         /* OUT.     May be NULL. */
+                             unsigned int     *color_indices /* OUT.     May be NULL. */)
+{
+  const OT::COLR& colr = _get_colr (face);
   unsigned int num_results = 0;
-  if (likely (color_count && colors))
+  unsigned int start_layer_index, num_layers = 0;
+  if (colr.get_base_glyph_record (gid, &start_layer_index, &num_layers))
   {
-    for (unsigned int i = start_offset;
-        i < cpal.numPaletteEntries && num_results < *color_count; ++i)
+    if (count)
     {
-      hb_ot_color_t* result = &colors[num_results];
-      result->red = crec[i].red;
-      result->green = crec[i].green;
-      result->blue = crec[i].blue;
-      result->alpha = crec[i].alpha;
-      ++num_results;
+      unsigned int layer_count = MIN<unsigned int>(*count, num_layers - start_offset);
+      printf ("%d ", *count);
+      for (unsigned int i = 0; i < layer_count; i++)
+      {
+       if (colr.get_layer_record (start_layer_index + start_offset + i,
+                                  &gids[num_results], &color_indices[num_results]))
+         ++num_results;
+      }
     }
   }
 
-  if (likely (color_count)) *color_count = num_results;
-  return cpal.numPaletteEntries;
+  if (likely (count)) *count = num_results;
+  return num_layers;
 }
-#endif
diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h
new file mode 100644 (file)
index 0000000..5b9e5aa
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2016  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Sascha Brawer
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_COLOR_H
+#define HB_OT_COLOR_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+/*
+ * CPAL -- Color Palette
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
+ */
+#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
+
+/**
+ * hb_ot_color_t:
+ * ARGB data type for holding color values.
+ *
+ * Since: REPLACEME
+ */
+typedef uint32_t hb_ot_color_t;
+
+HB_EXTERN hb_bool_t
+hb_ot_color_has_cpal_data (hb_face_t *face);
+
+HB_EXTERN hb_bool_t
+hb_ot_color_has_colr_data (hb_face_t *face);
+
+HB_EXTERN unsigned int
+hb_ot_color_get_palette_count (hb_face_t *face);
+
+// HB_EXTERN unsigned int
+// hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette);
+
+// HB_EXTERN hb_ot_color_palette_flags_t
+// hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette);
+
+HB_EXTERN unsigned int
+hb_ot_color_get_palette_colors (hb_face_t      *face,
+                               unsigned int    palette, /* default=0 */
+                               unsigned int    start_offset,
+                               unsigned int   *color_count /* IN/OUT */,
+                               hb_ot_color_t  *colors /* OUT */);
+
+
+HB_EXTERN unsigned int
+hb_ot_color_get_color_layers (hb_face_t       *face,
+                              hb_codepoint_t   gid,
+                              unsigned int     offset,
+                              unsigned int    *count, /* IN/OUT */
+                              hb_codepoint_t  *gids, /* OUT */
+                              unsigned int    *color_indices /* OUT */);
+
+HB_END_DECLS
+
+#endif /* HB_OT_COLOR_H */
index e305922..441b8dc 100644 (file)
@@ -47,6 +47,9 @@
     /* OpenType shaping. */ \
     HB_OT_TABLE(OT, JSTF) \
     HB_OT_TABLE(OT, BASE) \
+    /* OpenType color */ \
+    HB_OT_TABLE(OT, COLR) \
+    HB_OT_TABLE(OT, CPAL) \
     /* AAT shaping. */ \
     HB_OT_TABLE(AAT, morx) \
     HB_OT_TABLE(AAT, kerx) \
index 4b6e3cf..47508d6 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "hb.h"
 
+#include "hb-ot-color.h"
 #include "hb-ot-font.h"
 #include "hb-ot-layout.h"
 #include "hb-ot-math.h"
index 254f015..d02144c 100644 (file)
@@ -98,27 +98,25 @@ static hb_face_t *cpal_v0 = NULL;
 */
 static hb_face_t *cpal_v1 = NULL;
 
-
-#if 0
 #define assert_color_rgba(colors, i, r, g, b, a) G_STMT_START {        \
   const hb_ot_color_t *_colors = (colors); \
   const size_t _i = (i); \
   const uint8_t red = (r), green = (g), blue = (b), alpha = (a); \
-  if (_colors[_i].red != red) { \
+  if ((_colors[_i] >> 16 & 0xff) != red) { \
     g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
-                               "colors[" #i "].red", _colors[_i].red, "==", red, 'x'); \
+                               "colors[" #i "]", _colors[_i], "==", red, 'x'); \
   } \
-  if (_colors[_i].green != green) { \
+  if ((_colors[_i] >> 8 & 0xff) != green) { \
     g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
-                               "colors[" #i "].green", _colors[_i].green, "==", green, 'x'); \
+                               "colors[" #i "]", _colors[_i], "==", green, 'x'); \
   } \
-  if (_colors[_i].blue != blue) { \
+  if ((_colors[_i] & 0xff) != blue) { \
     g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
-                               "colors[" #i "].blue", colors[i].blue, "==", blue, 'x'); \
+                               "colors[" #i "]", colors[_i], "==", blue, 'x'); \
   } \
-  if (_colors[_i].alpha != alpha) { \
+  if ((_colors[_i] >> 24 & 0xff) != alpha) { \
     g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
-                               "colors[" #i "].alpha", _colors[_i].alpha, "==", alpha, 'x'); \
+                               "colors[" #i "]", _colors[_i], "==", alpha, 'x'); \
   } \
 } G_STMT_END
 
@@ -132,6 +130,7 @@ test_hb_ot_color_get_palette_count (void)
 }
 
 
+#if 0
 static void
 test_hb_ot_color_get_palette_name_id_empty (void)
 {
@@ -193,6 +192,7 @@ test_hb_ot_color_get_palette_flags_v1 (void)
   /* numPalettes=3, so palette #3 is out of bounds */
   g_assert_cmpint (hb_ot_color_get_palette_flags (cpal_v0, 3), ==, HB_OT_COLOR_PALETTE_FLAG_DEFAULT);
 }
+#endif
 
 
 static void
@@ -292,26 +292,37 @@ test_hb_ot_color_get_palette_colors_v1 (void)
   assert_color_rgba (colors, 1, 0x77, 0x77, 0x77, 0x77);  /* untouched */
   assert_color_rgba (colors, 2, 0x77, 0x77, 0x77, 0x77);  /* untouched */
 }
+
+static inline hb_face_t *
+open_font (const char *font_path)
+{
+#if GLIB_CHECK_VERSION(2,37,2)
+  char* path = g_test_build_filename(G_TEST_DIST, font_path, NULL);
+#else
+  char* path = g_strdup(font_path);
 #endif
 
+  return hb_face_create (hb_blob_create_from_file (path), 0);
+}
+
 int
 main (int argc, char **argv)
 {
   int status = 0;
 
   hb_test_init (&argc, &argv);
-  // cpal_v0 = hb_test_load_face ("../shaping/data/in-house/fonts/e90374e5e439e00725b4fe7a8d73db57c5a97f82.ttf");
-  // cpal_v1 = hb_test_load_face ("../shaping/data/in-house/fonts/319f5d7ebffbefc5c5e6569f8cea73444d7a7268.ttf");
-  // hb_test_add (test_hb_ot_color_get_palette_count);
+  cpal_v0 = open_font ("fonts/cpal-v0.ttf");
+  cpal_v1 = open_font ("fonts/cpal-v1.ttf");
+  hb_test_add (test_hb_ot_color_get_palette_count);
   // hb_test_add (test_hb_ot_color_get_palette_name_id_empty);
   // hb_test_add (test_hb_ot_color_get_palette_name_id_v0);
   // hb_test_add (test_hb_ot_color_get_palette_name_id_v1);
   // hb_test_add (test_hb_ot_color_get_palette_flags_empty);
   // hb_test_add (test_hb_ot_color_get_palette_flags_v0);
   // hb_test_add (test_hb_ot_color_get_palette_flags_v1);
-  // hb_test_add (test_hb_ot_color_get_palette_colors_empty);
-  // hb_test_add (test_hb_ot_color_get_palette_colors_v0);
-  // hb_test_add (test_hb_ot_color_get_palette_colors_v1);
+  hb_test_add (test_hb_ot_color_get_palette_colors_empty);
+  hb_test_add (test_hb_ot_color_get_palette_colors_v0);
+  hb_test_add (test_hb_ot_color_get_palette_colors_v1);
   status = hb_test_run();
   hb_face_destroy (cpal_v0);
   hb_face_destroy (cpal_v1);