tor-browser

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

AlternateSubstFormat1.hh (4808B)


      1 #ifndef OT_LAYOUT_GSUB_ALTERNATESUBSTFORMAT1_HH
      2 #define OT_LAYOUT_GSUB_ALTERNATESUBSTFORMAT1_HH
      3 
      4 #include "AlternateSet.hh"
      5 #include "Common.hh"
      6 
      7 namespace OT {
      8 namespace Layout {
      9 namespace GSUB_impl {
     10 
     11 template <typename Types>
     12 struct AlternateSubstFormat1_2
     13 {
     14  protected:
     15  HBUINT16      format;                 /* Format identifier--format = 1 */
     16  typename Types::template OffsetTo<Coverage>
     17                coverage;               /* Offset to Coverage table--from
     18                                         * beginning of Substitution table */
     19  Array16Of<typename Types::template OffsetTo<AlternateSet<Types>>>
     20                alternateSet;           /* Array of AlternateSet tables
     21                                         * ordered by Coverage Index */
     22  public:
     23  DEFINE_SIZE_ARRAY (2 + 2 * Types::size, alternateSet);
     24 
     25  bool sanitize (hb_sanitize_context_t *c) const
     26  {
     27    TRACE_SANITIZE (this);
     28    return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
     29  }
     30 
     31  bool intersects (const hb_set_t *glyphs) const
     32  { return (this+coverage).intersects (glyphs); }
     33 
     34  bool may_have_non_1to1 () const
     35  { return false; }
     36 
     37  void closure (hb_closure_context_t *c) const
     38  {
     39    + hb_zip (this+coverage, alternateSet)
     40    | hb_filter (c->parent_active_glyphs (), hb_first)
     41    | hb_map (hb_second)
     42    | hb_map (hb_add (this))
     43    | hb_apply ([c] (const AlternateSet<Types> &_) { _.closure (c); })
     44    ;
     45  }
     46 
     47  void closure_lookups (hb_closure_lookups_context_t *c) const {}
     48 
     49  void collect_glyphs (hb_collect_glyphs_context_t *c) const
     50  {
     51    if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
     52    + hb_zip (this+coverage, alternateSet)
     53    | hb_map (hb_second)
     54    | hb_map (hb_add (this))
     55    | hb_apply ([c] (const AlternateSet<Types> &_) { _.collect_glyphs (c); })
     56    ;
     57  }
     58 
     59  const Coverage &get_coverage () const { return this+coverage; }
     60 
     61  bool would_apply (hb_would_apply_context_t *c) const
     62  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
     63 
     64  unsigned
     65  get_glyph_alternates (hb_codepoint_t  gid,
     66                        unsigned        start_offset,
     67                        unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
     68                        hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
     69  { return (this+alternateSet[(this+coverage).get_coverage (gid)])
     70           .get_alternates (start_offset, alternate_count, alternate_glyphs); }
     71 
     72  void
     73  collect_glyph_alternates (hb_map_t  *alternate_count /* IN/OUT */,
     74 		    hb_map_t  *alternate_glyphs /* IN/OUT */) const
     75  {
     76    + hb_iter (alternateSet)
     77    | hb_map (hb_add (this))
     78    | hb_zip (this+coverage)
     79    | hb_apply ([&] (const hb_pair_t<const AlternateSet<Types> &, hb_codepoint_t> _) {
     80 	  _.first.collect_alternates (_.second, alternate_count, alternate_glyphs);
     81 	})
     82    ;
     83  }
     84 
     85  bool apply (hb_ot_apply_context_t *c) const
     86  {
     87    TRACE_APPLY (this);
     88 
     89    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
     90    if (index == NOT_COVERED) return_trace (false);
     91 
     92    return_trace ((this+alternateSet[index]).apply (c));
     93  }
     94 
     95  bool serialize (hb_serialize_context_t *c,
     96                  hb_sorted_array_t<const HBGlyphID16> glyphs,
     97                  hb_array_t<const unsigned int> alternate_len_list,
     98                  hb_array_t<const HBGlyphID16> alternate_glyphs_list)
     99  {
    100    TRACE_SERIALIZE (this);
    101    if (unlikely (!c->extend_min (this))) return_trace (false);
    102    if (unlikely (!alternateSet.serialize (c, glyphs.length))) return_trace (false);
    103    for (unsigned int i = 0; i < glyphs.length; i++)
    104    {
    105      unsigned int alternate_len = alternate_len_list[i];
    106      if (unlikely (!alternateSet[i]
    107                        .serialize_serialize (c, alternate_glyphs_list.sub_array (0, alternate_len))))
    108        return_trace (false);
    109      alternate_glyphs_list += alternate_len;
    110    }
    111    return_trace (coverage.serialize_serialize (c, glyphs));
    112  }
    113 
    114  bool subset (hb_subset_context_t *c) const
    115  {
    116    TRACE_SUBSET (this);
    117    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
    118    const hb_map_t &glyph_map = *c->plan->glyph_map;
    119 
    120    auto *out = c->serializer->start_embed (*this);
    121    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
    122    out->format = format;
    123 
    124    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
    125    + hb_zip (this+coverage, alternateSet)
    126    | hb_filter (glyphset, hb_first)
    127    | hb_filter (subset_offset_array (c, out->alternateSet, this), hb_second)
    128    | hb_map (hb_first)
    129    | hb_map (glyph_map)
    130    | hb_sink (new_coverage)
    131    ;
    132    out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
    133    return_trace (bool (new_coverage));
    134  }
    135 };
    136 
    137 }
    138 }
    139 }
    140 
    141 #endif  /* OT_LAYOUT_GSUB_ALTERNATESUBSTFORMAT1_HH */