[CPAL] Add palette entry and enable palette flag API

This commit is contained in:
Ebrahim Byagowi 2018-10-21 09:44:16 +03:30 committed by Khaled Hosny
parent d4261b4bb6
commit b8ee3a0ec8
4 changed files with 159 additions and 76 deletions

View File

@ -48,32 +48,47 @@ struct CPALV1Tail
friend struct CPAL; friend struct CPAL;
inline bool inline bool
sanitize (hb_sanitize_context_t *c, const void *base, unsigned int palettes) const sanitize (hb_sanitize_context_t *c, const void *base,
unsigned int palettes, unsigned int paletteEntries) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && return_trace (c->check_struct (this) &&
(base+paletteFlagsZ).sanitize (c, palettes) && (base+paletteFlagsZ).sanitize (c, palettes) &&
(base+paletteLabelZ).sanitize (c, palettes) /*&& (base+paletteLabelZ).sanitize (c, palettes) &&
(base+paletteEntryLabelZ).sanitize (c, palettes)*/); (base+paletteEntryLabelZ).sanitize (c, paletteEntries));
} }
private: private:
#if 0
inline hb_ot_color_palette_flags_t inline hb_ot_color_palette_flags_t
get_palette_flags (const void *base, unsigned int palette) const get_palette_flags (const void *base, unsigned int palette,
unsigned int palettes_count) const
{ {
// range checked at the CPAL caller if (unlikely (palette >= palettes_count))
return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
return (hb_ot_color_palette_flags_t) (uint32_t) (base+paletteFlagsZ)[palette]; return (hb_ot_color_palette_flags_t) (uint32_t) (base+paletteFlagsZ)[palette];
} }
#endif
inline unsigned int inline unsigned int
get_palette_name_id (const void *base, unsigned int palette) const get_palette_name_id (const void *base, unsigned int palette,
unsigned int palettes_count) const
{ {
// range checked at the CPAL caller if (unlikely (palette >= palettes_count))
return HB_NAME_ID_INVALID;
return (base+paletteLabelZ)[palette]; return (base+paletteLabelZ)[palette];
} }
inline unsigned int
get_palette_entry_name_id (const void *base, unsigned int palette_entry,
unsigned int palettes_entries_count) const
{
if (unlikely (palette_entry >= palettes_entries_count))
return HB_NAME_ID_INVALID;
return (base+paletteEntryLabelZ)[palette_entry];
}
protected: protected:
LOffsetTo<UnsizedArrayOf<HBUINT32>, false> LOffsetTo<UnsizedArrayOf<HBUINT32>, false>
paletteFlagsZ; /* Offset from the beginning of CPAL table to paletteFlagsZ; /* Offset from the beginning of CPAL table to
@ -83,12 +98,12 @@ struct CPALV1Tail
paletteLabelZ; /* Offset from the beginning of CPAL table to paletteLabelZ; /* Offset from the beginning of CPAL table to
* the Palette Labels Array. Set to 0 if no * the Palette Labels Array. Set to 0 if no
* array is provided. */ * array is provided. */
/*LOffsetTo<UnsizedArrayOf<HBUINT16>, false> LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
paletteEntryLabelZ;*/ /* Offset from the beginning of CPAL table to paletteEntryLabelZ; /* Offset from the beginning of CPAL table to
* the Palette Entry Label Array. Set to 0 * the Palette Entry Label Array. Set to 0
* if no array is provided. */ * if no array is provided. */
public: public:
DEFINE_SIZE_STATIC (/*12*/8); DEFINE_SIZE_STATIC (12);
}; };
typedef HBUINT32 BGRAColor; typedef HBUINT32 BGRAColor;
@ -115,7 +130,7 @@ struct CPAL
return_trace (true); return_trace (true);
const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this); const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this);
return_trace (likely (v1.sanitize (c, this, numPalettes))); return_trace (likely (v1.sanitize (c, this, numPalettes, numPaletteEntries)));
} }
inline unsigned int get_size (void) const inline unsigned int get_size (void) const
@ -123,35 +138,38 @@ struct CPAL
return min_size + numPalettes * sizeof (HBUINT16); return min_size + numPalettes * sizeof (HBUINT16);
} }
#if 0
inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette) const inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette) const
{ {
if (unlikely (version == 0 || palette >= numPalettes)) if (unlikely (version == 0))
return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this); const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this);
return cpal1.get_palette_flags (this, palette); return cpal1.get_palette_flags (this, palette, numPalettes);
} }
#endif
inline unsigned int get_palette_name_id (unsigned int palette) const inline unsigned int get_palette_name_id (unsigned int palette) const
{ {
if (unlikely (version == 0 || palette >= numPalettes)) if (unlikely (version == 0))
return HB_NAME_ID_INVALID; return HB_NAME_ID_INVALID;
const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this); const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this);
return cpal1.get_palette_name_id (this, palette); return cpal1.get_palette_name_id (this, palette, numPalettes);
}
inline unsigned int get_palette_entry_name_id (unsigned int palette_entry) const
{
if (unlikely (version == 0))
return HB_NAME_ID_INVALID;
const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this);
return cpal1.get_palette_entry_name_id (this, palette_entry, numPaletteEntries);
} }
inline unsigned int get_palette_count () const inline unsigned int get_palette_count () const
{ { return numPalettes; }
return numPalettes;
}
inline unsigned int get_palette_entries_count () const inline unsigned int get_palette_entries_count () const
{ { return numPaletteEntries; }
return numPaletteEntries;
}
bool bool
get_color_record_argb (unsigned int color_index, unsigned int palette, hb_color_t* color) const get_color_record_argb (unsigned int color_index, unsigned int palette, hb_color_t* color) const

