1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker * Copyright © 2018 Ebrahim Byagowi
3*2d1272b8SAndroid Build Coastguard Worker *
4*2d1272b8SAndroid Build Coastguard Worker * This is part of HarfBuzz, a text shaping library.
5*2d1272b8SAndroid Build Coastguard Worker *
6*2d1272b8SAndroid Build Coastguard Worker * Permission is hereby granted, without written agreement and without
7*2d1272b8SAndroid Build Coastguard Worker * license or royalty fees, to use, copy, modify, and distribute this
8*2d1272b8SAndroid Build Coastguard Worker * software and its documentation for any purpose, provided that the
9*2d1272b8SAndroid Build Coastguard Worker * above copyright notice and the following two paragraphs appear in
10*2d1272b8SAndroid Build Coastguard Worker * all copies of this software.
11*2d1272b8SAndroid Build Coastguard Worker *
12*2d1272b8SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13*2d1272b8SAndroid Build Coastguard Worker * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14*2d1272b8SAndroid Build Coastguard Worker * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15*2d1272b8SAndroid Build Coastguard Worker * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16*2d1272b8SAndroid Build Coastguard Worker * DAMAGE.
17*2d1272b8SAndroid Build Coastguard Worker *
18*2d1272b8SAndroid Build Coastguard Worker * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19*2d1272b8SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20*2d1272b8SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21*2d1272b8SAndroid Build Coastguard Worker * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22*2d1272b8SAndroid Build Coastguard Worker * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23*2d1272b8SAndroid Build Coastguard Worker */
24*2d1272b8SAndroid Build Coastguard Worker
25*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_OT_STAT_TABLE_HH
26*2d1272b8SAndroid Build Coastguard Worker #define HB_OT_STAT_TABLE_HH
27*2d1272b8SAndroid Build Coastguard Worker
28*2d1272b8SAndroid Build Coastguard Worker #include "hb-open-type.hh"
29*2d1272b8SAndroid Build Coastguard Worker #include "hb-ot-layout-common.hh"
30*2d1272b8SAndroid Build Coastguard Worker
31*2d1272b8SAndroid Build Coastguard Worker /*
32*2d1272b8SAndroid Build Coastguard Worker * STAT -- Style Attributes
33*2d1272b8SAndroid Build Coastguard Worker * https://docs.microsoft.com/en-us/typography/opentype/spec/stat
34*2d1272b8SAndroid Build Coastguard Worker */
35*2d1272b8SAndroid Build Coastguard Worker #define HB_OT_TAG_STAT HB_TAG('S','T','A','T')
36*2d1272b8SAndroid Build Coastguard Worker
37*2d1272b8SAndroid Build Coastguard Worker
38*2d1272b8SAndroid Build Coastguard Worker namespace OT {
39*2d1272b8SAndroid Build Coastguard Worker
40*2d1272b8SAndroid Build Coastguard Worker enum
41*2d1272b8SAndroid Build Coastguard Worker {
42*2d1272b8SAndroid Build Coastguard Worker OLDER_SIBLING_FONT_ATTRIBUTE = 0x0001, /* If set, this axis value table
43*2d1272b8SAndroid Build Coastguard Worker * provides axis value information
44*2d1272b8SAndroid Build Coastguard Worker * that is applicable to other fonts
45*2d1272b8SAndroid Build Coastguard Worker * within the same font family. This
46*2d1272b8SAndroid Build Coastguard Worker * is used if the other fonts were
47*2d1272b8SAndroid Build Coastguard Worker * released earlier and did not include
48*2d1272b8SAndroid Build Coastguard Worker * information about values for some axis.
49*2d1272b8SAndroid Build Coastguard Worker * If newer versions of the other
50*2d1272b8SAndroid Build Coastguard Worker * fonts include the information
51*2d1272b8SAndroid Build Coastguard Worker * themselves and are present,
52*2d1272b8SAndroid Build Coastguard Worker * then this record is ignored. */
53*2d1272b8SAndroid Build Coastguard Worker ELIDABLE_AXIS_VALUE_NAME = 0x0002 /* If set, it indicates that the axis
54*2d1272b8SAndroid Build Coastguard Worker * value represents the “normal” value
55*2d1272b8SAndroid Build Coastguard Worker * for the axis and may be omitted when
56*2d1272b8SAndroid Build Coastguard Worker * composing name strings. */
57*2d1272b8SAndroid Build Coastguard Worker // Reserved = 0xFFFC /* Reserved for future use — set to zero. */
58*2d1272b8SAndroid Build Coastguard Worker };
59*2d1272b8SAndroid Build Coastguard Worker
axis_value_is_outside_axis_range(hb_tag_t axis_tag,float axis_value,const hb_hashmap_t<hb_tag_t,Triple> * user_axes_location)60*2d1272b8SAndroid Build Coastguard Worker static bool axis_value_is_outside_axis_range (hb_tag_t axis_tag, float axis_value,
61*2d1272b8SAndroid Build Coastguard Worker const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location)
62*2d1272b8SAndroid Build Coastguard Worker {
63*2d1272b8SAndroid Build Coastguard Worker if (!user_axes_location->has (axis_tag))
64*2d1272b8SAndroid Build Coastguard Worker return false;
65*2d1272b8SAndroid Build Coastguard Worker
66*2d1272b8SAndroid Build Coastguard Worker double axis_value_double = static_cast<double>(axis_value);
67*2d1272b8SAndroid Build Coastguard Worker Triple axis_range = user_axes_location->get (axis_tag);
68*2d1272b8SAndroid Build Coastguard Worker return (axis_value_double < axis_range.minimum || axis_value_double > axis_range.maximum);
69*2d1272b8SAndroid Build Coastguard Worker }
70*2d1272b8SAndroid Build Coastguard Worker
71*2d1272b8SAndroid Build Coastguard Worker struct StatAxisRecord
72*2d1272b8SAndroid Build Coastguard Worker {
cmpOT::StatAxisRecord73*2d1272b8SAndroid Build Coastguard Worker int cmp (hb_tag_t key) const { return tag.cmp (key); }
74*2d1272b8SAndroid Build Coastguard Worker
get_name_idOT::StatAxisRecord75*2d1272b8SAndroid Build Coastguard Worker hb_ot_name_id_t get_name_id () const { return nameID; }
76*2d1272b8SAndroid Build Coastguard Worker
get_axis_tagOT::StatAxisRecord77*2d1272b8SAndroid Build Coastguard Worker hb_tag_t get_axis_tag () const { return tag; }
78*2d1272b8SAndroid Build Coastguard Worker
sanitizeOT::StatAxisRecord79*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const
80*2d1272b8SAndroid Build Coastguard Worker {
81*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this);
82*2d1272b8SAndroid Build Coastguard Worker return_trace (likely (c->check_struct (this)));
83*2d1272b8SAndroid Build Coastguard Worker }
84*2d1272b8SAndroid Build Coastguard Worker
85*2d1272b8SAndroid Build Coastguard Worker protected:
86*2d1272b8SAndroid Build Coastguard Worker Tag tag; /* A tag identifying the axis of design variation. */
87*2d1272b8SAndroid Build Coastguard Worker NameID nameID; /* The name ID for entries in the 'name' table that
88*2d1272b8SAndroid Build Coastguard Worker * provide a display string for this axis. */
89*2d1272b8SAndroid Build Coastguard Worker HBUINT16 ordering; /* A value that applications can use to determine
90*2d1272b8SAndroid Build Coastguard Worker * primary sorting of face names, or for ordering
91*2d1272b8SAndroid Build Coastguard Worker * of descriptors when composing family or face names. */
92*2d1272b8SAndroid Build Coastguard Worker public:
93*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_STATIC (8);
94*2d1272b8SAndroid Build Coastguard Worker };
95*2d1272b8SAndroid Build Coastguard Worker
96*2d1272b8SAndroid Build Coastguard Worker struct AxisValueFormat1
97*2d1272b8SAndroid Build Coastguard Worker {
get_axis_indexOT::AxisValueFormat198*2d1272b8SAndroid Build Coastguard Worker unsigned int get_axis_index () const { return axisIndex; }
get_valueOT::AxisValueFormat199*2d1272b8SAndroid Build Coastguard Worker float get_value () const { return value.to_float (); }
100*2d1272b8SAndroid Build Coastguard Worker
get_value_name_idOT::AxisValueFormat1101*2d1272b8SAndroid Build Coastguard Worker hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
102*2d1272b8SAndroid Build Coastguard Worker
get_axis_tagOT::AxisValueFormat1103*2d1272b8SAndroid Build Coastguard Worker hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const
104*2d1272b8SAndroid Build Coastguard Worker {
105*2d1272b8SAndroid Build Coastguard Worker unsigned axis_idx = get_axis_index ();
106*2d1272b8SAndroid Build Coastguard Worker return axis_records[axis_idx].get_axis_tag ();
107*2d1272b8SAndroid Build Coastguard Worker }
108*2d1272b8SAndroid Build Coastguard Worker
keep_axis_valueOT::AxisValueFormat1109*2d1272b8SAndroid Build Coastguard Worker bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
110*2d1272b8SAndroid Build Coastguard Worker const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
111*2d1272b8SAndroid Build Coastguard Worker {
112*2d1272b8SAndroid Build Coastguard Worker hb_tag_t axis_tag = get_axis_tag (axis_records);
113*2d1272b8SAndroid Build Coastguard Worker float axis_value = get_value ();
114*2d1272b8SAndroid Build Coastguard Worker
115*2d1272b8SAndroid Build Coastguard Worker return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location);
116*2d1272b8SAndroid Build Coastguard Worker }
117*2d1272b8SAndroid Build Coastguard Worker
subsetOT::AxisValueFormat1118*2d1272b8SAndroid Build Coastguard Worker bool subset (hb_subset_context_t *c,
119*2d1272b8SAndroid Build Coastguard Worker const hb_array_t<const StatAxisRecord> axis_records) const
120*2d1272b8SAndroid Build Coastguard Worker {
121*2d1272b8SAndroid Build Coastguard Worker TRACE_SUBSET (this);
122*2d1272b8SAndroid Build Coastguard Worker const hb_hashmap_t<hb_tag_t, Triple>* user_axes_location = &c->plan->user_axes_location;
123*2d1272b8SAndroid Build Coastguard Worker
124*2d1272b8SAndroid Build Coastguard Worker if (keep_axis_value (axis_records, user_axes_location))
125*2d1272b8SAndroid Build Coastguard Worker return_trace (c->serializer->embed (this));
126*2d1272b8SAndroid Build Coastguard Worker
127*2d1272b8SAndroid Build Coastguard Worker return_trace (false);
128*2d1272b8SAndroid Build Coastguard Worker }
129*2d1272b8SAndroid Build Coastguard Worker
sanitizeOT::AxisValueFormat1130*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const
131*2d1272b8SAndroid Build Coastguard Worker {
132*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this);
133*2d1272b8SAndroid Build Coastguard Worker return_trace (c->check_struct (this));
134*2d1272b8SAndroid Build Coastguard Worker }
135*2d1272b8SAndroid Build Coastguard Worker
136*2d1272b8SAndroid Build Coastguard Worker protected:
137*2d1272b8SAndroid Build Coastguard Worker HBUINT16 format; /* Format identifier — set to 1. */
138*2d1272b8SAndroid Build Coastguard Worker HBUINT16 axisIndex; /* Zero-base index into the axis record array
139*2d1272b8SAndroid Build Coastguard Worker * identifying the axis of design variation
140*2d1272b8SAndroid Build Coastguard Worker * to which the axis value record applies.
141*2d1272b8SAndroid Build Coastguard Worker * Must be less than designAxisCount. */
142*2d1272b8SAndroid Build Coastguard Worker HBUINT16 flags; /* Flags — see below for details. */
143*2d1272b8SAndroid Build Coastguard Worker NameID valueNameID; /* The name ID for entries in the 'name' table
144*2d1272b8SAndroid Build Coastguard Worker * that provide a display string for this
145*2d1272b8SAndroid Build Coastguard Worker * attribute value. */
146*2d1272b8SAndroid Build Coastguard Worker F16DOT16 value; /* A numeric value for this attribute value. */
147*2d1272b8SAndroid Build Coastguard Worker public:
148*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_STATIC (12);
149*2d1272b8SAndroid Build Coastguard Worker };
150*2d1272b8SAndroid Build Coastguard Worker
151*2d1272b8SAndroid Build Coastguard Worker struct AxisValueFormat2
152*2d1272b8SAndroid Build Coastguard Worker {
get_axis_indexOT::AxisValueFormat2153*2d1272b8SAndroid Build Coastguard Worker unsigned int get_axis_index () const { return axisIndex; }
get_valueOT::AxisValueFormat2154*2d1272b8SAndroid Build Coastguard Worker float get_value () const { return nominalValue.to_float (); }
155*2d1272b8SAndroid Build Coastguard Worker
get_value_name_idOT::AxisValueFormat2156*2d1272b8SAndroid Build Coastguard Worker hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
157*2d1272b8SAndroid Build Coastguard Worker
get_axis_tagOT::AxisValueFormat2158*2d1272b8SAndroid Build Coastguard Worker hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const
159*2d1272b8SAndroid Build Coastguard Worker {
160*2d1272b8SAndroid Build Coastguard Worker unsigned axis_idx = get_axis_index ();
161*2d1272b8SAndroid Build Coastguard Worker return axis_records[axis_idx].get_axis_tag ();
162*2d1272b8SAndroid Build Coastguard Worker }
163*2d1272b8SAndroid Build Coastguard Worker
keep_axis_valueOT::AxisValueFormat2164*2d1272b8SAndroid Build Coastguard Worker bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
165*2d1272b8SAndroid Build Coastguard Worker const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
166*2d1272b8SAndroid Build Coastguard Worker {
167*2d1272b8SAndroid Build Coastguard Worker hb_tag_t axis_tag = get_axis_tag (axis_records);
168*2d1272b8SAndroid Build Coastguard Worker float axis_value = get_value ();
169*2d1272b8SAndroid Build Coastguard Worker
170*2d1272b8SAndroid Build Coastguard Worker return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location);
171*2d1272b8SAndroid Build Coastguard Worker }
172*2d1272b8SAndroid Build Coastguard Worker
subsetOT::AxisValueFormat2173*2d1272b8SAndroid Build Coastguard Worker bool subset (hb_subset_context_t *c,
174*2d1272b8SAndroid Build Coastguard Worker const hb_array_t<const StatAxisRecord> axis_records) const
175*2d1272b8SAndroid Build Coastguard Worker {
176*2d1272b8SAndroid Build Coastguard Worker TRACE_SUBSET (this);
177*2d1272b8SAndroid Build Coastguard Worker const hb_hashmap_t<hb_tag_t, Triple>* user_axes_location = &c->plan->user_axes_location;
178*2d1272b8SAndroid Build Coastguard Worker
179*2d1272b8SAndroid Build Coastguard Worker if (keep_axis_value (axis_records, user_axes_location))
180*2d1272b8SAndroid Build Coastguard Worker return_trace (c->serializer->embed (this));
181*2d1272b8SAndroid Build Coastguard Worker
182*2d1272b8SAndroid Build Coastguard Worker return_trace (false);
183*2d1272b8SAndroid Build Coastguard Worker }
184*2d1272b8SAndroid Build Coastguard Worker
sanitizeOT::AxisValueFormat2185*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const
186*2d1272b8SAndroid Build Coastguard Worker {
187*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this);
188*2d1272b8SAndroid Build Coastguard Worker return_trace (c->check_struct (this));
189*2d1272b8SAndroid Build Coastguard Worker }
190*2d1272b8SAndroid Build Coastguard Worker
191*2d1272b8SAndroid Build Coastguard Worker protected:
192*2d1272b8SAndroid Build Coastguard Worker HBUINT16 format; /* Format identifier — set to 2. */
193*2d1272b8SAndroid Build Coastguard Worker HBUINT16 axisIndex; /* Zero-base index into the axis record array
194*2d1272b8SAndroid Build Coastguard Worker * identifying the axis of design variation
195*2d1272b8SAndroid Build Coastguard Worker * to which the axis value record applies.
196*2d1272b8SAndroid Build Coastguard Worker * Must be less than designAxisCount. */
197*2d1272b8SAndroid Build Coastguard Worker HBUINT16 flags; /* Flags — see below for details. */
198*2d1272b8SAndroid Build Coastguard Worker NameID valueNameID; /* The name ID for entries in the 'name' table
199*2d1272b8SAndroid Build Coastguard Worker * that provide a display string for this
200*2d1272b8SAndroid Build Coastguard Worker * attribute value. */
201*2d1272b8SAndroid Build Coastguard Worker F16DOT16 nominalValue; /* A numeric value for this attribute value. */
202*2d1272b8SAndroid Build Coastguard Worker F16DOT16 rangeMinValue; /* The minimum value for a range associated
203*2d1272b8SAndroid Build Coastguard Worker * with the specified name ID. */
204*2d1272b8SAndroid Build Coastguard Worker F16DOT16 rangeMaxValue; /* The maximum value for a range associated
205*2d1272b8SAndroid Build Coastguard Worker * with the specified name ID. */
206*2d1272b8SAndroid Build Coastguard Worker public:
207*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_STATIC (20);
208*2d1272b8SAndroid Build Coastguard Worker };
209*2d1272b8SAndroid Build Coastguard Worker
210*2d1272b8SAndroid Build Coastguard Worker struct AxisValueFormat3
211*2d1272b8SAndroid Build Coastguard Worker {
get_axis_indexOT::AxisValueFormat3212*2d1272b8SAndroid Build Coastguard Worker unsigned int get_axis_index () const { return axisIndex; }
get_valueOT::AxisValueFormat3213*2d1272b8SAndroid Build Coastguard Worker float get_value () const { return value.to_float (); }
214*2d1272b8SAndroid Build Coastguard Worker
get_value_name_idOT::AxisValueFormat3215*2d1272b8SAndroid Build Coastguard Worker hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
216*2d1272b8SAndroid Build Coastguard Worker
get_axis_tagOT::AxisValueFormat3217*2d1272b8SAndroid Build Coastguard Worker hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const
218*2d1272b8SAndroid Build Coastguard Worker {
219*2d1272b8SAndroid Build Coastguard Worker unsigned axis_idx = get_axis_index ();
220*2d1272b8SAndroid Build Coastguard Worker return axis_records[axis_idx].get_axis_tag ();
221*2d1272b8SAndroid Build Coastguard Worker }
222*2d1272b8SAndroid Build Coastguard Worker
keep_axis_valueOT::AxisValueFormat3223*2d1272b8SAndroid Build Coastguard Worker bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
224*2d1272b8SAndroid Build Coastguard Worker const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
225*2d1272b8SAndroid Build Coastguard Worker {
226*2d1272b8SAndroid Build Coastguard Worker hb_tag_t axis_tag = get_axis_tag (axis_records);
227*2d1272b8SAndroid Build Coastguard Worker float axis_value = get_value ();
228*2d1272b8SAndroid Build Coastguard Worker
229*2d1272b8SAndroid Build Coastguard Worker return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location);
230*2d1272b8SAndroid Build Coastguard Worker }
231*2d1272b8SAndroid Build Coastguard Worker
subsetOT::AxisValueFormat3232*2d1272b8SAndroid Build Coastguard Worker bool subset (hb_subset_context_t *c,
233*2d1272b8SAndroid Build Coastguard Worker const hb_array_t<const StatAxisRecord> axis_records) const
234*2d1272b8SAndroid Build Coastguard Worker {
235*2d1272b8SAndroid Build Coastguard Worker TRACE_SUBSET (this);
236*2d1272b8SAndroid Build Coastguard Worker const hb_hashmap_t<hb_tag_t, Triple>* user_axes_location = &c->plan->user_axes_location;
237*2d1272b8SAndroid Build Coastguard Worker
238*2d1272b8SAndroid Build Coastguard Worker if (keep_axis_value (axis_records, user_axes_location))
239*2d1272b8SAndroid Build Coastguard Worker return_trace (c->serializer->embed (this));
240*2d1272b8SAndroid Build Coastguard Worker
241*2d1272b8SAndroid Build Coastguard Worker return_trace (false);
242*2d1272b8SAndroid Build Coastguard Worker }
243*2d1272b8SAndroid Build Coastguard Worker
sanitizeOT::AxisValueFormat3244*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const
245*2d1272b8SAndroid Build Coastguard Worker {
246*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this);
247*2d1272b8SAndroid Build Coastguard Worker return_trace (c->check_struct (this));
248*2d1272b8SAndroid Build Coastguard Worker }
249*2d1272b8SAndroid Build Coastguard Worker
250*2d1272b8SAndroid Build Coastguard Worker protected:
251*2d1272b8SAndroid Build Coastguard Worker HBUINT16 format; /* Format identifier — set to 3. */
252*2d1272b8SAndroid Build Coastguard Worker HBUINT16 axisIndex; /* Zero-base index into the axis record array
253*2d1272b8SAndroid Build Coastguard Worker * identifying the axis of design variation
254*2d1272b8SAndroid Build Coastguard Worker * to which the axis value record applies.
255*2d1272b8SAndroid Build Coastguard Worker * Must be less than designAxisCount. */
256*2d1272b8SAndroid Build Coastguard Worker HBUINT16 flags; /* Flags — see below for details. */
257*2d1272b8SAndroid Build Coastguard Worker NameID valueNameID; /* The name ID for entries in the 'name' table
258*2d1272b8SAndroid Build Coastguard Worker * that provide a display string for this
259*2d1272b8SAndroid Build Coastguard Worker * attribute value. */
260*2d1272b8SAndroid Build Coastguard Worker F16DOT16 value; /* A numeric value for this attribute value. */
261*2d1272b8SAndroid Build Coastguard Worker F16DOT16 linkedValue; /* The numeric value for a style-linked mapping
262*2d1272b8SAndroid Build Coastguard Worker * from this value. */
263*2d1272b8SAndroid Build Coastguard Worker public:
264*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_STATIC (16);
265*2d1272b8SAndroid Build Coastguard Worker };
266*2d1272b8SAndroid Build Coastguard Worker
267*2d1272b8SAndroid Build Coastguard Worker struct AxisValueRecord
268*2d1272b8SAndroid Build Coastguard Worker {
get_axis_indexOT::AxisValueRecord269*2d1272b8SAndroid Build Coastguard Worker unsigned int get_axis_index () const { return axisIndex; }
get_valueOT::AxisValueRecord270*2d1272b8SAndroid Build Coastguard Worker float get_value () const { return value.to_float (); }
271*2d1272b8SAndroid Build Coastguard Worker
sanitizeOT::AxisValueRecord272*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const
273*2d1272b8SAndroid Build Coastguard Worker {
274*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this);
275*2d1272b8SAndroid Build Coastguard Worker return_trace (c->check_struct (this));
276*2d1272b8SAndroid Build Coastguard Worker }
277*2d1272b8SAndroid Build Coastguard Worker
278*2d1272b8SAndroid Build Coastguard Worker protected:
279*2d1272b8SAndroid Build Coastguard Worker HBUINT16 axisIndex; /* Zero-base index into the axis record array
280*2d1272b8SAndroid Build Coastguard Worker * identifying the axis to which this value
281*2d1272b8SAndroid Build Coastguard Worker * applies. Must be less than designAxisCount. */
282*2d1272b8SAndroid Build Coastguard Worker F16DOT16 value; /* A numeric value for this attribute value. */
283*2d1272b8SAndroid Build Coastguard Worker public:
284*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_STATIC (6);
285*2d1272b8SAndroid Build Coastguard Worker };
286*2d1272b8SAndroid Build Coastguard Worker
287*2d1272b8SAndroid Build Coastguard Worker struct AxisValueFormat4
288*2d1272b8SAndroid Build Coastguard Worker {
get_axis_recordOT::AxisValueFormat4289*2d1272b8SAndroid Build Coastguard Worker const AxisValueRecord &get_axis_record (unsigned int axis_index) const
290*2d1272b8SAndroid Build Coastguard Worker { return axisValues.as_array (axisCount)[axis_index]; }
291*2d1272b8SAndroid Build Coastguard Worker
keep_axis_valueOT::AxisValueFormat4292*2d1272b8SAndroid Build Coastguard Worker bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
293*2d1272b8SAndroid Build Coastguard Worker const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
294*2d1272b8SAndroid Build Coastguard Worker {
295*2d1272b8SAndroid Build Coastguard Worker hb_array_t<const AxisValueRecord> axis_value_records = axisValues.as_array (axisCount);
296*2d1272b8SAndroid Build Coastguard Worker
297*2d1272b8SAndroid Build Coastguard Worker for (const auto& rec : axis_value_records)
298*2d1272b8SAndroid Build Coastguard Worker {
299*2d1272b8SAndroid Build Coastguard Worker unsigned axis_idx = rec.get_axis_index ();
300*2d1272b8SAndroid Build Coastguard Worker float axis_value = rec.get_value ();
301*2d1272b8SAndroid Build Coastguard Worker hb_tag_t axis_tag = axis_records[axis_idx].get_axis_tag ();
302*2d1272b8SAndroid Build Coastguard Worker
303*2d1272b8SAndroid Build Coastguard Worker if (axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location))
304*2d1272b8SAndroid Build Coastguard Worker return false;
305*2d1272b8SAndroid Build Coastguard Worker }
306*2d1272b8SAndroid Build Coastguard Worker
307*2d1272b8SAndroid Build Coastguard Worker return true;
308*2d1272b8SAndroid Build Coastguard Worker }
309*2d1272b8SAndroid Build Coastguard Worker
subsetOT::AxisValueFormat4310*2d1272b8SAndroid Build Coastguard Worker bool subset (hb_subset_context_t *c,
311*2d1272b8SAndroid Build Coastguard Worker const hb_array_t<const StatAxisRecord> axis_records) const
312*2d1272b8SAndroid Build Coastguard Worker {
313*2d1272b8SAndroid Build Coastguard Worker TRACE_SUBSET (this);
314*2d1272b8SAndroid Build Coastguard Worker const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location = &c->plan->user_axes_location;
315*2d1272b8SAndroid Build Coastguard Worker if (!keep_axis_value (axis_records, user_axes_location))
316*2d1272b8SAndroid Build Coastguard Worker return_trace (false);
317*2d1272b8SAndroid Build Coastguard Worker
318*2d1272b8SAndroid Build Coastguard Worker unsigned total_size = min_size + axisCount * AxisValueRecord::static_size;
319*2d1272b8SAndroid Build Coastguard Worker auto *out = c->serializer->allocate_size<AxisValueFormat4> (total_size);
320*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!out)) return_trace (false);
321*2d1272b8SAndroid Build Coastguard Worker hb_memcpy (out, this, total_size);
322*2d1272b8SAndroid Build Coastguard Worker return_trace (true);
323*2d1272b8SAndroid Build Coastguard Worker }
324*2d1272b8SAndroid Build Coastguard Worker
get_value_name_idOT::AxisValueFormat4325*2d1272b8SAndroid Build Coastguard Worker hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
326*2d1272b8SAndroid Build Coastguard Worker
sanitizeOT::AxisValueFormat4327*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const
328*2d1272b8SAndroid Build Coastguard Worker {
329*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this);
330*2d1272b8SAndroid Build Coastguard Worker return_trace (likely (c->check_struct (this) &&
331*2d1272b8SAndroid Build Coastguard Worker hb_barrier () &&
332*2d1272b8SAndroid Build Coastguard Worker axisValues.sanitize (c, axisCount)));
333*2d1272b8SAndroid Build Coastguard Worker }
334*2d1272b8SAndroid Build Coastguard Worker
335*2d1272b8SAndroid Build Coastguard Worker protected:
336*2d1272b8SAndroid Build Coastguard Worker HBUINT16 format; /* Format identifier — set to 4. */
337*2d1272b8SAndroid Build Coastguard Worker HBUINT16 axisCount; /* The total number of axes contributing to
338*2d1272b8SAndroid Build Coastguard Worker * this axis-values combination. */
339*2d1272b8SAndroid Build Coastguard Worker HBUINT16 flags; /* Flags — see below for details. */
340*2d1272b8SAndroid Build Coastguard Worker NameID valueNameID; /* The name ID for entries in the 'name' table
341*2d1272b8SAndroid Build Coastguard Worker * that provide a display string for this
342*2d1272b8SAndroid Build Coastguard Worker * attribute value. */
343*2d1272b8SAndroid Build Coastguard Worker UnsizedArrayOf<AxisValueRecord>
344*2d1272b8SAndroid Build Coastguard Worker axisValues; /* Array of AxisValue records that provide the
345*2d1272b8SAndroid Build Coastguard Worker * combination of axis values, one for each
346*2d1272b8SAndroid Build Coastguard Worker * contributing axis. */
347*2d1272b8SAndroid Build Coastguard Worker public:
348*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_ARRAY (8, axisValues);
349*2d1272b8SAndroid Build Coastguard Worker };
350*2d1272b8SAndroid Build Coastguard Worker
351*2d1272b8SAndroid Build Coastguard Worker struct AxisValue
352*2d1272b8SAndroid Build Coastguard Worker {
get_valueOT::AxisValue353*2d1272b8SAndroid Build Coastguard Worker float get_value (unsigned int axis_index) const
354*2d1272b8SAndroid Build Coastguard Worker {
355*2d1272b8SAndroid Build Coastguard Worker switch (u.format)
356*2d1272b8SAndroid Build Coastguard Worker {
357*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return u.format1.get_value ();
358*2d1272b8SAndroid Build Coastguard Worker case 2: hb_barrier (); return u.format2.get_value ();
359*2d1272b8SAndroid Build Coastguard Worker case 3: hb_barrier (); return u.format3.get_value ();
360*2d1272b8SAndroid Build Coastguard Worker case 4: hb_barrier (); return u.format4.get_axis_record (axis_index).get_value ();
361*2d1272b8SAndroid Build Coastguard Worker default:return 0.f;
362*2d1272b8SAndroid Build Coastguard Worker }
363*2d1272b8SAndroid Build Coastguard Worker }
364*2d1272b8SAndroid Build Coastguard Worker
get_axis_indexOT::AxisValue365*2d1272b8SAndroid Build Coastguard Worker unsigned int get_axis_index () const
366*2d1272b8SAndroid Build Coastguard Worker {
367*2d1272b8SAndroid Build Coastguard Worker switch (u.format)
368*2d1272b8SAndroid Build Coastguard Worker {
369*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return u.format1.get_axis_index ();
370*2d1272b8SAndroid Build Coastguard Worker case 2: hb_barrier (); return u.format2.get_axis_index ();
371*2d1272b8SAndroid Build Coastguard Worker case 3: hb_barrier (); return u.format3.get_axis_index ();
372*2d1272b8SAndroid Build Coastguard Worker /* case 4: Makes more sense for variable fonts which are handled by fvar in hb-style */
373*2d1272b8SAndroid Build Coastguard Worker default:return -1;
374*2d1272b8SAndroid Build Coastguard Worker }
375*2d1272b8SAndroid Build Coastguard Worker }
376*2d1272b8SAndroid Build Coastguard Worker
get_value_name_idOT::AxisValue377*2d1272b8SAndroid Build Coastguard Worker hb_ot_name_id_t get_value_name_id () const
378*2d1272b8SAndroid Build Coastguard Worker {
379*2d1272b8SAndroid Build Coastguard Worker switch (u.format)
380*2d1272b8SAndroid Build Coastguard Worker {
381*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return u.format1.get_value_name_id ();
382*2d1272b8SAndroid Build Coastguard Worker case 2: hb_barrier (); return u.format2.get_value_name_id ();
383*2d1272b8SAndroid Build Coastguard Worker case 3: hb_barrier (); return u.format3.get_value_name_id ();
384*2d1272b8SAndroid Build Coastguard Worker case 4: hb_barrier (); return u.format4.get_value_name_id ();
385*2d1272b8SAndroid Build Coastguard Worker default:return HB_OT_NAME_ID_INVALID;
386*2d1272b8SAndroid Build Coastguard Worker }
387*2d1272b8SAndroid Build Coastguard Worker }
388*2d1272b8SAndroid Build Coastguard Worker
389*2d1272b8SAndroid Build Coastguard Worker template <typename context_t, typename ...Ts>
dispatchOT::AxisValue390*2d1272b8SAndroid Build Coastguard Worker typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
391*2d1272b8SAndroid Build Coastguard Worker {
392*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
393*2d1272b8SAndroid Build Coastguard Worker TRACE_DISPATCH (this, u.format);
394*2d1272b8SAndroid Build Coastguard Worker switch (u.format) {
395*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
396*2d1272b8SAndroid Build Coastguard Worker case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
397*2d1272b8SAndroid Build Coastguard Worker case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
398*2d1272b8SAndroid Build Coastguard Worker case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
399*2d1272b8SAndroid Build Coastguard Worker default:return_trace (c->default_return_value ());
400*2d1272b8SAndroid Build Coastguard Worker }
401*2d1272b8SAndroid Build Coastguard Worker }
402*2d1272b8SAndroid Build Coastguard Worker
keep_axis_valueOT::AxisValue403*2d1272b8SAndroid Build Coastguard Worker bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
404*2d1272b8SAndroid Build Coastguard Worker hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
405*2d1272b8SAndroid Build Coastguard Worker {
406*2d1272b8SAndroid Build Coastguard Worker switch (u.format)
407*2d1272b8SAndroid Build Coastguard Worker {
408*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return u.format1.keep_axis_value (axis_records, user_axes_location);
409*2d1272b8SAndroid Build Coastguard Worker case 2: hb_barrier (); return u.format2.keep_axis_value (axis_records, user_axes_location);
410*2d1272b8SAndroid Build Coastguard Worker case 3: hb_barrier (); return u.format3.keep_axis_value (axis_records, user_axes_location);
411*2d1272b8SAndroid Build Coastguard Worker case 4: hb_barrier (); return u.format4.keep_axis_value (axis_records, user_axes_location);
412*2d1272b8SAndroid Build Coastguard Worker default:return false;
413*2d1272b8SAndroid Build Coastguard Worker }
414*2d1272b8SAndroid Build Coastguard Worker }
415*2d1272b8SAndroid Build Coastguard Worker
sanitizeOT::AxisValue416*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const
417*2d1272b8SAndroid Build Coastguard Worker {
418*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this);
419*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!c->check_struct (this)))
420*2d1272b8SAndroid Build Coastguard Worker return_trace (false);
421*2d1272b8SAndroid Build Coastguard Worker hb_barrier ();
422*2d1272b8SAndroid Build Coastguard Worker
423*2d1272b8SAndroid Build Coastguard Worker switch (u.format)
424*2d1272b8SAndroid Build Coastguard Worker {
425*2d1272b8SAndroid Build Coastguard Worker case 1: hb_barrier (); return_trace (u.format1.sanitize (c));
426*2d1272b8SAndroid Build Coastguard Worker case 2: hb_barrier (); return_trace (u.format2.sanitize (c));
427*2d1272b8SAndroid Build Coastguard Worker case 3: hb_barrier (); return_trace (u.format3.sanitize (c));
428*2d1272b8SAndroid Build Coastguard Worker case 4: hb_barrier (); return_trace (u.format4.sanitize (c));
429*2d1272b8SAndroid Build Coastguard Worker default:return_trace (true);
430*2d1272b8SAndroid Build Coastguard Worker }
431*2d1272b8SAndroid Build Coastguard Worker }
432*2d1272b8SAndroid Build Coastguard Worker
433*2d1272b8SAndroid Build Coastguard Worker protected:
434*2d1272b8SAndroid Build Coastguard Worker union
435*2d1272b8SAndroid Build Coastguard Worker {
436*2d1272b8SAndroid Build Coastguard Worker HBUINT16 format;
437*2d1272b8SAndroid Build Coastguard Worker AxisValueFormat1 format1;
438*2d1272b8SAndroid Build Coastguard Worker AxisValueFormat2 format2;
439*2d1272b8SAndroid Build Coastguard Worker AxisValueFormat3 format3;
440*2d1272b8SAndroid Build Coastguard Worker AxisValueFormat4 format4;
441*2d1272b8SAndroid Build Coastguard Worker } u;
442*2d1272b8SAndroid Build Coastguard Worker public:
443*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_UNION (2, format);
444*2d1272b8SAndroid Build Coastguard Worker };
445*2d1272b8SAndroid Build Coastguard Worker
446*2d1272b8SAndroid Build Coastguard Worker struct AxisValueOffsetArray: UnsizedArrayOf<Offset16To<AxisValue>>
447*2d1272b8SAndroid Build Coastguard Worker {
subsetOT::AxisValueOffsetArray448*2d1272b8SAndroid Build Coastguard Worker bool subset (hb_subset_context_t *c,
449*2d1272b8SAndroid Build Coastguard Worker unsigned axisValueCount,
450*2d1272b8SAndroid Build Coastguard Worker unsigned& count,
451*2d1272b8SAndroid Build Coastguard Worker const hb_array_t<const StatAxisRecord> axis_records) const
452*2d1272b8SAndroid Build Coastguard Worker {
453*2d1272b8SAndroid Build Coastguard Worker TRACE_SUBSET (this);
454*2d1272b8SAndroid Build Coastguard Worker
455*2d1272b8SAndroid Build Coastguard Worker auto axisValueOffsets = as_array (axisValueCount);
456*2d1272b8SAndroid Build Coastguard Worker count = 0;
457*2d1272b8SAndroid Build Coastguard Worker for (const auto& offset : axisValueOffsets)
458*2d1272b8SAndroid Build Coastguard Worker {
459*2d1272b8SAndroid Build Coastguard Worker if (!offset) continue;
460*2d1272b8SAndroid Build Coastguard Worker auto o_snap = c->serializer->snapshot ();
461*2d1272b8SAndroid Build Coastguard Worker auto *o = c->serializer->embed (offset);
462*2d1272b8SAndroid Build Coastguard Worker if (!o) return_trace (false);
463*2d1272b8SAndroid Build Coastguard Worker if (!o->serialize_subset (c, offset, this, axis_records))
464*2d1272b8SAndroid Build Coastguard Worker {
465*2d1272b8SAndroid Build Coastguard Worker c->serializer->revert (o_snap);
466*2d1272b8SAndroid Build Coastguard Worker continue;
467*2d1272b8SAndroid Build Coastguard Worker }
468*2d1272b8SAndroid Build Coastguard Worker count++;
469*2d1272b8SAndroid Build Coastguard Worker }
470*2d1272b8SAndroid Build Coastguard Worker
471*2d1272b8SAndroid Build Coastguard Worker return_trace (count);
472*2d1272b8SAndroid Build Coastguard Worker }
473*2d1272b8SAndroid Build Coastguard Worker };
474*2d1272b8SAndroid Build Coastguard Worker
475*2d1272b8SAndroid Build Coastguard Worker struct STAT
476*2d1272b8SAndroid Build Coastguard Worker {
477*2d1272b8SAndroid Build Coastguard Worker static constexpr hb_tag_t tableTag = HB_OT_TAG_STAT;
478*2d1272b8SAndroid Build Coastguard Worker
has_dataOT::STAT479*2d1272b8SAndroid Build Coastguard Worker bool has_data () const { return version.to_int (); }
480*2d1272b8SAndroid Build Coastguard Worker
get_valueOT::STAT481*2d1272b8SAndroid Build Coastguard Worker bool get_value (hb_tag_t tag, float *value) const
482*2d1272b8SAndroid Build Coastguard Worker {
483*2d1272b8SAndroid Build Coastguard Worker unsigned int axis_index;
484*2d1272b8SAndroid Build Coastguard Worker if (!get_design_axes ().lfind (tag, &axis_index)) return false;
485*2d1272b8SAndroid Build Coastguard Worker
486*2d1272b8SAndroid Build Coastguard Worker hb_array_t<const Offset16To<AxisValue>> axis_values = get_axis_value_offsets ();
487*2d1272b8SAndroid Build Coastguard Worker for (unsigned int i = 0; i < axis_values.length; i++)
488*2d1272b8SAndroid Build Coastguard Worker {
489*2d1272b8SAndroid Build Coastguard Worker const AxisValue& axis_value = this+offsetToAxisValueOffsets+axis_values[i];
490*2d1272b8SAndroid Build Coastguard Worker if (axis_value.get_axis_index () == axis_index)
491*2d1272b8SAndroid Build Coastguard Worker {
492*2d1272b8SAndroid Build Coastguard Worker if (value)
493*2d1272b8SAndroid Build Coastguard Worker *value = axis_value.get_value (axis_index);
494*2d1272b8SAndroid Build Coastguard Worker return true;
495*2d1272b8SAndroid Build Coastguard Worker }
496*2d1272b8SAndroid Build Coastguard Worker }
497*2d1272b8SAndroid Build Coastguard Worker return false;
498*2d1272b8SAndroid Build Coastguard Worker }
499*2d1272b8SAndroid Build Coastguard Worker
get_design_axis_countOT::STAT500*2d1272b8SAndroid Build Coastguard Worker unsigned get_design_axis_count () const { return designAxisCount; }
501*2d1272b8SAndroid Build Coastguard Worker
get_axis_record_name_idOT::STAT502*2d1272b8SAndroid Build Coastguard Worker hb_ot_name_id_t get_axis_record_name_id (unsigned axis_record_index) const
503*2d1272b8SAndroid Build Coastguard Worker {
504*2d1272b8SAndroid Build Coastguard Worker if (unlikely (axis_record_index >= designAxisCount)) return HB_OT_NAME_ID_INVALID;
505*2d1272b8SAndroid Build Coastguard Worker const StatAxisRecord &axis_record = get_design_axes ()[axis_record_index];
506*2d1272b8SAndroid Build Coastguard Worker return axis_record.get_name_id ();
507*2d1272b8SAndroid Build Coastguard Worker }
508*2d1272b8SAndroid Build Coastguard Worker
get_axis_value_countOT::STAT509*2d1272b8SAndroid Build Coastguard Worker unsigned get_axis_value_count () const { return axisValueCount; }
510*2d1272b8SAndroid Build Coastguard Worker
get_axis_value_name_idOT::STAT511*2d1272b8SAndroid Build Coastguard Worker hb_ot_name_id_t get_axis_value_name_id (unsigned axis_value_index) const
512*2d1272b8SAndroid Build Coastguard Worker {
513*2d1272b8SAndroid Build Coastguard Worker if (unlikely (axis_value_index >= axisValueCount)) return HB_OT_NAME_ID_INVALID;
514*2d1272b8SAndroid Build Coastguard Worker const AxisValue &axis_value = (this + get_axis_value_offsets ()[axis_value_index]);
515*2d1272b8SAndroid Build Coastguard Worker return axis_value.get_value_name_id ();
516*2d1272b8SAndroid Build Coastguard Worker }
517*2d1272b8SAndroid Build Coastguard Worker
collect_name_idsOT::STAT518*2d1272b8SAndroid Build Coastguard Worker void collect_name_ids (hb_hashmap_t<hb_tag_t, Triple> *user_axes_location,
519*2d1272b8SAndroid Build Coastguard Worker hb_set_t *nameids_to_retain /* OUT */) const
520*2d1272b8SAndroid Build Coastguard Worker {
521*2d1272b8SAndroid Build Coastguard Worker if (!has_data ()) return;
522*2d1272b8SAndroid Build Coastguard Worker
523*2d1272b8SAndroid Build Coastguard Worker + get_design_axes ()
524*2d1272b8SAndroid Build Coastguard Worker | hb_map (&StatAxisRecord::get_name_id)
525*2d1272b8SAndroid Build Coastguard Worker | hb_sink (nameids_to_retain)
526*2d1272b8SAndroid Build Coastguard Worker ;
527*2d1272b8SAndroid Build Coastguard Worker
528*2d1272b8SAndroid Build Coastguard Worker auto designAxes = get_design_axes ();
529*2d1272b8SAndroid Build Coastguard Worker
530*2d1272b8SAndroid Build Coastguard Worker + get_axis_value_offsets ()
531*2d1272b8SAndroid Build Coastguard Worker | hb_map (hb_add (&(this + offsetToAxisValueOffsets)))
532*2d1272b8SAndroid Build Coastguard Worker | hb_filter ([&] (const AxisValue& _)
533*2d1272b8SAndroid Build Coastguard Worker { return _.keep_axis_value (designAxes, user_axes_location); })
534*2d1272b8SAndroid Build Coastguard Worker | hb_map (&AxisValue::get_value_name_id)
535*2d1272b8SAndroid Build Coastguard Worker | hb_sink (nameids_to_retain)
536*2d1272b8SAndroid Build Coastguard Worker ;
537*2d1272b8SAndroid Build Coastguard Worker
538*2d1272b8SAndroid Build Coastguard Worker nameids_to_retain->add (elidedFallbackNameID);
539*2d1272b8SAndroid Build Coastguard Worker }
540*2d1272b8SAndroid Build Coastguard Worker
subsetOT::STAT541*2d1272b8SAndroid Build Coastguard Worker bool subset (hb_subset_context_t *c) const
542*2d1272b8SAndroid Build Coastguard Worker {
543*2d1272b8SAndroid Build Coastguard Worker TRACE_SUBSET (this);
544*2d1272b8SAndroid Build Coastguard Worker STAT *out = c->serializer->embed (this);
545*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!out)) return_trace (false);
546*2d1272b8SAndroid Build Coastguard Worker
547*2d1272b8SAndroid Build Coastguard Worker auto designAxes = get_design_axes ();
548*2d1272b8SAndroid Build Coastguard Worker for (unsigned i = 0; i < (unsigned)designAxisCount; i++)
549*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!c->serializer->embed (designAxes[i])))
550*2d1272b8SAndroid Build Coastguard Worker return_trace (false);
551*2d1272b8SAndroid Build Coastguard Worker
552*2d1272b8SAndroid Build Coastguard Worker if (designAxisCount)
553*2d1272b8SAndroid Build Coastguard Worker c->serializer->check_assign (out->designAxesOffset, this->get_size (),
554*2d1272b8SAndroid Build Coastguard Worker HB_SERIALIZE_ERROR_INT_OVERFLOW);
555*2d1272b8SAndroid Build Coastguard Worker
556*2d1272b8SAndroid Build Coastguard Worker unsigned count = 0;
557*2d1272b8SAndroid Build Coastguard Worker out->offsetToAxisValueOffsets.serialize_subset (c, offsetToAxisValueOffsets, this,
558*2d1272b8SAndroid Build Coastguard Worker axisValueCount, count, designAxes);
559*2d1272b8SAndroid Build Coastguard Worker return_trace (c->serializer->check_assign (out->axisValueCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
560*2d1272b8SAndroid Build Coastguard Worker }
561*2d1272b8SAndroid Build Coastguard Worker
sanitizeOT::STAT562*2d1272b8SAndroid Build Coastguard Worker bool sanitize (hb_sanitize_context_t *c) const
563*2d1272b8SAndroid Build Coastguard Worker {
564*2d1272b8SAndroid Build Coastguard Worker TRACE_SANITIZE (this);
565*2d1272b8SAndroid Build Coastguard Worker return_trace (likely (c->check_struct (this) &&
566*2d1272b8SAndroid Build Coastguard Worker hb_barrier () &&
567*2d1272b8SAndroid Build Coastguard Worker version.major == 1 &&
568*2d1272b8SAndroid Build Coastguard Worker version.minor > 0 &&
569*2d1272b8SAndroid Build Coastguard Worker designAxesOffset.sanitize (c, this, designAxisCount) &&
570*2d1272b8SAndroid Build Coastguard Worker offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
571*2d1272b8SAndroid Build Coastguard Worker }
572*2d1272b8SAndroid Build Coastguard Worker
573*2d1272b8SAndroid Build Coastguard Worker protected:
get_design_axesOT::STAT574*2d1272b8SAndroid Build Coastguard Worker hb_array_t<const StatAxisRecord> const get_design_axes () const
575*2d1272b8SAndroid Build Coastguard Worker { return (this+designAxesOffset).as_array (designAxisCount); }
576*2d1272b8SAndroid Build Coastguard Worker
get_axis_value_offsetsOT::STAT577*2d1272b8SAndroid Build Coastguard Worker hb_array_t<const Offset16To<AxisValue>> const get_axis_value_offsets () const
578*2d1272b8SAndroid Build Coastguard Worker { return (this+offsetToAxisValueOffsets).as_array (axisValueCount); }
579*2d1272b8SAndroid Build Coastguard Worker
580*2d1272b8SAndroid Build Coastguard Worker
581*2d1272b8SAndroid Build Coastguard Worker protected:
582*2d1272b8SAndroid Build Coastguard Worker FixedVersion<>version; /* Version of the stat table
583*2d1272b8SAndroid Build Coastguard Worker * initially set to 0x00010002u */
584*2d1272b8SAndroid Build Coastguard Worker HBUINT16 designAxisSize; /* The size in bytes of each axis record. */
585*2d1272b8SAndroid Build Coastguard Worker HBUINT16 designAxisCount;/* The number of design axis records. In a
586*2d1272b8SAndroid Build Coastguard Worker * font with an 'fvar' table, this value must be
587*2d1272b8SAndroid Build Coastguard Worker * greater than or equal to the axisCount value
588*2d1272b8SAndroid Build Coastguard Worker * in the 'fvar' table. In all fonts, must
589*2d1272b8SAndroid Build Coastguard Worker * be greater than zero if axisValueCount
590*2d1272b8SAndroid Build Coastguard Worker * is greater than zero. */
591*2d1272b8SAndroid Build Coastguard Worker NNOffset32To<UnsizedArrayOf<StatAxisRecord>>
592*2d1272b8SAndroid Build Coastguard Worker designAxesOffset;
593*2d1272b8SAndroid Build Coastguard Worker /* Offset in bytes from the beginning of
594*2d1272b8SAndroid Build Coastguard Worker * the STAT table to the start of the design
595*2d1272b8SAndroid Build Coastguard Worker * axes array. If designAxisCount is zero,
596*2d1272b8SAndroid Build Coastguard Worker * set to zero; if designAxisCount is greater
597*2d1272b8SAndroid Build Coastguard Worker * than zero, must be greater than zero. */
598*2d1272b8SAndroid Build Coastguard Worker HBUINT16 axisValueCount; /* The number of axis value tables. */
599*2d1272b8SAndroid Build Coastguard Worker NNOffset32To<AxisValueOffsetArray>
600*2d1272b8SAndroid Build Coastguard Worker offsetToAxisValueOffsets;
601*2d1272b8SAndroid Build Coastguard Worker /* Offset in bytes from the beginning of
602*2d1272b8SAndroid Build Coastguard Worker * the STAT table to the start of the design
603*2d1272b8SAndroid Build Coastguard Worker * axes value offsets array. If axisValueCount
604*2d1272b8SAndroid Build Coastguard Worker * is zero, set to zero; if axisValueCount is
605*2d1272b8SAndroid Build Coastguard Worker * greater than zero, must be greater than zero. */
606*2d1272b8SAndroid Build Coastguard Worker NameID elidedFallbackNameID;
607*2d1272b8SAndroid Build Coastguard Worker /* Name ID used as fallback when projection of
608*2d1272b8SAndroid Build Coastguard Worker * names into a particular font model produces
609*2d1272b8SAndroid Build Coastguard Worker * a subfamily name containing only elidable
610*2d1272b8SAndroid Build Coastguard Worker * elements. */
611*2d1272b8SAndroid Build Coastguard Worker public:
612*2d1272b8SAndroid Build Coastguard Worker DEFINE_SIZE_STATIC (20);
613*2d1272b8SAndroid Build Coastguard Worker };
614*2d1272b8SAndroid Build Coastguard Worker
615*2d1272b8SAndroid Build Coastguard Worker
616*2d1272b8SAndroid Build Coastguard Worker } /* namespace OT */
617*2d1272b8SAndroid Build Coastguard Worker
618*2d1272b8SAndroid Build Coastguard Worker
619*2d1272b8SAndroid Build Coastguard Worker #endif /* HB_OT_STAT_TABLE_HH */
620