From 7364b7d212329847a151749079985c070a427603 Mon Sep 17 00:00:00 2001 From: William Candillon Date: Mon, 6 Jul 2026 09:04:14 +0200 Subject: [PATCH 1/3] :wrench: --- .../src/__tests__/snapshots/aa/bezier-8x.png | Bin 0 -> 8669 bytes .../src/__tests__/snapshots/aa/circle-8x.png | Bin 0 -> 8098 bytes .../__tests__/e2e/AntiAliasing.spec.tsx | 100 ++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 packages/skia/src/__tests__/snapshots/aa/bezier-8x.png create mode 100644 packages/skia/src/__tests__/snapshots/aa/circle-8x.png create mode 100644 packages/skia/src/renderer/__tests__/e2e/AntiAliasing.spec.tsx diff --git a/packages/skia/src/__tests__/snapshots/aa/bezier-8x.png b/packages/skia/src/__tests__/snapshots/aa/bezier-8x.png new file mode 100644 index 0000000000000000000000000000000000000000..26e8964742465979f76b96e0cbbedec654540cdd GIT binary patch literal 8669 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 { + it("should magnify an anti-aliased circle 8x with a pixel grid", async () => { + const image = await surface.drawOffscreen((Skia, canvas, ctx) => { + const draw = (c: typeof canvas) => { + const paint = Skia.Paint(); + paint.setAntiAlias(true); + paint.setColor(Skia.Color("black")); + c.drawCircle(ctx.size / 2, ctx.size / 2, ctx.size / 2 - 3, paint); + }; + const src = Skia.Surface.MakeOffscreen(ctx.size, ctx.size)!; + const srcCanvas = src.getCanvas(); + srcCanvas.clear(Skia.Color("white")); + draw(srcCanvas); + src.flush(); + const snapshot = src.makeImageSnapshot(); + const dstSize = ctx.size * ctx.zoom; + canvas.drawImageRectOptions( + snapshot, + Skia.XYWHRect(0, 0, ctx.size, ctx.size), + Skia.XYWHRect(0, 0, dstSize, dstSize), + ctx.nearest, + ctx.noMipmap + ); + const grid = Skia.Paint(); + grid.setColor(Skia.Color("rgba(0, 128, 255, 0.5)")); + grid.setStyle(ctx.stroke); + grid.setStrokeWidth(0); + grid.setAntiAlias(false); + for (let i = 0; i <= ctx.size; i++) { + const p = i * ctx.zoom; + canvas.drawLine(p, 0, p, dstSize, grid); + canvas.drawLine(0, p, dstSize, p, grid); + } + }, magnifyCtx); + checkImage(image, "snapshots/aa/circle-8x.png"); + }); + + it("should magnify an anti-aliased bezier curve 8x with a pixel grid", async () => { + const image = await surface.drawOffscreen((Skia, canvas, ctx) => { + const draw = (c: typeof canvas) => { + const paint = Skia.Paint(); + paint.setAntiAlias(true); + paint.setColor(Skia.Color("black")); + paint.setStyle(ctx.stroke); + paint.setStrokeWidth(2); + const path = Skia.PathBuilder.Make() + .moveTo(2, 28) + .cubicTo(8, -8, 24, 40, 30, 4) + .detach(); + c.drawPath(path, paint); + }; + const src = Skia.Surface.MakeOffscreen(ctx.size, ctx.size)!; + const srcCanvas = src.getCanvas(); + srcCanvas.clear(Skia.Color("white")); + draw(srcCanvas); + src.flush(); + const snapshot = src.makeImageSnapshot(); + const dstSize = ctx.size * ctx.zoom; + canvas.drawImageRectOptions( + snapshot, + Skia.XYWHRect(0, 0, ctx.size, ctx.size), + Skia.XYWHRect(0, 0, dstSize, dstSize), + ctx.nearest, + ctx.noMipmap + ); + const grid = Skia.Paint(); + grid.setColor(Skia.Color("rgba(0, 128, 255, 0.5)")); + grid.setStyle(ctx.stroke); + grid.setStrokeWidth(0); + grid.setAntiAlias(false); + for (let i = 0; i <= ctx.size; i++) { + const p = i * ctx.zoom; + canvas.drawLine(p, 0, p, dstSize, grid); + canvas.drawLine(0, p, dstSize, p, grid); + } + }, magnifyCtx); + checkImage(image, "snapshots/aa/bezier-8x.png"); + }); +}); From 53fb57e0b3aa9c6a3436a12425a09b5b1e4f6f5e Mon Sep 17 00:00:00 2001 From: William Candillon Date: Mon, 6 Jul 2026 09:28:46 +0200 Subject: [PATCH 2/3] :wrench: --- .../src/__tests__/snapshots/aa/bezier-8x.png | Bin 8669 -> 8695 bytes .../__tests__/snapshots/aa/bezier-sdf-8x.png | Bin 0 -> 8535 bytes .../__tests__/snapshots/aa/calligraphy-8x.png | Bin 0 -> 7671 bytes .../snapshots/aa/calligraphy-sdf-8x.png | Bin 0 -> 7799 bytes .../snapshots/aa/calligraphy-sdf.png | Bin 0 -> 64925 bytes .../__tests__/snapshots/aa/calligraphy.png | Bin 0 -> 64722 bytes .../__tests__/snapshots/aa/circle-sdf-8x.png | Bin 0 -> 7584 bytes .../__tests__/e2e/AntiAliasing.spec.tsx | 341 +++++++++++++++++- 8 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 packages/skia/src/__tests__/snapshots/aa/bezier-sdf-8x.png create mode 100644 packages/skia/src/__tests__/snapshots/aa/calligraphy-8x.png create mode 100644 packages/skia/src/__tests__/snapshots/aa/calligraphy-sdf-8x.png create mode 100644 packages/skia/src/__tests__/snapshots/aa/calligraphy-sdf.png create mode 100644 packages/skia/src/__tests__/snapshots/aa/calligraphy.png create mode 100644 packages/skia/src/__tests__/snapshots/aa/circle-sdf-8x.png diff --git a/packages/skia/src/__tests__/snapshots/aa/bezier-8x.png b/packages/skia/src/__tests__/snapshots/aa/bezier-8x.png index 26e8964742465979f76b96e0cbbedec654540cdd..1b5a0a6e957f4a716cc9790198e7ec1df2fff934 100644 GIT binary patch literal 8695 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 C1{C!G literal 8669 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 GAO8;{bIf-D literal 0 HcmV?d00001 diff --git a/packages/skia/src/__tests__/snapshots/aa/calligraphy-8x.png b/packages/skia/src/__tests__/snapshots/aa/calligraphy-8x.png new file mode 100644 index 0000000000000000000000000000000000000000..905907ac0a34b59c1eae13070e5325923fb66e9e GIT binary patch literal 7671 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

FKp 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 literal 0 HcmV?d00001 diff --git a/packages/skia/src/__tests__/snapshots/aa/calligraphy.png b/packages/skia/src/__tests__/snapshots/aa/calligraphy.png new file mode 100644 index 0000000000000000000000000000000000000000..f117457cdd12350234b245c4865deb0c765ee133 GIT binary patch literal 64722 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 literal 0 HcmV?d00001 diff --git a/packages/skia/src/__tests__/snapshots/aa/circle-sdf-8x.png b/packages/skia/src/__tests__/snapshots/aa/circle-sdf-8x.png new file mode 100644 index 0000000000000000000000000000000000000000..92032d22dea00abf3cc0bff5d49d79700aab828e GIT binary patch literal 7584 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 { @@ -64,6 +72,9 @@ describe("Anti-aliasing", () => { paint.setColor(Skia.Color("black")); paint.setStyle(ctx.stroke); paint.setStrokeWidth(2); + // Round caps to match the SDF version, where the distance to the + // curve naturally produces round caps at the endpoints + paint.setStrokeCap(ctx.roundCap); const path = Skia.PathBuilder.Make() .moveTo(2, 28) .cubicTo(8, -8, 24, 40, 30, 4) @@ -97,4 +108,332 @@ describe("Anti-aliasing", () => { }, magnifyCtx); checkImage(image, "snapshots/aa/bezier-8x.png"); }); + + // SDF versions of the same two shapes, rendered with a runtime shader. + // Coverage is derived from the signed distance and the SDF gradient with a + // linear ramp (analytic box-filter coverage of a straight edge crossing the + // pixel): clamp(0.5 - sdf * gradLen, 0, 1). Both SDFs are exact distances + // in pixel space, so gradLen is 1 and the transition spans one pixel. + it("should magnify an SDF-shaded circle 8x with a pixel grid", async () => { + const image = await surface.drawOffscreen((Skia, canvas, ctx) => { + const effect = Skia.RuntimeEffect.Make(` +const float2 c = float2(16.0, 16.0); +const float r = 13.0; + +half4 main(float2 p) { + float2 d = p - c; + float len = length(d); + float sdf = len - r; + float2 grad = len > 0.0 ? d / len : float2(0.0); + float gradLen = length(grad); + float coverage = gradLen == 0.0 + ? (sdf > 0.0 ? 0.0 : 1.0) + : clamp(0.5 - sdf * gradLen, 0.0, 1.0); + return half4(half3(1.0 - coverage), 1.0); +}`)!; + const paint = Skia.Paint(); + paint.setShader(effect.makeShader([])); + const src = Skia.Surface.MakeOffscreen(ctx.size, ctx.size)!; + const srcCanvas = src.getCanvas(); + srcCanvas.drawPaint(paint); + src.flush(); + const snapshot = src.makeImageSnapshot(); + const dstSize = ctx.size * ctx.zoom; + canvas.drawImageRectOptions( + snapshot, + Skia.XYWHRect(0, 0, ctx.size, ctx.size), + Skia.XYWHRect(0, 0, dstSize, dstSize), + ctx.nearest, + ctx.noMipmap + ); + const grid = Skia.Paint(); + grid.setColor(Skia.Color("rgba(0, 128, 255, 0.5)")); + grid.setStyle(ctx.stroke); + grid.setStrokeWidth(0); + grid.setAntiAlias(false); + for (let i = 0; i <= ctx.size; i++) { + const p = i * ctx.zoom; + canvas.drawLine(p, 0, p, dstSize, grid); + canvas.drawLine(0, p, dstSize, p, grid); + } + }, magnifyCtx); + checkImage(image, "snapshots/aa/circle-sdf-8x.png"); + }); + + it("should magnify an SDF-shaded bezier curve 8x with a pixel grid", async () => { + const image = await surface.drawOffscreen((Skia, canvas, ctx) => { + // Distance to the cubic is found with a coarse scan along t followed by + // a local ternary-search refinement (SkSL runtime effects follow ES2 + // rules, so the ITP root-finding used in Redraw is not portable here) + const effect = Skia.RuntimeEffect.Make(` +const float2 A = float2(2.0, 28.0); +const float2 B = float2(8.0, -8.0); +const float2 C = float2(24.0, 40.0); +const float2 D = float2(30.0, 4.0); +const float halfWidth = 1.0; + +float2 cubicEval(float t) { + float mt = 1.0 - t; + return mt * mt * mt * A + 3.0 * mt * mt * t * B + + 3.0 * mt * t * t * C + t * t * t * D; +} + +half4 main(float2 p) { + float bestT = 0.0; + float bestD = 1e20; + for (int i = 0; i <= 32; i++) { + float t = float(i) / 32.0; + float2 q = cubicEval(t) - p; + float d = dot(q, q); + if (d < bestD) { + bestD = d; + bestT = t; + } + } + float lo = max(bestT - 1.0 / 32.0, 0.0); + float hi = min(bestT + 1.0 / 32.0, 1.0); + for (int j = 0; j < 20; j++) { + float m1 = lo + (hi - lo) / 3.0; + float m2 = hi - (hi - lo) / 3.0; + float2 q1 = cubicEval(m1) - p; + float2 q2 = cubicEval(m2) - p; + if (dot(q1, q1) < dot(q2, q2)) { + hi = m2; + } else { + lo = m1; + } + } + float2 closest = cubicEval((lo + hi) * 0.5); + float dist = distance(p, closest); + float sdf = dist - halfWidth; + float2 grad = dist > 0.0 ? (p - closest) / dist : float2(0.0); + float gradLen = length(grad); + float coverage = gradLen == 0.0 + ? (sdf > 0.0 ? 0.0 : 1.0) + : clamp(0.5 - sdf * gradLen, 0.0, 1.0); + return half4(half3(1.0 - coverage), 1.0); +}`)!; + const paint = Skia.Paint(); + paint.setShader(effect.makeShader([])); + const src = Skia.Surface.MakeOffscreen(ctx.size, ctx.size)!; + const srcCanvas = src.getCanvas(); + srcCanvas.drawPaint(paint); + src.flush(); + const snapshot = src.makeImageSnapshot(); + const dstSize = ctx.size * ctx.zoom; + canvas.drawImageRectOptions( + snapshot, + Skia.XYWHRect(0, 0, ctx.size, ctx.size), + Skia.XYWHRect(0, 0, dstSize, dstSize), + ctx.nearest, + ctx.noMipmap + ); + const grid = Skia.Paint(); + grid.setColor(Skia.Color("rgba(0, 128, 255, 0.5)")); + grid.setStyle(ctx.stroke); + grid.setStrokeWidth(0); + grid.setAntiAlias(false); + for (let i = 0; i <= ctx.size; i++) { + const p = i * ctx.zoom; + canvas.drawLine(p, 0, p, dstSize, grid); + canvas.drawLine(0, p, dstSize, p, grid); + } + }, magnifyCtx); + checkImage(image, "snapshots/aa/bezier-sdf-8x.png"); + }); + + // Calligraphy: a broad-nib pen stroke modeled as a union of circles sampled + // along the path contours, with the radius given by the nib projected onto + // the normal of the direction of travel. Rendered once with the Skia + // rasterizer (a single path holding all the dots) and once from the circle + // SDF with the linear coverage ramp. The union of circles is min(sdf), and + // since the ramp is monotonic in sdf, per-pixel max(coverage) is exactly + // the coverage of the union SDF; that is what the CPU rasterizer + // accumulates. Each variant produces a full view and an 8x crop. + const calligraphyCtx = { + ...magnifyCtx, + d: "M13.6 247.8C13.6 247.8 51.8 206.1 84.2 168.8 140.8 103.4 202.8 27.1 150.1 14.3 131 9.7 116.4 29.3 107.3 44.8 69.7 108.4 58 213.8 57.5 302M58 302C67.7 271.3 104.4 190.3 140.2 192.5 181.5 195.1 145.3 257 154.5 283.8 168.8 321.6 208.2 292.3 230 276.9 265.9 251.5 289 230.7 289 199.9 289 161 235.3 173.5 223.3 204.6 213.9 228.9 214.3 265.3 229.3 283.6 247.5 305.7 287.7 309.4 312.2 287.9 337 266.2 354.7 234 368.7 212.5 403.9 158.3 464.4 85.6 449.1 29.5 447 21.9 440.4 16 432.5 15.7 393.6 14.2 381.8 98.6 375.3 128.8 368.8 159.3 345.2 260.8 373.1 292.5 404.4 328 446.3 261.9 464.7 231.1 468.7 224.8 472.6 217.9 476.1 212.5 511.3 158.4 571.8 85.6 556.5 29.5 554.4 21.9 547.8 16.1 539.9 15.8 501 14.2 489.2 98.7 482.8 128.8 476.2 159.3 452.6 260.8 480.5 292.6 511.8 328.1 562.4 265 572.6 232.3 587.3 185.4 620.9 171 660.9 179.7M660.9 179.7C616 166.1 580.9 199.1 572.6 232.6 566.8 256.4 573.5 281.6 599.2 295.2 668.5 331.9 742.8 211.1 660.9 179.7ZM660.9 179.7C643.7 181.3 636.1 204.2 643.3 227.2 654.3 263.4 704.3 267.7 733.1 255.5", + nibAngle: (45 * Math.PI) / 180, + rMin: 0.4, + rMax: 5, + step: 1, + crop: { x: 140, y: 185 }, + linear: FilterMode.Linear, + rgba8888: ColorType.RGBA_8888, + opaque: AlphaType.Opaque, + }; + + // Samples the nib dots on the testing surface and returns them as plain + // data, so the draw callbacks below only receive serializable context + const sampleCalligraphyDots = () => + surface.eval((Skia, ctx) => { + const source = Skia.Path.MakeFromSVGString(ctx.d)!; + const dots: { x: number; y: number; r: number }[] = []; + const it = Skia.ContourMeasureIter(source, false, 1); + let contour = it.next(); + while (contour !== null) { + const total = contour.length(); + for (let dist = 0; dist <= total; dist += ctx.step) { + const [pos, tan] = contour.getPosTan(dist); + const theta = Math.atan2(tan.y, tan.x); + const r = + ctx.rMin + + (ctx.rMax - ctx.rMin) * Math.abs(Math.sin(theta - ctx.nibAngle)); + dots.push({ x: pos.x, y: pos.y, r }); + } + contour = it.next(); + } + const b = source.getBounds(); + return { + dots, + w: Math.ceil(b.x + b.width + ctx.rMax + 1), + h: Math.ceil(b.y + b.height + ctx.rMax + 1), + }; + }, calligraphyCtx); + + it("should render calligraphy dots with Skia and magnify a crop 8x", async () => { + const { dots, w, h } = await sampleCalligraphyDots(); + const ctx = { ...calligraphyCtx, dots, w, h }; + const full = await surface.drawOffscreen((Skia, canvas, c) => { + const builder = Skia.PathBuilder.Make(); + for (const dot of c.dots) { + builder.addCircle(dot.x, dot.y, dot.r); + } + const src = Skia.Surface.MakeOffscreen(c.w, c.h)!; + const srcCanvas = src.getCanvas(); + srcCanvas.clear(Skia.Color("white")); + const paint = Skia.Paint(); + paint.setAntiAlias(true); + paint.setColor(Skia.Color("black")); + srcCanvas.drawPath(builder.detach(), paint); + src.flush(); + const snapshot = src.makeImageSnapshot(); + canvas.clear(Skia.Color("white")); + const scale = 256 / c.w; + canvas.drawImageRectOptions( + snapshot, + Skia.XYWHRect(0, 0, c.w, c.h), + Skia.XYWHRect(0, (256 - c.h * scale) / 2, 256, c.h * scale), + c.linear, + c.noMipmap + ); + }, ctx); + checkImage(full, "snapshots/aa/calligraphy.png"); + + const zoomed = await surface.drawOffscreen((Skia, canvas, c) => { + const builder = Skia.PathBuilder.Make(); + for (const dot of c.dots) { + builder.addCircle(dot.x, dot.y, dot.r); + } + const src = Skia.Surface.MakeOffscreen(c.w, c.h)!; + const srcCanvas = src.getCanvas(); + srcCanvas.clear(Skia.Color("white")); + const paint = Skia.Paint(); + paint.setAntiAlias(true); + paint.setColor(Skia.Color("black")); + srcCanvas.drawPath(builder.detach(), paint); + src.flush(); + const snapshot = src.makeImageSnapshot(); + const dstSize = c.size * c.zoom; + canvas.drawImageRectOptions( + snapshot, + Skia.XYWHRect(c.crop.x, c.crop.y, c.size, c.size), + Skia.XYWHRect(0, 0, dstSize, dstSize), + c.nearest, + c.noMipmap + ); + const grid = Skia.Paint(); + grid.setColor(Skia.Color("rgba(0, 128, 255, 0.5)")); + grid.setStyle(c.stroke); + grid.setStrokeWidth(0); + grid.setAntiAlias(false); + for (let i = 0; i <= c.size; i++) { + const p = i * c.zoom; + canvas.drawLine(p, 0, p, dstSize, grid); + canvas.drawLine(0, p, dstSize, p, grid); + } + }, ctx); + checkImage(zoomed, "snapshots/aa/calligraphy-8x.png"); + }); + + it("should render calligraphy dots with the circle SDF and magnify a crop 8x", async () => { + const { dots, w, h } = await sampleCalligraphyDots(); + // CPU rasterizer, pure JS: per-pixel coverage from the circle SDF with + // the linear ramp, max over circles = coverage of the union SDF + const cov = new Float32Array(w * h); + for (const dot of dots) { + const x0 = Math.max(0, Math.floor(dot.x - dot.r - 1)); + const x1 = Math.min(w - 1, Math.ceil(dot.x + dot.r + 1)); + const y0 = Math.max(0, Math.floor(dot.y - dot.r - 1)); + const y1 = Math.min(h - 1, Math.ceil(dot.y + dot.r + 1)); + for (let py = y0; py <= y1; py++) { + for (let px = x0; px <= x1; px++) { + const dx = px + 0.5 - dot.x; + const dy = py + 0.5 - dot.y; + const sdf = Math.sqrt(dx * dx + dy * dy) - dot.r; + const coverage = Math.min(1, Math.max(0, 0.5 - sdf)); + const i = py * w + px; + if (coverage > cov[i]) { + cov[i] = coverage; + } + } + } + } + const bytes = new Uint8Array(w * h * 4); + for (let i = 0; i < w * h; i++) { + const v = Math.round(255 * (1 - cov[i])); + bytes[i * 4] = v; + bytes[i * 4 + 1] = v; + bytes[i * 4 + 2] = v; + bytes[i * 4 + 3] = 255; + } + const ctx = { ...calligraphyCtx, bytes: Array.from(bytes), w, h }; + + const full = await surface.drawOffscreen((Skia, canvas, c) => { + const data = Skia.Data.fromBytes(new Uint8Array(c.bytes)); + const image = Skia.Image.MakeImage( + { width: c.w, height: c.h, colorType: c.rgba8888, alphaType: c.opaque }, + data, + c.w * 4 + )!; + canvas.clear(Skia.Color("white")); + const scale = 256 / c.w; + canvas.drawImageRectOptions( + image, + Skia.XYWHRect(0, 0, c.w, c.h), + Skia.XYWHRect(0, (256 - c.h * scale) / 2, 256, c.h * scale), + c.linear, + c.noMipmap + ); + }, ctx); + checkImage(full, "snapshots/aa/calligraphy-sdf.png"); + + const zoomed = await surface.drawOffscreen((Skia, canvas, c) => { + const data = Skia.Data.fromBytes(new Uint8Array(c.bytes)); + const image = Skia.Image.MakeImage( + { width: c.w, height: c.h, colorType: c.rgba8888, alphaType: c.opaque }, + data, + c.w * 4 + )!; + const dstSize = c.size * c.zoom; + canvas.drawImageRectOptions( + image, + Skia.XYWHRect(c.crop.x, c.crop.y, c.size, c.size), + Skia.XYWHRect(0, 0, dstSize, dstSize), + c.nearest, + c.noMipmap + ); + const grid = Skia.Paint(); + grid.setColor(Skia.Color("rgba(0, 128, 255, 0.5)")); + grid.setStyle(c.stroke); + grid.setStrokeWidth(0); + grid.setAntiAlias(false); + for (let i = 0; i <= c.size; i++) { + const p = i * c.zoom; + canvas.drawLine(p, 0, p, dstSize, grid); + canvas.drawLine(0, p, dstSize, p, grid); + } + }, ctx); + checkImage(zoomed, "snapshots/aa/calligraphy-sdf-8x.png"); + }); }); From ac861e15e1be305c886013fcf98d0cb0cb87fe40 Mon Sep 17 00:00:00 2001 From: William Candillon Date: Mon, 6 Jul 2026 09:51:43 +0200 Subject: [PATCH 3/3] :wrench: --- .../snapshots/aa/bezier-exact-8x.png | Bin 0 -> 8808 bytes .../snapshots/aa/circle-exact-8x.png | Bin 0 -> 7757 bytes .../snapshots/aa/circle-sdf-ss4-8x.png | Bin 0 -> 7448 bytes .../snapshots/aa/circle-sdf-ss8-8x.png | Bin 0 -> 7655 bytes .../__tests__/e2e/AntiAliasing.spec.tsx | 243 +++++++++++++++++- 5 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 packages/skia/src/__tests__/snapshots/aa/bezier-exact-8x.png create mode 100644 packages/skia/src/__tests__/snapshots/aa/circle-exact-8x.png create mode 100644 packages/skia/src/__tests__/snapshots/aa/circle-sdf-ss4-8x.png create mode 100644 packages/skia/src/__tests__/snapshots/aa/circle-sdf-ss8-8x.png diff --git a/packages/skia/src/__tests__/snapshots/aa/bezier-exact-8x.png b/packages/skia/src/__tests__/snapshots/aa/bezier-exact-8x.png new file mode 100644 index 0000000000000000000000000000000000000000..797e66f282a462ccd8b2f83ac87aa53d695ab66b GIT binary patch literal 8808 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 J6|CKT^gmAJGlT#D literal 0 HcmV?d00001 diff --git a/packages/skia/src/renderer/__tests__/e2e/AntiAliasing.spec.tsx b/packages/skia/src/renderer/__tests__/e2e/AntiAliasing.spec.tsx index 818397b9fe..0bbcd68298 100644 --- a/packages/skia/src/renderer/__tests__/e2e/AntiAliasing.spec.tsx +++ b/packages/skia/src/renderer/__tests__/e2e/AntiAliasing.spec.tsx @@ -25,6 +25,78 @@ const magnifyCtx = { noMipmap: MipmapMode.None, stroke: PaintStyle.Stroke, roundCap: StrokeCap.Round, + rgba8888: ColorType.RGBA_8888, + opaque: AlphaType.Opaque, +}; + +// Ground truth: the exact box-filter integral of a union of disks. The +// intersection of a disk with a vertical line is a closed-form interval, so +// coverage is integrated exactly in y (interval union merging) and only +// discretized in x with midpoint sampling; the numerical error is well below +// one 8-bit gray level. A stroked curve with round caps is exactly the +// Minkowski sum of the curve with a disk, i.e. a union of disks densely +// sampled along the curve. +const LINES_PER_COLUMN = 256; + +const exactUnionCoverage = ( + disks: { x: number; y: number; r: number }[], + size: number +) => { + const cov = new Float64Array(size * size); + for (let col = 0; col < size; col++) { + const candidates = disks.filter( + (d) => d.x - d.r < col + 1 && d.x + d.r > col + ); + if (candidates.length === 0) { + continue; + } + for (let k = 0; k < LINES_PER_COLUMN; k++) { + const x = col + (k + 0.5) / LINES_PER_COLUMN; + const intervals: [number, number][] = []; + for (const d of candidates) { + const t = d.r * d.r - (x - d.x) * (x - d.x); + if (t > 0) { + const s = Math.sqrt(t); + intervals.push([d.y - s, d.y + s]); + } + } + if (intervals.length === 0) { + continue; + } + intervals.sort((a, b) => a[0] - b[0]); + const add = (a: number, b: number) => { + const j0 = Math.max(0, Math.floor(a)); + const j1 = Math.min(size - 1, Math.ceil(b) - 1); + for (let j = j0; j <= j1; j++) { + const seg = Math.min(b, j + 1) - Math.max(a, j); + if (seg > 0) { + cov[j * size + col] += seg; + } + } + }; + let [lo, hi] = intervals[0]; + for (let m = 1; m < intervals.length; m++) { + const [ilo, ihi] = intervals[m]; + if (ilo <= hi) { + hi = Math.max(hi, ihi); + } else { + add(lo, hi); + lo = ilo; + hi = ihi; + } + } + add(lo, hi); + } + } + const bytes = new Uint8Array(size * size * 4); + for (let i = 0; i < size * size; i++) { + const v = Math.round(255 * (1 - cov[i] / LINES_PER_COLUMN)); + bytes[i * 4] = v; + bytes[i * 4 + 1] = v; + bytes[i * 4 + 2] = v; + bytes[i * 4 + 3] = 255; + } + return Array.from(bytes); }; describe("Anti-aliasing", () => { @@ -160,6 +232,175 @@ half4 main(float2 p) { checkImage(image, "snapshots/aa/circle-sdf-8x.png"); }); + // Same circle SDF, but coverage is estimated by supersampling: a hard + // inside/outside test at NxN stratified sub-pixel positions, averaged. + // This converges to the true box-filter area coverage as N grows, so it + // acts as ground truth to judge both Skia's analytic coverage and the + // linear ramp approximation. + it("should magnify a supersampled SDF circle 8x with a pixel grid", async () => { + for (const ss of [4, 8]) { + const image = await surface.drawOffscreen( + (Skia, canvas, ctx) => { + const effect = Skia.RuntimeEffect.Make(` +const float2 c = float2(16.0, 16.0); +const float r = 13.0; + +half4 main(float2 p) { + float cov = 0.0; + for (int i = 0; i < ${ctx.ss}; i++) { + for (int j = 0; j < ${ctx.ss}; j++) { + float2 o = (float2(float(i), float(j)) + 0.5) / ${ctx.ss}.0 - 0.5; + float sdf = length(p + o - c) - r; + cov += sdf <= 0.0 ? 1.0 : 0.0; + } + } + cov /= ${ctx.ss * ctx.ss}.0; + return half4(half3(1.0 - cov), 1.0); +}`)!; + const paint = Skia.Paint(); + paint.setShader(effect.makeShader([])); + const src = Skia.Surface.MakeOffscreen(ctx.size, ctx.size)!; + const srcCanvas = src.getCanvas(); + srcCanvas.drawPaint(paint); + src.flush(); + const snapshot = src.makeImageSnapshot(); + const dstSize = ctx.size * ctx.zoom; + canvas.drawImageRectOptions( + snapshot, + Skia.XYWHRect(0, 0, ctx.size, ctx.size), + Skia.XYWHRect(0, 0, dstSize, dstSize), + ctx.nearest, + ctx.noMipmap + ); + const grid = Skia.Paint(); + grid.setColor(Skia.Color("rgba(0, 128, 255, 0.5)")); + grid.setStyle(ctx.stroke); + grid.setStrokeWidth(0); + grid.setAntiAlias(false); + for (let i = 0; i <= ctx.size; i++) { + const p = i * ctx.zoom; + canvas.drawLine(p, 0, p, dstSize, grid); + canvas.drawLine(0, p, dstSize, p, grid); + } + }, + { ...magnifyCtx, ss } + ); + checkImage(image, `snapshots/aa/circle-sdf-ss${ss}-8x.png`); + } + }); + + it("should build the exact box-filter coverage for the circle", async () => { + const bytes = exactUnionCoverage([{ x: 16, y: 16, r: 13 }], SRC_SIZE); + const image = await surface.drawOffscreen( + (Skia, canvas, ctx) => { + const data = Skia.Data.fromBytes(new Uint8Array(ctx.bytes)); + const exact = Skia.Image.MakeImage( + { + width: ctx.size, + height: ctx.size, + colorType: ctx.rgba8888, + alphaType: ctx.opaque, + }, + data, + ctx.size * 4 + )!; + const dstSize = ctx.size * ctx.zoom; + canvas.drawImageRectOptions( + exact, + Skia.XYWHRect(0, 0, ctx.size, ctx.size), + Skia.XYWHRect(0, 0, dstSize, dstSize), + ctx.nearest, + ctx.noMipmap + ); + const grid = Skia.Paint(); + grid.setColor(Skia.Color("rgba(0, 128, 255, 0.5)")); + grid.setStyle(ctx.stroke); + grid.setStrokeWidth(0); + grid.setAntiAlias(false); + for (let i = 0; i <= ctx.size; i++) { + const p = i * ctx.zoom; + canvas.drawLine(p, 0, p, dstSize, grid); + canvas.drawLine(0, p, dstSize, p, grid); + } + }, + { ...magnifyCtx, bytes } + ); + checkImage(image, "snapshots/aa/circle-exact-8x.png"); + }); + + it("should build the exact box-filter coverage for the bezier curve", async () => { + // Same cubic as the other bezier tests, stroke width 2, round caps. The + // stroke region is the union of radius-1 disks centered on the curve; + // disks are emitted at even arc-length steps small enough that the + // scalloping error is far below one gray level. + const A = { x: 2, y: 28 }; + const B = { x: 8, y: -8 }; + const C = { x: 24, y: 40 }; + const D = { x: 30, y: 4 }; + const cubic = (t: number) => { + const mt = 1 - t; + const a = mt * mt * mt; + const b = 3 * mt * mt * t; + const c = 3 * mt * t * t; + const d = t * t * t; + return { + x: a * A.x + b * B.x + c * C.x + d * D.x, + y: a * A.y + b * B.y + c * C.y + d * D.y, + }; + }; + const DS = 0.05; + const M = 20000; + const disks: { x: number; y: number; r: number }[] = []; + let prev = cubic(0); + let acc = 0; + disks.push({ ...prev, r: 1 }); + for (let i = 1; i <= M; i++) { + const pt = cubic(i / M); + acc += Math.hypot(pt.x - prev.x, pt.y - prev.y); + prev = pt; + if (acc >= DS || i === M) { + disks.push({ ...pt, r: 1 }); + acc = 0; + } + } + const bytes = exactUnionCoverage(disks, SRC_SIZE); + const image = await surface.drawOffscreen( + (Skia, canvas, ctx) => { + const data = Skia.Data.fromBytes(new Uint8Array(ctx.bytes)); + const exact = Skia.Image.MakeImage( + { + width: ctx.size, + height: ctx.size, + colorType: ctx.rgba8888, + alphaType: ctx.opaque, + }, + data, + ctx.size * 4 + )!; + const dstSize = ctx.size * ctx.zoom; + canvas.drawImageRectOptions( + exact, + Skia.XYWHRect(0, 0, ctx.size, ctx.size), + Skia.XYWHRect(0, 0, dstSize, dstSize), + ctx.nearest, + ctx.noMipmap + ); + const grid = Skia.Paint(); + grid.setColor(Skia.Color("rgba(0, 128, 255, 0.5)")); + grid.setStyle(ctx.stroke); + grid.setStrokeWidth(0); + grid.setAntiAlias(false); + for (let i = 0; i <= ctx.size; i++) { + const p = i * ctx.zoom; + canvas.drawLine(p, 0, p, dstSize, grid); + canvas.drawLine(0, p, dstSize, p, grid); + } + }, + { ...magnifyCtx, bytes } + ); + checkImage(image, "snapshots/aa/bezier-exact-8x.png"); + }, 30000); + it("should magnify an SDF-shaded bezier curve 8x with a pixel grid", async () => { const image = await surface.drawOffscreen((Skia, canvas, ctx) => { // Distance to the cubic is found with a coarse scan along t followed by @@ -259,8 +500,6 @@ half4 main(float2 p) { step: 1, crop: { x: 140, y: 185 }, linear: FilterMode.Linear, - rgba8888: ColorType.RGBA_8888, - opaque: AlphaType.Opaque, }; // Samples the nib dots on the testing surface and returns them as plain