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
33
34/*
35 * Following parts to be moved to a public header.
36 */
37
38/**
39 * hb_ot_color_t:
40 * ARGB data type for holding color values.
41 *
42 * Since: REPLACEME
43 */
44typedef uint32_t hb_ot_color_t;
45
46
47/**
48 * hb_ot_color_palette_flags_t:
49 * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special to note about a color palette.
50 * @HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND: flag indicating that the color palette is suitable for rendering text on light background.
51 * @HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND: flag indicating that the color palette is suitable for rendering text on dark background.
52 *
53 * Since: REPLACEME
54 */
55typedef enum { /*< flags >*/
56 HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u,
57 HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND = 0x00000001u,
58 HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u,
59} hb_ot_color_palette_flags_t;
60
61// HB_EXTERN unsigned int
62// hb_ot_color_get_palette_count (hb_face_t *face);
63
64// HB_EXTERN unsigned int
65// hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette);
66
67// HB_EXTERN hb_ot_color_palette_flags_t
68// hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette);
69
70// HB_EXTERN unsigned int
71// hb_ot_color_get_palette_colors (hb_face_t *face,
72// unsigned int palette, /* default=0 */
73// unsigned int start_offset,
74// unsigned int *color_count /* IN/OUT */,
75// hb_ot_color_t *colors /* OUT */);
76
77
78
79
80
81/*
82 * CPAL -- Color Palette
83 * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
84 */
85#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
86
87
88namespace OT {
89
90
91struct CPALV1Tail
92{
93 friend struct CPAL;
94
95 inline bool
96 sanitize (hb_sanitize_context_t *c, const void *base, unsigned int palettes) const
97 {
98 TRACE_SANITIZE (this);
99 return_trace (c->check_struct (this) &&
100 (base+paletteFlagsZ).sanitize (c, palettes) &&
101 (base+paletteLabelZ).sanitize (c, palettes) &&
102 (base+paletteEntryLabelZ).sanitize (c, palettes));
103 }
104
105 private:
106 inline hb_ot_color_palette_flags_t
107 get_palette_flags (const void *base, unsigned int palette) const
108 {
109 // range checked at the CPAL caller
110 return (hb_ot_color_palette_flags_t) (uint32_t) (base+paletteFlagsZ)[palette];
111 }
112
113 inline unsigned int
114 get_palette_name_id (const void *base, unsigned int palette) const
115 {
116 // range checked at the CPAL caller
117 return (base+paletteLabelZ)[palette];
118 }
119
120 protected:
121 LOffsetTo<UnsizedArrayOf<HBUINT32> >
122 paletteFlagsZ; /* Offset from the beginning of CPAL table to
123 * the Palette Type Array. Set to 0 if no array
124 * is provided. */
125 LOffsetTo<UnsizedArrayOf<HBUINT16> >
126 paletteLabelZ; /* Offset from the beginning of CPAL table to
127 * the Palette Labels Array. Set to 0 if no
128 * array is provided. */
129 LOffsetTo<UnsizedArrayOf<HBUINT16> >
130 paletteEntryLabelZ; /* Offset from the beginning of CPAL table to
131 * the Palette Entry Label Array. Set to 0
132 * if no array is provided. */
133 public:
134 DEFINE_SIZE_STATIC (12);
135};
136
137typedef HBUINT32 BGRAColor;
138
139struct CPAL
140{
141 static const hb_tag_t tableTag = HB_OT_TAG_CPAL;
142
143 inline bool sanitize (hb_sanitize_context_t *c) const
144 {
145 TRACE_SANITIZE (this);
146 if (unlikely (!(c->check_struct (this) && // it checks colorRecordIndices also
147 // see #get_size
148 (this+colorRecordsZ).sanitize (c, numColorRecords))))
149 return_trace (false);
150
151 // Check for indices sanity so no need for doing it runtime
152 for (unsigned int i = 0; i < numPalettes; ++i)
153 if (unlikely (colorRecordIndicesZ[i] + numPaletteEntries > numColorRecords))
154 return_trace (false);
155
156 // If version is zero, we are done here; otherwise we need to check tail also
157 if (version == 0)
158 return_trace (true);
159
160 const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this);
161 return_trace (likely (v1.sanitize (c, this, numPalettes)));
162 }
163
164 inline unsigned int get_size (void) const
165 {
166 return min_size + numPalettes * sizeof (HBUINT16);
167 }
168
169 inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette) const
170 {
171 if (unlikely (version == 0 || palette >= numPalettes))
172 return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
173
174 const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this);
175 return cpal1.get_palette_flags (this, palette);
176 }
177
178 inline unsigned int get_palette_name_id (unsigned int palette) const
179 {
180 if (unlikely (version == 0 || palette >= numPalettes))
181 return 0xFFFF;
182
183 const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this);
184 return cpal1.get_palette_name_id (this, palette);
185 }
186
187 inline unsigned int get_palette_count () const
188 {
189 return numPalettes;
190 }
191
192 inline hb_ot_color_t
193 get_color_record_argb (unsigned int color_index, unsigned int palette) const
194 {
195 if (unlikely (color_index >= numPaletteEntries || palette >= numPalettes))
196 return 0;
197
198 // No need for more range check as it is already done on #sanitize
199 const UnsizedArrayOf<BGRAColor>& color_records = this+colorRecordsZ;
200 return color_records[colorRecordIndicesZ[palette] + color_index];
201 }
202
203 protected:
204 HBUINT16 version; /* Table version number */
205 /* Version 0 */
206 HBUINT16 numPaletteEntries; /* Number of palette entries in each palette. */
207 HBUINT16 numPalettes; /* Number of palettes in the table. */
208 HBUINT16 numColorRecords; /* Total number of color records, combined for
209 * all palettes. */
210 LOffsetTo<UnsizedArrayOf<BGRAColor> >
211 colorRecordsZ; /* Offset from the beginning of CPAL table to
212 * the first ColorRecord. */
213 UnsizedArrayOf<HBUINT16>
214 colorRecordIndicesZ; /* Index of each palette’s first color record in
215 * the combined color record array. */
216/*CPALV1Tail v1;*/
217 public:
218 DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ);
219};
220
221} /* namespace OT */
222
223
224#endif /* HB_OT_COLOR_CPAL_TABLE_HH */
225