rustybuzz/hb/ot/layout/GSUB/
ligature.rs1use crate::hb::ot_layout_gsubgpos::OT::hb_ot_apply_context_t;
2use crate::hb::ot_layout_gsubgpos::{
3 ligate_input, match_glyph, match_input, Apply, WouldApply, WouldApplyContext,
4};
5use ttf_parser::gsub::Ligature;
6
7impl WouldApply for Ligature<'_> {
8 fn would_apply(&self, ctx: &WouldApplyContext) -> bool {
9 ctx.glyphs.len() == usize::from(self.components.len()) + 1
10 && self
11 .components
12 .into_iter()
13 .enumerate()
14 .all(|(i, comp)| ctx.glyphs[i + 1] == comp)
15 }
16}
17
18impl Apply for Ligature<'_> {
19 fn apply(&self, ctx: &mut hb_ot_apply_context_t) -> Option<()> {
20 if self.components.is_empty() {
23 ctx.replace_glyph(self.glyph);
24 Some(())
25 } else {
26 let f = |glyph, index| {
27 let value = self.components.get(index).unwrap();
28 match_glyph(glyph, value.0)
29 };
30
31 let mut match_end = 0;
32 let mut match_positions = smallvec::SmallVec::from_elem(0, 4);
33 let mut total_component_count = 0;
34
35 if !match_input(
36 ctx,
37 self.components.len(),
38 &f,
39 &mut match_end,
40 &mut match_positions,
41 Some(&mut total_component_count),
42 ) {
43 ctx.buffer
44 .unsafe_to_concat(Some(ctx.buffer.idx), Some(match_end));
45 return None;
46 }
47
48 let count = usize::from(self.components.len()) + 1;
49 ligate_input(
50 ctx,
51 count,
52 &match_positions,
53 match_end,
54 total_component_count,
55 self.glyph,
56 );
57 Some(())
58 }
59 }
60}