blob: eb4c3b46e2f4cdb057e721c26f0caea66d795e01 [file] [log] [blame]
Elie Rouxf748e112017-02-18 19:54:33 +01001/*
Ebrahim Byagowia1573422019-07-28 18:54:13 +04302 * Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu>
Behdad Esfahbod7a70c202018-02-27 12:45:26 -08003 * Copyright © 2018 Google, Inc.
Ebrahim Byagowia1573422019-07-28 18:54:13 +04304 * Copyright © 2018-2019 Ebrahim Byagowi
Elie Rouxf748e112017-02-18 19:54:33 +01005 *
6 * This is part of HarfBuzz, a text shaping library.
7 *
8 * Permission is hereby granted, without written agreement and without
9 * license or royalty fees, to use, copy, modify, and distribute this
10 * software and its documentation for any purpose, provided that the
11 * above copyright notice and the following two paragraphs appear in
12 * all copies of this software.
13 *
14 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
15 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
17 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18 * DAMAGE.
19 *
20 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
21 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
23 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
24 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25 *
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080026 * Google Author(s): Behdad Esfahbod
Elie Rouxf748e112017-02-18 19:54:33 +010027 */
28
Ebrahim Byagowi0ad8c662018-02-26 12:45:08 +033029#ifndef HB_OT_LAYOUT_BASE_TABLE_HH
30#define HB_OT_LAYOUT_BASE_TABLE_HH
Elie Rouxf748e112017-02-18 19:54:33 +010031
Behdad Esfahbodc77ae402018-08-25 22:36:36 -070032#include "hb-open-type.hh"
33#include "hb-ot-layout-common.hh"
Elie Rouxf748e112017-02-18 19:54:33 +010034
35namespace OT {
36
37/*
Ebrahim Byagowia02c3ee2018-04-12 13:38:19 +043038 * BASE -- Baseline
39 * https://docs.microsoft.com/en-us/typography/opentype/spec/base
Elie Rouxf748e112017-02-18 19:54:33 +010040 */
41
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080042struct BaseCoordFormat1
43{
Ebrahim Byagowie4120082018-12-17 21:31:01 +033044 hb_position_t get_coord () const { return coordinate; }
Elie Rouxd34e35b2017-02-25 20:41:05 +010045
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +033046 bool sanitize (hb_sanitize_context_t *c) const
Elie Roux1d30c6d2017-02-25 16:19:35 +010047 {
48 TRACE_SANITIZE (this);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +033049 return_trace (likely (c->check_struct (this)));
Elie Roux1d30c6d2017-02-25 16:19:35 +010050 }
51
Elie Rouxf748e112017-02-18 19:54:33 +010052 protected:
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080053 HBUINT16 format; /* Format identifier--format = 1 */
Behdad Esfahbodda48aca2018-08-06 05:52:12 -070054 FWORD coordinate; /* X or Y value, in design units */
Elie Rouxf748e112017-02-18 19:54:33 +010055 public:
56 DEFINE_SIZE_STATIC (4);
57};
58
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080059struct BaseCoordFormat2
60{
Ebrahim Byagowie4120082018-12-17 21:31:01 +033061 hb_position_t get_coord () const
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080062 {
63 /* TODO */
64 return coordinate;
65 }
Elie Rouxd34e35b2017-02-25 20:41:05 +010066
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +033067 bool sanitize (hb_sanitize_context_t *c) const
Elie Roux1d30c6d2017-02-25 16:19:35 +010068 {
69 TRACE_SANITIZE (this);
70 return_trace (c->check_struct (this));
71 }
72
Elie Rouxf748e112017-02-18 19:54:33 +010073 protected:
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080074 HBUINT16 format; /* Format identifier--format = 2 */
Behdad Esfahbodda48aca2018-08-06 05:52:12 -070075 FWORD coordinate; /* X or Y value, in design units */
Behdad Esfahbodc852b862021-09-19 16:30:12 -040076 HBGlyphID16 referenceGlyph; /* Glyph ID of control glyph */
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080077 HBUINT16 coordPoint; /* Index of contour point on the
78 * reference glyph */
Elie Rouxf748e112017-02-18 19:54:33 +010079 public:
80 DEFINE_SIZE_STATIC (8);
81};
82
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080083struct BaseCoordFormat3
84{
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +033085 hb_position_t get_coord (hb_font_t *font,
86 const VariationStore &var_store,
87 hb_direction_t direction) const
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080088 {
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +033089 const Device &device = this+deviceTable;
90 return coordinate + (HB_DIRECTION_IS_VERTICAL (direction) ?
91 device.get_y_delta (font, var_store) :
92 device.get_x_delta (font, var_store));
Behdad Esfahbod7a70c202018-02-27 12:45:26 -080093 }
Elie Rouxd34e35b2017-02-25 20:41:05 +010094
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +033095
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +033096 bool sanitize (hb_sanitize_context_t *c) const
Elie Roux1d30c6d2017-02-25 16:19:35 +010097 {
98 TRACE_SANITIZE (this);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +033099 return_trace (likely (c->check_struct (this) &&
100 deviceTable.sanitize (c, this)));
Elie Roux1d30c6d2017-02-25 16:19:35 +0100101 }
102
Elie Rouxf748e112017-02-18 19:54:33 +0100103 protected:
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330104 HBUINT16 format; /* Format identifier--format = 3 */
105 FWORD coordinate; /* X or Y value, in design units */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600106 Offset16To<Device>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330107 deviceTable; /* Offset to Device table for X or
108 * Y value, from beginning of
109 * BaseCoord table (may be NULL). */
Elie Rouxf748e112017-02-18 19:54:33 +0100110 public:
111 DEFINE_SIZE_STATIC (6);
112};
113
Behdad Esfahbod7a70c202018-02-27 12:45:26 -0800114struct BaseCoord
115{
Ebrahim Byagowid9c44e72019-07-28 20:35:32 +0430116 bool has_data () const { return u.format; }
117
Ebrahim Byagowied2965a2019-07-30 03:34:10 +0430118 hb_position_t get_coord (hb_font_t *font,
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330119 const VariationStore &var_store,
Ebrahim Byagowied2965a2019-07-30 03:34:10 +0430120 hb_direction_t direction) const
Behdad Esfahbod7a70c202018-02-27 12:45:26 -0800121 {
122 switch (u.format) {
123 case 1: return u.format1.get_coord ();
124 case 2: return u.format2.get_coord ();
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330125 case 3: return u.format3.get_coord (font, var_store, direction);
Behdad Esfahbod7a70c202018-02-27 12:45:26 -0800126 default:return 0;
127 }
128 }
Elie Rouxd34e35b2017-02-25 20:41:05 +0100129
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330130 bool sanitize (hb_sanitize_context_t *c) const
Elie Roux1d30c6d2017-02-25 16:19:35 +0100131 {
132 TRACE_SANITIZE (this);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330133 if (unlikely (!u.format.sanitize (c))) return_trace (false);
Behdad Esfahbod7a70c202018-02-27 12:45:26 -0800134 switch (u.format) {
Elie Roux1d30c6d2017-02-25 16:19:35 +0100135 case 1: return_trace (u.format1.sanitize (c));
136 case 2: return_trace (u.format2.sanitize (c));
137 case 3: return_trace (u.format3.sanitize (c));
Elie Roux39633152017-02-26 15:07:53 +0100138 default:return_trace (false);
Elie Roux1d30c6d2017-02-25 16:19:35 +0100139 }
140 }
141
Elie Rouxf748e112017-02-18 19:54:33 +0100142 protected:
143 union {
Ebrahim Byagowid9c44e72019-07-28 20:35:32 +0430144 HBUINT16 format;
145 BaseCoordFormat1 format1;
146 BaseCoordFormat2 format2;
147 BaseCoordFormat3 format3;
Elie Rouxf748e112017-02-18 19:54:33 +0100148 } u;
Elie Rouxf748e112017-02-18 19:54:33 +0100149 public:
Behdad Esfahbod7a70c202018-02-27 12:45:26 -0800150 DEFINE_SIZE_UNION (2, format);
Elie Rouxf748e112017-02-18 19:54:33 +0100151};
152
Behdad Esfahbod7a70c202018-02-27 12:45:26 -0800153struct FeatMinMaxRecord
154{
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430155 int cmp (hb_tag_t key) const { return tag.cmp (key); }
156
157 bool has_data () const { return tag; }
Elie Roux1d30c6d2017-02-25 16:19:35 +0100158
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330159 void get_min_max (const BaseCoord **min, const BaseCoord **max) const
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330160 {
161 if (likely (min)) *min = &(this+minCoord);
162 if (likely (max)) *max = &(this+maxCoord);
163 }
Elie Rouxd34e35b2017-02-25 20:41:05 +0100164
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330165 bool sanitize (hb_sanitize_context_t *c, const void *base) const
Elie Roux1d30c6d2017-02-25 16:19:35 +0100166 {
167 TRACE_SANITIZE (this);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330168 return_trace (likely (c->check_struct (this) &&
169 minCoord.sanitize (c, this) &&
170 maxCoord.sanitize (c, this)));
Elie Roux1d30c6d2017-02-25 16:19:35 +0100171 }
172
Elie Rouxf748e112017-02-18 19:54:33 +0100173 protected:
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330174 Tag tag; /* 4-byte feature identification tag--must
175 * match feature tag in FeatureList */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600176 Offset16To<BaseCoord>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330177 minCoord; /* Offset to BaseCoord table that defines
178 * the minimum extent value, from beginning
179 * of MinMax table (may be NULL) */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600180 Offset16To<BaseCoord>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330181 maxCoord; /* Offset to BaseCoord table that defines
182 * the maximum extent value, from beginning
183 * of MinMax table (may be NULL) */
Elie Rouxf748e112017-02-18 19:54:33 +0100184 public:
185 DEFINE_SIZE_STATIC (8);
186
187};
188
Behdad Esfahbod7a70c202018-02-27 12:45:26 -0800189struct MinMax
190{
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330191 void get_min_max (hb_tag_t feature_tag,
Ebrahim Byagowieddd4562019-07-28 02:21:54 +0430192 const BaseCoord **min,
193 const BaseCoord **max) const
Elie Rouxd34e35b2017-02-25 20:41:05 +0100194 {
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430195 const FeatMinMaxRecord &minMaxCoord = featMinMaxRecords.bsearch (feature_tag);
196 if (minMaxCoord.has_data ())
197 minMaxCoord.get_min_max (min, max);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330198 else
Behdad Esfahbod7a70c202018-02-27 12:45:26 -0800199 {
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330200 if (likely (min)) *min = &(this+minCoord);
201 if (likely (max)) *max = &(this+maxCoord);
Elie Rouxd34e35b2017-02-25 20:41:05 +0100202 }
Elie Roux39633152017-02-26 15:07:53 +0100203 }
Elie Rouxd34e35b2017-02-25 20:41:05 +0100204
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330205 bool sanitize (hb_sanitize_context_t *c) const
Elie Roux1d30c6d2017-02-25 16:19:35 +0100206 {
207 TRACE_SANITIZE (this);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330208 return_trace (likely (c->check_struct (this) &&
209 minCoord.sanitize (c, this) &&
210 maxCoord.sanitize (c, this) &&
211 featMinMaxRecords.sanitize (c, this)));
Elie Roux1d30c6d2017-02-25 16:19:35 +0100212 }
213
Elie Rouxf748e112017-02-18 19:54:33 +0100214 protected:
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600215 Offset16To<BaseCoord>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330216 minCoord; /* Offset to BaseCoord table that defines
217 * minimum extent value, from the beginning
218 * of MinMax table (may be NULL) */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600219 Offset16To<BaseCoord>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330220 maxCoord; /* Offset to BaseCoord table that defines
221 * maximum extent value, from the beginning
222 * of MinMax table (may be NULL) */
Behdad Esfahbod4dba7492021-03-31 16:09:39 -0600223 SortedArray16Of<FeatMinMaxRecord>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330224 featMinMaxRecords;
225 /* Array of FeatMinMaxRecords, in alphabetical
226 * order by featureTableTag */
Elie Rouxf748e112017-02-18 19:54:33 +0100227 public:
Behdad Esfahbod7a70c202018-02-27 12:45:26 -0800228 DEFINE_SIZE_ARRAY (6, featMinMaxRecords);
Elie Rouxf748e112017-02-18 19:54:33 +0100229};
230
Behdad Esfahbod551fa2d2018-02-25 16:32:17 -0800231struct BaseValues
232{
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330233 const BaseCoord &get_base_coord (int baseline_tag_index) const
Elie Roux39633152017-02-26 15:07:53 +0100234 {
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330235 if (baseline_tag_index == -1) baseline_tag_index = defaultIndex;
236 return this+baseCoords[baseline_tag_index];
Elie Roux39633152017-02-26 15:07:53 +0100237 }
238
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330239 bool sanitize (hb_sanitize_context_t *c) const
Elie Roux1d30c6d2017-02-25 16:19:35 +0100240 {
241 TRACE_SANITIZE (this);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330242 return_trace (likely (c->check_struct (this) &&
243 baseCoords.sanitize (c, this)));
Elie Roux1d30c6d2017-02-25 16:19:35 +0100244 }
245
Elie Rouxf748e112017-02-18 19:54:33 +0100246 protected:
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330247 Index defaultIndex; /* Index number of default baseline for this
248 * script — equals index position of baseline tag
249 * in baselineTags array of the BaseTagList */
Behdad Esfahbod6c4e0492021-03-31 15:31:32 -0600250 Array16OfOffset16To<BaseCoord>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330251 baseCoords; /* Number of BaseCoord tables defined — should equal
252 * baseTagCount in the BaseTagList
253 *
254 * Array of offsets to BaseCoord tables, from beginning of
255 * BaseValues table — order matches baselineTags array in
256 * the BaseTagList */
Elie Rouxf748e112017-02-18 19:54:33 +0100257 public:
Behdad Esfahbodda48aca2018-08-06 05:52:12 -0700258 DEFINE_SIZE_ARRAY (4, baseCoords);
Elie Rouxf748e112017-02-18 19:54:33 +0100259};
260
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330261struct BaseLangSysRecord
262{
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430263 int cmp (hb_tag_t key) const { return baseLangSysTag.cmp (key); }
264
265 bool has_data () const { return baseLangSysTag; }
Elie Rouxd34e35b2017-02-25 20:41:05 +0100266
Ebrahim Byagowi69655d52019-07-28 20:39:20 +0430267 const MinMax &get_min_max () const { return this+minMax; }
Elie Rouxd34e35b2017-02-25 20:41:05 +0100268
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330269 bool sanitize (hb_sanitize_context_t *c, const void *base) const
Elie Roux1d30c6d2017-02-25 16:19:35 +0100270 {
271 TRACE_SANITIZE (this);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330272 return_trace (likely (c->check_struct (this) &&
273 minMax.sanitize (c, this)));
Elie Roux1d30c6d2017-02-25 16:19:35 +0100274 }
275
Elie Rouxf748e112017-02-18 19:54:33 +0100276 protected:
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330277 Tag baseLangSysTag; /* 4-byte language system identification tag */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600278 Offset16To<MinMax>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330279 minMax; /* Offset to MinMax table, from beginning
280 * of BaseScript table */
Elie Rouxf748e112017-02-18 19:54:33 +0100281 public:
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330282 DEFINE_SIZE_STATIC (6);
Elie Rouxf748e112017-02-18 19:54:33 +0100283};
284
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330285struct BaseScript
286{
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330287 const MinMax &get_min_max (hb_tag_t language_tag) const
Elie Rouxd34e35b2017-02-25 20:41:05 +0100288 {
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430289 const BaseLangSysRecord& record = baseLangSysRecords.bsearch (language_tag);
290 return record.has_data () ? record.get_min_max () : this+defaultMinMax;
Elie Rouxd34e35b2017-02-25 20:41:05 +0100291 }
292
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330293 const BaseCoord &get_base_coord (int baseline_tag_index) const
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330294 { return (this+baseValues).get_base_coord (baseline_tag_index); }
295
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430296 bool has_data () const { return baseValues; }
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330297
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330298 bool sanitize (hb_sanitize_context_t *c) const
Ebrahim Byagowi0ad8c662018-02-26 12:45:08 +0330299 {
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330300 TRACE_SANITIZE (this);
301 return_trace (likely (c->check_struct (this) &&
302 baseValues.sanitize (c, this) &&
303 defaultMinMax.sanitize (c, this) &&
304 baseLangSysRecords.sanitize (c, this)));
Elie Roux39633152017-02-26 15:07:53 +0100305 }
306
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330307 protected:
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600308 Offset16To<BaseValues>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330309 baseValues; /* Offset to BaseValues table, from beginning
310 * of BaseScript table (may be NULL) */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600311 Offset16To<MinMax>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330312 defaultMinMax; /* Offset to MinMax table, from beginning of
313 * BaseScript table (may be NULL) */
Behdad Esfahbod4dba7492021-03-31 16:09:39 -0600314 SortedArray16Of<BaseLangSysRecord>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330315 baseLangSysRecords;
316 /* Number of BaseLangSysRecords
317 * defined — may be zero (0) */
318
319 public:
320 DEFINE_SIZE_ARRAY (6, baseLangSysRecords);
321};
322
323struct BaseScriptList;
324struct BaseScriptRecord
325{
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430326 int cmp (hb_tag_t key) const { return baseScriptTag.cmp (key); }
327
328 bool has_data () const { return baseScriptTag; }
Elie Roux39633152017-02-26 15:07:53 +0100329
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330330 const BaseScript &get_base_script (const BaseScriptList *list) const
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330331 { return list+baseScript; }
332
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330333 bool sanitize (hb_sanitize_context_t *c, const void *base) const
Elie Roux39633152017-02-26 15:07:53 +0100334 {
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330335 TRACE_SANITIZE (this);
336 return_trace (likely (c->check_struct (this) &&
337 baseScript.sanitize (c, base)));
Elie Roux39633152017-02-26 15:07:53 +0100338 }
339
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330340 protected:
341 Tag baseScriptTag; /* 4-byte script identification tag */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600342 Offset16To<BaseScript>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330343 baseScript; /* Offset to BaseScript table, from beginning
344 * of BaseScriptList */
345
346 public:
347 DEFINE_SIZE_STATIC (6);
348};
349
350struct BaseScriptList
351{
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330352 const BaseScript &get_base_script (hb_tag_t script) const
Elie Roux39633152017-02-26 15:07:53 +0100353 {
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430354 const BaseScriptRecord *record = &baseScriptRecords.bsearch (script);
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430355 if (!record->has_data ()) record = &baseScriptRecords.bsearch (HB_TAG ('D','F','L','T'));
Ebrahim Byagowic7b22b92019-07-28 19:46:57 +0430356 return record->has_data () ? record->get_base_script (this) : Null (BaseScript);
Elie Rouxd34e35b2017-02-25 20:41:05 +0100357 }
358
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330359 bool sanitize (hb_sanitize_context_t *c) const
Elie Roux1d30c6d2017-02-25 16:19:35 +0100360 {
361 TRACE_SANITIZE (this);
362 return_trace (c->check_struct (this) &&
Behdad Esfahbodda48aca2018-08-06 05:52:12 -0700363 baseScriptRecords.sanitize (c, this));
Elie Roux1d30c6d2017-02-25 16:19:35 +0100364 }
365
Elie Rouxf748e112017-02-18 19:54:33 +0100366 protected:
Behdad Esfahbod4dba7492021-03-31 16:09:39 -0600367 SortedArray16Of<BaseScriptRecord>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330368 baseScriptRecords;
Elie Rouxf748e112017-02-18 19:54:33 +0100369
370 public:
Behdad Esfahbodda48aca2018-08-06 05:52:12 -0700371 DEFINE_SIZE_ARRAY (2, baseScriptRecords);
Elie Rouxf748e112017-02-18 19:54:33 +0100372};
373
Elie Rouxa0bdd542017-02-25 16:34:58 +0100374struct Axis
Elie Rouxf748e112017-02-18 19:54:33 +0100375{
Ebrahim Byagowied2965a2019-07-30 03:34:10 +0430376 bool get_baseline (hb_tag_t baseline_tag,
377 hb_tag_t script_tag,
378 hb_tag_t language_tag,
379 const BaseCoord **coord) const
Elie Rouxd34e35b2017-02-25 20:41:05 +0100380 {
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330381 const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
Koji Ishii7e6070a2020-08-31 17:21:21 +0900382 if (!base_script.has_data ())
383 {
384 *coord = nullptr;
385 return false;
386 }
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330387
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430388 if (likely (coord))
389 {
390 unsigned int tag_index = 0;
Koji Ishii7e6070a2020-08-31 17:21:21 +0900391 if (!(this+baseTagList).bfind (baseline_tag, &tag_index))
392 {
393 *coord = nullptr;
394 return false;
395 }
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430396 *coord = &base_script.get_base_coord (tag_index);
397 }
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330398
399 return true;
Elie Roux39633152017-02-26 15:07:53 +0100400 }
401
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330402 bool get_min_max (hb_tag_t script_tag,
403 hb_tag_t language_tag,
404 hb_tag_t feature_tag,
405 const BaseCoord **min_coord,
406 const BaseCoord **max_coord) const
Ebrahim Byagowi0ad8c662018-02-26 12:45:08 +0330407 {
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330408 const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
Koji Ishii7e6070a2020-08-31 17:21:21 +0900409 if (!base_script.has_data ())
410 {
411 *min_coord = *max_coord = nullptr;
412 return false;
413 }
Elie Roux39633152017-02-26 15:07:53 +0100414
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330415 base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);
Elie Roux39633152017-02-26 15:07:53 +0100416
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330417 return true;
Elie Rouxd34e35b2017-02-25 20:41:05 +0100418 }
419
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330420 bool sanitize (hb_sanitize_context_t *c) const
Elie Roux1d30c6d2017-02-25 16:19:35 +0100421 {
422 TRACE_SANITIZE (this);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330423 return_trace (likely (c->check_struct (this) &&
424 (this+baseTagList).sanitize (c) &&
425 (this+baseScriptList).sanitize (c)));
Elie Roux1d30c6d2017-02-25 16:19:35 +0100426 }
427
Elie Rouxf748e112017-02-18 19:54:33 +0100428 protected:
Behdad Esfahbod4dba7492021-03-31 16:09:39 -0600429 Offset16To<SortedArray16Of<Tag>>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330430 baseTagList; /* Offset to BaseTagList table, from beginning
431 * of Axis table (may be NULL)
432 * Array of 4-byte baseline identification tags — must
433 * be in alphabetical order */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600434 Offset16To<BaseScriptList>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330435 baseScriptList; /* Offset to BaseScriptList table, from beginning
436 * of Axis table
437 * Array of BaseScriptRecords, in alphabetical order
438 * by baseScriptTag */
Elie Rouxf748e112017-02-18 19:54:33 +0100439
440 public:
441 DEFINE_SIZE_STATIC (4);
442};
443
Behdad Esfahbodd7633d02018-02-27 12:50:57 -0800444struct BASE
Elie Rouxf131f002017-02-19 10:12:22 +0100445{
Behdad Esfahbodef006542019-01-22 12:08:57 +0100446 static constexpr hb_tag_t tableTag = HB_OT_TAG_BASE;
Elie Rouxf131f002017-02-19 10:12:22 +0100447
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330448 const Axis &get_axis (hb_direction_t direction) const
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330449 { return HB_DIRECTION_IS_VERTICAL (direction) ? this+vAxis : this+hAxis; }
Elie Roux39633152017-02-26 15:07:53 +0100450
Ebrahim Byagowie4120082018-12-17 21:31:01 +0330451 const VariationStore &get_var_store () const
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330452 { return version.to_int () < 0x00010001u ? Null (VariationStore) : this+varStore; }
Elie Roux39633152017-02-26 15:07:53 +0100453
Ebrahim Byagowied2965a2019-07-30 03:34:10 +0430454 bool get_baseline (hb_font_t *font,
455 hb_tag_t baseline_tag,
456 hb_direction_t direction,
457 hb_tag_t script_tag,
458 hb_tag_t language_tag,
459 hb_position_t *base) const
Elie Roux39633152017-02-26 15:07:53 +0100460 {
Ebrahim Byagowi69655d52019-07-28 20:39:20 +0430461 const BaseCoord *base_coord = nullptr;
Ebrahim Byagowied2965a2019-07-30 03:34:10 +0430462 if (unlikely (!get_axis (direction).get_baseline (baseline_tag, script_tag, language_tag, &base_coord) ||
Ebrahim Byagowi87454c42019-07-28 20:46:47 +0430463 !base_coord || !base_coord->has_data ()))
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330464 return false;
465
Ebrahim Byagowi87454c42019-07-28 20:46:47 +0430466 if (likely (base))
Ebrahim Byagowia1573422019-07-28 18:54:13 +0430467 *base = base_coord->get_coord (font, get_var_store (), direction);
468
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330469 return true;
Elie Roux39633152017-02-26 15:07:53 +0100470 }
471
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330472 /* TODO: Expose this separately sometime? */
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330473 bool get_min_max (hb_font_t *font,
474 hb_direction_t direction,
475 hb_tag_t script_tag,
476 hb_tag_t language_tag,
477 hb_tag_t feature_tag,
478 hb_position_t *min,
479 hb_position_t *max)
Ebrahim Byagowi0ad8c662018-02-26 12:45:08 +0330480 {
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330481 const BaseCoord *min_coord, *max_coord;
482 if (!get_axis (direction).get_min_max (script_tag, language_tag, feature_tag,
483 &min_coord, &max_coord))
484 return false;
Elie Roux39633152017-02-26 15:07:53 +0100485
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330486 const VariationStore &var_store = get_var_store ();
487 if (likely (min && min_coord)) *min = min_coord->get_coord (font, var_store, direction);
488 if (likely (max && max_coord)) *max = max_coord->get_coord (font, var_store, direction);
489 return true;
Elie Roux39633152017-02-26 15:07:53 +0100490 }
491
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330492 bool sanitize (hb_sanitize_context_t *c) const
Elie Roux1d30c6d2017-02-25 16:19:35 +0100493 {
494 TRACE_SANITIZE (this);
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330495 return_trace (likely (c->check_struct (this) &&
496 likely (version.major == 1) &&
497 hAxis.sanitize (c, this) &&
498 vAxis.sanitize (c, this) &&
499 (version.to_int () < 0x00010001u || varStore.sanitize (c, this))));
Elie Roux1d30c6d2017-02-25 16:19:35 +0100500 }
501
Elie Rouxf131f002017-02-19 10:12:22 +0100502 protected:
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330503 FixedVersion<>version; /* Version of the BASE table */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600504 Offset16To<Axis>hAxis; /* Offset to horizontal Axis table, from beginning
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330505 * of BASE table (may be NULL) */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600506 Offset16To<Axis>vAxis; /* Offset to vertical Axis table, from beginning
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330507 * of BASE table (may be NULL) */
Behdad Esfahbodad28f972021-03-31 12:49:14 -0600508 Offset32To<VariationStore>
Ebrahim Byagowib8a78ce2018-11-03 22:28:30 +0330509 varStore; /* Offset to the table of Item Variation
510 * Store--from beginning of BASE
511 * header (may be NULL). Introduced
512 * in version 0x00010001. */
Elie Rouxf131f002017-02-19 10:12:22 +0100513 public:
Behdad Esfahbodd7633d02018-02-27 12:50:57 -0800514 DEFINE_SIZE_MIN (8);
Elie Rouxf748e112017-02-18 19:54:33 +0100515};
516
517
518} /* namespace OT */
519
520
Ebrahim Byagowi0ad8c662018-02-26 12:45:08 +0330521#endif /* HB_OT_LAYOUT_BASE_TABLE_HH */