1 | use crate::buffer::{Buffer, BufferFlags}; |
2 | use crate::{Face, GlyphInfo}; |
3 | |
4 | pub fn insert_dotted_circles( |
5 | face: &Face, |
6 | buffer: &mut Buffer, |
7 | broken_syllable_type: u8, |
8 | dottedcircle_category: u8, |
9 | repha_category: Option<u8>, |
10 | dottedcircle_position: Option<u8>, |
11 | ) { |
12 | if buffer |
13 | .flags |
14 | .contains(BufferFlags::DO_NOT_INSERT_DOTTED_CIRCLE) |
15 | { |
16 | return; |
17 | } |
18 | |
19 | // Note: This loop is extra overhead, but should not be measurable. |
20 | // TODO Use a buffer scratch flag to remove the loop. |
21 | let has_broken_syllables = buffer |
22 | .info_slice() |
23 | .iter() |
24 | .any(|info| info.syllable() & 0x0F == broken_syllable_type); |
25 | |
26 | if !has_broken_syllables { |
27 | return; |
28 | } |
29 | |
30 | let dottedcircle_glyph = match face.glyph_index(0x25CC) { |
31 | Some(g) => g.0 as u32, |
32 | None => return, |
33 | }; |
34 | |
35 | let mut dottedcircle = GlyphInfo { |
36 | glyph_id: 0x25CC, |
37 | ..GlyphInfo::default() |
38 | }; |
39 | dottedcircle.set_complex_var_u8_category(dottedcircle_category); |
40 | if let Some(dottedcircle_position) = dottedcircle_position { |
41 | dottedcircle.set_complex_var_u8_auxiliary(dottedcircle_position); |
42 | } |
43 | dottedcircle.glyph_id = dottedcircle_glyph; |
44 | |
45 | buffer.clear_output(); |
46 | |
47 | buffer.idx = 0; |
48 | let mut last_syllable = 0; |
49 | while buffer.idx < buffer.len { |
50 | let syllable = buffer.cur(0).syllable(); |
51 | if last_syllable != syllable && (syllable & 0x0F) == broken_syllable_type { |
52 | last_syllable = syllable; |
53 | |
54 | let mut ginfo = dottedcircle; |
55 | ginfo.cluster = buffer.cur(0).cluster; |
56 | ginfo.mask = buffer.cur(0).mask; |
57 | ginfo.set_syllable(buffer.cur(0).syllable()); |
58 | |
59 | // Insert dottedcircle after possible Repha. |
60 | if let Some(repha_category) = repha_category { |
61 | while buffer.idx < buffer.len |
62 | && last_syllable == buffer.cur(0).syllable() |
63 | && buffer.cur(0).complex_var_u8_category() == repha_category |
64 | { |
65 | buffer.next_glyph(); |
66 | } |
67 | } |
68 | |
69 | buffer.output_info(ginfo); |
70 | } else { |
71 | buffer.next_glyph(); |
72 | } |
73 | } |
74 | |
75 | buffer.sync(); |
76 | } |
77 | |