tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hb-ot-var-mvar-table.hh (5728B)


      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_MVAR_TABLE_HH
     28 #define HB_OT_VAR_MVAR_TABLE_HH
     29 
     30 #include "hb-ot-var-common.hh"
     31 
     32 
     33 namespace OT {
     34 
     35 
     36 struct VariationValueRecord
     37 {
     38  bool sanitize (hb_sanitize_context_t *c) const
     39  {
     40    TRACE_SANITIZE (this);
     41    return_trace (c->check_struct (this));
     42  }
     43 
     44  bool subset (hb_subset_context_t *c,
     45               const hb_map_t& varidx_map) const
     46  {
     47    TRACE_SUBSET (this);
     48    auto *out = c->serializer->embed (*this);
     49    if (unlikely (!out)) return_trace (false);
     50 
     51    hb_codepoint_t *new_idx;
     52    return_trace (c->serializer->check_assign (out->varIdx,
     53                                               (varidx_map.has (varIdx, &new_idx)) ? *new_idx : HB_OT_LAYOUT_NO_VARIATIONS_INDEX,
     54                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
     55  }
     56 
     57  public:
     58  Tag		valueTag;	/* Four-byte tag identifying a font-wide measure. */
     59  VarIdx	varIdx;		/* Outer/inner index into ItemVariationStore item. */
     60 
     61  public:
     62  DEFINE_SIZE_STATIC (8);
     63 };
     64 
     65 
     66 /*
     67 * MVAR -- Metrics Variations
     68 * https://docs.microsoft.com/en-us/typography/opentype/spec/mvar
     69 */
     70 #define HB_OT_TAG_MVAR HB_TAG('M','V','A','R')
     71 
     72 struct MVAR
     73 {
     74  static constexpr hb_tag_t tableTag = HB_OT_TAG_MVAR;
     75 
     76  bool sanitize (hb_sanitize_context_t *c) const
     77  {
     78    TRACE_SANITIZE (this);
     79    return_trace (version.sanitize (c) &&
     80 	  hb_barrier () &&
     81 	  likely (version.major == 1) &&
     82 	  c->check_struct (this) &&
     83 	  hb_barrier () &&
     84 	  valueRecordSize >= VariationValueRecord::static_size &&
     85 	  varStore.sanitize (c, this) &&
     86 	  c->check_range (valuesZ.arrayZ,
     87 			  valueRecordCount,
     88 			  valueRecordSize));
     89  }
     90 
     91  bool subset (hb_subset_context_t *c) const
     92  {
     93    TRACE_SUBSET (this);
     94 #ifdef HB_NO_VAR
     95    return_trace (false);
     96 #endif
     97 
     98    if (c->plan->all_axes_pinned)
     99      return_trace (false);
    100 
    101    MVAR *out = c->serializer->start_embed (*this);
    102    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
    103    out->version = version;
    104    out->reserved = reserved;
    105    out->valueRecordSize = valueRecordSize;
    106    out->valueRecordCount = valueRecordCount;
    107 
    108    item_variations_t item_vars;
    109    const ItemVariationStore& src_var_store = this+varStore;
    110 
    111    if (!item_vars.instantiate (src_var_store, c->plan))
    112      return_trace (false);
    113 
    114    /* serialize varstore */
    115    if (!out->varStore.serialize_serialize (c->serializer, item_vars.has_long_word (),
    116                                            c->plan->axis_tags,
    117                                            item_vars.get_region_list (),
    118                                            item_vars.get_vardata_encodings ()))
    119      return_trace (false);
    120 
    121    /* serialize value records array */
    122    unsigned value_rec_count = valueRecordCount;
    123    const VariationValueRecord *record = reinterpret_cast<const VariationValueRecord*> (valuesZ.arrayZ);
    124    for (unsigned i = 0; i < value_rec_count; i++)
    125    {
    126      if (!record->subset (c, item_vars.get_varidx_map ())) return_trace (false);
    127      record++;
    128    }
    129    return_trace (true);
    130  }
    131 
    132  float get_var (hb_tag_t tag,
    133 	 const int *coords, unsigned int coord_count) const
    134  {
    135    const VariationValueRecord *record;
    136    record = (VariationValueRecord *) hb_bsearch (tag,
    137 					  (const VariationValueRecord *)
    138 					    (const HBUINT8 *) valuesZ,
    139 					  valueRecordCount, valueRecordSize,
    140 					  tag_compare);
    141    if (!record)
    142      return 0.;
    143 
    144    return (this+varStore).get_delta (record->varIdx, coords, coord_count);
    145  }
    146 
    147 protected:
    148  static int tag_compare (const void *pa, const void *pb)
    149  {
    150    const hb_tag_t *a = (const hb_tag_t *) pa;
    151    const Tag *b = (const Tag *) pb;
    152    return b->cmp (*a);
    153  }
    154 
    155  protected:
    156  FixedVersion<>version;	/* Version of the metrics variation table
    157 			 * initially set to 0x00010000u */
    158  HBUINT16	reserved;	/* Not used; set to 0. */
    159  HBUINT16	valueRecordSize;/* The size in bytes of each value record —
    160 			 * must be greater than zero. */
    161  HBUINT16	valueRecordCount;/* The number of value records — may be zero. */
    162  Offset16To<ItemVariationStore>
    163 	varStore;	/* Offset to item variation store table. */
    164  UnsizedArrayOf<HBUINT8>
    165 	valuesZ;	/* Array of value records. The records must be
    166 			 * in binary order of their valueTag field. */
    167 
    168  public:
    169  DEFINE_SIZE_ARRAY (12, valuesZ);
    170 };
    171 
    172 } /* namespace OT */
    173 
    174 
    175 #define HB_ADD_MVAR_VAR(tag, field) \
    176       c->serializer->check_assign (table->field, \
    177 			    roundf (table->field + \
    178 				    MVAR.get_var (tag, \
    179 						  c->plan->normalized_coords.arrayZ, \
    180 						  c->plan->normalized_coords.length)), \
    181 			    HB_SERIALIZE_ERROR_INT_OVERFLOW)
    182 
    183 
    184 #endif /* HB_OT_VAR_MVAR_TABLE_HH */