1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright © 2017 Google, Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * This is part of HarfBuzz, a text shaping library. 5cb93a386Sopenharmony_ci * 6cb93a386Sopenharmony_ci * Permission is hereby granted, without written agreement and without 7cb93a386Sopenharmony_ci * license or royalty fees, to use, copy, modify, and distribute this 8cb93a386Sopenharmony_ci * software and its documentation for any purpose, provided that the 9cb93a386Sopenharmony_ci * above copyright notice and the following two paragraphs appear in 10cb93a386Sopenharmony_ci * all copies of this software. 11cb93a386Sopenharmony_ci * 12cb93a386Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13cb93a386Sopenharmony_ci * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14cb93a386Sopenharmony_ci * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15cb93a386Sopenharmony_ci * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16cb93a386Sopenharmony_ci * DAMAGE. 17cb93a386Sopenharmony_ci * 18cb93a386Sopenharmony_ci * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19cb93a386Sopenharmony_ci * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20cb93a386Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21cb93a386Sopenharmony_ci * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22cb93a386Sopenharmony_ci * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23cb93a386Sopenharmony_ci * 24cb93a386Sopenharmony_ci * Google Author(s): Behdad Esfahbod 25cb93a386Sopenharmony_ci */ 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci#ifndef HB_OT_VAR_AVAR_TABLE_HH 28cb93a386Sopenharmony_ci#define HB_OT_VAR_AVAR_TABLE_HH 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci#include "hb-open-type.hh" 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci/* 33cb93a386Sopenharmony_ci * avar -- Axis Variations 34cb93a386Sopenharmony_ci * https://docs.microsoft.com/en-us/typography/opentype/spec/avar 35cb93a386Sopenharmony_ci */ 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci#define HB_OT_TAG_avar HB_TAG('a','v','a','r') 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_cinamespace OT { 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_cistruct AxisValueMap 44cb93a386Sopenharmony_ci{ 45cb93a386Sopenharmony_ci bool sanitize (hb_sanitize_context_t *c) const 46cb93a386Sopenharmony_ci { 47cb93a386Sopenharmony_ci TRACE_SANITIZE (this); 48cb93a386Sopenharmony_ci return_trace (c->check_struct (this)); 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci public: 52cb93a386Sopenharmony_ci F2DOT14 coords[2]; 53cb93a386Sopenharmony_ci// F2DOT14 fromCoord; /* A normalized coordinate value obtained using 54cb93a386Sopenharmony_ci// * default normalization. */ 55cb93a386Sopenharmony_ci// F2DOT14 toCoord; /* The modified, normalized coordinate value. */ 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci public: 58cb93a386Sopenharmony_ci DEFINE_SIZE_STATIC (4); 59cb93a386Sopenharmony_ci}; 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_cistruct SegmentMaps : Array16Of<AxisValueMap> 62cb93a386Sopenharmony_ci{ 63cb93a386Sopenharmony_ci int map (int value, unsigned int from_offset = 0, unsigned int to_offset = 1) const 64cb93a386Sopenharmony_ci { 65cb93a386Sopenharmony_ci#define fromCoord coords[from_offset] 66cb93a386Sopenharmony_ci#define toCoord coords[to_offset] 67cb93a386Sopenharmony_ci /* The following special-cases are not part of OpenType, which requires 68cb93a386Sopenharmony_ci * that at least -1, 0, and +1 must be mapped. But we include these as 69cb93a386Sopenharmony_ci * part of a better error recovery scheme. */ 70cb93a386Sopenharmony_ci if (len < 2) 71cb93a386Sopenharmony_ci { 72cb93a386Sopenharmony_ci if (!len) 73cb93a386Sopenharmony_ci return value; 74cb93a386Sopenharmony_ci else /* len == 1*/ 75cb93a386Sopenharmony_ci return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci if (value <= arrayZ[0].fromCoord) 79cb93a386Sopenharmony_ci return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci unsigned int i; 82cb93a386Sopenharmony_ci unsigned int count = len - 1; 83cb93a386Sopenharmony_ci for (i = 1; i < count && value > arrayZ[i].fromCoord; i++) 84cb93a386Sopenharmony_ci ; 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci if (value >= arrayZ[i].fromCoord) 87cb93a386Sopenharmony_ci return value - arrayZ[i].fromCoord + arrayZ[i].toCoord; 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci if (unlikely (arrayZ[i-1].fromCoord == arrayZ[i].fromCoord)) 90cb93a386Sopenharmony_ci return arrayZ[i-1].toCoord; 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord; 93cb93a386Sopenharmony_ci return roundf (arrayZ[i-1].toCoord + ((float) (arrayZ[i].toCoord - arrayZ[i-1].toCoord) * 94cb93a386Sopenharmony_ci (value - arrayZ[i-1].fromCoord)) / denom); 95cb93a386Sopenharmony_ci#undef toCoord 96cb93a386Sopenharmony_ci#undef fromCoord 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci int unmap (int value) const { return map (value, 1, 0); } 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci public: 102cb93a386Sopenharmony_ci DEFINE_SIZE_ARRAY (2, *this); 103cb93a386Sopenharmony_ci}; 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_cistruct avar 106cb93a386Sopenharmony_ci{ 107cb93a386Sopenharmony_ci static constexpr hb_tag_t tableTag = HB_OT_TAG_avar; 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci bool sanitize (hb_sanitize_context_t *c) const 110cb93a386Sopenharmony_ci { 111cb93a386Sopenharmony_ci TRACE_SANITIZE (this); 112cb93a386Sopenharmony_ci if (unlikely (!(version.sanitize (c) && 113cb93a386Sopenharmony_ci version.major == 1 && 114cb93a386Sopenharmony_ci c->check_struct (this)))) 115cb93a386Sopenharmony_ci return_trace (false); 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci const SegmentMaps *map = &firstAxisSegmentMaps; 118cb93a386Sopenharmony_ci unsigned int count = axisCount; 119cb93a386Sopenharmony_ci for (unsigned int i = 0; i < count; i++) 120cb93a386Sopenharmony_ci { 121cb93a386Sopenharmony_ci if (unlikely (!map->sanitize (c))) 122cb93a386Sopenharmony_ci return_trace (false); 123cb93a386Sopenharmony_ci map = &StructAfter<SegmentMaps> (*map); 124cb93a386Sopenharmony_ci } 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ci return_trace (true); 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci void map_coords (int *coords, unsigned int coords_length) const 130cb93a386Sopenharmony_ci { 131cb93a386Sopenharmony_ci unsigned int count = hb_min (coords_length, axisCount); 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci const SegmentMaps *map = &firstAxisSegmentMaps; 134cb93a386Sopenharmony_ci for (unsigned int i = 0; i < count; i++) 135cb93a386Sopenharmony_ci { 136cb93a386Sopenharmony_ci coords[i] = map->map (coords[i]); 137cb93a386Sopenharmony_ci map = &StructAfter<SegmentMaps> (*map); 138cb93a386Sopenharmony_ci } 139cb93a386Sopenharmony_ci } 140cb93a386Sopenharmony_ci 141cb93a386Sopenharmony_ci void unmap_coords (int *coords, unsigned int coords_length) const 142cb93a386Sopenharmony_ci { 143cb93a386Sopenharmony_ci unsigned int count = hb_min (coords_length, axisCount); 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ci const SegmentMaps *map = &firstAxisSegmentMaps; 146cb93a386Sopenharmony_ci for (unsigned int i = 0; i < count; i++) 147cb93a386Sopenharmony_ci { 148cb93a386Sopenharmony_ci coords[i] = map->unmap (coords[i]); 149cb93a386Sopenharmony_ci map = &StructAfter<SegmentMaps> (*map); 150cb93a386Sopenharmony_ci } 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ci protected: 154cb93a386Sopenharmony_ci FixedVersion<>version; /* Version of the avar table 155cb93a386Sopenharmony_ci * initially set to 0x00010000u */ 156cb93a386Sopenharmony_ci HBUINT16 reserved; /* This field is permanently reserved. Set to 0. */ 157cb93a386Sopenharmony_ci HBUINT16 axisCount; /* The number of variation axes in the font. This 158cb93a386Sopenharmony_ci * must be the same number as axisCount in the 159cb93a386Sopenharmony_ci * 'fvar' table. */ 160cb93a386Sopenharmony_ci SegmentMaps firstAxisSegmentMaps; 161cb93a386Sopenharmony_ci 162cb93a386Sopenharmony_ci public: 163cb93a386Sopenharmony_ci DEFINE_SIZE_MIN (8); 164cb93a386Sopenharmony_ci}; 165cb93a386Sopenharmony_ci 166cb93a386Sopenharmony_ci} /* namespace OT */ 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci#endif /* HB_OT_VAR_AVAR_TABLE_HH */ 170