Skip to content

Strokes: tessellate thick strokes to triangles so joint and cap styles apply#12

Open
neilrackett wants to merge 1 commit into
awayjs:devfrom
mesmotronic:fix/stroke-joints-triangle-tessellation
Open

Strokes: tessellate thick strokes to triangles so joint and cap styles apply#12
neilrackett wants to merge 1 commit into
awayjs:devfrom
mesmotronic:fix/stroke-joints-triangle-tessellation

Conversation

@neilrackett

Copy link
Copy Markdown

Strokes: tessellate thick strokes to triangles so joint and cap styles apply

This PR makes lineStyle joint styles (miter/bevel/round) and cap styles work
for runtime-drawn strokes. Currently a polyline drawn with e.g.
JointStyle.MITER renders with a notch at every corner:

before — each segment is an independent quad, corners are two butt ends;
after — corners are proper mitered joints (or bevel/round as requested).

image

The bug

GraphicsFactoryStrokes.draw_pathes is hardcoded to build strokes as
GPU-expanded LineElements. Each segment is expanded to a quad independently,
so no joint geometry can exist between segments — the requested JointStyle
and CapsStyle on interior corners are ignored by construction. A
commented-out branch in draw_pathes suggests there used to be a choice of
path here.

Meanwhile getTriangleElements — a complete CPU tessellation with full
miter/bevel/round joint handling and cap support (including the miter-limit
clamp) — is unreachable: nothing in the codebase calls it.

The fix

Route non-hairline strokes thicker than 1.5px through getTriangleElements,
using the same UnpackFillStyle material path that fills use. Hairlines and
very thin strokes keep the fast LineElements path, where joints are
invisible anyway.

Bookkeeping: triangle-built stroke shapes are created fresh via
Shape.getShape (not from the LineElements stroke pool); tryPoolShape
already routes triangle shapes to the triangle pool, and the existing
_lastStroke remove-and-rebuild mechanism works unchanged.

Real-world impact

Found reviving an AS3/Flex-era charting app under AwayFL: 8px chart polylines
drawn with JointStyle.MITER, miterLimit 255 rendered with a visible notch at
every data point. With this change the peaks render as sharp mitered corners,
matching Flash. Verified against the app end-to-end (charts, plus a sweep of
other pages for stroke regressions).

…s apply

draw_pathes was hardcoded to GPU-expanded LineElements, which draw every
segment as an independent quad: polylines rendered with a notch at each
corner regardless of the JointStyle requested via lineStyle (a commented
out branch shows a choice used to exist here). The complete miter/bevel/
round joint and cap implementation in getTriangleElements was unreachable
- nothing called it.

Route non-hairline strokes thicker than 1.5px through the triangle
tessellator, using the same UnpackFillStyle material path as fills;
hairlines and very thin strokes keep the fast LineElements path, where
joints are invisible anyway. Triangle-built stroke shapes skip the
LineElements shape pool (tryPoolShape already routes them to the
triangle pool) and participate in the existing _lastStroke rebuild
mechanism unchanged.

Observed with an AS3 charting app drawing 8px polylines with
JointStyle.MITER: corners rendered as two butt ends with a notch;
with this change they render as proper mitered joints.
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