rustybuzz/hb/
ot_shaper_syllabic.rs

1use super::buffer::{hb_buffer_t, HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE};
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) -> bool {
13    if buffer
14        .flags
15        .contains(BufferFlags::DO_NOT_INSERT_DOTTED_CIRCLE)
16    {
17        return false;
18    }
19
20    if (buffer.scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE) == 0 {
21        return false;
22    }
23
24    let dottedcircle_glyph = match face.get_nominal_glyph(0x25CC) {
25        Some(g) => g.0 as u32,
26        None => return false,
27    };
28
29    let mut dottedcircle = hb_glyph_info_t {
30        glyph_id: 0x25CC,
31        ..hb_glyph_info_t::default()
32    };
33    dottedcircle.set_ot_shaper_var_u8_category(dottedcircle_category);
34    if let Some(dottedcircle_position) = dottedcircle_position {
35        dottedcircle.set_ot_shaper_var_u8_auxiliary(dottedcircle_position);
36    }
37    dottedcircle.glyph_id = dottedcircle_glyph;
38
39    buffer.clear_output();
40
41    buffer.idx = 0;
42    let mut last_syllable = 0;
43    while buffer.idx < buffer.len {
44        let syllable = buffer.cur(0).syllable();
45        if last_syllable != syllable && (syllable & 0x0F) == broken_syllable_type {
46            last_syllable = syllable;
47
48            let mut ginfo = dottedcircle;
49            ginfo.cluster = buffer.cur(0).cluster;
50            ginfo.mask = buffer.cur(0).mask;
51            ginfo.set_syllable(buffer.cur(0).syllable());
52
53            // Insert dottedcircle after possible Repha.
54            if let Some(repha_category) = repha_category {
55                while buffer.idx < buffer.len
56                    && last_syllable == buffer.cur(0).syllable()
57                    && buffer.cur(0).ot_shaper_var_u8_category() == repha_category
58                {
59                    buffer.next_glyph();
60                }
61            }
62
63            buffer.output_info(ginfo);
64        } else {
65            buffer.next_glyph();
66        }
67    }
68
69    buffer.sync();
70
71    true
72}