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 friend struct COLR;
43
44 inline bool sanitize (hb_sanitize_context_t *c) const
45 {
46 TRACE_SANITIZE (this);
47 return_trace (c->check_struct (this));
48 }
49
50 protected:
51 GlyphID glyphid; /* Glyph ID of layer glyph */
52 HBUINT16 colorIdx; /* Index value to use with a selected color palette */
53 public:
54 DEFINE_SIZE_STATIC (4);
55};
56
57struct BaseGlyphRecord
58{
59 friend struct COLR;
60
61 inline bool sanitize (hb_sanitize_context_t *c) const
62 {
63 TRACE_SANITIZE (this);
64 return_trace (likely (c->check_struct (this)));
65 }
66
67 inline int cmp (hb_codepoint_t g) const {
68 return g < glyphid ? -1 : g > glyphid ? 1 : 0;
69 }
70
71 protected:
72 GlyphID glyphid; /* Glyph ID of reference glyph */
73 HBUINT16 firstLayerIdx; /* Index to the layer record */
74 HBUINT16 numLayers; /* Number of color layers associated with this glyph */
75 public:
76 DEFINE_SIZE_STATIC (6);
77};
78
79static int compare_bgr (const void *pa, const void *pb)
80{
81 const hb_codepoint_t *a = (const hb_codepoint_t *) pa;
82 const BaseGlyphRecord *b = (const BaseGlyphRecord *) pb;
83 return b->cmp (*a);
84}
85
86struct COLR
87{
88 static const hb_tag_t tableTag = HB_OT_TAG_COLR;
89
90 inline bool sanitize (hb_sanitize_context_t *c) const
91 {
92 TRACE_SANITIZE (this);
93 return_trace (likely (c->check_struct (this) &&
94 (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
95 (this+layersZ).sanitize (c, numLayers)));
96 }
97
98 inline bool get_base_glyph_record (hb_codepoint_t glyph_id,
99 unsigned int *first_layer /* OUT */,
100 unsigned int *num_layers /* OUT */) const
101 {
102 const BaseGlyphRecord* record;
103 record = (BaseGlyphRecord *) bsearch (&glyph_id, &(this+baseGlyphsZ), numBaseGlyphs,
104 sizeof (BaseGlyphRecord), compare_bgr);
105 if (unlikely (!record))
106 return false;
107
108 *first_layer = record->firstLayerIdx;
109 *num_layers = record->numLayers;
110 return true;
111 }
112
113 inline bool get_layer_record (unsigned int record,
114 hb_codepoint_t *glyph_id /* OUT */,
115 unsigned int *palette_index /* OUT */) const
116 {
117 if (unlikely (record >= numLayers))
118 {
119 *glyph_id = 0;
120 *palette_index = 0xFFFF;
121 return false;
122 }
123 const LayerRecord &layer = (this+layersZ)[record];
124 *glyph_id = layer.glyphid;
125 *palette_index = layer.colorIdx;
126 return true;
127 }
128
129 protected:
130 HBUINT16 version; /* Table version number */
131 HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records */
132 LOffsetTo<UnsizedArrayOf<BaseGlyphRecord> >
133 baseGlyphsZ; /* Offset to Base Glyph records. */
134 LOffsetTo<UnsizedArrayOf<LayerRecord> >
135 layersZ; /* Offset to Layer Records */
136 HBUINT16 numLayers; /* Number of Layer Records */
137 public:
138 DEFINE_SIZE_STATIC (14);
139};
140
141} /* namespace OT */
142
143
144#endif /* HB_OT_COLOR_COLR_TABLE_HH */
145