rustybuzz/hb/
ot_shape_complex_syllabic.rs
1use super::buffer::hb_buffer_t;
2use super::{hb_font_t, hb_glyph_info_t};
3use crate::BufferFlags;
4
5pub fn insert_dotted_circles(
6 face: &hb_font_t,
7 buffer: &mut hb_buffer_t,
8 broken_syllable_type: u8,
9 dottedcircle_category: u8,
10 repha_category: Option<u8>,
11 dottedcircle_position: Option<u8>,
12) {
13 if buffer
14 .flags
15 .contains(BufferFlags::DO_NOT_INSERT_DOTTED_CIRCLE)
16 {
17 return;
18 }
19
20 let has_broken_syllables = buffer
23 .info_slice()
24 .iter()
25 .any(|info| info.syllable() & 0x0F == broken_syllable_type);
26
27 if !has_broken_syllables {
28 return;
29 }
30
31 let dottedcircle_glyph = match face.get_nominal_glyph(0x25CC) {
32 Some(g) => g.0 as u32,
33 None => return,
34 };
35
36 let mut dottedcircle = hb_glyph_info_t {
37 glyph_id: 0x25CC,
38 ..hb_glyph_info_t::default()
39 };
40 dottedcircle.set_complex_var_u8_category(dottedcircle_category);
41 if let Some(dottedcircle_position) = dottedcircle_position {
42 dottedcircle.set_complex_var_u8_auxiliary(dottedcircle_position);
43 }
44 dottedcircle.glyph_id = dottedcircle_glyph;
45
46 buffer.clear_output();
47
48 buffer.idx = 0;
49 let mut last_syllable = 0;
50 while buffer.idx < buffer.len {
51 let syllable = buffer.cur(0).syllable();
52 if last_syllable != syllable && (syllable & 0x0F) == broken_syllable_type {
53 last_syllable = syllable;
54
55 let mut ginfo = dottedcircle;
56 ginfo.cluster = buffer.cur(0).cluster;
57 ginfo.mask = buffer.cur(0).mask;
58 ginfo.set_syllable(buffer.cur(0).syllable());
59
60 if let Some(repha_category) = repha_category {
62 while buffer.idx < buffer.len
63 && last_syllable == buffer.cur(0).syllable()
64 && buffer.cur(0).complex_var_u8_category() == repha_category
65 {
66 buffer.next_glyph();
67 }
68 }
69
70 buffer.output_info(ginfo);
71 } else {
72 buffer.next_glyph();
73 }
74 }
75
76 buffer.sync();
77}