Skip to main content

ass_renderer/layout/
multiline.rs

1//! Multi-line text layout
2
3#[cfg(feature = "nostd")]
4use alloc::{
5    string::{String, ToString},
6    vec::Vec,
7};
8#[cfg(not(feature = "nostd"))]
9use std::{string::String, vec::Vec};
10
11use super::{Alignment, LayoutContext};
12
13/// Multi-line text layout
14pub struct MultiLineLayout {
15    pub lines: Vec<LineLayout>,
16    pub total_width: f32,
17    pub total_height: f32,
18}
19
20/// Single line layout information
21pub struct LineLayout {
22    pub text: String,
23    pub x: f32,
24    pub y: f32,
25    pub width: f32,
26    pub height: f32,
27    pub baseline: f32,
28}
29
30impl MultiLineLayout {
31    /// Create layout for multi-line text
32    pub fn new(
33        text: &str,
34        _context: &LayoutContext,
35        alignment: Alignment,
36        line_spacing: f32,
37    ) -> Self {
38        // Text has already been processed by ass-core, so \N is now \n
39        let lines: Vec<&str> = text.split('\n').collect();
40        let mut line_layouts = Vec::new();
41        let mut total_height = 0.0;
42        let mut max_width = 0.0;
43
44        // TODO: Actual text shaping would go here
45        // For now, use estimates
46        let line_height = 50.0; // Placeholder
47
48        for (i, line) in lines.iter().enumerate() {
49            let line_width = line.len() as f32 * 20.0; // Placeholder
50            max_width = f32::max(max_width, line_width);
51
52            let y_offset = i as f32 * (line_height + line_spacing);
53
54            line_layouts.push(LineLayout {
55                text: line.to_string(),
56                x: 0.0, // Will be adjusted based on alignment
57                y: y_offset,
58                width: line_width,
59                height: line_height,
60                baseline: line_height * 0.8,
61            });
62
63            total_height = y_offset + line_height;
64        }
65
66        // Adjust line positions based on alignment
67        for line in &mut line_layouts {
68            line.x = match alignment {
69                Alignment::BottomLeft | Alignment::MiddleLeft | Alignment::TopLeft => 0.0,
70                Alignment::BottomCenter | Alignment::Center | Alignment::TopCenter => {
71                    (max_width - line.width) / 2.0
72                }
73                Alignment::BottomRight | Alignment::MiddleRight | Alignment::TopRight => {
74                    max_width - line.width
75                }
76            };
77        }
78
79        Self {
80            lines: line_layouts,
81            total_width: max_width,
82            total_height,
83        }
84    }
85}