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_STAT_TABLE_HH
26#define HB_OT_STAT_TABLE_HH
27
28#include "hb-open-type.hh"
29#include "hb-ot-layout-common.hh"
30
31/*
32 * STAT -- Style Attributes
33 * https://docs.microsoft.com/en-us/typography/opentype/spec/stat
34 */
35#define HB_OT_TAG_STAT HB_TAG('S','T','A','T')
36
37
38namespace OT {
39
40enum
41{
42 OLDER_SIBLING_FONT_ATTRIBUTE = 0x0001, /* If set, this axis value table
43 * provides axis value information
44 * that is applicable to other fonts
45 * within the same font family. This
46 * is used if the other fonts were
47 * released earlier and did not include
48 * information about values for some axis.
49 * If newer versions of the other
50 * fonts include the information
51 * themselves and are present,
52 * then this record is ignored. */
53 ELIDABLE_AXIS_VALUE_NAME = 0x0002 /* If set, it indicates that the axis
54 * value represents the “normal” value
55 * for the axis and may be omitted when
56 * composing name strings. */
57 // Reserved = 0xFFFC /* Reserved for future use — set to zero. */
58};
59
60struct AxisValueFormat1
61{
62 bool sanitize (hb_sanitize_context_t *c) const
63 {
64 TRACE_SANITIZE (this);
65 return_trace (likely (c->check_struct (this)));
66 }
67
68 protected:
69 HBUINT16 format; /* Format identifier — set to 1. */
70 HBUINT16 axisIndex; /* Zero-base index into the axis record array
71 * identifying the axis of design variation
72 * to which the axis value record applies.
73 * Must be less than designAxisCount. */
74 HBUINT16 flags; /* Flags — see below for details. */
75 NameID valueNameID; /* The name ID for entries in the 'name' table
76 * that provide a display string for this
77 * attribute value. */
78 Fixed value; /* A numeric value for this attribute value. */
79 public:
80 DEFINE_SIZE_STATIC (12);
81};
82
83struct AxisValueFormat2
84{
85 bool sanitize (hb_sanitize_context_t *c) const
86 {
87 TRACE_SANITIZE (this);
88 return_trace (likely (c->check_struct (this)));
89 }
90
91 protected:
92 HBUINT16 format; /* Format identifier — set to 2. */
93 HBUINT16 axisIndex; /* Zero-base index into the axis record array
94 * identifying the axis of design variation
95 * to which the axis value record applies.
96 * Must be less than designAxisCount. */
97 HBUINT16 flags; /* Flags — see below for details. */
98 NameID valueNameID; /* The name ID for entries in the 'name' table
99 * that provide a display string for this
100 * attribute value. */
101 Fixed nominalValue; /* A numeric value for this attribute value. */
102 Fixed rangeMinValue; /* The minimum value for a range associated
103 * with the specified name ID. */
104 Fixed rangeMaxValue; /* The maximum value for a range associated
105 * with the specified name ID. */
106 public:
107 DEFINE_SIZE_STATIC (20);
108};
109
110struct AxisValueFormat3
111{
112 bool sanitize (hb_sanitize_context_t *c) const
113 {
114 TRACE_SANITIZE (this);
115 return_trace (likely (c->check_struct (this)));
116 }
117
118 protected:
119 HBUINT16 format; /* Format identifier — set to 3. */
120 HBUINT16 axisIndex; /* Zero-base index into the axis record array
121 * identifying the axis of design variation
122 * to which the axis value record applies.
123 * Must be less than designAxisCount. */
124 HBUINT16 flags; /* Flags — see below for details. */
125 NameID valueNameID; /* The name ID for entries in the 'name' table
126 * that provide a display string for this
127 * attribute value. */
128 Fixed value; /* A numeric value for this attribute value. */
129 Fixed linkedValue; /* The numeric value for a style-linked mapping
130 * from this value. */
131 public:
132 DEFINE_SIZE_STATIC (16);
133};
134
135struct AxisValueRecord
136{
137 bool sanitize (hb_sanitize_context_t *c) const
138 {
139 TRACE_SANITIZE (this);
140 return_trace (likely (c->check_struct (this)));
141 }
142
143 protected:
144 HBUINT16 axisIndex; /* Zero-base index into the axis record array
145 * identifying the axis to which this value
146 * applies. Must be less than designAxisCount. */
147 Fixed value; /* A numeric value for this attribute value. */
148 public:
149 DEFINE_SIZE_STATIC (6);
150};
151
152struct AxisValueFormat4
153{
154 bool sanitize (hb_sanitize_context_t *c) const
155 {
156 TRACE_SANITIZE (this);
157 return_trace (likely (c->check_struct (this)));
158 }
159
160 protected:
161 HBUINT16 format; /* Format identifier — set to 4. */
162 HBUINT16 axisCount; /* The total number of axes contributing to
163 * this axis-values combination. */
164 HBUINT16 flags; /* Flags — see below for details. */
165 NameID valueNameID; /* The name ID for entries in the 'name' table
166 * that provide a display string for this
167 * attribute value. */
168 UnsizedArrayOf<AxisValueRecord>
169 axisValues; /* Array of AxisValue records that provide the
170 * combination of axis values, one for each
171 * contributing axis. */
172 public:
173 DEFINE_SIZE_ARRAY (8, axisValues);
174};
175
176struct AxisValue
177{
178 bool sanitize (hb_sanitize_context_t *c) const
179 {
180 TRACE_SANITIZE (this);
181 if (unlikely (c->check_struct (this)))
182 return_trace (false);
183
184 switch (u.format)
185 {
186 case 1: return_trace (likely (u.format1.sanitize (c)));
187 case 2: return_trace (likely (u.format2.sanitize (c)));
188 case 3: return_trace (likely (u.format3.sanitize (c)));
189 case 4: return_trace (likely (u.format4.sanitize (c)));
190 default: return_trace (true);
191 }
192 }
193
194 protected:
195 union
196 {
197 HBUINT16 format;
198 AxisValueFormat1 format1;
199 AxisValueFormat2 format2;
200 AxisValueFormat3 format3;
201 AxisValueFormat4 format4;
202 } u;
203 public:
204 DEFINE_SIZE_UNION (2, format);
205};
206
207struct StatAxisRecord
208{
209 bool sanitize (hb_sanitize_context_t *c) const
210 {
211 TRACE_SANITIZE (this);
212 return_trace (likely (c->check_struct (this)));
213 }
214
215 protected:
216 Tag tag; /* A tag identifying the axis of design variation. */
217 NameID nameID; /* The name ID for entries in the 'name' table that
218 * provide a display string for this axis. */
219 HBUINT16 ordering; /* A value that applications can use to determine
220 * primary sorting of face names, or for ordering
221 * of descriptors when composing family or face names. */
222 public:
223 DEFINE_SIZE_STATIC (8);
224};
225
226struct STAT
227{
228 static constexpr hb_tag_t tableTag = HB_OT_TAG_STAT;
229
230 bool sanitize (hb_sanitize_context_t *c) const
231 {
232 TRACE_SANITIZE (this);
233 return_trace (likely (c->check_struct (this) &&
234 majorVersion == 1 &&
235 minorVersion > 0 &&
236 designAxesOffset.sanitize (c, this, designAxisCount) &&
237 offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
238 }
239
240 protected:
241 HBUINT16 majorVersion; /* Major version number of the style attributes
242 * table — set to 1. */
243 HBUINT16 minorVersion; /* Minor version number of the style attributes
244 * table — set to 2. */
245 HBUINT16 designAxisSize; /* The size in bytes of each axis record. */
246 HBUINT16 designAxisCount;/* The number of design axis records. In a
247 * font with an 'fvar' table, this value must be
248 * greater than or equal to the axisCount value
249 * in the 'fvar' table. In all fonts, must
250 * be greater than zero if axisValueCount
251 * is greater than zero. */
252 LNNOffsetTo<UnsizedArrayOf<StatAxisRecord> >
253 designAxesOffset;
254 /* Offset in bytes from the beginning of
255 * the STAT table to the start of the design
256 * axes array. If designAxisCount is zero,
257 * set to zero; if designAxisCount is greater
258 * than zero, must be greater than zero. */
259 HBUINT16 axisValueCount; /* The number of axis value tables. */
260 LNNOffsetTo<UnsizedArrayOf<OffsetTo<AxisValue> > >
261 offsetToAxisValueOffsets;
262 /* Offset in bytes from the beginning of
263 * the STAT table to the start of the design
264 * axes value offsets array. If axisValueCount
265 * is zero, set to zero; if axisValueCount is
266 * greater than zero, must be greater than zero. */
267 NameID elidedFallbackNameID;
268 /* Name ID used as fallback when projection of
269 * names into a particular font model produces
270 * a subfamily name containing only elidable
271 * elements. */
272 public:
273 DEFINE_SIZE_STATIC (20);
274};
275
276
277} /* namespace OT */
278
279
280#endif /* HB_OT_STAT_TABLE_HH */
281