Skip to content

Commit

Permalink
Support calc() values in CSS
Browse files Browse the repository at this point in the history
Signed-off-by: Nico Burns <[email protected]>
  • Loading branch information
nicoburns committed Jan 6, 2025
1 parent fca4d93 commit fc3bf13
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 257 deletions.
13 changes: 7 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ license = "MIT OR Apache-2.0"

[workspace.dependencies]
# Servo dependencies
style = { git = "https://github.com/nicoburns/stylo", rev = "80741aba", package = "style" } # u64-opaque-element
style_config = { git = "https://github.com/nicoburns/stylo", rev = "80741aba", package = "style_config" } # u64-opaque-element
style_traits = { git = "https://github.com/nicoburns/stylo", rev = "80741aba", package = "style_traits" } # u64-opaque-element
style_dom = { git = "https://github.com/nicoburns/stylo", rev = "80741aba", package = "dom" } # u64-opaque-element
selectors = { git = "https://github.com/nicoburns/stylo", rev = "80741aba", package = "selectors" } # u64-opaque-element
style = { git = "https://github.com/nicoburns/stylo", rev = "9ceb7369", package = "style" } # blitz
style_config = { git = "https://github.com/nicoburns/stylo", rev = "9ceb7369", package = "style_config" } # blitz
style_traits = { git = "https://github.com/nicoburns/stylo", rev = "9ceb7369", package = "style_traits" } # blitz
style_dom = { git = "https://github.com/nicoburns/stylo", rev = "9ceb7369", package = "dom" } # blitz
selectors = { git = "https://github.com/nicoburns/stylo", rev = "9ceb7369", package = "selectors" } # blitz

markup5ever = "0.14" # needs to match stylo markup5ever version
html5ever = "0.29" # needs to match stylo markup5ever version
xml5ever = "0.20" # needs to match stylo markup5ever version
Expand All @@ -39,7 +40,7 @@ dioxus-core = { version = "0.6" }
dioxus-html = { version = "0.6" }
dioxus-cli-config = { version = "0.6" }
dioxus-devtools = { version = "0.6" }
taffy = { version = "0.7.1", default-features = false, features = ["std", "flexbox", "grid", "block_layout", "content_size"] }
taffy = { git = "https://github.com/dioxuslabs/taffy", rev = "0386dc966a", default-features = false, features = ["std", "flexbox", "grid", "block_layout", "content_size"] }

# Linebender + WGPU
peniko = "0.2"
Expand Down
8 changes: 5 additions & 3 deletions packages/blitz-dom/src/image.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use taffy::{MaybeMath, MaybeResolve};

use crate::layout::resolve_calc_value;

