freya_code_editor/
metrics.rs1use freya_core::prelude::consume_root_context;
2use freya_engine::prelude::*;
3use ropey::Rope;
4use tree_sitter::InputEdit;
5
6use crate::{
7 editor_theme::EditorSyntaxTheme,
8 syntax::*,
9};
10
11pub struct EditorMetrics {
12 pub(crate) syntax_blocks: SyntaxBlocks,
13 pub(crate) longest_width: f32,
14 pub(crate) char_width: f32,
15 pub(crate) highlighter: SyntaxHighlighter,
16}
17
18impl Default for EditorMetrics {
19 fn default() -> Self {
20 Self::new()
21 }
22}
23
24impl EditorMetrics {
25 pub fn new() -> Self {
26 Self {
27 syntax_blocks: SyntaxBlocks::default(),
28 longest_width: 0.0,
29 char_width: 0.0,
30 highlighter: SyntaxHighlighter::new(),
31 }
32 }
33
34 pub fn measure_longest_line(&mut self, font_size: f32, font_family: &str, rope: &Rope) {
35 let font_collection = consume_root_context::<FontCollection>();
39 let mut paragraph_style = ParagraphStyle::default();
40 let mut text_style = TextStyle::default();
41 text_style.set_font_size(font_size);
42 text_style.set_font_families(&[font_family]);
43 paragraph_style.set_text_style(&text_style);
44 let mut paragraph_builder = ParagraphBuilder::new(¶graph_style, font_collection);
45
46 paragraph_builder.add_text("W");
48 let mut paragraph = paragraph_builder.build();
49 paragraph.layout(f32::MAX);
50 let char_width = paragraph.longest_line();
51
52 let max_chars = rope.lines().map(|line| line.len_chars()).max().unwrap_or(0);
54
55 self.char_width = char_width;
56 self.longest_width = max_chars as f32 * char_width;
57 }
58
59 pub fn run_parser(&mut self, rope: &Rope, edit: Option<InputEdit>, theme: &EditorSyntaxTheme) {
60 self.highlighter
61 .parse(rope, &mut self.syntax_blocks, edit, theme);
62 }
63}