Skip to main content

harfrust/hb/
ot_shaper_syllabic.rs

1use super::buffer::*;
2use super::font_funcs::FontFuncsDispatch;
3use super::ot_shape_plan::hb_ot_shape_plan_t;
4use super::GlyphInfo;
5use crate::BufferFlags;
6
7pub fn insert_dotted_circles(
8    font_funcs: &mut FontFuncsDispatch,
9    buffer: &mut hb_buffer_t,
10    broken_syllable_type: u8,
11    dottedcircle_category: u8,
12    repha_category: Option<u8>,
13    dottedcircle_position: Option<u8>,
14) -> bool {
15    if buffer
16        .flags
17        .contains(BufferFlags::DO_NOT_INSERT_DOTTED_CIRCLE)
18    {
19        return false;
20    }
21
22    if (buffer.scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE) == 0 {
23        return false;
24    }
25
26    let dottedcircle_glyph = match font_funcs.nominal_glyph(0x25CC) {
27        Some(g) => g.to_u32(),
28        None => return false,
29    };
30
31    let mut dottedcircle = GlyphInfo {
32        glyph_id: 0x25CC,
33        ..GlyphInfo::default()
34    };
35    dottedcircle.set_ot_shaper_var_u8_category(dottedcircle_category);
36    if let Some(dottedcircle_position) = dottedcircle_position {
37        dottedcircle.set_ot_shaper_var_u8_auxiliary(dottedcircle_position);
38    }
39    dottedcircle.glyph_id = dottedcircle_glyph;
40
41    buffer.clear_output();
42
43    buffer.idx = 0;
44    let mut last_syllable = 0;
45    while buffer.idx < buffer.len {
46        let syllable = buffer.cur(0).syllable();
47        if last_syllable != syllable && (syllable & 0x0F) == broken_syllable_type {
48            last_syllable = syllable;
49
50            let mut ginfo = dottedcircle;
51            ginfo.cluster = buffer.cur(0).cluster;
52            ginfo.mask = buffer.cur(0).mask;
53            ginfo.set_syllable(buffer.cur(0).syllable());
54
55            // Insert dottedcircle after possible Repha.
56            if let Some(repha_category) = repha_category {
57                while buffer.idx < buffer.len
58                    && last_syllable == buffer.cur(0).syllable()
59                    && buffer.cur(0).ot_shaper_var_u8_category() == repha_category
60                {
61                    buffer.next_glyph();
62                }
63            }
64
65            buffer.output_info(ginfo);
66        } else {
67            buffer.next_glyph();
68        }
69    }
70
71    buffer.sync();
72
73    true
74}
75
76pub(crate) fn syllabic_clear_var(
77    _: &hb_ot_shape_plan_t,
78    _: &mut FontFuncsDispatch,
79    buffer: &mut hb_buffer_t,
80) -> bool {
81    for info in &mut buffer.info {
82        info.set_syllable(0);
83    }
84    buffer.deallocate_var(GlyphInfo::SYLLABLE_VAR);
85
86    false
87}