Skip to content

P6a-dash: dashed and dotted borders as Blink 145 paints them (device-pixels iOS 135→61, Android 182→90) - #63

Merged
thejackshelton merged 11 commits into
masterfrom
p6a-dash-v2
Oct 1, 2026
Merged

thejackshelton merged 11 commits into
masterfrom
p6a-dash-v2

Conversation

@thejackshelton

@thejackshelton thejackshelton commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

P6a-dash (T075; notes/T008-p5-review.md; the T046 Amendment T075J split): dashed and dotted borders painted the way Blink 145 paints them, in device px.

Device-pixels delta (pnpm run parity:devices on this tree, against master 0ee050a)

Case iOS Android
color-border-sides 30 → 0 34 → 0
css-wide-keywords 6 → 0 10 → 0
logical-border 19 → 0 24 → 0
logical-border-rtl 19 → 0 24 → 0
Total device-pixels failures 135 → 61 182 → 90
  • The new border-dash-fit and border-dot-fit cases pass on both targets.
  • The remaining failures are master's position-* and selectors-universal-root cases, unchanged.
  • Every other lane is in master's state, and lane parity passes.

What changed

  • The dash geometry. packages/layout/src/paint-dash.ts ports:

    • BoxBorderPainter's complex side path, for boxes without radii;
    • StyledStrokeData's dash selection;
    • BorderEdge;
    • Skia's dashed-line geometry.

    It is translated to Swift and Kotlin. The border module draws a box with a visible dashed or dotted side from these operations; every other box keeps the band painter.

  • Plants. dash-phase-1 and dash-gap-unfitted, each judged on its own cases and the border/edge sample rules (plantVerdict).

  • The software-raster precondition. parity:pixel-capture refuses any raster path other than disabled_software, and records the path in the pixel manifest. Lane parity refuses a manifest set without it.

  • Fixtures. border-dash-fit and border-dot-fit, plus dash paint vectors.

  • docs/ports.json.

    • It registers box_border_painter.cc, styled_stroke_data.cc and border_edge.cc (145.0.7632.6), and SkDashPath.cpp (Skia 2ab8add5). Each entry has its sha256s, licence and cited ranges.
    • It adds computed_style_constants.h as a reference. That file is LGPL class A, and only the EBorderStyle order is used.
    • THIRD_PARTY_NOTICES.md is regenerated.
  • regen.ts MANUAL. It names the producer of paint-vectors/*/inputs.jsonl: paint-dash.test.ts with DRAGON_WRITE_DASH_INPUTS=1. A regen step would never rerun, because regen ignores test-file changes. The test fails if the committed file is stale.

  • Profiles. No profile row is added or removed, and no status changes.

What passed

  • pnpm typecheck.
  • pnpm test: 156 files; 3180 tests pass and 1 is skipped. The skipped test is the full pnpm regen --check, which runs only when asked.
  • pnpm regen is at a fixed point.
  • The device run above.

Changed tests

  • chrome-ports.test.ts: .jsonl is added to its DATA list, so the dash vector inputs count as data. That file was the only unclassified one, and no check is relaxed.
  • dragon paint-seams.test: it pins the two dash plants after the glyph plants.

No tolerance, check or test is loosened or removed. The reviewed diff is 116 KB in 25 files.

🤖 Generated with Claude Code

Note

Implement Blink 145 device-pixel dash and dot border painting for iOS and Android

  • Adds paint-dash.ts, a shared device-pixel border painter ported from Blink 145, Skia, and StyledStrokeData. It produces structured border operations (layers, save/restore, clipping, polygon fills, dots) with dash lengths, fitted gaps, corner miters, and square-vs-round dots by thickness. New public exports: borderPaintOps, borderNeedsSidePainter, selectBestDashGap, BorderOp, NO_DASH_FAULTS
  • Rewrites the UIKit and Android border emitters in border.ts to route dashed/dotted sides through the new side painter instead of the band painter, and removes the old Core Graphics DashPathEffect stroke paths. Double borders narrower than 3 device pixels paint as solid
  • Adds two intentional dash-fault raster plants (dash-phase-1, dash-gap-unfitted) used as negative cases by the new pixel-oracle test in p6a-dash-oracle.test.ts
  • Adds border-dash-fit and border-dot-fit parity fixtures, snapshots, and expected pixels at DPR 1, 2, 2.625, and 3 for darwin-arm64; recorded device-pixel failures drop from 135 to 61 on iOS and 182 to 90 on Android
  • Risk: dashed or dotted sides that reach the fallback band painter now raise an identifier-bearing error instead of drawing a stroke; groove, ridge, inset, outset beside a dashed border are rejected from native programs

Macroscope summarized c4274db.

…§5.5 B1, notes/T008-p5-review.md), on EMS

Rebuilt on EMS-b from p6a-promote cf1cdb46's dash and pixel slice (the PM-approved split, Amendment T075J); no profile, project or native-lanes change.
- packages/layout/src/paint-dash.ts: Blink's dash and dot geometry (styled_stroke_data.cc, box_border_painter.cc) as border operations in absolute device px; paint-vectors/dash inputs.
- The border module draws a box with a visible dashed or dotted side from the translated operations (emit/paint/border.ts) and declares the dash-phase-1 and dash-gap-unfitted plants; the harness gains the paint:dash suite.
- Raster plants: glyph plants judged against the clean run (judgeGlyphPlant), dash plants on their own cases and sample rules (plantVerdict).
- The SystemInfo software-raster precondition: parity:pixel-capture records each set's raster path in the pixel manifest, and lane parity refuses a set without it.
- Fixtures border-dash-fit and border-dot-fit (border-paint group, before values); tests paint-dash, p6a-dash-oracle, p6a-raster, the seam and plant pins.
…itest run packages/layout/test/paint-dash.test.ts; grammar:gen, ua:capture, parity:capture, profile:rows, parity:capture, profile:rows, layout:vectors, parity:dpr-capture, layout:dpr-vectors, layout:break-vectors, parity:break-capture, parity:pixel-capture, layout:paint-vectors, native:gen, node --conditions=dragon-internal examples/music-player/tools/check.ts, wpt:run --target web, wpt:update-expectations --target web, tw:sweep, parity:glyph-b3 --write-bottom-pins, media-sweep.ts and --check, parity:lanes --run-host): the border-dash-fit and border-dot-fit captures, DPR captures, vectors, break vectors and Chrome PNGs; the pixel manifest gains each set's raster record; the dash paint vectors; the border-paint cases join the proofs of the rows they use (no row added or removed and no status changed on ios, android or web), so the emitted CSS digests move; the translated PaintDash and harness; corpus-dpr.json; host-only lanes.json
…into p6a-dash-v2: harness.ts keeps master's paintResult with the dash cases added; paint-seams.test keeps the P6a plant pins; generated files kept from this side for pnpm regen to rebuild
 (/tmp/heavy-lease.sh pnpm regen: fixed point after 2 passes, every step run): the translated engine and harness (PaintDash with master's rt roots and EMS-b's paint routing); every capture, vector, profile and emitted file was already current; lanes.json follows from the device run
… from the device run on the merge of origin/master 0ee050a (/tmp/device-lease.sh pnpm run parity:devices): device-pixels ios 135 -> 61, android 182 -> 90; every dashed and dotted border failure is gone (color-border-sides 30/34, css-wide-keywords 6/10, logical-border 19/24, logical-border-rtl 19/24 -> 0) and the new border-dash-fit and border-dot-fit cases pass; the remaining failures are master's position-* and selectors-universal-root (B2 paint order) unchanged; lane states equal master's (device-pixels still fail on B2), lane parity passes
…docs/ports.json registers what paint-dash.ts ports (box_border_painter.cc, styled_stroke_data.cc and border_edge.cc at 145.0.7632.6, SkDashPath.cpp at Skia 2ab8add5, each fetched per docs/ports.md with its sha256, header sha256, licence, notice and cited ranges) and its reference to computed_style_constants.h (LGPL class A: styleRank uses only the EBorderStyle order); chrome-ports.test classes .jsonl as data (the dash vector inputs); regen.ts MANUAL names the producer of paint-vectors/*/inputs.jsonl (paint-dash.test.ts with DRAGON_WRITE_DASH_INPUTS=1; a test file is outside every regen step's inputs, so it is not a step)
Comment thread packages/layout/src/paint-dash.ts Outdated
Comment thread packages/layout/src/paint-dash.ts
Comment thread packages/parity/test/p6a-dash-oracle.test.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a substantial Blink/Skia-derived border renderer and changes existing dashed/dotted rendering across both iOS and Android, creating a broad customer-visible runtime impact. An unresolved medium-severity oracle finding also concerns overlap coverage, so the production behavior and validation warrant human review.

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

- paint-dash.ts: the inner border rect is Blink's PixelSnappedContouredInnerBorder (contoured_border_geometry.cc:207-231, now in docs/ports.json): the box less the unclamped widths with its size clamped at zero (ClampNegativeToZero), taken before ClampWidth as Blink does; a border wider than the box no longer inverts the inner corners of the clip polygons. innerBorderRect is pinned in paint-dash.test (both tests fail without the clamp), and the dash vector inputs gain a mixed-style box whose widths exceed it.
- paint-seams.test: a dashed side beside groove, ridge, inset or outset never reaches a native program (lowering blocks the case: border-right-style <k> has no native paint technique), so the side painter's refusal of those styles cannot fire on a device.
- p6a-dash-oracle.test: only the element boxes after a box in paint order (its descendants and later boxes) occlude its border; an earlier sibling's overlap is compared now.
…out/paint-vectors/dash/vectors.json (pnpm run layout:paint-vectors) for round 1: the contoured_border_geometry.cc entry and the added dash vector case
…m regen: fixed point after 2 passes): PaintDash innerBorderRect; lanes.json follows from the device run
…evice-lease.sh pnpm run parity:devices): device-failures-{ios,android}.json unchanged (ios 61, android 90; master 135, 182); lane states equal master's, lane parity passes
@thejackshelton
thejackshelton merged commit 5d3433c into master Oct 1, 2026
4 checks passed
thejackshelton added a commit that referenced this pull request Oct 1, 2026
thejackshelton added a commit that referenced this pull request Oct 2, 2026
…-round: no source conflicts; generated outputs keep this side (merge=dragon-generated) and pnpm regen rebuilds them next
thejackshelton added a commit that referenced this pull request Oct 2, 2026
… runs master's border-paint group, then sizing-ratio, then values (last, as values.test.ts requires); device-failures-*.json take master's, rewritten by the device run
thejackshelton added a commit that referenced this pull request Oct 2, 2026
…: /tmp/heavy-lease.sh pnpm regen (fixed point after 3 passes). node scripts/check-aspect-ratio-migration.ts origin/master exits 0: vectors and captures of master's new border-paint cases gain only the neutral aspect-ratio keys, emitted CSS only the declaration and its digest header; profiles, native engine (P6a-dash's paint code beside SIZE-ar's ratio code), notices and host lanes rebuilt
thejackshelton added a commit that referenced this pull request Oct 2, 2026
…argin: no source conflicts; generated outputs keep this side (merge=dragon-generated) and pnpm regen rebuilds them next
thejackshelton added a commit that referenced this pull request Oct 2, 2026
…ocs/ports.json takes master's registry (p6a-dash's new entries, among them contoured_border_geometry.cc) and re-adds SELD-R1b's entries on top (rt-hit.ts joins the contoured_border_geometry.cc entry as a reference; header-bsd-9 and adobe-bsd-2 licence texts); generated outputs keep this side and pnpm regen rebuilds them next
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant