Skip to main content

text_typeset/layout/
line.rs

1use std::ops::Range;
2
3use crate::shaping::run::ShapedRun;
4
5pub struct LayoutLine {
6    pub runs: Vec<PositionedRun>,
7    /// Baseline y relative to block top (set by block layout).
8    pub y: f32,
9    pub ascent: f32,
10    pub descent: f32,
11    pub leading: f32,
12    /// Total line height: ascent + descent + leading.
13    pub line_height: f32,
14    /// Actual content width (sum of run advances).
15    pub width: f32,
16    /// Character range in the block's text.
17    pub char_range: Range<usize>,
18}
19
20impl LayoutLine {
21    /// Find the x coordinate for a char offset within this line.
22    ///
23    /// Walks runs and glyphs, returning the x position of the first glyph
24    /// whose cluster >= `offset`. Falls back to the end of the line.
25    pub fn x_for_offset(&self, offset: usize) -> f32 {
26        for (i, run) in self.runs.iter().enumerate() {
27            let mut glyph_x = run.x;
28            for glyph in &run.shaped_run.glyphs {
29                if glyph.cluster as usize >= offset {
30                    return glyph_x;
31                }
32                glyph_x += glyph.x_advance;
33            }
34            // Only return from this run if the offset doesn't belong to a later run
35            let next_run_start = self
36                .runs
37                .get(i + 1)
38                .and_then(|r| r.shaped_run.glyphs.first())
39                .map(|g| g.cluster as usize);
40            match next_run_start {
41                Some(next_start) if offset >= next_start => continue,
42                _ => return glyph_x,
43            }
44        }
45        self.runs
46            .last()
47            .map(|r| r.x + r.shaped_run.advance_width)
48            .unwrap_or(0.0)
49    }
50}
51
52pub struct PositionedRun {
53    pub shaped_run: ShapedRun,
54    /// X offset from the left edge of the content area.
55    pub x: f32,
56    /// Decoration flags for this run.
57    pub decorations: RunDecorations,
58}
59
60/// Text decoration flags and metadata carried from the source TextFormat.
61#[derive(Clone, Debug, Default)]
62pub struct RunDecorations {
63    pub underline_style: crate::types::UnderlineStyle,
64    pub overline: bool,
65    pub strikeout: bool,
66    pub is_link: bool,
67    /// Text foreground color (RGBA). None means default (black).
68    pub foreground_color: Option<[f32; 4]>,
69    /// Underline color (RGBA). None means use foreground_color.
70    pub underline_color: Option<[f32; 4]>,
71    /// Text-level background highlight color (RGBA). None means transparent.
72    pub background_color: Option<[f32; 4]>,
73    /// Hyperlink destination URL.
74    pub anchor_href: Option<String>,
75    /// Tooltip text.
76    pub tooltip: Option<String>,
77    /// Vertical alignment (normal, superscript, subscript).
78    pub vertical_alignment: crate::types::VerticalAlignment,
79}