1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use crate::style::computed::{BorderImagePaint, VerticalAlign};
use crate::types::{Color, CornerRadii, EdgeSizes};
use super::engine::{LayoutBorder, LayoutBorderSide, RasterImageAsset, TextLine};
/// A solid vector stroke centered on a box contour.
///
/// Unlike a CSS border, half of this stroke paints outside the nominal box.
/// UA-supplied geometric markers use that contour without changing layout.
#[derive(Debug, Clone, Copy)]
pub struct CenteredStroke {
side: LayoutBorderSide,
}
impl CenteredStroke {
pub const fn solid(width: f32, color: Color) -> Self {
Self {
side: LayoutBorderSide::solid(width, color),
}
}
pub(crate) const fn side(self) -> LayoutBorderSide {
self.side
}
pub(crate) fn transform_color(&mut self, transform: impl FnOnce(Color) -> Color) {
self.side.color = transform(self.side.color);
}
}
/// Paint owned by one atomic inline box.
///
/// Grouping these values keeps decoration decisions independent from inline
/// sizing, baseline participation, and replaced content.
#[derive(Debug, Clone, Default)]
pub struct InlineBoxPaint {
pub background_color: Option<Color>,
pub border: LayoutBorder,
pub border_image: Option<BorderImagePaint>,
pub border_radii: CornerRadii,
pub centered_stroke: Option<CenteredStroke>,
}
/// An atomic inline-level box laid out inside a line of text.
#[derive(Debug, Clone, Default)]
pub struct InlineBox {
/// Border-box width (the painted box width).
pub width: f32,
/// Border-box height (used to grow the line box and for vertical-align).
pub height: f32,
/// Horizontal margins add inline advance but are not painted.
pub margin_left: f32,
pub margin_right: f32,
pub paint: InlineBoxPaint,
pub padding: EdgeSizes,
/// CSS `vertical-align` relative to the line baseline.
pub vertical_align: VerticalAlign,
/// Distance from the top border edge to this box's baseline.
pub baseline_ascent: Option<f32>,
/// Pre-wrapped inner text lines (empty for content-less boxes).
pub lines: Vec<TextLine>,
/// Replaced content painted into the content box.
pub image: Option<RasterImageAsset>,
/// CSS relative-position paint offset (right, down) in points.
pub rel_offset_x: f32,
pub rel_offset_y: f32,
}
impl InlineBox {
/// A non-painting inline advance.
pub fn advance_only(advance: f32) -> Self {
Self {
margin_right: advance,
..Self::default()
}
}
/// Total inline advance including horizontal margins.
pub fn outer_width(&self) -> f32 {
self.width + self.margin_left + self.margin_right
}
}