Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738// Translucent fills take a fast path in `lineh`; it must match `blend` exactly.import assert from "node:assert/strict";import test from "node:test";
globalThis.ImageData ??= class { constructor(width, height) { Object.assign(this, { width, height, data: new Uint8ClampedArray(width * height * 4) }); }};const graph = await import("../system/public/aesthetic.computer/lib/graph.mjs");
// `blend` from graph.mjs, per pixel, as the reference.function reference(dst, i, [r, g, b, a]) { if (dst[i + 3] < 255) { const s = a / 255, d = dst[i + 3] / 255, out = s + (1 - s) * d; [r, g, b].forEach((v, k) => { dst[i + k] = (v * s + dst[i + k] * (1 - s) * d) / (out + 1e-10); }); dst[i + 3] = out * 255; } else { const alpha = a + 1, inv = 256 - alpha; [r, g, b].forEach((v, k) => { dst[i + k] = (alpha * v + inv * dst[i + k]) >> 8; }); }}
test("translucent box blends like blend over opaque and see-through pixels", () => { const width = 16, height = 4; const pixels = new Uint8ClampedArray(width * height * 4); for (let i = 0; i < pixels.length; i += 4) { pixels.set([(i * 7) % 256, (i * 13) % 256, (i * 29) % 256, i % 12 === 0 ? 90 : 255], i); } const expected = pixels.slice(); for (let i = 0; i < expected.length; i += 4) reference(expected, i, [200, 40, 120, 77]);
graph.setBuffer({ width, height, pixels }); graph.color(200, 40, 120, 77); graph.box(0, 0, width, height); assert.deepEqual([...pixels], [...expected]);});