View File

@ -84,7 +84,7 @@ hb_ot_color_has_colr_data (hb_face_t *face)
* hb_ot_color_get_palette_count: * hb_ot_color_get_palette_count:
* @face: a font face. * @face: a font face.
* *
* Returns: whether CPAL table available * Returns:
* *
* Since: REPLACEME * Since: REPLACEME
*/ */
@ -94,6 +94,57 @@ hb_ot_color_get_palette_count (hb_face_t *face)
return _get_cpal (face).get_palette_count (); return _get_cpal (face).get_palette_count ();
} }
/**
* hb_ot_color_get_palette_name_id:
* @face: a font face.
* @palette: the index of the color palette whose name is being requested.
*
* Retrieves the name id of a color palette. For example, a color font can
* have themed palettes like "Spring", "Summer", "Fall", and "Winter".
*
* Returns: an identifier within @face's `name` table.
* If the requested palette has no name, or if @face has no colors,
* or if @palette is not between 0 and hb_ot_color_get_palette_count(),
* the result is 0xFFFF. The implementation does not check whether
* the returned palette name id is actually in @face's `name` table.
*
* Since: REPLACEME
*/
hb_name_id_t
hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette)
{
return _get_cpal (face).get_palette_name_id (palette);
}
/**
* hb_ot_color_get_palette_count:
* @face: a font face.
*
* Returns: Number of entries on each palette
*
* Since: REPLACEME
*/
unsigned int
hb_ot_color_get_palette_entry_count (hb_face_t *face)
{
return _get_cpal (face).get_palette_entries_count ();
}
/**
* hb_ot_color_get_palette_entry_name_id:
* @face: a font face.
* @palette_entry:
*
* Returns: Name ID associated with an palette entry, e.g. eye color
*
* Since: REPLACEME
*/
hb_name_id_t
hb_ot_color_get_palette_entry_name_id (hb_face_t *face, unsigned int palette_entry)
{
return _get_cpal (face).get_palette_entry_name_id (palette_entry);
}
/** /**
* hb_ot_color_get_palette_colors: * hb_ot_color_get_palette_colors:
* @face: a font face. * @face: a font face.
@ -150,6 +201,17 @@ hb_ot_color_get_palette_colors (hb_face_t *face,
return cpal.get_palette_entries_count (); return cpal.get_palette_entries_count ();
} }
/**
* hb_ot_color_get_color_layers:
* @gid:
* @start_offset:
* @count: (inout) (optional):
* @color_indices: (array length=color_count) (optional):
*
* Returns:
*
* Since: REPLACEME
*/
unsigned int unsigned int
hb_ot_color_get_color_layers (hb_face_t *face, hb_ot_color_get_color_layers (hb_face_t *face,
hb_codepoint_t gid, hb_codepoint_t gid,
@ -179,29 +241,6 @@ hb_ot_color_get_color_layers (hb_face_t *face,
return num_layers; return num_layers;
} }
/**
* hb_ot_color_get_palette_name_id:
* @face: a font face.
* @palette: the index of the color palette whose name is being requested.
*
* Retrieves the name id of a color palette. For example, a color font can
* have themed palettes like "Spring", "Summer", "Fall", and "Winter".
*
* Returns: an identifier within @face's `name` table.
* If the requested palette has no name, or if @face has no colors,
* or if @palette is not between 0 and hb_ot_color_get_palette_count(),
* the result is 0xFFFF. The implementation does not check whether
* the returned palette name id is actually in @face's `name` table.
*
* Since: REPLACEME
*/
hb_name_id_t
hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette)
{
return _get_cpal (face).get_palette_name_id (palette);
}
#if 0
/** /**
* hb_ot_color_get_palette_flags: * hb_ot_color_get_palette_flags:
* @face: a font face * @face: a font face
@ -219,25 +258,3 @@ 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);
} }
/*
* Following parts to be moved to a public header.
*/
/**
* 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.
* @HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND: flag indicating that the color palette is suitable for rendering text on dark background.
*
* Since: DONTREPLACEME
*/
typedef enum { /*< flags >*/
HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u,
HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND = 0x00000001u,
HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u,
} hb_ot_color_palette_flags_t;
HB_EXTERN hb_ot_color_palette_flags_t
hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette);
#endif

View File

