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-private.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 */ 44 typedef 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 */ 55 typedef 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 88 namespace OT { 89 90 91 struct 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 137 typedef HBUINT32 BGRAColor; 138 139 struct 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 */ | 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 43 namespace OT { 44 45 46 struct CPALV1Tail 47 { 48 friend struct CPAL; 49 50 private: 51 hb_ot_color_palette_flags_t get_palette_flags (const void *base, 52 unsigned int palette_index, 53 unsigned int palette_count) const 54 { 55 if (!paletteFlagsZ) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; 56 return (hb_ot_color_palette_flags_t) (uint32_t) 57 (base+paletteFlagsZ).as_array (palette_count)[palette_index]; 58 } 59 60 hb_ot_name_id_t get_palette_name_id (const void *base, 61 unsigned int palette_index, 62 unsigned int palette_count) const 63 { 64 if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID; 65 return (base+paletteLabelsZ).as_array (palette_count)[palette_index]; 66 } 67 68 hb_ot_name_id_t get_color_name_id (const void *base, 69 unsigned int color_index, 70 unsigned int color_count) const 71 { 72 if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID; 73 return (base+colorLabelsZ).as_array (color_count)[color_index]; 74 } 75 76 public: 77 bool sanitize (hb_sanitize_context_t *c, 78 const void *base, 79 unsigned int palette_count, 80 unsigned int color_count) const 81 { 82 TRACE_SANITIZE (this); 83 return_trace (c->check_struct (this) && 84 (!paletteFlagsZ || (base+paletteFlagsZ).sanitize (c, palette_count)) && 85 (!paletteLabelsZ || (base+paletteLabelsZ).sanitize (c, palette_count)) && 86 (!colorLabelsZ || (base+colorLabelsZ).sanitize (c, color_count))); 87 } 88 89 protected: 90 LNNOffsetTo<UnsizedArrayOf<HBUINT32> > 91 paletteFlagsZ; /* Offset from the beginning of CPAL table to 92 * the Palette Type Array. Set to 0 if no array 93 * is provided. */ 94 LNNOffsetTo<UnsizedArrayOf<NameID> > 95 paletteLabelsZ; /* Offset from the beginning of CPAL table to 96 * the palette labels array. Set to 0 if no 97 * array is provided. */ 98 LNNOffsetTo<UnsizedArrayOf<NameID> > 99 colorLabelsZ; /* Offset from the beginning of CPAL table to 100 * the color labels array. Set to 0 101 * if no array is provided. */ 102 public: 103 DEFINE_SIZE_STATIC (12); 104 }; 105 106 typedef HBUINT32 BGRAColor; 107 108 struct CPAL 109 { 110 static constexpr hb_tag_t tableTag = HB_OT_TAG_CPAL; 111 112 bool has_data () const { return numPalettes; } 113 114 unsigned int get_size () const 115 { return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); } 116 117 unsigned int get_palette_count () const { return numPalettes; } 118 unsigned int get_color_count () const { return numColors; } 119 120 hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const 121 { return v1 ().get_palette_flags (this, palette_index, numPalettes); } 122 123 hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const 124 { return v1 ().get_palette_name_id (this, palette_index, numPalettes); } 125 126 hb_ot_name_id_t get_color_name_id (unsigned int color_index) const 127 { return v1 ().get_color_name_id (this, color_index, numColors); } 128 129 unsigned int get_palette_colors (unsigned int palette_index, 130 unsigned int start_offset, 131 unsigned int *color_count, /* IN/OUT. May be NULL. */ 132 hb_color_t *colors /* OUT. May be NULL. */) const 133 { 134 if (unlikely (palette_index >= numPalettes)) 135 { 136 if (color_count) *color_count = 0; 137 return 0; 138 } 139 unsigned int start_index = colorRecordIndicesZ[palette_index]; 140 hb_array_t<const BGRAColor> all_colors ((this+colorRecordsZ).arrayZ, numColorRecords); 141 hb_array_t<const BGRAColor> palette_colors = all_colors.sub_array (start_index, 142 numColors); 143 if (color_count) 144 { 145 hb_array_t<const BGRAColor> segment_colors = palette_colors.sub_array (start_offset, *color_count); 146 /* Always return numColors colors per palette even if it has out-of-bounds start index. */ 147 unsigned int count = MIN<unsigned int> (MAX<int> (numColors - start_offset, 0), *color_count); 148 *color_count = count; 149 for (unsigned int i = 0; i < count; i++) 150 colors[i] = segment_colors[i]; /* Bound-checked read. */ 151 } 152 return numColors; 153 } 154 155 private: 156 const CPALV1Tail& v1 () const 157 { 158 if (version == 0) return Null(CPALV1Tail); 159 return StructAfter<CPALV1Tail> (*this); 160 } 161 162 public: 163 bool sanitize (hb_sanitize_context_t *c) const 164 { 165 TRACE_SANITIZE (this); 166 return_trace (c->check_struct (this) && 167 (this+colorRecordsZ).sanitize (c, numColorRecords) && 168 colorRecordIndicesZ.sanitize (c, numPalettes) && 169 (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors))); 170 } 171 172 protected: 173 HBUINT16 version; /* Table version number */ 174 /* Version 0 */ 175 HBUINT16 numColors; /* Number of colors in each palette. */ 176 HBUINT16 numPalettes; /* Number of palettes in the table. */ 177 HBUINT16 numColorRecords; /* Total number of color records, combined for 178 * all palettes. */ 179 LNNOffsetTo<UnsizedArrayOf<BGRAColor> > 180 colorRecordsZ; /* Offset from the beginning of CPAL table to 181 * the first ColorRecord. */ 182 UnsizedArrayOf<HBUINT16> 183 colorRecordIndicesZ; /* Index of each palette’s first color record in 184 * the combined color record array. */ 185 /*CPALV1Tail v1;*/ 186 public: 187 DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ); 188 }; 189 190 } /* namespace OT */ 191 192 193 #endif /* HB_OT_COLOR_CPAL_TABLE_HH */ |