1/*
2 * Copyright © 2018 Ebrahim Byagowi
3 *
4 * This is part of HarfBuzz, a text shaping library.
5 *
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
11 *
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE.
17 *
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 */
24
25#ifndef HB_OT_COLOR_COLR_TABLE_HH
26#define HB_OT_COLOR_COLR_TABLE_HH
27
28#include "hb-open-type.hh"
29
30/*
31 * COLR -- Color
32 * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
33 */
34#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
35
36
37namespace OT {
38
39
40struct LayerRecord
41{
42 bool sanitize (hb_sanitize_context_t *c) const
43 {
44 TRACE_SANITIZE (this);
45 return_trace (c->check_struct (this));
46 }
47
48 public:
49 GlyphID glyphId; /* Glyph ID of layer glyph */
50 Index colorIdx; /* Index value to use with a
51 * selected color palette.
52 * An index value of 0xFFFF
53 * is a special case indicating
54 * that the text foreground
55 * color (defined by a
56 * higher-level client) should
57 * be used and shall not be
58 * treated as actual index
59 * into CPAL ColorRecord array. */
60 public:
61 DEFINE_SIZE_STATIC (4);
62};
63
64struct BaseGlyphRecord
65{
66 int cmp (hb_codepoint_t g) const
67 { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
68
69 bool sanitize (hb_sanitize_context_t *c) const
70 {
71 TRACE_SANITIZE (this);
72 return_trace (likely (c->check_struct (this)));
73 }
74
75 public:
76 GlyphID glyphId; /* Glyph ID of reference glyph */
77 HBUINT16 firstLayerIdx; /* Index (from beginning of
78 * the Layer Records) to the
79 * layer record. There will be
80 * numLayers consecutive entries
81 * for this base glyph. */
82 HBUINT16 numLayers; /* Number of color layers
83 * associated with this glyph */
84 public:
85 DEFINE_SIZE_STATIC (6);
86};
87
88struct COLR
89{
90 static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR;
91
92 bool has_data () const { return numBaseGlyphs; }
93
94 unsigned int get_glyph_layers (hb_codepoint_t glyph,
95 unsigned int start_offset,
96 unsigned int *count, /* IN/OUT. May be NULL. */
97 hb_ot_color_layer_t *layers /* OUT. May be NULL. */) const
98 {
99 const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph);
100
101 hb_array_t<const LayerRecord> all_layers ((this+layersZ).arrayZ, numLayers);
102 hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
103 record.numLayers);
104 if (count)
105 {
106 hb_array_t<const LayerRecord> segment_layers = glyph_layers.sub_array (start_offset, *count);
107 *count = segment_layers.length;
108 for (unsigned int i = 0; i < segment_layers.length; i++)
109 {
110 layers[i].glyph = segment_layers.arrayZ[i].glyphId;
111 layers[i].color_index = segment_layers.arrayZ[i].colorIdx;
112 }
113 }
114 return glyph_layers.length;
115 }
116
117 bool sanitize (hb_sanitize_context_t *c) const
118 {
119 TRACE_SANITIZE (this);
120 return_trace (likely (c->check_struct (this) &&
121 (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
122 (this+layersZ).sanitize (c, numLayers)));
123 }
124
125 protected:
126 HBUINT16 version; /* Table version number (starts at 0). */
127 HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */
128 LNNOffsetTo<SortedUnsizedArrayOf<BaseGlyphRecord> >
129 baseGlyphsZ; /* Offset to Base Glyph records. */
130 LNNOffsetTo<UnsizedArrayOf<LayerRecord> >
131 layersZ; /* Offset to Layer Records. */
132 HBUINT16 numLayers; /* Number of Layer Records. */
133 public:
134 DEFINE_SIZE_STATIC (14);
135};
136
137} /* namespace OT */
138
139
140#endif /* HB_OT_COLOR_COLR_TABLE_HH */
141