#[derive(Debug, Clone, Copy)]
pub struct ImageContext {
pub inherent_size: taffy::Size<f32>,
Expand All @@ -22,15 +24,15 @@ pub fn image_measure_function(
// Resolve sizes
let style_size = style
.size
.maybe_resolve(parent_size)
.maybe_resolve(parent_size, resolve_calc_value)
.maybe_apply_aspect_ratio(Some(aspect_ratio));
let min_size = style
.min_size
.maybe_resolve(parent_size)
.maybe_resolve(parent_size, resolve_calc_value)
.maybe_apply_aspect_ratio(Some(aspect_ratio));
let max_size = style
.max_size
.maybe_resolve(parent_size)
.maybe_resolve(parent_size, resolve_calc_value)
.maybe_apply_aspect_ratio(Some(aspect_ratio));
let attr_size = image_context
.attr_size
Expand Down
371 changes: 198 additions & 173 deletions packages/blitz-dom/src/layout/inline.rs

Large diffs are not rendered by default.

34 changes: 24 additions & 10 deletions packages/blitz-dom/src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use crate::{
use markup5ever::local_name;
use std::cell::Ref;
use std::sync::Arc;
use style::values::computed::length_percentage::CalcLengthPercentage;
use style::values::computed::CSSPixelLength;
use taffy::{
compute_block_layout, compute_cached_layout, compute_flexbox_layout, compute_grid_layout,
compute_leaf_layout, prelude::*, FlexDirection, LayoutPartialTree, NodeId, ResolveOrZero,
Expand All @@ -25,6 +27,12 @@ pub(crate) mod table;

use self::table::TableTreeWrapper;

pub(crate) fn resolve_calc_value(calc_value: u64, parent_size: f32) -> f32 {
let calc_ptr = calc_value as usize as *const CalcLengthPercentage;
let calc = unsafe { &*calc_ptr };
calc.resolve(CSSPixelLength::new(parent_size)).px()
}

impl BaseDocument {
fn node_from_id(&self, node_id: taffy::prelude::NodeId) -> &Node {
&self.nodes[node_id.into()]
Expand Down Expand Up @@ -79,6 +87,10 @@ impl LayoutPartialTree for BaseDocument {
self.node_from_id_mut(node_id).unrounded_layout = *layout;
}

fn resolve_calc_value(&self, calc_value: u64, parent_size: f32) -> f32 {
resolve_calc_value(calc_value, parent_size)
}

fn compute_child_layout(
&mut self,
node_id: NodeId,
Expand Down Expand Up @@ -152,6 +164,7 @@ impl LayoutPartialTree for BaseDocument {
return compute_leaf_layout(
inputs,
&node.style,
resolve_calc_value,
|_known_size, _available_space| taffy::Size {
width: cols
.map(|cols| cols * font_size.unwrap_or(16.0) * 0.6)
Expand All @@ -172,17 +185,16 @@ impl LayoutPartialTree for BaseDocument {
return compute_leaf_layout(
inputs,
&node.style,
resolve_calc_value,
|_known_size, _available_space| {
let width = node
.style
.size
.width
.resolve_or_zero(inputs.parent_size.width);
let height = node
.style
.size
.height
.resolve_or_zero(inputs.parent_size.height);
let width = node.style.size.width.resolve_or_zero(
inputs.parent_size.width,
resolve_calc_value,
);
let height = node.style.size.height.resolve_or_zero(
inputs.parent_size.height,
resolve_calc_value,
);
let min_size = width.min(height);
taffy::Size {
width: min_size,
Expand All @@ -195,6 +207,7 @@ impl LayoutPartialTree for BaseDocument {
return compute_leaf_layout(
inputs,
&node.style,
resolve_calc_value,
|_known_size, _available_space| taffy::Size {
width: 300.0,
height: resolved_line_height.unwrap_or(16.0),
Expand Down Expand Up @@ -250,6 +263,7 @@ impl LayoutPartialTree for BaseDocument {
let computed = compute_leaf_layout(
inputs,
&node.style,
resolve_calc_value,
|known_dimensions, _available_space| {
image_measure_function(
known_dimensions,
Expand Down
58 changes: 36 additions & 22 deletions packages/blitz-dom/src/layout/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ use std::{ops::Range, sync::Arc};
use markup5ever::local_name;
use style::computed_values::table_layout::T as TableLayout;
use style::values::specified::box_::DisplayInside;
use taffy::{compute_leaf_layout, style_helpers, Dimension, LayoutPartialTree as _, ResolveOrZero};
use taffy::{
compute_leaf_layout, style_helpers, Dimension, LayoutPartialTree as _,
NonRepeatedTrackSizingFunction, ResolveOrZero,
};

use crate::BaseDocument;

use super::resolve_calc_value;

pub struct TableTreeWrapper<'doc> {
pub(crate) doc: &'doc mut BaseDocument,
pub(crate) ctx: Arc<TableContext>,
Expand Down Expand Up @@ -74,11 +79,7 @@ pub(crate) fn build_table_context(

style.grid_template_columns = column_sizes
.into_iter()
.map(|size| match size {
taffy::Dimension::Length(len) => style_helpers::length(len),
taffy::Dimension::Percent(percent) => style_helpers::percent(percent),
taffy::Dimension::Auto => style_helpers::auto(),
})
.map(|dim| NonRepeatedTrackSizingFunction::from(dim).into())
.collect();
style.grid_template_rows = vec![style_helpers::auto(); row as usize];

Expand Down Expand Up @@ -162,24 +163,31 @@ pub(crate) fn collect_table_cells(

// TODO: account for padding/border/margin
if *row == 1 {
let column = match &style.size.width {
taffy::Dimension::Length(len) => {
let padding = style.padding.resolve_or_zero(None);
style_helpers::length(*len + padding.left + padding.right)
let column = match style.size.width.tag() {
taffy::CompactLength::LENGTH_TAG => {
let len = style.size.width.value();
let padding = style.padding.resolve_or_zero(None, resolve_calc_value);
style_helpers::length(len + padding.left + padding.right)
}
taffy::CompactLength::PERCENT_TAG => {
style_helpers::percent(style.size.width.value())
}
taffy::Dimension::Percent(percent) => style_helpers::percent(*percent),
taffy::Dimension::Auto => style_helpers::auto(),
taffy::CompactLength::AUTO_TAG => style_helpers::auto(),
_ => unreachable!(),
};
columns.push(column);
} else if !is_fixed && (*col as usize) < columns.len() {
if let taffy::Dimension::Length(new_len) = &style.size.width {
columns[*col as usize] = match columns[*col as usize] {
taffy::Dimension::Length(len) => {
taffy::Dimension::Length(len.max(*new_len))
}
taffy::Dimension::Auto => taffy::Dimension::Length(*new_len),
taffy::Dimension::Percent(percent) => taffy::Dimension::Percent(percent),
}
} else if !is_fixed
&& (*col as usize) < columns.len()
&& taffy::CompactLength::LENGTH_TAG == style.size.width.tag()
{
let new_len = style.size.width.value();
let tag = columns[*col as usize].tag();
let value = columns[*col as usize].value();
columns[*col as usize] = match tag {
taffy::CompactLength::LENGTH_TAG => style_helpers::length(value.max(new_len)),
taffy::CompactLength::AUTO_TAG => style_helpers::length(new_len),
taffy::CompactLength::PERCENT_TAG => style_helpers::percent(value),
_ => unreachable!(),
}
}

Expand Down Expand Up @@ -248,6 +256,10 @@ impl taffy::LayoutPartialTree for TableTreeWrapper<'_> {
&self.ctx.style
}

fn resolve_calc_value(&self, calc_value: u64, parent_size: f32) -> f32 {
resolve_calc_value(calc_value, parent_size)
}

fn set_unrounded_layout(&mut self, node_id: taffy::NodeId, layout: &taffy::Layout) {
let node_id = taffy::NodeId::from(self.ctx.items[usize::from(node_id)].node_id);
self.doc.set_unrounded_layout(node_id, layout)
Expand All @@ -261,7 +273,9 @@ impl taffy::LayoutPartialTree for TableTreeWrapper<'_> {
let cell = &self.ctx.items[usize::from(node_id)];
match cell.kind {
TableItemKind::Row => {
compute_leaf_layout(inputs, &cell.style, |_, _| taffy::Size::ZERO)
compute_leaf_layout(inputs, &cell.style, resolve_calc_value, |_, _| {
taffy::Size::ZERO
})
}
TableItemKind::Cell => {
let node_id = taffy::NodeId::from(cell.node_id);
Expand Down
Loading

0 comments on commit fc3bf13

Please sign in to comment.