[color] Minimal API for COLR/CPAL

This commit is contained in:
Khaled Hosny 2018-05-01 17:16:46 +02:00
parent 0229eaea29
commit d4e928b142
11 changed files with 253 additions and 136 deletions

View File

@ -170,6 +170,7 @@ HB_OT_RAGEL_sources = \
HB_OT_headers = \ HB_OT_headers = \
hb-ot.h \ hb-ot.h \
hb-ot-color.h \
hb-ot-font.h \ hb-ot-font.h \
hb-ot-layout.h \ hb-ot-layout.h \
hb-ot-math.h \ hb-ot-math.h \

View File

@ -83,13 +83,21 @@ static void svg_callback (const uint8_t* data, unsigned int length,
fclose (f); fclose (f);
} }
static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upem, unsigned int num_glyphs, static void colr_cpal_rendering (hb_face_t *face, cairo_font_face_t *cairo_face)
const OT::COLR *colr, const OT::CPAL *cpal)
{ {
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; unsigned int num_layers = hb_ot_color_get_color_layers (face, gid, 0, nullptr, nullptr, nullptr);
if (colr->get_base_glyph_record (i, &first_layer_index, &num_layers)) 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 // Measure
cairo_text_extents_t extents; 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)); cairo_glyph_t *glyphs = (cairo_glyph_t *) calloc (num_layers, sizeof (cairo_glyph_t));
for (unsigned int j = 0; j < num_layers; ++j) for (unsigned int j = 0; j < num_layers; ++j)
{ glyphs[j].index = layer_gids[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;
}
cairo_glyph_extents (cr, glyphs, num_layers, &extents); cairo_glyph_extents (cr, glyphs, num_layers, &extents);
free (glyphs); free (glyphs);
cairo_surface_destroy (surface); cairo_surface_destroy (surface);
@ -120,28 +123,34 @@ static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upe
extents.y_bearing -= extents.height / 20; extents.y_bearing -= extents.height / 20;
// Render // 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) { for (unsigned int pallet = 0; pallet < pallet_count; ++pallet) {
char output_path[255]; char output_path[255];
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 we have more than one pallet, use a better namin
if (pallet_count == 1) if (pallet_count == 1)
sprintf (output_path, "out/colr-%d.svg", i); sprintf (output_path, "out/colr-%d.svg", gid);
else else
sprintf (output_path, "out/colr-%d-%d.svg", i, pallet); 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_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
cairo_t *cr = cairo_create (surface); cairo_t *cr = cairo_create (surface);
cairo_set_font_face (cr, cairo_face); cairo_set_font_face (cr, cairo_face);
cairo_set_font_size (cr, upem); cairo_set_font_size (cr, upem);
for (unsigned int j = 0; j < num_layers; ++j) for (unsigned int layer = 0; layer < num_layers; ++layer)
{ {
hb_codepoint_t glyph_id; uint32_t color = 0xFF;
unsigned int color_index; if (color_indices[layer] != 0xFFFF)
colr->get_layer_record (first_layer_index + j, &glyph_id, &color_index); color = colors[color_indices[layer]];
uint32_t color = cpal->get_color_record_argb (color_index, pallet);
int alpha = color & 0xFF; int alpha = color & 0xFF;
int r = (color >> 8) & 0xFF; int r = (color >> 8) & 0xFF;
int g = (color >> 16) & 0xFF; int g = (color >> 16) & 0xFF;
@ -149,7 +158,7 @@ static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upe
cairo_set_source_rgba (cr, r / 255., g / 255., b / 255., alpha); cairo_set_source_rgba (cr, r / 255., g / 255., b / 255., alpha);
cairo_glyph_t glyph; cairo_glyph_t glyph;
glyph.index = glyph_id; glyph.index = layer_gids[layer];
glyph.x = -extents.x_bearing; glyph.x = -extents.x_bearing;
glyph.y = -extents.y_bearing; glyph.y = -extents.y_bearing;
cairo_show_glyphs (cr, &glyph, 1); cairo_show_glyphs (cr, &glyph, 1);
@ -158,8 +167,13 @@ static void colr_cpal_rendering (cairo_font_face_t *cairo_face, unsigned int upe
cairo_surface_destroy (surface); cairo_surface_destroy (surface);
cairo_destroy (cr); cairo_destroy (cr);
} }
free (colors);
} }
} }
free (layer_gids);
free (color_indices);
}
} }
static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem, static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
@ -228,7 +242,7 @@ int main (int argc, char **argv)
font_name_file = fopen ("out/_font_name_file.txt", "w"); font_name_file = fopen ("out/_font_name_file.txt", "w");
if (font_name_file == nullptr) 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); exit (1);
} }
fwrite (argv[1], 1, strlen (argv[1]), font_name_file); 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.dump (svg_callback);
svg.fini (); 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; cairo_font_face_t *cairo_face;
{ {
FT_Library library; 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 num_glyphs = hb_face_get_glyph_count (face);
unsigned int upem = hb_face_get_upem (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); dump_glyphs (cairo_face, upem, num_glyphs);

View File

@ -105,24 +105,24 @@ struct COLR
if (unlikely (!record)) if (unlikely (!record))
return false; return false;
*first_layer = record->firstLayerIdx; if (first_layer) *first_layer = record->firstLayerIdx;
*num_layers = record->numLayers; if (num_layers) *num_layers = record->numLayers;
return true; return true;
} }
inline bool get_layer_record (unsigned int record, inline bool get_layer_record (unsigned int record,
hb_codepoint_t *glyph_id /* OUT */, hb_codepoint_t *glyph_id /* OUT */,
unsigned int *palette_index /* OUT */) const unsigned int *color_index /* OUT */) const
{ {
if (unlikely (record >= numLayers)) if (unlikely (record >= numLayers))
{ {
*glyph_id = 0; *glyph_id = 0;
*palette_index = 0xFFFF; *color_index = 0xFFFF;
return false; return false;
} }
const LayerRecord &layer = (this+layersZ)[record]; const LayerRecord &layer = (this+layersZ)[record];
*glyph_id = layer.glyphid; if (glyph_id) *glyph_id = layer.glyphid;
*palette_index = layer.colorIdx; if (color_index) *color_index = layer.colorIdx;
return true; return true;
} }

