comparison mupdf-source/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 #ifndef OT_LAYOUT_GSUB_SINGLESUBSTFORMAT2_HH
2 #define OT_LAYOUT_GSUB_SINGLESUBSTFORMAT2_HH
3
4 #include "Common.hh"
5
6 namespace OT {
7 namespace Layout {
8 namespace GSUB_impl {
9
10 template <typename Types>
11 struct SingleSubstFormat2_4
12 {
13 protected:
14 HBUINT16 format; /* Format identifier--format = 2 */
15 typename Types::template OffsetTo<Coverage>
16 coverage; /* Offset to Coverage table--from
17 * beginning of Substitution table */
18 Array16Of<typename Types::HBGlyphID>
19 substitute; /* Array of substitute
20 * GlyphIDs--ordered by Coverage Index */
21
22 public:
23 DEFINE_SIZE_ARRAY (4 + Types::size, substitute);
24
25 bool sanitize (hb_sanitize_context_t *c) const
26 {
27 TRACE_SANITIZE (this);
28 return_trace (coverage.sanitize (c, this) && substitute.sanitize (c));
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 auto &cov = this+coverage;
40 auto &glyph_set = c->parent_active_glyphs ();
41
42 if (substitute.len > glyph_set.get_population () * 4)
43 {
44 for (auto g : glyph_set)
45 {
46 unsigned i = cov.get_coverage (g);
47 if (i == NOT_COVERED || i >= substitute.len)
48 continue;
49 c->output->add (substitute.arrayZ[i]);
50 }
51
52 return;
53 }
54
55 + hb_zip (cov, substitute)
56 | hb_filter (glyph_set, hb_first)
57 | hb_map (hb_second)
58 | hb_sink (c->output)
59 ;
60 }
61
62 void closure_lookups (hb_closure_lookups_context_t *c) const {}
63
64 void collect_glyphs (hb_collect_glyphs_context_t *c) const
65 {
66 if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
67 + hb_zip (this+coverage, substitute)
68 | hb_map (hb_second)
69 | hb_sink (c->output)
70 ;
71 }
72
73 const Coverage &get_coverage () const { return this+coverage; }
74
75 bool would_apply (hb_would_apply_context_t *c) const
76 { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
77
78 bool apply (hb_ot_apply_context_t *c) const
79 {
80 TRACE_APPLY (this);
81 unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
82 if (likely (index == NOT_COVERED)) return_trace (false);
83
84 if (unlikely (index >= substitute.len)) return_trace (false);
85
86 if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
87 {
88 c->buffer->sync_so_far ();
89 c->buffer->message (c->font,
90 "replacing glyph at %d (single substitution)",
91 c->buffer->idx);
92 }
93
94 c->replace_glyph (substitute[index]);
95
96 if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
97 {
98 c->buffer->message (c->font,
99 "replaced glyph at %d (single substitution)",
100 c->buffer->idx - 1);
101 }
102
103 return_trace (true);
104 }
105
106 template<typename Iterator,
107 hb_requires (hb_is_sorted_source_of (Iterator,
108 hb_codepoint_pair_t))>
109 bool serialize (hb_serialize_context_t *c,
110 Iterator it)
111 {
112 TRACE_SERIALIZE (this);
113 auto substitutes =
114 + it
115 | hb_map (hb_second)
116 ;
117 auto glyphs =
118 + it
119 | hb_map_retains_sorting (hb_first)
120 ;
121 if (unlikely (!c->extend_min (this))) return_trace (false);
122 if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false);
123 if (unlikely (!coverage.serialize_serialize (c, glyphs))) return_trace (false);
124 return_trace (true);
125 }
126
127 bool subset (hb_subset_context_t *c) const
128 {
129 TRACE_SUBSET (this);
130 const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
131 const hb_map_t &glyph_map = *c->plan->glyph_map;
132
133 auto it =
134 + hb_zip (this+coverage, substitute)
135 | hb_filter (glyphset, hb_first)
136 | hb_filter (glyphset, hb_second)
137 | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const typename Types::HBGlyphID &> p) -> hb_codepoint_pair_t
138 { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
139 ;
140
141 bool ret = bool (it);
142 SingleSubst_serialize (c->serializer, it);
143 return_trace (ret);
144 }
145 };
146
147 }
148 }
149 }
150
151 #endif /* OT_LAYOUT_GSUB_SINGLESUBSTFORMAT2_HH */