fix(render): lay out text nodes in taffy and implement inline flow
This commit is contained in:
1 parent
193e30deb5
commit
9c8d62e13b
4 files changed
+41
-6
No files matched your search
@@ -140,6 +140,25 @@ fn build(
|
|||||||
styles: &HashMap<NodeId, crate::LayoutStyle>,
|
styles: &HashMap<NodeId, crate::LayoutStyle>,
|
||||||
) -> Option<taffy::NodeId> {
|
) -> Option<taffy::NodeId> {
|
||||||
let node = tree.get_node(id)?;
|
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 _name = node.as_element()?;
|
||||||
let style = styles.get(&id)?;
|
let style = styles.get(&id)?;
|
||||||
let taffy_style = to_taffy_style(style);
|
let taffy_style = to_taffy_style(style);
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ pub enum Display {
|
|||||||
#[default]
|
#[default]
|
||||||
Block,
|
Block,
|
||||||
Flex,
|
Flex,
|
||||||
|
Inline,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
@@ -144,8 +145,13 @@ pub(crate) fn to_taffy_style(style: &LayoutStyle) -> Style {
|
|||||||
s.display = match style.display {
|
s.display = match style.display {
|
||||||
Display::Block => taffy::style::Display::Block,
|
Display::Block => taffy::style::Display::Block,
|
||||||
Display::Flex => taffy::style::Display::Flex,
|
Display::Flex => taffy::style::Display::Flex,
|
||||||
|
Display::Inline => taffy::style::Display::Flex,
|
||||||
Display::None => taffy::style::Display::None,
|
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 {
|
s.size = taffy::Size {
|
||||||
width: dimension(style.width),
|
width: dimension(style.width),
|
||||||
height: dimension(style.height),
|
height: dimension(style.height),
|
||||||
|
|||||||
@@ -117,17 +117,23 @@ fn paint_text_node(
|
|||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
let node = tree.get_node(nid)?;
|
let node = tree.get_node(nid)?;
|
||||||
let text = match &node.data {
|
let text = match &node.data {
|
||||||
obscura_dom::tree::NodeData::Text { contents } => contents,
|
obscura_dom::tree::NodeData::Text { contents } => contents.trim(),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
if text.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// Find parent element to get geometry and color
|
|
||||||
let parent = node.parent?;
|
let parent = node.parent?;
|
||||||
let rect = laid.rects.get(&parent)?;
|
|
||||||
let style = laid.styles.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]);
|
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
|
// Paint text at rect.x, rect.y
|
||||||
draw_text(pixmap, text, rect.x, rect.y, color);
|
draw_text(pixmap, text, rect.x, rect.y, color);
|
||||||
Some(())
|
Some(())
|
||||||
|
|||||||
@@ -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
|
/// Built-in UA defaults. Inline elements currently map to block layout; real
|
||||||
/// inline/text layout arrives with the text/paint phase.
|
/// inline/text layout arrives with the text/paint phase.
|
||||||
pub fn ua_style(tag: &str) -> LayoutStyle {
|
pub fn ua_style(tag: &str) -> LayoutStyle {
|
||||||
let _ = tag;
|
let display = match tag {
|
||||||
LayoutStyle { display: Display::Block, ..Default::default() }
|
"span" | "a" | "b" | "i" | "strong" | "em" => Display::Inline,
|
||||||
|
_ => Display::Block,
|
||||||
|
};
|
||||||
|
LayoutStyle { display, ..Default::default() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_inline(style: &mut LayoutStyle, css: &str) {
|
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 {
|
"display" => match value {
|
||||||
"block" => style.display = Display::Block,
|
"block" => style.display = Display::Block,
|
||||||
"flex" => style.display = Display::Flex,
|
"flex" => style.display = Display::Flex,
|
||||||
|
"inline" => style.display = Display::Inline,
|
||||||
"none" => style.display = Display::None,
|
"none" => style.display = Display::None,
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in new issue
Block a user