Commit Graph
198 Commits
Author SHA1 Message Date
ldm0 54546adf32 fix(paint): align overflow clips with snapped box edges
Overflow clip geometry retained fractional layout offsets while its box
background used snapped paint geometry. Atomic flow grouping changed which
background and text commands shared a clip layer, exposing different edge
blending in three grid scrollbar reftests (240 pixels, max difference 17).

Snap owned overflow clips in the same pre-transform paint space as box
backgrounds. Preserve CSSOM geometry, property transforms and clip-chain
reuse. Cover block and grid containers with fractional offsets and sizes.
2026-11-13 03:28:46 +08:00
lanyue-llk 8c64bf14ab fix(layout): return border-box content quads 2026-11-13 01:25:08 +08:00
ldm0 0116a9864a test(layout): cover nested positioning and frozen projection contracts 2026-11-12 20:35:12 +08:00
ldm0 7142220841 fix(layout): resolve sticky scroll-space dependencies explicitly 2026-11-12 20:35:12 +08:00
ldm0 a571d4f05b refactor(layout): separate placement rules and space composition 2026-11-12 20:35:12 +08:00
ldm0 0c1b66e048 fix(layout): account for scroll offsets in sticky positioning 2026-11-12 20:35:12 +08:00
ldm0 0a0d0f0d11 refactor(paint): remove rendering work budgets 2026-11-12 20:24:33 +08:00
ldm0 69602b1c63 fix(layout): paint glyphless inline selection ranges 2026-11-12 16:02:40 +08:00
ldm0 cbf4d0149f fix(layout): paint mixed inline carets without glyph runs 2026-11-12 04:42:48 +08:00
ldm0 40ace558e3 fix(layout): retain atomic paint stages and inline interleaving 2026-11-12 04:42:48 +08:00
ldm0 077025be8b fix(layout): share atomic inline paint and hit-test ordering 2026-11-12 04:42:48 +08:00
Eren Küçüker d19796b5d7 fix(layout): paint atomic inlines above their wrapping inline boxes
An in-flow atomic inline painted its background in the block background
phase, before the backgrounds of the inline boxes that wrap it. A wrapping
span's background covered the box, and because hit testing shares the paint
order, points inside the box resolved to the span.

Paint the atomic background inside its formatting context, after the inline
box backgrounds and before the line's text. The owner's text becomes its own
paint event so it can follow them.

Fixes #385
2026-11-12 02:17:28 +08:00
ldm0 13a216cf25 refactor(layout): share table roles and display classification
Table construction and invariant validation maintain duplicate role enums, display mappings and diagnostic names. Use one internal role type and classification while keeping construction-only parent requirements, world validation and invalid-box errors at their existing sites.
2026-11-09 22:11:24 +08:00
ldm0 f54c3fabb9 refactor(layout): reuse rectangle outset calculation
Paint culling repeats the rectangle expansion already owned by overflow geometry. Reuse that existing helper, preserving f32 evaluation order, edge subtraction and zero-clamping of the resulting dimensions.
2026-11-09 18:48:51 +08:00
ldm0 2db52b45ba fix(svg): resolve inherited relative font weights correctly 2026-11-03 11:55:43 +08:00
wslee 46f7e37989 test(svg): cover inherited italic and condensed faces 2026-11-03 11:55:43 +08:00
ldm0 5a4588fbd0 fix(fonts): skip discarded anonymous flex and grid text 2026-10-29 03:49:54 +08:00
ldm0 f5ad0f909f test(layout): verify optical sizing with variable glyph advances 2026-10-28 17:04:36 +08:00
Maxim M 80c7b8e197 fix(layout): apply font-optical-sizing auto as opsz
Chromium sets the opsz axis to the font size in CSS pixels for variable fonts
when font-optical-sizing is auto. moli left opsz at the font default, so
system-ui on macOS (SFNS.ttf, default opsz 28) was shaped with the Display
design and measured 372.41 px instead of 420.95 px for a 16 px sentence.
The family choice and the trak tracking were already right.

An explicit opsz in font-variation-settings still wins. Fonts without an opsz
axis ignore the value.
2026-10-28 17:04:36 +08:00
ldm0 25654131ad refactor(layout): share child box retention with font discovery 2026-10-28 05:55:19 +08:00
ldm0 0874186dc9 refactor(fonts): share completion handling and remove unused state 2026-10-28 05:55:19 +08:00
ldm0 6fdc19ce13 fix(fonts): load used fonts during resource processing
Discover font demand from computed styles without triggering layout.
Honor the FONT policy, recheck fallback demand before readiness, and
invalidate child-document scans for ancestor style and viewport changes.

