@thi.ng/webgl-msdf 2.1.100 → 2.1.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-12-09T19:12:04Z
3
+ - **Last updated**: 2023-12-11T10:07:09Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
package/api.js CHANGED
@@ -1 +0,0 @@
1
- export {};
package/convert.js CHANGED
@@ -1,24 +1,20 @@
1
- /**
2
- * Takes a JSON spec produced by the MSDF font generator at
3
- * https://github.com/donmccurdy/msdf-bmfont-web and transforms it into a
4
- * filtered, more compact glyph spec used by the functions of this module.
5
- *
6
- * @param raw -
7
- */
8
- export const convertGlyphs = (raw) => ({
9
- fontFace: raw.info.face,
10
- fontSize: raw.info.size,
11
- lineHeight: raw.common.lineHeight,
12
- baseLine: raw.common.base,
13
- tex: raw.pages[0],
14
- size: [raw.common.scaleW, raw.common.scaleH],
15
- chars: raw.chars.reduce((acc, ch) => {
16
- acc[String.fromCharCode(ch.id)] = {
17
- pos: [ch.x, ch.y],
18
- offset: [ch.xoffset, ch.yoffset],
19
- size: [ch.width, ch.height],
20
- step: ch.xadvance,
21
- };
22
- return acc;
23
- }, {}),
1
+ const convertGlyphs = (raw) => ({
2
+ fontFace: raw.info.face,
3
+ fontSize: raw.info.size,
4
+ lineHeight: raw.common.lineHeight,
5
+ baseLine: raw.common.base,
6
+ tex: raw.pages[0],
7
+ size: [raw.common.scaleW, raw.common.scaleH],
8
+ chars: raw.chars.reduce((acc, ch) => {
9
+ acc[String.fromCharCode(ch.id)] = {
10
+ pos: [ch.x, ch.y],
11
+ offset: [ch.xoffset, ch.yoffset],
12
+ size: [ch.width, ch.height],
13
+ step: ch.xadvance
14
+ };
15
+ return acc;
16
+ }, {})
24
17
  });
18
+ export {
19
+ convertGlyphs
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/webgl-msdf",
3
- "version": "2.1.100",
3
+ "version": "2.1.101",
4
4
  "description": "Multi-channel SDF font rendering & basic text layout for WebGL",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -24,7 +24,9 @@
24
24
  "author": "Karsten Schmidt (https://thi.ng)",
25
25
  "license": "Apache-2.0",
26
26
  "scripts": {
27
- "build": "yarn clean && tsc --declaration",
27
+ "build": "yarn build:esbuild && yarn build:decl",
28
+ "build:decl": "tsc --declaration --emitDeclarationOnly",
29
+ "build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
28
30
  "clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
29
31
  "doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
30
32
  "doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
@@ -33,16 +35,17 @@
33
35
  "test": "bun test"
34
36
  },
35
37
  "dependencies": {
36
- "@thi.ng/api": "^8.9.11",
37
- "@thi.ng/shader-ast": "^0.12.84",
38
- "@thi.ng/transducers": "^8.8.14",
39
- "@thi.ng/vector-pools": "^3.1.89",
40
- "@thi.ng/vectors": "^7.8.8",
41
- "@thi.ng/webgl": "^6.6.11"
38
+ "@thi.ng/api": "^8.9.12",
39
+ "@thi.ng/shader-ast": "^0.12.85",
40
+ "@thi.ng/transducers": "^8.8.15",
41
+ "@thi.ng/vector-pools": "^3.1.90",
42
+ "@thi.ng/vectors": "^7.8.9",
43
+ "@thi.ng/webgl": "^6.6.12"
42
44
  },
43
45
  "devDependencies": {
44
46
  "@microsoft/api-extractor": "^7.38.3",
45
47
  "@types/node": "^20.10.2",
48
+ "esbuild": "^0.19.8",
46
49
  "rimraf": "^5.0.5",
47
50
  "tools": "^0.0.1",
48
51
  "typedoc": "^0.25.4",
@@ -92,5 +95,5 @@
92
95
  "parent": "@thi.ng/webgl",
93
96
  "year": 2019
94
97
  },
95
- "gitHead": "25f2ac8ff795a432a930119661b364d4d93b59a0\n"
98
+ "gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
96
99
  }
package/shader.js CHANGED
@@ -1,7 +1,13 @@
1
1
  import { assign } from "@thi.ng/shader-ast/ast/assign";
2
2
  import { discard, ifThen } from "@thi.ng/shader-ast/ast/controlflow";
3
3
  import { defMain, defn, ret } from "@thi.ng/shader-ast/ast/function";
4
- import { FLOAT0, FLOAT05, FLOAT1, vec2, vec4, } from "@thi.ng/shader-ast/ast/lit";
4
+ import {
5
+ FLOAT0,
6
+ FLOAT05,
7
+ FLOAT1,
8
+ vec2,
9
+ vec4
10
+ } from "@thi.ng/shader-ast/ast/lit";
5
11
  import { add, div, lt, mul, sub } from "@thi.ng/shader-ast/ast/ops";
6
12
  import { $x, $xyz, $y, $z } from "@thi.ng/shader-ast/ast/swizzle";
7
13
  import { sym } from "@thi.ng/shader-ast/ast/sym";
@@ -9,58 +15,74 @@ import { clamp, max, min, mix } from "@thi.ng/shader-ast/builtin/math";
9
15
  import { fwidth, texture } from "@thi.ng/shader-ast/builtin/texture";
10
16
  import { ONE4, ZERO4 } from "@thi.ng/vectors/api";
11
17
  import { BLEND_NORMAL } from "@thi.ng/webgl/api/blend";
12
- export const median3 = defn("float", "median3", ["vec3"], (v) => [
13
- ret(max(min($x(v), $y(v)), min(max($x(v), $y(v)), $z(v)))),
18
+ const median3 = defn("float", "median3", ["vec3"], (v) => [
19
+ ret(max(min($x(v), $y(v)), min(max($x(v), $y(v)), $z(v))))
14
20
  ]);
15
- export const msdfSample = defn("vec2", "msdfSample", ["sampler2D", "vec2"], (tex, uv) => {
21
+ const msdfSample = defn(
22
+ "vec2",
23
+ "msdfSample",
24
+ ["sampler2D", "vec2"],
25
+ (tex, uv) => {
16
26
  let sd;
17
27
  let w;
18
28
  return [
19
- (sd = sym(sub(median3($xyz(texture(tex, uv))), FLOAT05))),
20
- (w = sym(clamp(add(div(sd, fwidth(sd)), FLOAT05), FLOAT0, FLOAT1))),
21
- ret(vec2(sd, w)),
29
+ sd = sym(sub(median3($xyz(texture(tex, uv))), FLOAT05)),
30
+ w = sym(clamp(add(div(sd, fwidth(sd)), FLOAT05), FLOAT0, FLOAT1)),
31
+ ret(vec2(sd, w))
22
32
  ];
33
+ }
34
+ );
35
+ const msdfShader = (opts = {}) => ({
36
+ vs: (gl, unis, ins, outs) => [
37
+ defMain(() => [
38
+ assign(outs.vuv, ins.uv),
39
+ opts.color ? assign(outs.vcolor, ins.color) : null,
40
+ assign(
41
+ gl.gl_Position,
42
+ mul(mul(unis.proj, unis.modelview), vec4(ins.position, 1))
43
+ )
44
+ ])
45
+ ],
46
+ fs: (_, unis, ins, outs) => [
47
+ defMain(() => {
48
+ let w;
49
+ return [
50
+ w = sym(msdfSample(unis.tex, ins.vuv)),
51
+ assign(
52
+ outs.fragColor,
53
+ mix(unis.bg, opts.color ? ins.vcolor : unis.fg, $y(w))
54
+ ),
55
+ ifThen(lt($x(w), unis.thresh), [discard])
56
+ ];
57
+ })
58
+ ],
59
+ ext: {
60
+ OES_standard_derivatives: true
61
+ },
62
+ attribs: {
63
+ position: "vec3",
64
+ uv: "vec2",
65
+ ...opts.color ? { color: "vec4" } : null
66
+ },
67
+ varying: {
68
+ vuv: "vec2",
69
+ ...opts.color ? { vcolor: "vec4" } : null
70
+ },
71
+ uniforms: {
72
+ modelview: "mat4",
73
+ proj: "mat4",
74
+ tex: "sampler2D",
75
+ thresh: ["float", 1e-3],
76
+ bg: ["vec4", ZERO4],
77
+ ...!opts.color ? { fg: ["vec4", ONE4] } : null
78
+ },
79
+ state: {
80
+ blend: true,
81
+ blendFn: BLEND_NORMAL
82
+ }
23
83
  });
24
- export const msdfShader = (opts = {}) => ({
25
- vs: (gl, unis, ins, outs) => [
26
- defMain(() => [
27
- assign(outs.vuv, ins.uv),
28
- opts.color ? assign(outs.vcolor, ins.color) : null,
29
- assign(gl.gl_Position, mul(mul(unis.proj, unis.modelview), vec4(ins.position, 1))),
30
- ]),
31
- ],
32
- fs: (_, unis, ins, outs) => [
33
- defMain(() => {
34
- let w;
35
- return [
36
- (w = sym(msdfSample(unis.tex, ins.vuv))),
37
- assign(outs.fragColor, mix(unis.bg, opts.color ? ins.vcolor : unis.fg, $y(w))),
38
- ifThen(lt($x(w), unis.thresh), [discard]),
39
- ];
40
- }),
41
- ],
42
- ext: {
43
- OES_standard_derivatives: true,
44
- },
45
- attribs: {
46
- position: "vec3",
47
- uv: "vec2",
48
- ...(opts.color ? { color: "vec4" } : null),
49
- },
50
- varying: {
51
- vuv: "vec2",
52
- ...(opts.color ? { vcolor: "vec4" } : null),
53
- },
54
- uniforms: {
55
- modelview: "mat4",
56
- proj: "mat4",
57
- tex: "sampler2D",
58
- thresh: ["float", 1e-3],
59
- bg: ["vec4", ZERO4],
60
- ...(!opts.color ? { fg: ["vec4", ONE4] } : null),
61
- },
62
- state: {
63
- blend: true,
64
- blendFn: BLEND_NORMAL,
65
- },
66
- });
84
+ export {
85
+ median3,
86
+ msdfSample,
87
+ msdfShader
88
+ };
package/text.js CHANGED
@@ -9,80 +9,102 @@ import { ONE4 } from "@thi.ng/vectors/api";
9
9
  import { invert2 } from "@thi.ng/vectors/invert";
10
10
  import { madd2 } from "@thi.ng/vectors/madd";
11
11
  import { mul2 } from "@thi.ng/vectors/mul";
12
- export const text = (glyphs, txt, opts) => {
13
- opts = {
14
- align: alignLeft,
15
- spacing: 1,
16
- leading: 1,
17
- dirX: 1,
18
- dirY: 1,
19
- color: ONE4,
20
- ...opts,
21
- };
22
- const dir = [opts.dirX, opts.dirY];
23
- const lineHeight = glyphs.lineHeight * opts.leading * opts.dirY;
24
- const len = txt.replace("\n", "").length;
25
- const attribs = new AttribPool({
26
- attribs: {
27
- position: { type: "f32", size: 3, byteOffset: 0 },
28
- uv: { type: "f32", size: 2, byteOffset: 12 },
29
- ...(opts.useColor
30
- ? {
31
- color: {
32
- type: "f32",
33
- default: opts.color,
34
- size: 4,
35
- byteOffset: 20,
36
- },
37
- }
38
- : null),
39
- },
40
- num: len * 4,
41
- mem: {
42
- size: len * 4 * (opts.useColor ? 36 : 20) + 8 + /* FIXME */ 40,
43
- },
44
- });
45
- const lines = txt.split("\n");
46
- const invSize = invert2([], glyphs.size);
47
- for (let i = 0, yy = 0, id = 0; i < lines.length; i++) {
48
- const line = lines[i];
49
- let xx = opts.align(glyphs, opts, line);
50
- for (let j = 0; j < line.length; j++, id++) {
51
- const { pos, size, offset, step } = glyphs.chars[line[j]];
52
- const [sx, sy] = mul2([], size, dir);
53
- const [x, y] = madd2([], offset, dir, [xx, yy]);
54
- attribs.setAttribValues("position", [
55
- [x, y, 0],
56
- [x + sx, y, 0],
57
- [x + sx, y + sy, 0],
58
- [x, y + sy, 0],
59
- ], id * 4);
60
- attribs.setAttribValues("uv", [
61
- mul2([], pos, invSize),
62
- mul2([], [pos[0] + size[0], pos[1]], invSize),
63
- addm2([], pos, size, invSize),
64
- mul2([], [pos[0], pos[1] + size[1]], invSize),
65
- ], id * 4);
66
- xx += step * opts.dirX * opts.spacing;
12
+ const text = (glyphs, txt, opts) => {
13
+ opts = {
14
+ align: alignLeft,
15
+ spacing: 1,
16
+ leading: 1,
17
+ dirX: 1,
18
+ dirY: 1,
19
+ color: ONE4,
20
+ ...opts
21
+ };
22
+ const dir = [opts.dirX, opts.dirY];
23
+ const lineHeight = glyphs.lineHeight * opts.leading * opts.dirY;
24
+ const len = txt.replace("\n", "").length;
25
+ const attribs = new AttribPool({
26
+ attribs: {
27
+ position: { type: "f32", size: 3, byteOffset: 0 },
28
+ uv: { type: "f32", size: 2, byteOffset: 12 },
29
+ ...opts.useColor ? {
30
+ color: {
31
+ type: "f32",
32
+ default: opts.color,
33
+ size: 4,
34
+ byteOffset: 20
67
35
  }
68
- yy += lineHeight;
36
+ } : null
37
+ },
38
+ num: len * 4,
39
+ mem: {
40
+ size: len * 4 * (opts.useColor ? 36 : 20) + 8 + /* FIXME */
41
+ 40
69
42
  }
70
- return {
71
- attribPool: attribs,
72
- indices: {
73
- data: new Uint16Array([
74
- ...mapcat((i) => [i, i + 1, i + 2, i, i + 2, i + 3], range(0, len * 4, 4)),
75
- ]),
76
- },
77
- uniforms: {},
78
- num: len * 6,
79
- mode: 4, // TRIANGLES
80
- };
43
+ });
44
+ const lines = txt.split("\n");
45
+ const invSize = invert2([], glyphs.size);
46
+ for (let i = 0, yy = 0, id = 0; i < lines.length; i++) {
47
+ const line = lines[i];
48
+ let xx = opts.align(glyphs, opts, line);
49
+ for (let j = 0; j < line.length; j++, id++) {
50
+ const { pos, size, offset, step } = glyphs.chars[line[j]];
51
+ const [sx, sy] = mul2([], size, dir);
52
+ const [x, y] = madd2([], offset, dir, [xx, yy]);
53
+ attribs.setAttribValues(
54
+ "position",
55
+ [
56
+ [x, y, 0],
57
+ [x + sx, y, 0],
58
+ [x + sx, y + sy, 0],
59
+ [x, y + sy, 0]
60
+ ],
61
+ id * 4
62
+ );
63
+ attribs.setAttribValues(
64
+ "uv",
65
+ [
66
+ mul2([], pos, invSize),
67
+ mul2([], [pos[0] + size[0], pos[1]], invSize),
68
+ addm2([], pos, size, invSize),
69
+ mul2([], [pos[0], pos[1] + size[1]], invSize)
70
+ ],
71
+ id * 4
72
+ );
73
+ xx += step * opts.dirX * opts.spacing;
74
+ }
75
+ yy += lineHeight;
76
+ }
77
+ return {
78
+ attribPool: attribs,
79
+ indices: {
80
+ data: new Uint16Array([
81
+ ...mapcat(
82
+ (i) => [i, i + 1, i + 2, i, i + 2, i + 3],
83
+ range(0, len * 4, 4)
84
+ )
85
+ ])
86
+ },
87
+ uniforms: {},
88
+ num: len * 6,
89
+ mode: 4
90
+ // TRIANGLES
91
+ };
92
+ };
93
+ const textWidth = (font, opts, txt) => {
94
+ const s = opts.spacing !== void 0 ? opts.spacing : 1;
95
+ return transduce(
96
+ map((x) => font.chars[x].step * s),
97
+ add(),
98
+ txt
99
+ );
81
100
  };
82
- export const textWidth = (font, opts, txt) => {
83
- const s = opts.spacing !== undefined ? opts.spacing : 1;
84
- return transduce(map((x) => font.chars[x].step * s), add(), txt);
101
+ const alignLeft = () => 0;
102
+ const alignRight = (font, opts, line) => -(opts.dirX || 1) * textWidth(font, opts, line);
103
+ const alignCenter = (font, opts, line) => -(opts.dirX || 1) * textWidth(font, opts, line) / 2;
104
+ export {
105
+ alignCenter,
106
+ alignLeft,
107
+ alignRight,
108
+ text,
109
+ textWidth
85
110
  };
86
- export const alignLeft = () => 0;
87
- export const alignRight = (font, opts, line) => -(opts.dirX || 1) * textWidth(font, opts, line);
88
- export const alignCenter = (font, opts, line) => (-(opts.dirX || 1) * textWidth(font, opts, line)) / 2;