Repository navigation
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This was referenced Sep 2, 2026
staging-devin-ai-integration
Bot
force-pushed
the
devin/1788383056-vertical-align
branch
13 times, most recently
from
September 9, 2026 13:56
32c3b48 to
79a458e
Compare
staging-devin-ai-integration
Bot
force-pushed
the
devin/1788383056-vertical-align
branch
3 times, most recently
from
September 16, 2026 10:43
db2513b to
db0bc66
Compare
nicoburns
force-pushed
the
devin/1788383056-vertical-align
branch
2 times, most recently
from
September 16, 2026 12:00
0f017fb to
4b86547
Compare
staging-devin-ai-integration
Bot
force-pushed
the
devin/1788383056-vertical-align
branch
5 times, most recently
from
September 23, 2026 11:56
346f8c5 to
8d193db
Compare
…box" Parley already uses "inline box" for `InlineBox`, an atomic box embedded in the text, so use "span" / "span box" for what CSS calls an inline box (the box generated by a style table entry on a line). Documents the term in the `style_metrics` module docs.
BreakerState::default() is public and can be passed to BreakLines::revert_to, but its LineBoxMetrics had no root aligned subtree, so the next line would index out of bounds. Default now contains the root subtree (without a strut) and reset builds on it, so the breaker is valid from any BreakerState.
Split the font-derived part into BoxMetrics, whose from_font returns a complete value and is what run_box_metrics needs; StyleMetrics::from_font is only meaningful inside resolve_style_metrics, which fills in the remaining tree-position fields.
Each style now resolves its first available font and metrics directly; cross-layout caching of both is left to the FontContext font cache.
Every non-root span's parent must precede it in the style table (debug-asserted); a malformed parent index falls back to the root rather than producing a self-parented orphan, so ancestor walks always end at 0.
Replaces the parallel inline_boxes / inline_box_styles vectors with a single
Vec<LayoutInlineBox { inline_box, style_index }>, so sorting is a plain
stable sort_by_key and the two can no longer get out of step.
Layout::inline_boxes() / inline_boxes_mut() now return ExactSizeIterators
over &InlineBox / &mut InlineBox instead of slices.
…n LayoutInlineBox
Signed-off-by: Nico Burns <nico@nicoburns.com>
Fonts without OS/2 sxHeight previously fell back to half the ascent. Gecko (DEFAULT_XHEIGHT_FACTOR) and Blink both estimate 0.56 * ascent in that case; css-inline-3 Appendix A.2 only suggests 0.5em as a last resort after glyph measurement.
`LineBoxMetrics::contributed` (style indices already counted on the current line) was a `SmallVec<[u16; 8]>` cloned with `LineState` at every break opportunity and re-extended on every `reset`. It is append-only, so it can live once on `BreakerState` with a saved length in `PrevBoundaryState` and a truncate on revert. `subtrees` stays inline: its entries are mutated in place, so a length is not enough to roll them back (see `lines_revert_restores_line_height`). Also reuse the `prev_state` allocation in `break_next` via `clone_from`. Benchmarked on ~250KB of prose: break+align -7.6% (plain) / -6.1% (styled) / -8.2% (styled + vertical-align) vs before; layouts identical.
…ghts With quantization enabled, `LineHeight::MetricsRelative` now sums the rounded ascent, descent and leading (as Blink and Gecko do for `line-height: normal`) so that such lines are a whole number of pixels tall. Previously the span box ascent/descent were rounded but the line height was not, leaving fractional line heights (e.g. 18.625px for a 16px Roboto line) that accumulated across lines. Both the run and the style span box line heights go through the shared `LineHeight::resolve`.
staging-devin-ai-integration
Bot
force-pushed
the
devin/1788383056-vertical-align
branch
from
September 26, 2026 02:44
9c10024 to
c6abe77
Compare
Signed-off-by: Nico Burns <nico@nicoburns.com>
nicoburns
force-pushed
the
devin/1788383056-vertical-align
branch
from
September 28, 2026 13:08
12189ce to
888cdcc
Compare
Signed-off-by: Nico Burns <nico@nicoburns.com>
Signed-off-by: Nico Burns <nico@nicoburns.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LLM Contributions: Written with Devin (Cognition AI); design and review by the author.
Implements the CSS 2.2 §10.8 inline alignment model. Commit-by-commit:
TreeStyleBuildernow materialises ancestor styles (even ones with no direct text) into the style table, parent-first, and eachStylecarriesparent: u16. Root style is index0and is the strut.RangedBuilderstyles all parent0.VerticalAlign— newStyleProperty::VerticalAlign(VerticalAlign)andInlineBox::vertical_align. Following css-inline-3,VerticalAlign { alignment: AlignmentBaseline, shift: BaselineShift }is a compound of the two longhands (AlignmentBaseline::{Baseline, TextTop, TextBottom, Middle},BaselineShift::{Length(f32), Sub, Super, Top, Bottom}), sovertical-align: text-top 2pxis representable and callers with the longhands (Blitz/Stylo) pass them through losslessly. The CSS 2 keywords are associated constants (VerticalAlign::SUPER,::TEXT_TOP, …) plusVerticalAlign::length(px). Percentages must be resolved by the caller.StyleMetricspass (layout/style_metrics.rs) — once per layout, per style: primary-font ascent/descent/x-height (FontMetrics::from_variations), line-height as half-leading →over/under, thenbaseline_offsetrelative to the parent = alignment offset (middleuses the parent x-height and the child's expanded box;text-top/bottomthe parent content box) + shift (sub/superuse WebKit'sfontSize/5,fontSize/3), andaligned_subtree(nearesttop/bottomancestor, else0).LineBoxMetricsbecomesSmallVec<SubtreeExtents>+ a per-line "contributed styles" set. Each line is seeded with the strut; each run/inline box adds its own style box at its baseline offset plus any not-yet-contributed ancestors.top/bottomsubtrees are sized separately and, infinish_line, grow the line below/above when taller than the root subtree; their offsets are stored onLineData::aligned_subtree_offsets. Lines containing only empty inline boxes stay zero-height.GlyphRun::baselineandPositionedInlineBox::yuse the style's shifted baseline viaLine::style_baseline/Line::inline_box_top.LineMetrics::baselinestays the root baseline; cursor/selection use whole-line block extents and are unaffected.Behaviour changes for existing users: lines containing only inline boxes (or none of the text's styles) now get strut height, and a span's inline box uses the primary-font metrics of that style (six snapshots updated). New
styles/vertical_alignsnapshot tests cover every keyword, nestedsuper, ancestor-only spans, inline boxes and talltop/bottomsubtrees; unit tests cover the metrics pass including composition of alignment + shift.Blitz follow-up: DioxusLabs/blitz#832.
Changelog
Link to Devin session: https://dioxus.staging.devinenterprise.com/sessions/da7669e341814cc7976e4ebf32b7eacb
Open in Devin Desktop: https://dioxus.staging.devinenterprise.com/desktop/session/da7669e341814cc7976e4ebf32b7eacb?variant=devin-insiders
Requested by: @nicoburns