tor-browser

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

SubstLookup.hh (7256B)


      1 #ifndef OT_LAYOUT_GSUB_SUBSTLOOKUP_HH
      2 #define OT_LAYOUT_GSUB_SUBSTLOOKUP_HH
      3 
      4 #include "Common.hh"
      5 #include "SubstLookupSubTable.hh"
      6 
      7 namespace OT {
      8 namespace Layout {
      9 namespace GSUB_impl {
     10 
     11 struct SubstLookup : Lookup
     12 {
     13  using SubTable = SubstLookupSubTable;
     14 
     15  bool sanitize (hb_sanitize_context_t *c) const
     16  { return Lookup::sanitize<SubTable> (c); }
     17 
     18  const SubTable& get_subtable (unsigned int i) const
     19  { return Lookup::get_subtable<SubTable> (i); }
     20 
     21  static inline bool lookup_type_is_reverse (unsigned int lookup_type)
     22  { return lookup_type == SubTable::ReverseChainSingle; }
     23 
     24  bool is_reverse () const
     25  {
     26    unsigned int type = get_type ();
     27    if (unlikely (type == SubTable::Extension))
     28      return get_subtable (0).u.extension.is_reverse ();
     29    return lookup_type_is_reverse (type);
     30  }
     31 
     32  bool may_have_non_1to1 () const
     33  {
     34    hb_have_non_1to1_context_t c;
     35    return dispatch (&c);
     36  }
     37 
     38  bool apply (hb_ot_apply_context_t *c) const
     39  {
     40    TRACE_APPLY (this);
     41    return_trace (dispatch (c));
     42  }
     43 
     44  bool intersects (const hb_set_t *glyphs) const
     45  {
     46    hb_intersects_context_t c (glyphs);
     47    return dispatch (&c);
     48  }
     49 
     50  hb_closure_context_t::return_t closure (hb_closure_context_t *c, unsigned int this_index) const
     51  {
     52    if (!c->should_visit_lookup (this_index))
     53      return hb_closure_context_t::default_return_value ();
     54 
     55    c->set_recurse_func (dispatch_closure_recurse_func);
     56 
     57    hb_closure_context_t::return_t ret = dispatch (c);
     58 
     59    c->flush ();
     60 
     61    return ret;
     62  }
     63 
     64  hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
     65  {
     66    if (c->is_lookup_visited (this_index))
     67      return hb_closure_lookups_context_t::default_return_value ();
     68 
     69    c->set_lookup_visited (this_index);
     70    if (!intersects (c->glyphs))
     71    {
     72      c->set_lookup_inactive (this_index);
     73      return hb_closure_lookups_context_t::default_return_value ();
     74    }
     75 
     76    hb_closure_lookups_context_t::return_t ret = dispatch (c);
     77    return ret;
     78  }
     79 
     80  hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
     81  {
     82    c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
     83    return dispatch (c);
     84  }
     85 
     86  template <typename set_t>
     87  void collect_coverage (set_t *glyphs) const
     88  {
     89    hb_collect_coverage_context_t<set_t> c (glyphs);
     90    dispatch (&c);
     91  }
     92 
     93  bool would_apply (hb_would_apply_context_t *c,
     94                    const hb_ot_layout_lookup_accelerator_t *accel) const
     95  {
     96    if (unlikely (!c->len)) return false;
     97    if (!accel->may_have (c->glyphs[0])) return false;
     98      return dispatch (c);
     99  }
    100 
    101  template<typename Glyphs, typename Substitutes,
    102    hb_requires (hb_is_sorted_source_of (Glyphs,
    103 					const hb_codepoint_t) &&
    104 		hb_is_source_of (Substitutes,
    105 				 const hb_codepoint_t))>
    106  bool serialize_single (hb_serialize_context_t *c,
    107                         uint32_t lookup_props,
    108                         Glyphs glyphs,
    109                         Substitutes substitutes)
    110  {
    111    TRACE_SERIALIZE (this);
    112    if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
    113    if (c->push<SubTable> ()->u.single.serialize (c, hb_zip (glyphs, substitutes)))
    114    {
    115      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
    116      return_trace (true);
    117    }
    118    c->pop_discard ();
    119    return_trace (false);
    120  }
    121 
    122  template<typename Iterator,
    123           hb_requires (hb_is_sorted_iterator (Iterator))>
    124  bool serialize (hb_serialize_context_t *c,
    125 	  uint32_t lookup_props,
    126 	  Iterator it)
    127  {
    128    TRACE_SERIALIZE (this);
    129    if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false);
    130    if (c->push<SubTable> ()->u.multiple.
    131        serialize (c, it))
    132    {
    133      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
    134      return_trace (true);
    135    }
    136    c->pop_discard ();
    137    return_trace (false);
    138  }
    139 
    140  bool serialize_alternate (hb_serialize_context_t *c,
    141                            uint32_t lookup_props,
    142                            hb_sorted_array_t<const HBGlyphID16> glyphs,
    143                            hb_array_t<const unsigned int> alternate_len_list,
    144                            hb_array_t<const HBGlyphID16> alternate_glyphs_list)
    145  {
    146    TRACE_SERIALIZE (this);
    147    if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false);
    148 
    149    if (c->push<SubTable> ()->u.alternate.
    150        serialize (c,
    151                   glyphs,
    152                   alternate_len_list,
    153                   alternate_glyphs_list))
    154    {
    155      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
    156      return_trace (true);
    157    }
    158    c->pop_discard ();
    159    return_trace (false);
    160  }
    161 
    162  bool serialize_ligature (hb_serialize_context_t *c,
    163                           uint32_t lookup_props,
    164                           hb_sorted_array_t<const HBGlyphID16> first_glyphs,
    165                           hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
    166                           hb_array_t<const HBGlyphID16> ligatures_list,
    167                           hb_array_t<const unsigned int> component_count_list,
    168                           hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
    169  {
    170    TRACE_SERIALIZE (this);
    171    if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false);
    172    if (c->push<SubTable> ()->u.ligature.
    173        serialize (c,
    174                   first_glyphs,
    175                   ligature_per_first_glyph_count_list,
    176                   ligatures_list,
    177                   component_count_list,
    178                   component_list))
    179    {
    180      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
    181      return_trace (true);
    182    }
    183    c->pop_discard ();
    184    return_trace (false);
    185  }
    186 
    187  template <typename context_t>
    188  static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
    189 
    190  static inline typename hb_closure_context_t::return_t closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index);
    191 
    192  static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index)
    193  {
    194    if (!c->should_visit_lookup (lookup_index))
    195      return hb_empty_t ();
    196 
    197    hb_closure_context_t::return_t ret = closure_glyphs_recurse_func (c, lookup_index, covered_seq_indices, seq_index, end_index);
    198 
    199    /* While in theory we should flush here, it will cause timeouts because a recursive
    200     * lookup can keep growing the glyph set.  Skip, and outer loop will retry up to
    201     * HB_CLOSURE_MAX_STAGES time, which should be enough for every realistic font. */
    202    //c->flush ();
    203 
    204    return ret;
    205  }
    206 
    207  template <typename context_t, typename ...Ts>
    208  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
    209  { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
    210 
    211  bool subset (hb_subset_context_t *c) const
    212  { return Lookup::subset<SubTable> (c); }
    213 };
    214 
    215 
    216 }
    217 }
    218 }
    219 
    220 #endif  /* OT_LAYOUT_GSUB_SUBSTLOOKUP_HH */