Imported Upstream version 2.6.4
[platform/upstream/harfbuzz.git] / src / hb-ot-color-colr-table.hh
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
37 namespace OT {
38
39
40 struct LayerRecord
41 {
42   operator hb_ot_color_layer_t () const { return {glyphId, colorIdx}; }
43
44   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   HBGlyphID     glyphId;        /* Glyph ID of layer glyph */
52   Index         colorIdx;       /* Index value to use with a
53                                  * selected color palette.
54                                  * An index value of 0xFFFF
55                                  * is a special case indicating
56                                  * that the text foreground
57                                  * color (defined by a
58                                  * higher-level client) should
59                                  * be used and shall not be
60                                  * treated as actual index
61                                  * into CPAL ColorRecord array. */
62   public:
63   DEFINE_SIZE_STATIC (4);
64 };
65
66 struct BaseGlyphRecord
67 {
68   int cmp (hb_codepoint_t g) const
69   { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
70
71   bool sanitize (hb_sanitize_context_t *c) const
72   {
73     TRACE_SANITIZE (this);
74     return_trace (likely (c->check_struct (this)));
75   }
76
77   public:
78   HBGlyphID     glyphId;        /* Glyph ID of reference glyph */
79   HBUINT16      firstLayerIdx;  /* Index (from beginning of
80                                  * the Layer Records) to the
81                                  * layer record. There will be
82                                  * numLayers consecutive entries
83                                  * for this base glyph. */
84   HBUINT16      numLayers;      /* Number of color layers
85                                  * associated with this glyph */
86   public:
87   DEFINE_SIZE_STATIC (6);
88 };
89
90 struct COLR
91 {
92   static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR;
93
94   bool has_data () const { return numBaseGlyphs; }
95
96   unsigned int get_glyph_layers (hb_codepoint_t       glyph,
97                                  unsigned int         start_offset,
98                                  unsigned int        *count, /* IN/OUT.  May be NULL. */
99                                  hb_ot_color_layer_t *layers /* OUT.     May be NULL. */) const
100   {
101     const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph);
102
103     hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
104     hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
105                                                                        record.numLayers);
106     if (count)
107     {
108       + glyph_layers.sub_array (start_offset, count)
109       | hb_sink (hb_array (layers, *count))
110       ;
111     }
112     return glyph_layers.length;
113   }
114
115   bool sanitize (hb_sanitize_context_t *c) const
116   {
117     TRACE_SANITIZE (this);
118     return_trace (likely (c->check_struct (this) &&
119                           (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
120                           (this+layersZ).sanitize (c, numLayers)));
121   }
122
123   protected:
124   HBUINT16      version;        /* Table version number (starts at 0). */
125   HBUINT16      numBaseGlyphs;  /* Number of Base Glyph Records. */
126   LNNOffsetTo<SortedUnsizedArrayOf<BaseGlyphRecord>>
127                 baseGlyphsZ;    /* Offset to Base Glyph records. */
128   LNNOffsetTo<UnsizedArrayOf<LayerRecord>>
129                 layersZ;        /* Offset to Layer Records. */
130   HBUINT16      numLayers;      /* Number of Layer Records. */
131   public:
132   DEFINE_SIZE_STATIC (14);
133 };
134
135 } /* namespace OT */
136
137
138 #endif /* HB_OT_COLOR_COLR_TABLE_HH */