xref: /aosp_15_r20/external/harfbuzz_ng/src/hb-aat-layout-feat-table.hh (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
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_AAT_LAYOUT_FEAT_TABLE_HH
26*2d1272b8SAndroid Build Coastguard Worker #define HB_AAT_LAYOUT_FEAT_TABLE_HH
27*2d1272b8SAndroid Build Coastguard Worker 
28*2d1272b8SAndroid Build Coastguard Worker #include "hb-aat-layout-common.hh"
29*2d1272b8SAndroid Build Coastguard Worker 
30*2d1272b8SAndroid Build Coastguard Worker /*
31*2d1272b8SAndroid Build Coastguard Worker  * feat -- Feature Name
32*2d1272b8SAndroid Build Coastguard Worker  * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6feat.html
33*2d1272b8SAndroid Build Coastguard Worker  */
34*2d1272b8SAndroid Build Coastguard Worker #define HB_AAT_TAG_feat HB_TAG('f','e','a','t')
35*2d1272b8SAndroid Build Coastguard Worker 
36*2d1272b8SAndroid Build Coastguard Worker 
37*2d1272b8SAndroid Build Coastguard Worker namespace AAT {
38*2d1272b8SAndroid Build Coastguard Worker 
39*2d1272b8SAndroid Build Coastguard Worker 
40*2d1272b8SAndroid Build Coastguard Worker struct SettingName
41*2d1272b8SAndroid Build Coastguard Worker {
42*2d1272b8SAndroid Build Coastguard Worker   friend struct FeatureName;
43*2d1272b8SAndroid Build Coastguard Worker 
cmpAAT::SettingName44*2d1272b8SAndroid Build Coastguard Worker   int cmp (hb_aat_layout_feature_selector_t key) const
45*2d1272b8SAndroid Build Coastguard Worker   { return (int) key - (int) setting; }
46*2d1272b8SAndroid Build Coastguard Worker 
get_selectorAAT::SettingName47*2d1272b8SAndroid Build Coastguard Worker   hb_aat_layout_feature_selector_t get_selector () const
48*2d1272b8SAndroid Build Coastguard Worker   { return (hb_aat_layout_feature_selector_t) (unsigned) setting; }
49*2d1272b8SAndroid Build Coastguard Worker 
get_infoAAT::SettingName50*2d1272b8SAndroid Build Coastguard Worker   hb_aat_layout_feature_selector_info_t get_info (hb_aat_layout_feature_selector_t default_selector) const
51*2d1272b8SAndroid Build Coastguard Worker   {
52*2d1272b8SAndroid Build Coastguard Worker     return {
53*2d1272b8SAndroid Build Coastguard Worker       nameIndex,
54*2d1272b8SAndroid Build Coastguard Worker       (hb_aat_layout_feature_selector_t) (unsigned int) setting,
55*2d1272b8SAndroid Build Coastguard Worker       default_selector == HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID
56*2d1272b8SAndroid Build Coastguard Worker 	? (hb_aat_layout_feature_selector_t) (setting + 1)
57*2d1272b8SAndroid Build Coastguard Worker 	: default_selector,
58*2d1272b8SAndroid Build Coastguard Worker       0
59*2d1272b8SAndroid Build Coastguard Worker     };
60*2d1272b8SAndroid Build Coastguard Worker   }
61*2d1272b8SAndroid Build Coastguard Worker 
sanitizeAAT::SettingName62*2d1272b8SAndroid Build Coastguard Worker   bool sanitize (hb_sanitize_context_t *c) const
63*2d1272b8SAndroid Build Coastguard Worker   {
64*2d1272b8SAndroid Build Coastguard Worker     TRACE_SANITIZE (this);
65*2d1272b8SAndroid Build Coastguard Worker     return_trace (c->check_struct (this));
66*2d1272b8SAndroid Build Coastguard Worker   }
67*2d1272b8SAndroid Build Coastguard Worker 
68*2d1272b8SAndroid Build Coastguard Worker   protected:
69*2d1272b8SAndroid Build Coastguard Worker   HBUINT16	setting;	/* The setting. */
70*2d1272b8SAndroid Build Coastguard Worker   NameID	nameIndex;	/* The name table index for the setting's name. */
71*2d1272b8SAndroid Build Coastguard Worker   public:
72*2d1272b8SAndroid Build Coastguard Worker   DEFINE_SIZE_STATIC (4);
73*2d1272b8SAndroid Build Coastguard Worker };
74*2d1272b8SAndroid Build Coastguard Worker DECLARE_NULL_NAMESPACE_BYTES (AAT, SettingName);
75*2d1272b8SAndroid Build Coastguard Worker 
76*2d1272b8SAndroid Build Coastguard Worker struct feat;
77*2d1272b8SAndroid Build Coastguard Worker 
78*2d1272b8SAndroid Build Coastguard Worker struct FeatureName
79*2d1272b8SAndroid Build Coastguard Worker {
cmpAAT::FeatureName80*2d1272b8SAndroid Build Coastguard Worker   int cmp (hb_aat_layout_feature_type_t key) const
81*2d1272b8SAndroid Build Coastguard Worker   { return (int) key - (int) feature; }
82*2d1272b8SAndroid Build Coastguard Worker 
83*2d1272b8SAndroid Build Coastguard Worker   enum {
84*2d1272b8SAndroid Build Coastguard Worker     Exclusive	= 0x8000,	/* If set, the feature settings are mutually exclusive. */
85*2d1272b8SAndroid Build Coastguard Worker     NotDefault	= 0x4000,	/* If clear, then the setting with an index of 0 in
86*2d1272b8SAndroid Build Coastguard Worker 				 * the setting name array for this feature should
87*2d1272b8SAndroid Build Coastguard Worker 				 * be taken as the default for the feature
88*2d1272b8SAndroid Build Coastguard Worker 				 * (if one is required). If set, then bits 0-15 of this
89*2d1272b8SAndroid Build Coastguard Worker 				 * featureFlags field contain the index of the setting
90*2d1272b8SAndroid Build Coastguard Worker 				 * which is to be taken as the default. */
91*2d1272b8SAndroid Build Coastguard Worker     IndexMask	= 0x00FF	/* If bits 30 and 31 are set, then these sixteen bits
92*2d1272b8SAndroid Build Coastguard Worker 				 * indicate the index of the setting in the setting name
93*2d1272b8SAndroid Build Coastguard Worker 				 * array for this feature which should be taken
94*2d1272b8SAndroid Build Coastguard Worker 				 * as the default. */
95*2d1272b8SAndroid Build Coastguard Worker   };
96*2d1272b8SAndroid Build Coastguard Worker 
get_selector_infosAAT::FeatureName97*2d1272b8SAndroid Build Coastguard Worker   unsigned int get_selector_infos (unsigned int                           start_offset,
98*2d1272b8SAndroid Build Coastguard Worker 				   unsigned int                          *selectors_count, /* IN/OUT.  May be NULL. */
99*2d1272b8SAndroid Build Coastguard Worker 				   hb_aat_layout_feature_selector_info_t *selectors,       /* OUT.     May be NULL. */
100*2d1272b8SAndroid Build Coastguard Worker 				   unsigned int                          *pdefault_index,  /* OUT.     May be NULL. */
101*2d1272b8SAndroid Build Coastguard Worker 				   const void *base) const
102*2d1272b8SAndroid Build Coastguard Worker   {
103*2d1272b8SAndroid Build Coastguard Worker     hb_array_t< const SettingName> settings_table = (base+settingTableZ).as_array (nSettings);
104*2d1272b8SAndroid Build Coastguard Worker 
105*2d1272b8SAndroid Build Coastguard Worker     static_assert (Index::NOT_FOUND_INDEX == HB_AAT_LAYOUT_NO_SELECTOR_INDEX, "");
106*2d1272b8SAndroid Build Coastguard Worker 
107*2d1272b8SAndroid Build Coastguard Worker     hb_aat_layout_feature_selector_t default_selector = HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID;
108*2d1272b8SAndroid Build Coastguard Worker     unsigned int default_index = Index::NOT_FOUND_INDEX;
109*2d1272b8SAndroid Build Coastguard Worker     if (featureFlags & Exclusive)
110*2d1272b8SAndroid Build Coastguard Worker     {
111*2d1272b8SAndroid Build Coastguard Worker       default_index = (featureFlags & NotDefault) ? featureFlags & IndexMask : 0;
112*2d1272b8SAndroid Build Coastguard Worker       default_selector = settings_table[default_index].get_selector ();
113*2d1272b8SAndroid Build Coastguard Worker     }
114*2d1272b8SAndroid Build Coastguard Worker     if (pdefault_index)
115*2d1272b8SAndroid Build Coastguard Worker       *pdefault_index = default_index;
116*2d1272b8SAndroid Build Coastguard Worker 
117*2d1272b8SAndroid Build Coastguard Worker     if (selectors_count)
118*2d1272b8SAndroid Build Coastguard Worker     {
119*2d1272b8SAndroid Build Coastguard Worker       + settings_table.sub_array (start_offset, selectors_count)
120*2d1272b8SAndroid Build Coastguard Worker       | hb_map ([=] (const SettingName& setting) { return setting.get_info (default_selector); })
121*2d1272b8SAndroid Build Coastguard Worker       | hb_sink (hb_array (selectors, *selectors_count))
122*2d1272b8SAndroid Build Coastguard Worker       ;
123*2d1272b8SAndroid Build Coastguard Worker     }
124*2d1272b8SAndroid Build Coastguard Worker     return settings_table.length;
125*2d1272b8SAndroid Build Coastguard Worker   }
126*2d1272b8SAndroid Build Coastguard Worker 
get_feature_typeAAT::FeatureName127*2d1272b8SAndroid Build Coastguard Worker   hb_aat_layout_feature_type_t get_feature_type () const
128*2d1272b8SAndroid Build Coastguard Worker   { return (hb_aat_layout_feature_type_t) (unsigned int) feature; }
129*2d1272b8SAndroid Build Coastguard Worker 
get_feature_name_idAAT::FeatureName130*2d1272b8SAndroid Build Coastguard Worker   hb_ot_name_id_t get_feature_name_id () const { return nameIndex; }
131*2d1272b8SAndroid Build Coastguard Worker 
is_exclusiveAAT::FeatureName132*2d1272b8SAndroid Build Coastguard Worker   bool is_exclusive () const { return featureFlags & Exclusive; }
133*2d1272b8SAndroid Build Coastguard Worker 
134*2d1272b8SAndroid Build Coastguard Worker   /* A FeatureName with no settings is meaningless */
has_dataAAT::FeatureName135*2d1272b8SAndroid Build Coastguard Worker   bool has_data () const { return nSettings; }
136*2d1272b8SAndroid Build Coastguard Worker 
sanitizeAAT::FeatureName137*2d1272b8SAndroid Build Coastguard Worker   bool sanitize (hb_sanitize_context_t *c, const void *base) const
138*2d1272b8SAndroid Build Coastguard Worker   {
139*2d1272b8SAndroid Build Coastguard Worker     TRACE_SANITIZE (this);
140*2d1272b8SAndroid Build Coastguard Worker     return_trace (likely (c->check_struct (this) &&
141*2d1272b8SAndroid Build Coastguard Worker 			  hb_barrier () &&
142*2d1272b8SAndroid Build Coastguard Worker 			  (base+settingTableZ).sanitize (c, nSettings)));
143*2d1272b8SAndroid Build Coastguard Worker   }
144*2d1272b8SAndroid Build Coastguard Worker 
145*2d1272b8SAndroid Build Coastguard Worker   protected:
146*2d1272b8SAndroid Build Coastguard Worker   HBUINT16	feature;	/* Feature type. */
147*2d1272b8SAndroid Build Coastguard Worker   HBUINT16	nSettings;	/* The number of records in the setting name array. */
148*2d1272b8SAndroid Build Coastguard Worker   NNOffset32To<UnsizedArrayOf<SettingName>>
149*2d1272b8SAndroid Build Coastguard Worker 		settingTableZ;	/* Offset in bytes from the beginning of this table to
150*2d1272b8SAndroid Build Coastguard Worker 				 * this feature's setting name array. The actual type of
151*2d1272b8SAndroid Build Coastguard Worker 				 * record this offset refers to will depend on the
152*2d1272b8SAndroid Build Coastguard Worker 				 * exclusivity value, as described below. */
153*2d1272b8SAndroid Build Coastguard Worker   HBUINT16	featureFlags;	/* Single-bit flags associated with the feature type. */
154*2d1272b8SAndroid Build Coastguard Worker   HBINT16	nameIndex;	/* The name table index for the feature's name.
155*2d1272b8SAndroid Build Coastguard Worker 				 * This index has values greater than 255 and
156*2d1272b8SAndroid Build Coastguard Worker 				 * less than 32768. */
157*2d1272b8SAndroid Build Coastguard Worker   public:
158*2d1272b8SAndroid Build Coastguard Worker   DEFINE_SIZE_STATIC (12);
159*2d1272b8SAndroid Build Coastguard Worker };
160*2d1272b8SAndroid Build Coastguard Worker 
161*2d1272b8SAndroid Build Coastguard Worker struct feat
162*2d1272b8SAndroid Build Coastguard Worker {
163*2d1272b8SAndroid Build Coastguard Worker   static constexpr hb_tag_t tableTag = HB_AAT_TAG_feat;
164*2d1272b8SAndroid Build Coastguard Worker 
has_dataAAT::feat165*2d1272b8SAndroid Build Coastguard Worker   bool has_data () const { return version.to_int (); }
166*2d1272b8SAndroid Build Coastguard Worker 
get_feature_typesAAT::feat167*2d1272b8SAndroid Build Coastguard Worker   unsigned int get_feature_types (unsigned int                  start_offset,
168*2d1272b8SAndroid Build Coastguard Worker 				  unsigned int                 *count,
169*2d1272b8SAndroid Build Coastguard Worker 				  hb_aat_layout_feature_type_t *features) const
170*2d1272b8SAndroid Build Coastguard Worker   {
171*2d1272b8SAndroid Build Coastguard Worker     if (count)
172*2d1272b8SAndroid Build Coastguard Worker     {
173*2d1272b8SAndroid Build Coastguard Worker       + namesZ.as_array (featureNameCount).sub_array (start_offset, count)
174*2d1272b8SAndroid Build Coastguard Worker       | hb_map (&FeatureName::get_feature_type)
175*2d1272b8SAndroid Build Coastguard Worker       | hb_sink (hb_array (features, *count))
176*2d1272b8SAndroid Build Coastguard Worker       ;
177*2d1272b8SAndroid Build Coastguard Worker     }
178*2d1272b8SAndroid Build Coastguard Worker     return featureNameCount;
179*2d1272b8SAndroid Build Coastguard Worker   }
180*2d1272b8SAndroid Build Coastguard Worker 
exposes_featureAAT::feat181*2d1272b8SAndroid Build Coastguard Worker   bool exposes_feature (hb_aat_layout_feature_type_t feature_type) const
182*2d1272b8SAndroid Build Coastguard Worker   { return get_feature (feature_type).has_data (); }
183*2d1272b8SAndroid Build Coastguard Worker 
get_featureAAT::feat184*2d1272b8SAndroid Build Coastguard Worker   const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const
185*2d1272b8SAndroid Build Coastguard Worker   { return namesZ.bsearch (featureNameCount, feature_type); }
186*2d1272b8SAndroid Build Coastguard Worker 
get_feature_name_idAAT::feat187*2d1272b8SAndroid Build Coastguard Worker   hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const
188*2d1272b8SAndroid Build Coastguard Worker   { return get_feature (feature).get_feature_name_id (); }
189*2d1272b8SAndroid Build Coastguard Worker 
get_selector_infosAAT::feat190*2d1272b8SAndroid Build Coastguard Worker   unsigned int get_selector_infos (hb_aat_layout_feature_type_t           feature_type,
191*2d1272b8SAndroid Build Coastguard Worker 				   unsigned int                           start_offset,
192*2d1272b8SAndroid Build Coastguard Worker 				   unsigned int                          *selectors_count, /* IN/OUT.  May be NULL. */
193*2d1272b8SAndroid Build Coastguard Worker 				   hb_aat_layout_feature_selector_info_t *selectors,       /* OUT.     May be NULL. */
194*2d1272b8SAndroid Build Coastguard Worker 				   unsigned int                          *default_index    /* OUT.     May be NULL. */) const
195*2d1272b8SAndroid Build Coastguard Worker   {
196*2d1272b8SAndroid Build Coastguard Worker     return get_feature (feature_type).get_selector_infos (start_offset, selectors_count, selectors,
197*2d1272b8SAndroid Build Coastguard Worker 							  default_index, this);
198*2d1272b8SAndroid Build Coastguard Worker   }
199*2d1272b8SAndroid Build Coastguard Worker 
sanitizeAAT::feat200*2d1272b8SAndroid Build Coastguard Worker   bool sanitize (hb_sanitize_context_t *c) const
201*2d1272b8SAndroid Build Coastguard Worker   {
202*2d1272b8SAndroid Build Coastguard Worker     TRACE_SANITIZE (this);
203*2d1272b8SAndroid Build Coastguard Worker     return_trace (likely (c->check_struct (this) &&
204*2d1272b8SAndroid Build Coastguard Worker 			  hb_barrier () &&
205*2d1272b8SAndroid Build Coastguard Worker 			  version.major == 1 &&
206*2d1272b8SAndroid Build Coastguard Worker 			  namesZ.sanitize (c, featureNameCount, this)));
207*2d1272b8SAndroid Build Coastguard Worker   }
208*2d1272b8SAndroid Build Coastguard Worker 
209*2d1272b8SAndroid Build Coastguard Worker   protected:
210*2d1272b8SAndroid Build Coastguard Worker   FixedVersion<>version;	/* Version number of the feature name table
211*2d1272b8SAndroid Build Coastguard Worker 				 * (0x00010000 for the current version). */
212*2d1272b8SAndroid Build Coastguard Worker   HBUINT16	featureNameCount;
213*2d1272b8SAndroid Build Coastguard Worker 				/* The number of entries in the feature name array. */
214*2d1272b8SAndroid Build Coastguard Worker   HBUINT16	reserved1;	/* Reserved (set to zero). */
215*2d1272b8SAndroid Build Coastguard Worker   HBUINT32	reserved2;	/* Reserved (set to zero). */
216*2d1272b8SAndroid Build Coastguard Worker   SortedUnsizedArrayOf<FeatureName>
217*2d1272b8SAndroid Build Coastguard Worker 		namesZ;		/* The feature name array. */
218*2d1272b8SAndroid Build Coastguard Worker   public:
219*2d1272b8SAndroid Build Coastguard Worker   DEFINE_SIZE_ARRAY (12, namesZ);
220*2d1272b8SAndroid Build Coastguard Worker };
221*2d1272b8SAndroid Build Coastguard Worker 
222*2d1272b8SAndroid Build Coastguard Worker } /* namespace AAT */
223*2d1272b8SAndroid Build Coastguard Worker 
224*2d1272b8SAndroid Build Coastguard Worker #endif /* HB_AAT_LAYOUT_FEAT_TABLE_HH */
225