Share rendered control labels, marker counters and text normalization,
including generated items, inline boundaries, leaf boxes and suppressed
contents. Cover Unicode subsets, readiness and zero layout passes.
2026-10-28 05:55:19 +08:00
ldm0 4fea7994ad fix(paint): align text stroke joins with Chromium
Use explicit miter joins and a shared miter limit of 4 for CPU and PDF
text strokes. Use the same conservative expansion for layout outsets
and native PDF clipping, including synthetic bold stroke widening.

Add deterministic triangle glyphs to cover pointed joins, bevel fallback,
and miter-only ink entering a PDF clip.
2026-10-26 19:26:49 +08:00
ldm0 9b4e94338e fix(layout): include text stroke in paint culling bounds 2026-10-26 19:26:49 +08:00
ldm0 9205de4fe4 fix(layout): preserve text stroke in background clip masks 2026-10-26 19:26:49 +08:00
local-draft 0982ba20c1 feat(paint): support -webkit-text-stroke and paint-order for glyph runs 2026-10-26 19:26:49 +08:00
ldm0 4487138ce7 fix(layout): derive hanging overflow and clip inline boxes 2026-10-25 04:14:30 +08:00
sicko7947 055be4b08f fix(layout): exclude hanging trailing spaces from scrollable overflow
A wrapped line whose trailing spaces hang past the content box made
scrollWidth exceed clientWidth, unlike Chromium. Keep the full line rect
for CSSOM line geometry and use a scrollable rect without the hanging
advance when aggregating inline scrollable overflow.
2026-10-25 04:14:30 +08:00
ldm0 d0c307301d refactor(fonts): name font selection priorities
Font selection stored priority as `(bool, usize)`, so callers had to infer the CSS/manual group and repeat fallback and tie-breaking rules.

Replace the tuple with `WebFontPriority { group, position }` and explicit `Stylesheet`/`Manual` groups. Use a shared order type, centralize registration fallback priorities, and reuse one candidate comparison key. Manual faces still outrank CSS-connected faces, later positions still win, and equal priorities retain the same slot tie-breaker.

Validation: cargo fmt --all; strict all-feature workspace Clippy;
cargo nextest run --no-fail-fast (20683 tests run: 20683 passed (9 slow), 19 skipped).
2026-10-24 06:19:21 +08:00
ldm0 a9e54b4a0a perf(fonts): batch membership retirement and update priorities in place
Clear and CSS manifest replacement rebuilt the physical font collection once per removed face; changing matching order also re-registered every font. Retire each Document membership change in one batch, rebuild at most once for actual removals, and update candidate priorities/caches in place for order or membership-only changes. Byte/descriptor replacements still rebuild to preserve other sources with identical Fontique attributes.

Validation: cargo fmt --all; strict all-feature workspace Clippy;
cargo nextest run --no-fail-fast (20683 tests run: 20683 passed (9 slow), 19 skipped).
2026-10-24 05:03:25 +08:00
ldm0 2593e76394 refactor(fonts): reuse native descriptors for font queries
FontFaceSet.check/load reconstructed matching data from five JS string slots for every face on every query. Read the same immutable native descriptor that constructors and successful setters publish to layout, cache its Chromium-compatible family key, and share computed capability ranges and Unicode coverage.

Validation: cargo fmt --all; strict all-feature workspace Clippy;
cargo nextest run --no-fail-fast (20680 tests run: 20680 passed (9 slow), 19 skipped).
2026-10-24 05:03:25 +08:00
ldm0 bf3c9d1093 fix(fonts): separate declaration identity from shared sources
Independent CSS FontFace wrappers shared mutable descriptors and a registration slot, while a permanent stylesheet flag made detached faces disappear after manual re-addition. Give each native rule and JS face a distinct registration identity, share only source loading/validated data, and track native CSS and FontFaceSet membership in each Document. Native CSS cleanup revokes only its own relation; descriptor changes affect only their owning face. Explicit native layout can map a newly inserted declaration to cached source bytes without mutating the authoritative registrations or borrowing another declaration's descriptor.

