Repository navigation
feat: ctxRoundRectXY and op 9, a rounded rect whose corners are elliptical - #10
Merged
Merged
Conversation
…tical appkit's verb: each corner its own pair of radii, drawn with Direct2D's own elliptical arc segments, square where a corner has no extent on one axis. ctxPath reads it as op 9, which is how react-x11 knows it may send one; an older bridge is sent the corners as curves. Four corners alike are one Direct2D rounded rect, which has an x and a y radius of its own.
sidorares
added a commit
to sidorares/react-x11
that referenced
this pull request
Sep 29, 2026
…aw an elliptical corner whole ntk 8.16.1 is sidorares/ntk#471: the tile plan and pixels this context draws shadows from. @windowkit/appkit 0.17.0 and @windowkit/win32 0.0.6 answer ctxRoundRectXY, windowkit/appkit#90 and windowkit/win32#10; the context feature-detects it, so an older bridge still draws the corners as curves.
sidorares
added a commit
to sidorares/react-x11
that referenced
this pull request
Sep 30, 2026
…le made once (#794) * perf(backend): a rect's or a rounded rect's shadow is drawn from a tile made once CoreGraphics blurs a shadow on every fill that has one set, at the cost of the shape's area times the blur's width. On a 2x display a page header's box-shadow: inset 0 0 100px, repainted by every strip a scroll exposed, was 130 to 380 ms, and a card's 200px hover shadow 110 ms: Zen Garden's home page scrolled at 11 to 14 frames a second wherever the header or the footer was in view, and its all-designs page at 18 with the pointer over a card. Direct2D draws no live shadow at all. The context Cocoa and Windows share now recognises the shapes a box shadow is made of: a fill of a path that is one rect or one roundRect, or two of them one inside the other filled evenodd, the frame an inset shadow is cast around, and a fillRect. Their shadow comes from a tile. A rounded rect's shadow is the same all along its straight edges, so it is made once for a copy of the shape shortened to three pixels of straight edge and drawn in up to nine pieces, the straight pixel stretched between the corners. The tile is named by the corners, the blur, the hole and the colour, not by where the shape is or what part a paint reaches: every card with one shadow shares it, and a scroll strip draws a strip of it. ntk plans it and makes its pixels, ntk/shadow-tiles, the code X11's shadows come from too. The header's inset shadow is 4 ms, and with the document drawing through it the same pages scroll at 50 to 60. A tiled shadow is the canvas spec's gaussian, sigma half the blur, within six levels of the exact one. REACT_X11_NO_SHADOW_TILES=1 puts every shadow back on the bridge. A blurred box shadow draws on macOS and Windows. It was baked on an X server, and without one it drew nothing; now it is the context's own shadow, which is a tile. roundRect takes its radii as canvas has them: a number, an { x, y } point for an elliptical corner, or a list of one to four of either, scaled down together where two corners on a side would meet. It took numbers alone and drew an { x, y } corner square. Elliptical corners go to the bridge as ctxRoundRectXY where it has one, and as op 9 in the ctxPath stream, and as curves where it does not. Needs ntk with ntk/shadow-tiles. * chore(deps): ntk 8.16.1 for ntk/shadow-tiles, and the bridges that draw an elliptical corner whole ntk 8.16.1 is sidorares/ntk#471: the tile plan and pixels this context draws shadows from. @windowkit/appkit 0.17.0 and @windowkit/win32 0.0.6 answer ctxRoundRectXY, windowkit/appkit#90 and windowkit/win32#10; the context feature-detects it, so an older bridge still draws the corners as curves.
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.
appkit's new verb, for the Windows bridge:
ctxRoundRectXY(surface, x, y, w, h, tlx, tly, trx, try, brx, bry, blx, bly), a rounded rect whose corners are elliptical, each its own pair of radii. Canvas'sroundRecttakes an{ x, y }point for a corner and CSS aborder-radius: 40px / 20px, and react-x11 had been drawing those square. Each corner is one of Direct2D's own elliptical arc segments, and a corner with no extent on one axis is square rather than cut off diagonally.ctxPathreads it as op 9, twelve numbers after the op. A bridge that answersctxRoundRectXYreads op 9 too, which is how react-x11 knows it may send one; an older bridge, which stops reading at an op it does not know, is sent the corners as curves. Four corners alike are one Direct2D rounded rect, which has an x and a y radius of its own, so they take the primitive route as circular ones do.test/path-stream.jsdraws op 9 in the stream the same as the verb, andtest/primitives.jsholds a uniform elliptical rounded rect's primitive to its path and checks elliptical and square corners of their own. Written on a Mac, so CI here is its first build.