1 /* 2 * Copyright © 2017 Google, Inc. 3 * 4 * This is part of HarfBuzz, a text shaping library. 5 * 6 * Permission is hereby granted, without written agreement and without 7 * license or royalty fees, to use, copy, modify, and distribute this 8 * software and its documentation for any purpose, provided that the 9 * above copyright notice and the following two paragraphs appear in 10 * all copies of this software. 11 * 12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 * DAMAGE. 17 * 18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 * 24 * Google Author(s): Behdad Esfahbod 25 */ 26 27 #ifndef HB_OT_VAR_FVAR_TABLE_HH 28 #define HB_OT_VAR_FVAR_TABLE_HH 29 30 #include "hb-open-type-private.hh" 31 32 namespace OT { 33 34 35 struct InstanceRecord 36 { sanitizeOT::InstanceRecord37 inline bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const 38 { 39 TRACE_SANITIZE (this); 40 return_trace (c->check_struct (this) && 41 c->check_array (coordinates, coordinates[0].static_size, axis_count)); 42 } 43 44 protected: 45 USHORT subfamilyNameID;/* The name ID for entries in the 'name' table 46 * that provide subfamily names for this instance. */ 47 USHORT reserved; /* Reserved for future use — set to 0. */ 48 Fixed coordinates[VAR];/* The coordinates array for this instance. */ 49 //USHORT postScriptNameIDX;/*Optional. The name ID for entries in the 'name' 50 // * table that provide PostScript names for this 51 // * instance. */ 52 53 public: 54 DEFINE_SIZE_ARRAY (4, coordinates); 55 }; 56 57 struct AxisRecord 58 { sanitizeOT::AxisRecord59 inline bool sanitize (hb_sanitize_context_t *c) const 60 { 61 TRACE_SANITIZE (this); 62 return_trace (c->check_struct (this)); 63 } 64 65 public: 66 Tag axisTag; /* Tag identifying the design variation for the axis. */ 67 Fixed minValue; /* The minimum coordinate value for the axis. */ 68 Fixed defaultValue; /* The default coordinate value for the axis. */ 69 Fixed maxValue; /* The maximum coordinate value for the axis. */ 70 USHORT reserved; /* Reserved for future use — set to 0. */ 71 USHORT axisNameID; /* The name ID for entries in the 'name' table that 72 * provide a display name for this axis. */ 73 74 public: 75 DEFINE_SIZE_STATIC (20); 76 }; 77 78 79 /* 80 * fvar — Font Variations Table 81 */ 82 83 #define HB_OT_TAG_fvar HB_TAG('f','v','a','r') 84 85 struct fvar 86 { 87 static const hb_tag_t tableTag = HB_OT_TAG_fvar; 88 sanitizeOT::fvar89 inline bool sanitize (hb_sanitize_context_t *c) const 90 { 91 TRACE_SANITIZE (this); 92 return_trace (version.sanitize (c) && 93 likely (version.major == 1) && 94 c->check_struct (this) && 95 instanceSize >= axisCount * 4 + 4 && 96 axisSize <= 1024 && /* Arbitrary, just to simplify overflow checks. */ 97 instanceSize <= 1024 && /* Arbitrary, just to simplify overflow checks. */ 98 c->check_range (this, things) && 99 c->check_range (&StructAtOffset<char> (this, things), 100 axisCount * axisSize + instanceCount * instanceSize)); 101 } 102 get_axis_countOT::fvar103 inline unsigned int get_axis_count (void) const 104 { return axisCount; } 105 get_axisOT::fvar106 inline bool get_axis (unsigned int index, hb_ot_var_axis_t *info) const 107 { 108 if (unlikely (index >= axisCount)) 109 return false; 110 111 if (info) 112 { 113 const AxisRecord &axis = get_axes ()[index]; 114 info->tag = axis.axisTag; 115 info->name_id = axis.axisNameID; 116 info->default_value = axis.defaultValue / 65536.; 117 /* Ensure order, to simplify client math. */ 118 info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.); 119 info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.); 120 } 121 122 return true; 123 } 124 get_axis_infosOT::fvar125 inline unsigned int get_axis_infos (unsigned int start_offset, 126 unsigned int *axes_count /* IN/OUT */, 127 hb_ot_var_axis_t *axes_array /* OUT */) const 128 { 129 if (axes_count) 130 { 131 unsigned int count = axisCount; 132 start_offset = MIN (start_offset, count); 133 134 count -= start_offset; 135 axes_array += start_offset; 136 137 count = MIN (count, *axes_count); 138 *axes_count = count; 139 140 for (unsigned int i = 0; i < count; i++) 141 get_axis (start_offset + i, axes_array + i); 142 } 143 return axisCount; 144 } 145 find_axisOT::fvar146 inline bool find_axis (hb_tag_t tag, unsigned int *index, hb_ot_var_axis_t *info) const 147 { 148 const AxisRecord *axes = get_axes (); 149 unsigned int count = get_axis_count (); 150 for (unsigned int i = 0; i < count; i++) 151 if (axes[i].axisTag == tag) 152 { 153 if (index) 154 *index = i; 155 return get_axis (i, info); 156 } 157 if (index) 158 *index = HB_OT_VAR_NO_AXIS_INDEX; 159 return false; 160 } 161 normalize_axis_valueOT::fvar162 inline int normalize_axis_value (unsigned int axis_index, float v) const 163 { 164 hb_ot_var_axis_t axis; 165 if (!get_axis (axis_index, &axis)) 166 return 0; 167 168 v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */ 169 170 if (v == axis.default_value) 171 return 0; 172 else if (v < axis.default_value) 173 v = (v - axis.default_value) / (axis.default_value - axis.min_value); 174 else 175 v = (v - axis.default_value) / (axis.max_value - axis.default_value); 176 return (int) (v * 16384. + (v >= 0. ? .5 : -.5)); 177 } 178 179 protected: get_axesOT::fvar180 inline const AxisRecord * get_axes (void) const 181 { return &StructAtOffset<AxisRecord> (this, things); } 182 get_instancesOT::fvar183 inline const InstanceRecord * get_instances (void) const 184 { return &StructAtOffset<InstanceRecord> (get_axes () + axisCount, 0); } 185 186 protected: 187 FixedVersion<>version; /* Version of the fvar table 188 * initially set to 0x00010000u */ 189 Offset<> things; /* Offset in bytes from the beginning of the table 190 * to the start of the AxisRecord array. */ 191 USHORT reserved; /* This field is permanently reserved. Set to 2. */ 192 USHORT axisCount; /* The number of variation axes in the font (the 193 * number of records in the axes array). */ 194 USHORT axisSize; /* The size in bytes of each VariationAxisRecord — 195 * set to 20 (0x0014) for this version. */ 196 USHORT instanceCount; /* The number of named instances defined in the font 197 * (the number of records in the instances array). */ 198 USHORT instanceSize; /* The size in bytes of each InstanceRecord — set 199 * to either axisCount * sizeof(Fixed) + 4, or to 200 * axisCount * sizeof(Fixed) + 6. */ 201 202 public: 203 DEFINE_SIZE_STATIC (16); 204 }; 205 206 } /* namespace OT */ 207 208 209 #endif /* HB_OT_VAR_FVAR_TABLE_HH */ 210