accessibility_tree/
text.rs1use crate::fonts::{Em, Font, FontError, GlyphId};
2use crate::primitives::Length;
3use std::sync::Arc;
4
5#[derive(Clone)]
6pub struct ShapedSegment {
7 pub font: Arc<Font>,
8 pub glyphs: Vec<GlyphId>,
9 pub advance_width: Length<Em>,
10}
11
12pub struct ShapedSegmentState {
13 glyphs: usize,
14 advance_width: Length<Em>,
15}
16
17impl std::fmt::Debug for ShapedSegment {
18 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
19 fmt.write_str("ShapedSegment")
20 }
21}
22
23impl ShapedSegment {
24 pub fn naive_shape(text: &str, font: Arc<Font>) -> Result<Self, FontError> {
31 let mut s = Self::new_with_naive_shaping(font);
32 s.append(text.chars())?;
33 Ok(s)
34 }
35
36 pub fn new_with_naive_shaping(font: Arc<Font>) -> Self {
37 Self {
38 font,
39 glyphs: Vec::new(),
40 advance_width: Length::new(0.),
41 }
42 }
43
44 pub fn append(&mut self, mut text: impl Iterator<Item = char>) -> Result<(), FontError> {
45 text.try_for_each(|ch| self.append_char(ch))
46 }
47
48 pub fn append_char(&mut self, ch: char) -> Result<(), FontError> {
49 let id = self.font.glyph_id(ch)?;
50 self.advance_width += self.font.glyph_width(id)?;
51 self.glyphs.push(id);
52 Ok(())
53 }
54
55 pub fn save(&self) -> ShapedSegmentState {
56 ShapedSegmentState {
57 glyphs: self.glyphs.len(),
58 advance_width: self.advance_width,
59 }
60 }
61
62 pub fn restore(&mut self, state: &ShapedSegmentState) {
63 self.glyphs.truncate(state.glyphs);
64 self.advance_width = state.advance_width;
65 }
66}