thi-ng/umbrella

View on GitHub
packages/rasterize/src/draw.ts

Summary

Maintainability
A
1 hr
Test Coverage
// thing:no-export
import type { IGrid2D, Nullable, TypedArray } from "@thi.ng/api";
import { isFunction } from "@thi.ng/checks/is-function";
import { isPrimitive } from "@thi.ng/checks/is-primitive";
import type { Shader2D } from "./api.js";

/** @internal */
export const __draw2D = <T extends any[] | TypedArray, P>(
    pts: Nullable<Iterable<ArrayLike<number>>>,
    grid: IGrid2D<T, P>,
    val: P | Shader2D<P>
) =>
    isFunction(val)
        ? __drawShader2D(pts, grid, val)
        : __drawSolid2D(pts, grid, val);

/** @internal */
export const __drawSolid2D = <T extends any[] | TypedArray, P>(
    pts: Nullable<Iterable<ArrayLike<number>>>,
    grid: IGrid2D<T, P>,
    val: P
) => {
    if (!pts) return grid;
    if (isPrimitive(val)) {
        const {
            data,
            offset,
            stride: [sx, sy],
        } = grid;
        for (let p of pts) {
            data[offset + p[0] * sx + p[1] * sy] = val;
        }
    } else {
        for (let p of pts) {
            grid.setAtUnsafe(p[0], p[1], val);
        }
    }
    return grid;
};

/** @internal */
export const __drawShader2D = <T extends any[] | TypedArray, P>(
    pts: Nullable<Iterable<ArrayLike<number>>>,
    grid: IGrid2D<T, P>,
    shader: Shader2D<P>
) => {
    if (!pts) return grid;
    if (isPrimitive(grid.getAtUnsafe(0, 0))) {
        const {
            data,
            offset,
            stride: [sx, sy],
        } = grid;
        for (let { 0: x, 1: y } of pts) {
            data[offset + x * sx + y * sy] = shader(grid, x, y);
        }
    } else {
        for (let { 0: x, 1: y } of pts) {
            grid.setAtUnsafe(x, y, shader(grid, x, y));
        }
    }
    return grid;
};