View File

@ -29,21 +29,13 @@
#define HB_OT_COLOR_CPAL_TABLE_HH #define HB_OT_COLOR_CPAL_TABLE_HH
#include "hb-open-type.hh" #include "hb-open-type.hh"
#include "hb-ot-color.h"
/* /*
* Following parts to be moved to a public header. * Following parts to be moved to a public header.
*/ */
/**
* 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_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_DEFAULT: default indicating that there is nothing special to note about a color palette.
@ -58,32 +50,6 @@ typedef enum { /*< flags >*/
HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u, HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u,
} hb_ot_color_palette_flags_t; } 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 { namespace OT {
@ -189,15 +155,22 @@ struct CPAL
return numPalettes; return numPalettes;
} }
inline hb_ot_color_t inline unsigned int get_palette_entries_count () const
get_color_record_argb (unsigned int color_index, unsigned int palette) 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)) if (unlikely (color_index >= numPaletteEntries || palette >= numPalettes))
return 0; return false;
// No need for more range check as it is already done on #sanitize // No need for more range check as it is already done on #sanitize
const UnsizedArrayOf<BGRAColor>& color_records = this+colorRecordsZ; 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: protected:

View File

@ -28,33 +28,45 @@
#include "hb-open-type.hh" #include "hb-open-type.hh"
#include "hb-ot-color-colr-table.hh" #include "hb-ot-color-colr-table.hh"
#include "hb-ot-color-cpal-table.hh" #include "hb-ot-color-cpal-table.hh"
#include "hb-ot-face.hh"
#include "hb-ot.h" #include "hb-ot.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "hb-ot-layout.hh" #include "hb-ot-layout.hh"
#include "hb-shaper.hh"
#if 0 #if 0
HB_MARK_AS_FLAG_T (hb_ot_color_palette_flags_t) HB_MARK_AS_FLAG_T (hb_ot_color_palette_flags_t)
//HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) Hmm? //HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) Hmm?
#endif
static inline const OT::COLR& static inline const OT::COLR&
_get_colr (hb_face_t *face) _get_colr (hb_face_t *face)
{ {
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::COLR); 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& static inline const OT::CPAL&
_get_cpal (hb_face_t *face) _get_cpal (hb_face_t *face)
{ {
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CPAL); 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: * 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 (); return cpal.get_palette_count ();
} }
#if 0
/** /**
* hb_ot_color_get_palette_name_id: * hb_ot_color_get_palette_name_id:
* @face: a font face. * @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); const OT::CPAL& cpal = _get_cpal(face);
return cpal.get_palette_flags (palette); 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 * @color_count: (inout) (optional): on input, how many colors
* can be maximally stored into the @colors array; * can be maximally stored into the @colors array;
* on output, how many colors were actually stored. * 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 * an array of #hb_ot_color_t records. After calling
* this function, @colors will be filled with * this function, @colors will be filled with
* the palette colors. If @colors is NULL, the function * the palette colors. If @colors is NULL, the function
@ -147,35 +160,57 @@ unsigned int
hb_ot_color_get_palette_colors (hb_face_t *face, hb_ot_color_get_palette_colors (hb_face_t *face,
unsigned int palette, /* default=0 */ unsigned int palette, /* default=0 */
unsigned int start_offset, unsigned int start_offset,
unsigned int *color_count /* IN/OUT */, unsigned int *count /* IN/OUT */,
hb_ot_color_t *colors /* OUT */) hb_ot_color_t *colors /* OUT */)
{ {
const OT::CPAL& cpal = _get_cpal(face); 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; return 0;
} }
const OT::ColorRecord* crec = &cpal.offsetFirstColorRecord (&cpal);
crec += cpal.colorRecordIndices[palette];
unsigned int num_results = 0; unsigned int num_results = 0;
if (likely (color_count && colors)) if (count)
{ {
for (unsigned int i = start_offset; unsigned int platte_count = MIN<unsigned int>(*count, cpal.get_palette_entries_count () - start_offset);
i < cpal.numPaletteEntries && num_results < *color_count; ++i) for (unsigned int i = 0; i < platte_count; i++)
{ {
hb_ot_color_t* result = &colors[num_results]; if (cpal.get_color_record_argb(start_offset + i, palette, &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; ++num_results;
} }
} }
if (likely (color_count)) *color_count = num_results; if (likely (count)) *count = num_results;
return cpal.numPaletteEntries; 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;
unsigned int start_layer_index, num_layers = 0;
if (colr.get_base_glyph_record (gid, &start_layer_index, &num_layers))
{
if (count)
{
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 (count)) *count = num_results;
return num_layers;
} }
#endif

85
src/hb-ot-color.h Normal file
View File

@ -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 */

View File

@ -47,6 +47,9 @@
/* OpenType shaping. */ \ /* OpenType shaping. */ \
HB_OT_TABLE(OT, JSTF) \ HB_OT_TABLE(OT, JSTF) \
HB_OT_TABLE(OT, BASE) \ HB_OT_TABLE(OT, BASE) \
/* OpenType color */ \
HB_OT_TABLE(OT, COLR) \
HB_OT_TABLE(OT, CPAL) \
/* AAT shaping. */ \ /* AAT shaping. */ \
HB_OT_TABLE(AAT, morx) \ HB_OT_TABLE(AAT, morx) \
HB_OT_TABLE(AAT, kerx) \ HB_OT_TABLE(AAT, kerx) \

View File

@ -30,6 +30,7 @@
#include "hb.h" #include "hb.h"
#include "hb-ot-color.h"
#include "hb-ot-font.h" #include "hb-ot-font.h"
#include "hb-ot-layout.h" #include "hb-ot-layout.h"
#include "hb-ot-math.h" #include "hb-ot-math.h"

View File

@ -98,27 +98,25 @@ static hb_face_t *cpal_v0 = NULL;
*/ */
static hb_face_t *cpal_v1 = NULL; static hb_face_t *cpal_v1 = NULL;
#if 0
#define assert_color_rgba(colors, i, r, g, b, a) G_STMT_START { \ #define assert_color_rgba(colors, i, r, g, b, a) G_STMT_START { \
const hb_ot_color_t *_colors = (colors); \ const hb_ot_color_t *_colors = (colors); \
const size_t _i = (i); \ const size_t _i = (i); \
const uint8_t red = (r), green = (g), blue = (b), alpha = (a); \ 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, \ 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, \ 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, \ 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, \ 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 } G_STMT_END
@ -132,6 +130,7 @@ test_hb_ot_color_get_palette_count (void)
} }
#if 0
static void static void
test_hb_ot_color_get_palette_name_id_empty (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 */ /* 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); g_assert_cmpint (hb_ot_color_get_palette_flags (cpal_v0, 3), ==, HB_OT_COLOR_PALETTE_FLAG_DEFAULT);
} }
#endif
static void 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, 1, 0x77, 0x77, 0x77, 0x77); /* untouched */
assert_color_rgba (colors, 2, 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 #endif
return hb_face_create (hb_blob_create_from_file (path), 0);
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
int status = 0; int status = 0;
hb_test_init (&argc, &argv); hb_test_init (&argc, &argv);
// cpal_v0 = hb_test_load_face ("../shaping/data/in-house/fonts/e90374e5e439e00725b4fe7a8d73db57c5a97f82.ttf"); cpal_v0 = open_font ("fonts/cpal-v0.ttf");
// cpal_v1 = hb_test_load_face ("../shaping/data/in-house/fonts/319f5d7ebffbefc5c5e6569f8cea73444d7a7268.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_count);
// hb_test_add (test_hb_ot_color_get_palette_name_id_empty); // 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_v0);
// hb_test_add (test_hb_ot_color_get_palette_name_id_v1); // 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_empty);
// hb_test_add (test_hb_ot_color_get_palette_flags_v0); // 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_flags_v1);
// hb_test_add (test_hb_ot_color_get_palette_colors_empty); 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_v0);
// hb_test_add (test_hb_ot_color_get_palette_colors_v1); hb_test_add (test_hb_ot_color_get_palette_colors_v1);
status = hb_test_run(); status = hb_test_run();
hb_face_destroy (cpal_v0); hb_face_destroy (cpal_v0);
hb_face_destroy (cpal_v1); hb_face_destroy (cpal_v1);