QtBase  v6.3.1
hb-ot-color-cpal-table.hh
Go to the documentation of this file.
1 /*
2  * Copyright © 2016 Google, Inc.
3  * Copyright © 2018 Ebrahim Byagowi
4  *
5  * This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Google Author(s): Sascha Brawer
26  */
27 
28 #ifndef HB_OT_COLOR_CPAL_TABLE_HH
29 #define HB_OT_COLOR_CPAL_TABLE_HH
30 
31 #include "hb-open-type.hh"
32 #include "hb-ot-color.h"
33 #include "hb-ot-name.h"
34 
35 
36 /*
37  * CPAL -- Color Palette
38  * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
39  */
40 #define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
41 
42 namespace OT {
43 
44 
45 struct CPALV1Tail
46 {
47  friend struct CPAL;
48 
49  private:
50  hb_ot_color_palette_flags_t get_palette_flags (const void *base,
51  unsigned int palette_index,
52  unsigned int palette_count) const
53  {
55  return (hb_ot_color_palette_flags_t) (uint32_t)
56  (base+paletteFlagsZ).as_array (palette_count)[palette_index];
57  }
58 
59  hb_ot_name_id_t get_palette_name_id (const void *base,
60  unsigned int palette_index,
61  unsigned int palette_count) const
62  {
64  return (base+paletteLabelsZ).as_array (palette_count)[palette_index];
65  }
66 
67  hb_ot_name_id_t get_color_name_id (const void *base,
68  unsigned int color_index,
69  unsigned int color_count) const
70  {
72  return (base+colorLabelsZ).as_array (color_count)[color_index];
73  }
74 
75  public:
77  unsigned palette_count,
78  unsigned color_count,
79  const void *base,
80  const hb_map_t *color_index_map) const
81  {
82  TRACE_SERIALIZE (this);
83  auto *out = c->allocate_size<CPALV1Tail> (static_size);
84  if (unlikely (!out)) return_trace (false);
85 
86  out->paletteFlagsZ = 0;
87  if (paletteFlagsZ)
88  out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count);
89 
90  out->paletteLabelsZ = 0;
91  if (paletteLabelsZ)
92  out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count);
93 
94  const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
95  if (colorLabelsZ)
96  {
97  c->push ();
98  for (const auto _ : colorLabels)
99  {
100  if (!color_index_map->has (_)) continue;
101  NameID new_color_idx;
102  new_color_idx = color_index_map->get (_);
103  if (!c->copy<NameID> (new_color_idx))
104  {
105  c->pop_discard ();
106  return_trace (false);
107  }
108  }
109  c->add_link (out->colorLabelsZ, c->pop_pack ());
110  }
111  return_trace (true);
112  }
113 
115  const void *base,
116  unsigned int palette_count,
117  unsigned int color_count) const
118  {
119  TRACE_SANITIZE (this);
120  return_trace (c->check_struct (this) &&
121  (!paletteFlagsZ || (base+paletteFlagsZ).sanitize (c, palette_count)) &&
122  (!paletteLabelsZ || (base+paletteLabelsZ).sanitize (c, palette_count)) &&
123  (!colorLabelsZ || (base+colorLabelsZ).sanitize (c, color_count)));
124  }
125 
126  protected:
127  // TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets
128  // here. Currently they are needed since UnsizedArrayOf doesn't define null_size
130  paletteFlagsZ; /* Offset from the beginning of CPAL table to
131  * the Palette Type Array. Set to 0 if no array
132  * is provided. */
134  paletteLabelsZ; /* Offset from the beginning of CPAL table to
135  * the palette labels array. Set to 0 if no
136  * array is provided. */
138  colorLabelsZ; /* Offset from the beginning of CPAL table to
139  * the color labels array. Set to 0
140  * if no array is provided. */
141  public:
143 };
144 
146 
147 struct CPAL
148 {
149  static constexpr hb_tag_t tableTag = HB_OT_TAG_CPAL;
150 
151  bool has_data () const { return numPalettes; }
152 
153  unsigned int get_size () const
154  { return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
155 
156  unsigned int get_palette_count () const { return numPalettes; }
157  unsigned int get_color_count () const { return numColors; }
158 
159  hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const
160  { return v1 ().get_palette_flags (this, palette_index, numPalettes); }
161 
162  hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const
163  { return v1 ().get_palette_name_id (this, palette_index, numPalettes); }
164 
165  hb_ot_name_id_t get_color_name_id (unsigned int color_index) const
166  { return v1 ().get_color_name_id (this, color_index, numColors); }
167 
168  unsigned int get_palette_colors (unsigned int palette_index,
169  unsigned int start_offset,
170  unsigned int *color_count, /* IN/OUT. May be NULL. */
171  hb_color_t *colors /* OUT. May be NULL. */) const
172  {
173  if (unlikely (palette_index >= numPalettes))
174  {
175  if (color_count) *color_count = 0;
176  return 0;
177  }
178  unsigned int start_index = colorRecordIndicesZ[palette_index];
179  hb_array_t<const BGRAColor> all_colors ((this+colorRecordsZ).arrayZ, numColorRecords);
180  hb_array_t<const BGRAColor> palette_colors = all_colors.sub_array (start_index,
181  numColors);
182  if (color_count)
183  {
184  + palette_colors.sub_array (start_offset, color_count)
185  | hb_sink (hb_array (colors, *color_count))
186  ;
187  }
188  return numColors;
189  }
190 
191  private:
192  const CPALV1Tail& v1 () const
193  {
194  if (version == 0) return Null (CPALV1Tail);
195  return StructAfter<CPALV1Tail> (*this);
196  }
197 
198  public:
200  const hb_array_t<const BGRAColor> &color_records,
201  const hb_array_t<const HBUINT16> &color_record_indices,
202  const hb_map_t &color_record_index_map,
203  const hb_set_t &retained_color_record_indices) const
204  {
205  TRACE_SERIALIZE (this);
206 
207  for (const auto idx : color_record_indices)
208  {
209  HBUINT16 new_idx;
210  if (idx == 0) new_idx = 0;
211  else new_idx = color_record_index_map.get (idx);
212  if (!c->copy<HBUINT16> (new_idx)) return_trace (false);
213  }
214 
215  c->push ();
216  for (const auto _ : retained_color_record_indices.iter ())
217  {
218  if (!c->copy<BGRAColor> (color_records[_]))
219  {
220  c->pop_discard ();
221  return_trace (false);
222  }
223  }
224  c->add_link (colorRecordsZ, c->pop_pack ());
225  return_trace (true);
226  }
227 
229  {
230  TRACE_SUBSET (this);
231  const hb_map_t *color_index_map = c->plan->colr_palettes;
232  if (color_index_map->is_empty ()) return_trace (false);
233 
234  hb_set_t retained_color_indices;
235  for (const auto _ : color_index_map->keys ())
236  {
237  if (_ == 0xFFFF) continue;
238  retained_color_indices.add (_);
239  }
240  if (retained_color_indices.is_empty ()) return_trace (false);
241 
242  auto *out = c->serializer->start_embed (*this);
243  if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
244 
245  out->version = version;
246  out->numColors = retained_color_indices.get_population ();
247  out->numPalettes = numPalettes;
248 
249  const hb_array_t<const HBUINT16> colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes);
250  hb_map_t color_record_index_map;
251  hb_set_t retained_color_record_indices;
252 
253  unsigned record_count = 0;
254  for (const auto first_color_record_idx : colorRecordIndices)
255  {
256  for (unsigned retained_color_idx : retained_color_indices.iter ())
257  {
258  unsigned color_record_idx = first_color_record_idx + retained_color_idx;
259  if (color_record_index_map.has (color_record_idx)) continue;
260  color_record_index_map.set (color_record_idx, record_count);
261  retained_color_record_indices.add (color_record_idx);
262  record_count++;
263  }
264  }
265 
266  out->numColorRecords = record_count;
267  const hb_array_t<const BGRAColor> color_records = (this+colorRecordsZ).as_array (numColorRecords);
268  if (!out->serialize (c->serializer, color_records, colorRecordIndices, color_record_index_map, retained_color_record_indices))
269  return_trace (false);
270 
271  if (version == 1)
272  return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map));
273 
274  return_trace (true);
275  }
276 
278  {
279  TRACE_SANITIZE (this);
280  return_trace (c->check_struct (this) &&
281  (this+colorRecordsZ).sanitize (c, numColorRecords) &&
282  colorRecordIndicesZ.sanitize (c, numPalettes) &&
283  (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors)));
284  }
285 
286  protected:
287  HBUINT16 version; /* Table version number */
288  /* Version 0 */
289  HBUINT16 numColors; /* Number of colors in each palette. */
290  HBUINT16 numPalettes; /* Number of palettes in the table. */
291  HBUINT16 numColorRecords; /* Total number of color records, combined for
292  * all palettes. */
294  colorRecordsZ; /* Offset from the beginning of CPAL table to
295  * the first ColorRecord. */
297  colorRecordIndicesZ; /* Index of each palette’s first color record in
298  * the combined color record array. */
299 /*CPALV1Tail v1;*/
300  public:
302 };
303 
304 } /* namespace OT */
305 
306 
307 #endif /* HB_OT_COLOR_CPAL_TABLE_HH */
FT_UInt idx
Definition: cffcmap.c:135
Definition: base.h:37
hb_array_t< T > hb_array(T *array, unsigned int length)
Definition: hb-array.hh:295
#define TRACE_SERIALIZE(this)
Definition: hb-debug.hh:426
#define TRACE_SANITIZE(this)
Definition: hb-debug.hh:414
#define return_trace(RET)
Definition: hb-debug.hh:349
#define TRACE_SUBSET(this)
Definition: hb-debug.hh:438
#define HB_OT_TAG_CPAL
hb_ot_color_palette_flags_t
Definition: hb-ot-color.h:73
@ HB_OT_COLOR_PALETTE_FLAG_DEFAULT
Definition: hb-ot-color.h:74
HB_EXTERN unsigned int start_offset
unsigned int hb_ot_name_id_t
Definition: hb-ot-name.h:109
@ HB_OT_NAME_ID_INVALID
Definition: hb-ot-name.h:106
#define _(S, M)
#define unlikely(expr)
Definition: hb.hh:251
HBUINT32 BGRAColor
GLint GLfloat GLfloat v1
const GLubyte * c
Definition: qopenglext.h:12701
uint32_t hb_color_t
Definition: hb-common.h:858
uint32_t hb_tag_t
Definition: hb-common.h:157
QTextStream out(stdout)
[7]
Definition: hb-null.hh:93
hb_ot_color_palette_flags_t get_palette_flags(unsigned int palette_index) const
static constexpr hb_tag_t tableTag
NNOffset32To< UnsizedArrayOf< BGRAColor > > colorRecordsZ
UnsizedArrayOf< HBUINT16 > colorRecordIndicesZ
unsigned int get_color_count() const
hb_ot_name_id_t get_palette_name_id(unsigned int palette_index) const
hb_ot_name_id_t get_color_name_id(unsigned int color_index) const
unsigned int get_palette_count() const
DEFINE_SIZE_ARRAY(12, colorRecordIndicesZ)
bool subset(hb_subset_context_t *c) const
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
unsigned int get_palette_colors(unsigned int palette_index, unsigned int start_offset, unsigned int *color_count, hb_color_t *colors) const
bool sanitize(hb_sanitize_context_t *c) const
bool has_data() const
unsigned int get_size() const
HBUINT16 numColorRecords
NNOffset32To< UnsizedArrayOf< NameID > > colorLabelsZ
bool serialize(hb_serialize_context_t *c, unsigned palette_count, unsigned color_count, const void *base, const hb_map_t *color_index_map) const
bool sanitize(hb_sanitize_context_t *c, const void *base, unsigned int palette_count, unsigned int color_count) const
NNOffset32To< UnsizedArrayOf< NameID > > paletteLabelsZ
NNOffset32To< UnsizedArrayOf< HBUINT32 > > paletteFlagsZ
hb_array_t sub_array(unsigned int start_offset=0, unsigned int *seg_count=nullptr) const
Definition: hb-array.hh:231
V get(K key) const
Definition: hb-map.hh:202
bool is_empty() const
Definition: hb-map.hh:235
bool set(K key, const V &value)
Definition: hb-map.hh:199
bool has(K k, V *vp=nullptr) const
Definition: hb-map.hh:214
iter_t iter() const
Definition: hb-set.hh:155
bool is_empty() const
Definition: hb-set.hh:83
unsigned int get_population() const
Definition: hb-set.hh:145
void add(hb_codepoint_t g)
Definition: hb-set.hh:85