fix(render): lay out text nodes in taffy and implement inline flow

This commit is contained in:
SGavrl committed 2026-07-02 20:02:07 +00:00
1 parent 193e30deb5
commit 9c8d62e13b
4 files changed
+41 -6

No files matched your search

+19
View File
@@ -140,6 +140,25 @@ fn build(
styles: &HashMap<NodeId, crate::LayoutStyle>,
) -> Option<taffy::NodeId> {
let node = tree.get_node(id)?;
if let obscura_dom::tree::NodeData::Text { contents } = &node.data {
let text = contents.trim();
if text.is_empty() {
return None;
}
let width = text.chars().count() as f32 * 9.0;
let style = taffy::Style {
size: taffy::Size {
width: taffy::Dimension::Length(width),
height: taffy::Dimension::Length(19.0),
},
..Default::default()
};
let taffy_id = taffy_tree.new_leaf(style).ok()?;
id_map.insert(taffy_id, id);
return Some(taffy_id);
}
let _name = node.as_element()?;
let style = styles.get(&id)?;
let taffy_style = to_taffy_style(style);
+6
View File
@@ -49,6 +49,7 @@ pub enum Display {
#[default]
Block,
Flex,
Inline,
#[allow(dead_code)]
None,
}
@@ -144,8 +145,13 @@ pub(crate) fn to_taffy_style(style: &LayoutStyle) -> Style {
s.display = match style.display {
Display::Block => taffy::style::Display::Block,
Display::Flex => taffy::style::Display::Flex,
Display::Inline => taffy::style::Display::Flex,
Display::None => taffy::style::Display::None,
};
if style.display == Display::Inline {
s.flex_direction = taffy::FlexDirection::Row;
}
s.flex_wrap = taffy::FlexWrap::Wrap;
s.size = taffy::Size {
width: dimension(style.width),
height: dimension(style.height),
+10 -4
View File
@@ -117,17 +117,23 @@ fn paint_text_node(
) -> Option<()> {
let node = tree.get_node(nid)?;
let text = match &node.data {
obscura_dom::tree::NodeData::Text { contents } => contents,
obscura_dom::tree::NodeData::Text { contents } => contents.trim(),
_ => return None,
};
if text.is_empty() {
return None;
}
// Find parent element to get geometry and color
let parent = node.parent?;
let rect = laid.rects.get(&parent)?;
let style = laid.styles.get(&parent)?;
// Default color to black if not specified.
let color = style.color.unwrap_or([0, 0, 0, 255]);
// Get geometry of the text node itself!
let rect = match laid.rects.get(&nid) {
Some(r) => r,
None => return None,
};
// Paint text at rect.x, rect.y
draw_text(pixmap, text, rect.x, rect.y, color);
Some(())
+6 -2
View File
@@ -23,8 +23,11 @@ pub fn compute_style(tag: &str, inline_css: Option<&str>) -> LayoutStyle {
/// Built-in UA defaults. Inline elements currently map to block layout; real
/// inline/text layout arrives with the text/paint phase.
pub fn ua_style(tag: &str) -> LayoutStyle {
let _ = tag;
LayoutStyle { display: Display::Block, ..Default::default() }
let display = match tag {
"span" | "a" | "b" | "i" | "strong" | "em" => Display::Inline,
_ => Display::Block,
};
LayoutStyle { display, ..Default::default() }
}
pub fn apply_inline(style: &mut LayoutStyle, css: &str) {
@@ -51,6 +54,7 @@ fn apply_value(style: &mut LayoutStyle, name: &str, value: &str) {
"display" => match value {
"block" => style.display = Display::Block,
"flex" => style.display = Display::Flex,
"inline" => style.display = Display::Inline,
"none" => style.display = Display::None,
_ => {}
},