Skip to content

Commit df30c06

Browse files
committed
Use first baseline for inline flex/grid, bump parley for strut + negative-leading fixes
- Inline-block uses its last in-flow line box baseline, but inline flex/grid containers use their first baseline per css-align. - Bump parley to DioxusLabs/parley#10 which fixes clamping of negative half-leading in line extents and adds opt-in CSS2 \u00a7 10.8 line-box strut support; enable the strut in Blitz's inline layout. - With an explicit baseline, an inline box's line-height contribution may legitimately be negative, so only clamp reserved space for bottom-aligned boxes, and position baseline-aligned boxes from the top of their margin box.
1 parent f388f09 commit df30c06

4 files changed

Lines changed: 42 additions & 25 deletions

File tree

‎Cargo.lock‎

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ taffy = { git = "https://github.com/DioxusLabs/taffy", rev = "f8a606e69ddf6a9f76
105105
"calc",
106106
"detailed_layout_info",
107107
] }
108-
parley = { git = "https://github.com/DioxusLabs/parley", rev = "a0752c7bdc3ad88dac19fc194d2b8e57e59bea2e", default-features = false, features = ["std"] }
108+
parley = { git = "https://github.com/DioxusLabs/parley", rev = "98db0dd04dd380b16a86afa7f000982da2892985", default-features = false, features = ["std"] }
109109
skrifa = { version = "0.44", default-features = false, features = [
110110
"std",
111111
] } # Should match parley and vello versions

‎packages/blitz-dom/src/layout/construct.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,7 @@ pub(crate) fn build_inline_layout_into(
10311031

10321032
// Create a parley tree builder
10331033
let mut builder = layout_ctx.tree_builder(font_ctx, scale, true, &parley_style);
1034+
builder.set_compute_strut(true);
10341035

10351036
// Set whitespace collapsing mode
10361037
let collapse_mode = root_node_style

‎packages/blitz-dom/src/layout/inline.rs‎

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use style::values::specified::box_::DisplayOutside;
44
use style::values::{computed::CSSPixelLength, generics::text::GenericTextIndent};
55
use taffy::{
66
AvailableSpace, BlockContext, BlockFormattingContext, BoxSizing, CollapsibleMarginSet,
7-
CoreStyle as _, Direction, LayoutInput, LayoutOutput, LayoutPartialTree as _, MaybeMath as _,
8-
MaybeResolve as _, Overflow, Point, Position, RequestedAxis, ResolveOrZero as _, RunMode, Size,
9-
SizingMode,
7+
CoreStyle as _, Direction, Display, LayoutInput, LayoutOutput, LayoutPartialTree as _,
8+
MaybeMath as _, MaybeResolve as _, Overflow, Point, Position, RequestedAxis,
9+
ResolveOrZero as _, RunMode, Size, SizingMode,
1010
};
1111

1212
#[cfg(feature = "floats")]
@@ -306,24 +306,33 @@ impl BaseDocument {
306306
} else {
307307
let is_scroll_container = style.overflow.x.is_scroll_container()
308308
|| style.overflow.y.is_scroll_container();
309+
let display = style.display;
309310
let output = self.compute_child_layout(taffy::NodeId::from(ibox.id), child_inputs);
310311
// Per CSS, an in-flow inline-block is baseline-aligned to the baseline of its
311-
// last in-flow line box, unless it is a scroll container or has no in-flow line
312-
// boxes, in which case its baseline is its bottom margin edge (Parley's fallback
313-
// when `baseline` is `None`, since `ibox.height` includes margins).
312+
// last in-flow line box, while inline flex/grid containers use their first
313+
// baseline. A scroll container or a box with no natural baseline uses its
314+
// bottom margin edge (Parley's fallback when `baseline` is `None`, since
315+
// `ibox.height` includes margins).
316+
let baseline = match display {
317+
Display::Flex | Display::Grid => output.baselines.first,
318+
_ => output.baselines.last,
319+
};
314320
ibox.baseline = if is_scroll_container {
315321
None
316322
} else {
317-
output
318-
.baselines
319-
.last
320-
.or(output.baselines.first)
321-
.map(|baseline| (margin.top + baseline) * scale)
323+
baseline.map(|baseline| (margin.top + baseline) * scale)
322324
};
323325
ibox.width = (margin.left + margin.right + output.size.width) * scale;
324-
// Vertical margins adjust the space the box reserves in the line, but the
325-
// reserved space cannot be negative.
326-
ibox.height = (margin.top + margin.bottom + output.size.height).max(0.0) * scale;
326+
// Vertical margins adjust the space the box reserves in the line. With an
327+
// explicit baseline the ascent/descent contributions may legitimately be
328+
// negative, but a bottom-aligned box (no baseline) contributes its height
329+
// as ascent, and the space it reserves cannot be negative.
330+
let height = margin.top + margin.bottom + output.size.height;
331+
ibox.height = if ibox.baseline.is_some() {
332+
height * scale
333+
} else {
334+
height.max(0.0) * scale
335+
};
327336
}
328337
}
329338

@@ -598,7 +607,7 @@ impl BaseDocument {
598607
// dbg!(&layout.size);
599608
// dbg!(&layout.location);
600609

601-
state.append_inline_box_to_line(box_break_data.advance, 0.0, 0.0, false);
610+
state.append_inline_box_to_line(box_break_data.advance, None, false);
602611

603612
// if float.is_floated() {
604613
// println!("INLINE FLOATED BOX ({}) {:?}", ibox.id, float);
@@ -807,11 +816,18 @@ impl BaseDocument {
807816
layout.size = size;
808817
layout.location.x =
809818
(ibox.x / scale) + margin.left + container_pb.left + inset_offset.x;
810-
// A negative `margin-top` shrinks the space the box reserves in the
811-
// line but does not move the box itself, which stays anchored to the
812-
// bottom of the reserved space.
819+
// For a baseline-aligned box, `ibox.y` is the top of the margin box,
820+
// so the border box sits `margin.top` below it. For a bottom-aligned
821+
// box (no baseline), a negative `margin-top` shrinks the space the box
822+
// reserves in the line but does not move the box itself, which stays
823+
// anchored to the bottom of the reserved space.
824+
let margin_top_offset = if ibox.baseline.is_some() {
825+
margin.top
826+
} else {
827+
margin.top.max(0.0)
828+
};
813829
layout.location.y = (ibox.y / scale)
814-
+ margin.top.max(0.0)
830+
+ margin_top_offset
815831
+ container_pb.top
816832
+ inset_offset.y;
817833
layout.padding = padding; //.map(|p| p / scale);

0 commit comments

Comments
 (0)