Validation: cargo fmt --all; strict all-feature workspace Clippy;
cargo nextest run --no-fail-fast (20680 tests run: 20680 passed (9 slow), 19 skipped).
2026-10-24 05:03:25 +08:00
ldm0 a2cf5c816b perf(fonts): register validated font data without copying
FontFaceResource converted validated FontFaceData back to Vec bytes, then layout decoded and validated that payload again. Add a registration path that retains FontFaceData directly and shares its Blob through renderer registration and Fontique. Preserve descriptor validation and the existing raw-byte validation path.

Validation: cargo fmt --all; strict all-feature workspace Clippy;
cargo nextest run --no-fail-fast (20676 tests run: 20676 passed (9 slow), 19 skipped).
2026-10-24 05:03:25 +08:00
ldm0 5953bd1622 fix(fonts): share Chromium-compatible Unicode family matching
FontFaceSet queries compared family names with ASCII-only case folding, while native web-font layout used Unicode lowercasing. The same face could be missed by check/load or selected differently during layout. Share a CSS family matching key between both consumers using Unicode simple folding of UTF-16 code units, matching [Blink's font-family cache hash](https://chromium.googlesource.com/chromium/src/+/a03603fe9af6230a12f1b2fb2c18a7d003a0d937/third_party/blink/renderer/platform/wtf/text/case_folding_hash.h#50). Keep original descriptor spelling and platform/local full-name lookup intact. Register each web font only under its private source family, so Fontique cannot bypass CSS matching through a second public alias. Keep Blob identity and incremental-registration assertions by resolving the CSS alias through the document registry in those tests.

Validation: cargo fmt --all; strict all-feature workspace Clippy;
cargo nextest run --no-fail-fast (20633 tests run: 20633 passed (9 slow), 19 skipped).
2026-10-24 01:03:35 +08:00
ldm0 b5c2605ea9 perf(fonts): reuse payloads and incrementally register faces
Retain shared Blob payloads and register new fonts in the live collection,
invalidating selection caches while rebuilding for replacements and removals.
Preserve owner-specific order across complete descriptor capability ranges,
including priority-index shifts after unloaded members are removed.

Compare incremental and fresh registrations for scalar and ranged arrivals;
retain the opt-in release microbenchmark.
2026-10-24 01:03:34 +08:00
ldm0 e24bd4a690 fix(fonts): share full descriptor capabilities with layout selection
Move computed capability parsing and matching into moli-css-parse and
retain complete ranges in native font registrations. Select all equally
matched ranges in document order before applying unicode ranges.

Use the shared representation for CSS and JS registrations and query
matching. Add real DOM geometry regressions for numeric, reversed and
calc descriptors, mutations and overlapping range priority.

Validation: cargo fmt --all; strict workspace Clippy;
cargo nextest run --no-fail-fast (20592 tests run: 20592 passed (9 slow), 18 skipped).
2026-10-24 01:03:34 +08:00
ldm0 4ae2dabfc6 fix(fonts): publish CSS declaration order without JS projection 2026-10-23 04:07:15 +08:00
ldm0 3a0f6ca178 fix(fonts): match queries and honor owner selection order
Select width, style and weight capabilities before filtering FontFaceSet
queries by text and unicodeRange. Share the matching path for check/load,
including CSS calculations and descriptor ranges, so unrelated unloaded
or broken sources do not affect a query.

Publish each Document's CSS/manual FontFaceSet order independently from
stable resource slots. Preserve manual overrides, re-addition priority
and different orders for shared faces across Documents.

Cover the matching and actual DOM geometry regressions with generated
narrow/wide fonts and a shared Chromium/Moli CDP oracle.
2026-10-23 04:07:15 +08:00
ldm0 c7130a3059 fix(fonts): share native FontFace loading across CSS and JS 2026-10-23 04:07:15 +08:00
ldm0 14d3c08cc8 fix(fonts): reject malformed FontFace payloads 2026-10-22 16:43:49 +08:00
ldm0 5a1c1cd7ab fix(layout): project scroll overflow in physical coordinates
Aggregate physical descendants once instead of treating Taffy's logical
scroll origin as a physical top-left corner. Share reachable scroll bounds
between scrollbar admission and final projection, including vertical writing
modes and reversed flex flows.

Preserve grid track areas, per-axis clipping, transformed borders, normal-flow
margins and end padding. Anchor vertical RTL block flow at the physical bottom
while keeping relative insets physical.

Add five native browser guards and a live Chromium differential covering
140 fixtures, two scrollbar modes and three fresh-document rounds.

Validation: root fmt, strict workspace/all-target/all-feature Clippy, and
Nextest (20380 passed, 18 skipped); Release; 840 Chromium comparisons;
960 flex geometry controls; MOL-463-468 probes; full 13631-case WPT Cross.
Three old/new control rounds found no new stable case, assertion or harness
regression. Cases are refreshed in the following commit.

Original-commit: d433653f0d
2026-10-21 17:55:02 +08:00
ldm0 87e044db18 fix(layout): preserve intrinsic width keywords across inline formatting roles
Subtract horizontal margins for explicit inline-block fit-content widths and carry float min/max-content constraints across the IFC boundary. Cover six font-backed role/keyword combinations, including an inline break that exercises the float path.

Validation: cargo fmt --all; cargo clippy --workspace --all-targets --all-features -- -D warnings; cargo nextest run --no-fail-fast (20284 passed, 18 skipped). The combined working tree passed these checks before this logical split. Frozen Release and focused browser/WPT validation also passed; final full WPT is running.

Original-commit: 00cfb54b45
2026-10-21 17:55:02 +08:00
ldm0 a1965aa9ae fix(layout): adopt fork constraint fixes and isolated content probes
Pin published Taffy and Stylo fixes for baseline provenance, intrinsic child bounds, grid/OOF ratio constraints, writing modes, selector matching, stylesheet nesting and calc type dependencies. Treat IFC ContentProbe inputs as intrinsic contribution measurements.

Validation: cargo fmt --all; cargo clippy --workspace --all-targets --all-features -- -D warnings; cargo nextest run --no-fail-fast (20283 passed, 18 skipped). Release v3 and five browser regression rounds. Full WPT recorded separately.

Original-commit: b002c0e823
2026-10-21 17:55:02 +08:00
ldm0 97b297830e fix(layout): retain normal grid stretching for native form controls
Map native controls to compressible replaced leaves without the image-only replaced flag. Cover checkbox, radio and range normal alignment at 50 by 50 pixels.

Validation: cargo fmt --all; cargo clippy --workspace --all-targets --all-features -- -D warnings; cargo nextest run --no-fail-fast (20283 passed, 18 skipped). Release v3 and five browser regression rounds. Full WPT recorded separately.

Original-commit: 143e72ec4d
2026-10-21 17:55:02 +08:00
ldm0 6424f9e555 fix(layout): integrate ratio and orthogonal grid regression fixes
Original-commit: 81c9bd1abd
2026-10-21 17:55:02 +08:00
ldm0 a551aba5d7 fix(layout): retain grid track areas for positioned descendants
Original-commit: 5976146db3
2026-10-21 17:55:02 +08:00
ldm0 e78f5a33b2 feat(layout): update Taffy and Stylo forks with current Blitz adapters
Move Taffy to 0.15 and Stylo to 0.22 using fixed fork revisions, with the
matching stylo_taffy adapter. Upgrade cssparser and the production HTML/XML
parsers while preserving the vendored XML behavior.

Adapt sizing inputs, baselines, grid positions, overflow and out-of-flow
ownership. Preserve font-stretch CSSOM compatibility and intrinsic sizing
through nested atomic inline probes.

Validation: root cargo fmt --all; strict workspace/all-target/all-feature
Clippy; Nextest 20280 passed, 18 skipped; Release build; five browser
regression rounds; RTL and nested intrinsic Chromium geometry controls.
Full WPT Cross is recorded separately with its Cases refresh.

Original-commit: 281a920d89
2026-10-21 17:55:02 +08:00
ldm0 a46e654706 perf(layout): bound initial numeric cache reservation
Reserve at most four existing boxes on the first store and grow with actual cache demand. Avoid the full-tree candidate scan and cover sparse stores in both flattened and ordinary block trees.
2026-10-18 20:01:57 +08:00
ldm0 515fe0c484 perf(layout): embed numeric cache slots in layout boxes
Replace the dense box-to-cache index vector with a one-based Option<NonZeroU32> slot in existing LayoutBox padding. Keep compact cache storage and preserve cache ownership through box compaction, growth, and invalidation.
2026-10-18 20:01:57 +08:00
ldm0 de08ab789b fix(layout): select CSS fonts from current pass styles 2026-10-18 03:28:37 +08:00