tor-browser

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

hb-ot-post-table-v2subset.hh (5121B)


      1 /*
      2 * Copyright © 2021  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 */
     25 
     26 #ifndef HB_OT_POST_TABLE_V2SUBSET_HH
     27 #define HB_OT_POST_TABLE_V2SUBSET_HH
     28 
     29 #include "hb-open-type.hh"
     30 #include "hb-ot-post-table.hh"
     31 
     32 /*
     33 * post -- PostScript
     34 * https://docs.microsoft.com/en-us/typography/opentype/spec/post
     35 */
     36 
     37 namespace OT {
     38 template<typename Iterator>
     39 HB_INTERNAL bool postV2Tail::serialize (hb_serialize_context_t *c,
     40                                        Iterator it,
     41                                        const void* _post) const
     42 {
     43  TRACE_SERIALIZE (this);
     44  auto *out = c->start_embed (this);
     45  if (unlikely (!c->check_success (out))) return_trace (false);
     46  if (!out->glyphNameIndex.serialize (c, + it
     47                                         | hb_map (hb_second)))
     48      return_trace (false);
     49 
     50  hb_set_t copied_indices;
     51  for (const auto& _ : + it )
     52  {
     53    unsigned glyph_id = _.first;
     54    unsigned new_index = _.second;
     55 
     56    if (new_index < 258) continue;
     57    if (copied_indices.has (new_index)) continue;
     58    copied_indices.add (new_index);
     59 
     60    hb_bytes_t s = reinterpret_cast<const post::accelerator_t*> (_post)->find_glyph_name (glyph_id);
     61    HBUINT8 *o = c->allocate_size<HBUINT8> (HBUINT8::static_size * (s.length + 1));
     62    if (unlikely (!o)) return_trace (false);
     63    if (!c->check_assign (o[0], s.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
     64    hb_memcpy (o+1, s.arrayZ, HBUINT8::static_size * s.length);
     65  }
     66 
     67  return_trace (true);
     68 }
     69 
     70 HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
     71 {
     72  TRACE_SUBSET (this);
     73 
     74  const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
     75  unsigned num_glyphs = c->plan->num_output_glyphs ();
     76  hb_map_t old_new_index_map, old_gid_new_index_map;
     77  unsigned i = 0;
     78 
     79  post::accelerator_t _post (c->plan->source);
     80 
     81  hb_hashmap_t<hb_bytes_t, uint32_t, true> glyph_name_to_new_index;
     82 
     83  old_new_index_map.alloc (num_glyphs);
     84  old_gid_new_index_map.alloc (num_glyphs);
     85  glyph_name_to_new_index.alloc (num_glyphs);
     86 
     87  for (auto _ : c->plan->new_to_old_gid_list)
     88  {
     89    hb_codepoint_t old_gid = _.second;
     90    unsigned old_index = glyphNameIndex[old_gid];
     91 
     92    unsigned new_index;
     93    const uint32_t *new_index2;
     94    if (old_index <= 257)
     95      new_index = old_index;
     96    else if (old_new_index_map.has (old_index, &new_index2))
     97      new_index = *new_index2;
     98    else
     99    {
    100      hb_bytes_t s = _post.find_glyph_name (old_gid);
    101      new_index = glyph_name_to_new_index.get (s);
    102      if (new_index == (unsigned)-1)
    103      {
    104        int standard_glyph_index = -1;
    105        for (unsigned i = 0; i < format1_names_length; i++)
    106        {
    107          if (s == format1_names (i))
    108          {
    109            standard_glyph_index = i;
    110            break;
    111          }
    112        }
    113 
    114        if (standard_glyph_index == -1)
    115        {
    116          new_index = 258 + i;
    117          i++;
    118        }
    119        else
    120        { new_index = standard_glyph_index; }
    121        glyph_name_to_new_index.set (s, new_index);
    122      }
    123      old_new_index_map.set (old_index, new_index);
    124    }
    125    old_gid_new_index_map.set (old_gid, new_index);
    126  }
    127 
    128  if (old_gid_new_index_map.in_error())
    129    return_trace (false);
    130 
    131  auto index_iter =
    132  + hb_range (num_glyphs)
    133  | hb_map_retains_sorting ([&](hb_codepoint_t new_gid)
    134                            {
    135                              hb_codepoint_t *old_gid;
    136                              /* use 0 for retain-gid holes, which refers to the name .notdef,
    137                               * as the glyphNameIndex entry for that glyph ID."*/
    138                              unsigned new_index = 0;
    139                              if (reverse_glyph_map.has (new_gid, &old_gid)) {
    140                                new_index = old_gid_new_index_map.get (*old_gid);
    141                                return hb_pair_t<unsigned, unsigned> (*old_gid, new_index);
    142                              }
    143                              return hb_pair_t<unsigned, unsigned> (new_gid, new_index);
    144                            })
    145  ;
    146 
    147  return_trace (serialize (c->serializer, index_iter, &_post));
    148 }
    149 
    150 } /* namespace OT */
    151 #endif /* HB_OT_POST_TABLE_V2SUBSET_HH */