@ -50,6 +50,12 @@ hb_ot_color_get_palette_count (hb_face_t *face);
HB_EXTERN hb_name_id_t HB_EXTERN hb_name_id_t
hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette); hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette);
HB_EXTERN unsigned int
hb_ot_color_get_palette_entry_count (hb_face_t *face);
HB_EXTERN hb_name_id_t
hb_ot_color_get_palette_entry_name_id (hb_face_t *face, unsigned int palette_entry);
HB_EXTERN unsigned int HB_EXTERN 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 */
@ -65,6 +71,23 @@ hb_ot_color_get_color_layers (hb_face_t *face,
hb_codepoint_t *gids, /* OUT */ hb_codepoint_t *gids, /* OUT */
unsigned int *color_indices /* OUT */); unsigned int *color_indices /* OUT */);
/**
* 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.
* @HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND: flag indicating that the color palette is suitable for rendering text on dark background.
*
* Since: REPLACEME
*/
typedef enum { /*< flags >*/
HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u,
HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND = 0x00000001u,
HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u,
} hb_ot_color_palette_flags_t;
HB_EXTERN hb_ot_color_palette_flags_t
hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette);
HB_END_DECLS HB_END_DECLS
#endif /* HB_OT_COLOR_H */ #endif /* HB_OT_COLOR_H */

View File

@ -129,6 +129,7 @@ test_hb_ot_color_get_palette_count (void)
g_assert_cmpint (hb_ot_color_get_palette_count (cpal_v1), ==, 3); g_assert_cmpint (hb_ot_color_get_palette_count (cpal_v1), ==, 3);
} }
static void static void
test_hb_ot_color_get_palette_name_id_empty (void) test_hb_ot_color_get_palette_name_id_empty (void)
{ {
@ -137,6 +138,7 @@ test_hb_ot_color_get_palette_name_id_empty (void)
g_assert_cmpint (hb_ot_color_get_palette_name_id (hb_face_get_empty(), 1), ==, HB_NAME_ID_INVALID); g_assert_cmpint (hb_ot_color_get_palette_name_id (hb_face_get_empty(), 1), ==, HB_NAME_ID_INVALID);
} }
static void static void
test_hb_ot_color_get_palette_name_id_v0 (void) test_hb_ot_color_get_palette_name_id_v0 (void)
{ {
@ -147,6 +149,7 @@ test_hb_ot_color_get_palette_name_id_v0 (void)
g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v0, 2), ==, HB_NAME_ID_INVALID); g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v0, 2), ==, HB_NAME_ID_INVALID);
} }
static void static void
test_hb_ot_color_get_palette_name_id_v1 (void) test_hb_ot_color_get_palette_name_id_v1 (void)
{ {
@ -158,7 +161,7 @@ test_hb_ot_color_get_palette_name_id_v1 (void)
g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v1, 3), ==, HB_NAME_ID_INVALID); g_assert_cmpint (hb_ot_color_get_palette_name_id (cpal_v1, 3), ==, HB_NAME_ID_INVALID);
} }
#if 0
static void static void
test_hb_ot_color_get_palette_flags_empty (void) test_hb_ot_color_get_palette_flags_empty (void)
{ {
@ -189,7 +192,6 @@ 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
@ -290,6 +292,28 @@ test_hb_ot_color_get_palette_colors_v1 (void)
assert_color_rgba (colors, 2, 0x77, 0x77, 0x77, 0x77); /* untouched */ assert_color_rgba (colors, 2, 0x77, 0x77, 0x77, 0x77); /* untouched */
} }
static void
test_hb_ot_color_get_palette_entry (void)
{
hb_face_t *empty = hb_face_get_empty ();
g_assert_cmpuint (hb_ot_color_get_palette_entry_count (empty), ==, 0);
g_assert_cmpuint (hb_ot_color_get_palette_entry_count (cpal_v0), ==, 2);
g_assert_cmpuint (hb_ot_color_get_palette_entry_count (cpal_v1), ==, 2);
g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (empty, 0), ==, HB_NAME_ID_INVALID);
g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (empty, 1), ==, HB_NAME_ID_INVALID);
g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (empty, 2), ==, HB_NAME_ID_INVALID);
g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v0, 0), ==, HB_NAME_ID_INVALID);
g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v0, 1), ==, HB_NAME_ID_INVALID);
g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v0, 2), ==, HB_NAME_ID_INVALID);
g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v1, 0), ==, HB_NAME_ID_INVALID);
g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v1, 1), ==, 256);
g_assert_cmpuint (hb_ot_color_get_palette_entry_name_id (cpal_v1, 2), ==, HB_NAME_ID_INVALID);
}
static void static void
test_hb_ot_color_get_color_layers (void) test_hb_ot_color_get_color_layers (void)
{ {
@ -328,12 +352,13 @@ main (int argc, char **argv)
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);
hb_test_add (test_hb_ot_color_get_palette_entry);
hb_test_add (test_hb_ot_color_get_color_layers); hb_test_add (test_hb_ot_color_get_color_layers);
status = hb_test_run(); status = hb_test_run();
hb_face_destroy (cpal_v0); hb_face_destroy (cpal_v0);