@oh-just-another/renderer-canvas 0.57.0
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 +18 -0
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/canvas-target.d.ts +83 -0
- package/dist/canvas-target.d.ts.map +1 -0
- package/dist/canvas-target.js +208 -0
- package/dist/canvas-target.js.map +1 -0
- package/dist/canvas-text-shaper.d.ts +11 -0
- package/dist/canvas-text-shaper.d.ts.map +1 -0
- package/dist/canvas-text-shaper.js +56 -0
- package/dist/canvas-text-shaper.js.map +1 -0
- package/dist/constants.d.ts +52 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +52 -0
- package/dist/constants.js.map +1 -0
- package/dist/hi-dpi.d.ts +26 -0
- package/dist/hi-dpi.d.ts.map +1 -0
- package/dist/hi-dpi.js +62 -0
- package/dist/hi-dpi.js.map +1 -0
- package/dist/image-source.d.ts +3 -0
- package/dist/image-source.d.ts.map +1 -0
- package/dist/image-source.js +65 -0
- package/dist/image-source.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/layered-canvas.d.ts +46 -0
- package/dist/layered-canvas.d.ts.map +1 -0
- package/dist/layered-canvas.js +95 -0
- package/dist/layered-canvas.js.map +1 -0
- package/dist/layered-surface.d.ts +75 -0
- package/dist/layered-surface.d.ts.map +1 -0
- package/dist/layered-surface.js +262 -0
- package/dist/layered-surface.js.map +1 -0
- package/dist/offscreen.d.ts +30 -0
- package/dist/offscreen.d.ts.map +1 -0
- package/dist/offscreen.js +50 -0
- package/dist/offscreen.js.map +1 -0
- package/dist/recording-target.d.ts +203 -0
- package/dist/recording-target.d.ts.map +1 -0
- package/dist/recording-target.js +260 -0
- package/dist/recording-target.js.map +1 -0
- package/dist/render-worker.d.ts +2 -0
- package/dist/render-worker.d.ts.map +1 -0
- package/dist/render-worker.js +112 -0
- package/dist/render-worker.js.map +1 -0
- package/dist/tile-compositor.d.ts +44 -0
- package/dist/tile-compositor.d.ts.map +1 -0
- package/dist/tile-compositor.js +110 -0
- package/dist/tile-compositor.js.map +1 -0
- package/dist/webgl2-color.d.ts +13 -0
- package/dist/webgl2-color.d.ts.map +1 -0
- package/dist/webgl2-color.js +26 -0
- package/dist/webgl2-color.js.map +1 -0
- package/dist/webgl2-curve.d.ts +46 -0
- package/dist/webgl2-curve.d.ts.map +1 -0
- package/dist/webgl2-curve.js +162 -0
- package/dist/webgl2-curve.js.map +1 -0
- package/dist/webgl2-ellipse.d.ts +52 -0
- package/dist/webgl2-ellipse.d.ts.map +1 -0
- package/dist/webgl2-ellipse.js +171 -0
- package/dist/webgl2-ellipse.js.map +1 -0
- package/dist/webgl2-msdf-text.d.ts +84 -0
- package/dist/webgl2-msdf-text.d.ts.map +1 -0
- package/dist/webgl2-msdf-text.js +306 -0
- package/dist/webgl2-msdf-text.js.map +1 -0
- package/dist/webgl2-stroke.d.ts +52 -0
- package/dist/webgl2-stroke.d.ts.map +1 -0
- package/dist/webgl2-stroke.js +318 -0
- package/dist/webgl2-stroke.js.map +1 -0
- package/dist/webgl2-target.d.ts +311 -0
- package/dist/webgl2-target.d.ts.map +1 -0
- package/dist/webgl2-target.js +1368 -0
- package/dist/webgl2-target.js.map +1 -0
- package/dist/webgpu-detect.d.ts +30 -0
- package/dist/webgpu-detect.d.ts.map +1 -0
- package/dist/webgpu-detect.js +74 -0
- package/dist/webgpu-detect.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
export class MsdfTextPipeline {
|
|
2
|
+
gl;
|
|
3
|
+
program;
|
|
4
|
+
vbo;
|
|
5
|
+
uTransform;
|
|
6
|
+
uColor;
|
|
7
|
+
uOpacity;
|
|
8
|
+
uAtlasSize;
|
|
9
|
+
uPxRange;
|
|
10
|
+
uAtlas;
|
|
11
|
+
aPos;
|
|
12
|
+
aUV;
|
|
13
|
+
constructor(gl) {
|
|
14
|
+
this.gl = gl;
|
|
15
|
+
const vert = compile(gl, gl.VERTEX_SHADER, VERTEX_SRC);
|
|
16
|
+
const frag = compile(gl, gl.FRAGMENT_SHADER, FRAGMENT_SRC);
|
|
17
|
+
this.program = link(gl, vert, frag);
|
|
18
|
+
this.vbo = glReq(gl.createBuffer());
|
|
19
|
+
this.aPos = gl.getAttribLocation(this.program, "aPos");
|
|
20
|
+
this.aUV = gl.getAttribLocation(this.program, "aUV");
|
|
21
|
+
this.uTransform = glReq(gl.getUniformLocation(this.program, "uTransform"));
|
|
22
|
+
this.uColor = glReq(gl.getUniformLocation(this.program, "uColor"));
|
|
23
|
+
this.uOpacity = glReq(gl.getUniformLocation(this.program, "uOpacity"));
|
|
24
|
+
this.uAtlasSize = glReq(gl.getUniformLocation(this.program, "uAtlasSize"));
|
|
25
|
+
this.uPxRange = glReq(gl.getUniformLocation(this.program, "uPxRange"));
|
|
26
|
+
this.uAtlas = glReq(gl.getUniformLocation(this.program, "uAtlas"));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build per-glyph quads for `text` starting at the cursor position
|
|
30
|
+
* `(x, y)` in world coordinates (top-left baseline convention —
|
|
31
|
+
* caller adjusts for textAlign / textBaseline upstream).
|
|
32
|
+
*
|
|
33
|
+
* Returns the screen-width of the rendered string in world units so
|
|
34
|
+
* callers can chain text or compute hit-test boxes. Returns 0 if the
|
|
35
|
+
* atlas couldn't bake one of the glyphs (atlas full) — the partial
|
|
36
|
+
* draw still lands.
|
|
37
|
+
*/
|
|
38
|
+
drawText(text, x, y, fontSize, atlas, style, surfaceSize,
|
|
39
|
+
/**
|
|
40
|
+
* Horizontal alignment factor: 0 = left (cursor at `x`), 0.5 =
|
|
41
|
+
* centre, 1 = right. Applied as a single world-space x shift after
|
|
42
|
+
* measuring the run, so there's no separate width-measuring walk
|
|
43
|
+
* over the atlas.
|
|
44
|
+
*/
|
|
45
|
+
alignFactor = 0,
|
|
46
|
+
/** Embedded font id (0=sans, 1=serif, 2=mono); selects atlas glyphs. */
|
|
47
|
+
fontId = 0) {
|
|
48
|
+
if (text.length === 0)
|
|
49
|
+
return 0;
|
|
50
|
+
// Walk glyphs, pack interleaved position+uv into one batch. Each
|
|
51
|
+
// glyph = 6 vertices (two triangles), 4 floats per vertex
|
|
52
|
+
// (x, y, u, v) = 24 floats.
|
|
53
|
+
const verticesPerGlyph = 6;
|
|
54
|
+
const floatsPerVertex = 4;
|
|
55
|
+
const needed = text.length * verticesPerGlyph * floatsPerVertex;
|
|
56
|
+
// Reuse the module-level scratch buffer — grow on demand.
|
|
57
|
+
ensureGlyphBufCapacity(needed);
|
|
58
|
+
const buf = scratchGlyphBuf;
|
|
59
|
+
let writeOffset = 0;
|
|
60
|
+
let cursor = x;
|
|
61
|
+
for (const ch of text) {
|
|
62
|
+
const cp = ch.codePointAt(0);
|
|
63
|
+
if (cp === undefined)
|
|
64
|
+
continue;
|
|
65
|
+
const glyph = atlas.getOrRasterize(cp, fontId);
|
|
66
|
+
if (!glyph)
|
|
67
|
+
break; // atlas full or shaper unavailable
|
|
68
|
+
const advancePx = (glyph.advance * fontSize) / glyph.unitsPerEm;
|
|
69
|
+
if (glyph.empty) {
|
|
70
|
+
cursor += advancePx;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
writeGlyphQuad(buf, writeOffset, glyph, cursor, y, fontSize, atlas);
|
|
74
|
+
writeOffset += verticesPerGlyph * floatsPerVertex;
|
|
75
|
+
cursor += advancePx;
|
|
76
|
+
}
|
|
77
|
+
if (writeOffset === 0)
|
|
78
|
+
return cursor - x; // every glyph empty / unavailable
|
|
79
|
+
const tex = atlas.uploadTo(this.gl);
|
|
80
|
+
const gl = this.gl;
|
|
81
|
+
gl.useProgram(this.program);
|
|
82
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo);
|
|
83
|
+
gl.bufferData(gl.ARRAY_BUFFER, buf.subarray(0, writeOffset), gl.DYNAMIC_DRAW);
|
|
84
|
+
gl.enableVertexAttribArray(this.aPos);
|
|
85
|
+
gl.vertexAttribPointer(this.aPos, 2, gl.FLOAT, false, 16, 0);
|
|
86
|
+
gl.enableVertexAttribArray(this.aUV);
|
|
87
|
+
gl.vertexAttribPointer(this.aUV, 2, gl.FLOAT, false, 16, 8);
|
|
88
|
+
// Alignment: shift the whole run left by `width × alignFactor` in
|
|
89
|
+
// world space, folded into the transform's translation (screen
|
|
90
|
+
// shift = column-0 × worldDx). One walk total — no separate width
|
|
91
|
+
// measurement pass.
|
|
92
|
+
const t = style.transform;
|
|
93
|
+
let mat = t;
|
|
94
|
+
if (alignFactor !== 0) {
|
|
95
|
+
const dx = -(cursor - x) * alignFactor;
|
|
96
|
+
mat = { ...t, e: t.e + t.a * dx, f: t.f + t.b * dx };
|
|
97
|
+
}
|
|
98
|
+
writeAffineToClipMat3(scratchMat3, mat, surfaceSize.width, surfaceSize.height);
|
|
99
|
+
gl.uniformMatrix3fv(this.uTransform, false, scratchMat3);
|
|
100
|
+
gl.uniform3f(this.uColor, style.color[0], style.color[1], style.color[2]);
|
|
101
|
+
gl.uniform1f(this.uOpacity, style.opacity);
|
|
102
|
+
gl.uniform1f(this.uAtlasSize, atlas.atlasSize);
|
|
103
|
+
// `pxRange` is the SDF range converted into screen pixels at the
|
|
104
|
+
// current font size: the shader needs it to keep the AA band the
|
|
105
|
+
// right thickness independent of zoom.
|
|
106
|
+
const tileGlyphPx = atlas.tileSize - 2 * atlas.range;
|
|
107
|
+
const pxRange = (atlas.range * fontSize) / Math.max(1, tileGlyphPx);
|
|
108
|
+
gl.uniform1f(this.uPxRange, pxRange);
|
|
109
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
110
|
+
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
111
|
+
gl.uniform1i(this.uAtlas, 0);
|
|
112
|
+
gl.drawArrays(gl.TRIANGLES, 0, writeOffset / floatsPerVertex);
|
|
113
|
+
return cursor - x;
|
|
114
|
+
}
|
|
115
|
+
dispose() {
|
|
116
|
+
this.gl.deleteBuffer(this.vbo);
|
|
117
|
+
this.gl.deleteProgram(this.program);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Pure-math helper: compute the screen-space rect + atlas UV rect for
|
|
122
|
+
* one glyph. Exported so tests can verify the geometry without booting
|
|
123
|
+
* a real WebGL2 context.
|
|
124
|
+
*
|
|
125
|
+
* Returns `{ left, top, right, bottom, u0, v0, u1, v1 }` in screen
|
|
126
|
+
* pixels / normalised UVs. Caller packs the six vertices into a vertex
|
|
127
|
+
* buffer.
|
|
128
|
+
*/
|
|
129
|
+
export const glyphQuadGeometry = (g, cursorX, cursorY, fontSize, atlas) => {
|
|
130
|
+
const unitToPx = fontSize / g.unitsPerEm;
|
|
131
|
+
// The MSDF tile is `tileSize × tileSize` but the glyph itself only
|
|
132
|
+
// occupies a `scaledW + 2*range` × `scaledH + 2*range` rectangle
|
|
133
|
+
// inside it — the rest of the tile is empty ("fully outside" SDF).
|
|
134
|
+
// The rasteriser scales by max(bboxW, bboxH) so the bigger axis fills
|
|
135
|
+
// `tileSize - 2*range` and the smaller axis is proportional. UVs must
|
|
136
|
+
// cover only that used rect, otherwise narrow letters ('i', 'l', 'I')
|
|
137
|
+
// get the empty atlas margin stretched into them and read as
|
|
138
|
+
// wide/skewed/distorted.
|
|
139
|
+
const tileGlyphAtlasPx = Math.max(1, atlas.tileSize - 2 * atlas.range);
|
|
140
|
+
const fontUnitsPerAtlasPx = Math.max(g.bboxW, g.bboxH) / tileGlyphAtlasPx;
|
|
141
|
+
// Atlas pixels occupied by the glyph + its SDF margin.
|
|
142
|
+
const usedW_atlas = g.bboxW / fontUnitsPerAtlasPx + 2 * atlas.range;
|
|
143
|
+
const usedH_atlas = g.bboxH / fontUnitsPerAtlasPx + 2 * atlas.range;
|
|
144
|
+
// Screen-pixel margin = the same `range` atlas pixels mapped through
|
|
145
|
+
// `fontUnitsPerAtlasPx × unitToPx`.
|
|
146
|
+
const marginPx = atlas.range * fontUnitsPerAtlasPx * unitToPx;
|
|
147
|
+
const w = g.bboxW * unitToPx + 2 * marginPx;
|
|
148
|
+
const h = g.bboxH * unitToPx + 2 * marginPx;
|
|
149
|
+
// Glyph quad position in screen coords (y-down). `cursorY` is the
|
|
150
|
+
// text baseline; the font bbox lives from baseline upward, so the
|
|
151
|
+
// glyph top sits at `cursor - bboxYMax * unitToPx`.
|
|
152
|
+
const left = cursorX + g.bboxXMin * unitToPx - marginPx;
|
|
153
|
+
const top = cursorY + (-g.bboxYMin - g.bboxH) * unitToPx - marginPx;
|
|
154
|
+
const right = left + w;
|
|
155
|
+
const bottom = top + h;
|
|
156
|
+
// Atlas UVs — cover the used rect, inset by half a texel on every
|
|
157
|
+
// side so the LINEAR filter never pulls in pixels from the adjacent
|
|
158
|
+
// tile. Without this inset the LINEAR sampler at a tile boundary
|
|
159
|
+
// averages the current glyph's edge with the neighbouring tile, which
|
|
160
|
+
// shows up as faint vertical / horizontal stripes between adjacent
|
|
161
|
+
// letters at certain zooms.
|
|
162
|
+
//
|
|
163
|
+
// The rasteriser writes the glyph right-side-up (y-flip applied in
|
|
164
|
+
// the Rust transform), so UV v=0 maps to the top of the glyph.
|
|
165
|
+
const inset = 0.5;
|
|
166
|
+
const u0 = (g.atlasX + inset) / atlas.atlasSize;
|
|
167
|
+
const v0 = (g.atlasY + inset) / atlas.atlasSize;
|
|
168
|
+
const u1 = (g.atlasX + usedW_atlas - inset) / atlas.atlasSize;
|
|
169
|
+
const v1 = (g.atlasY + usedH_atlas - inset) / atlas.atlasSize;
|
|
170
|
+
return { left, top, right, bottom, u0, v0, u1, v1 };
|
|
171
|
+
};
|
|
172
|
+
const writeGlyphQuad = (buf, offset, g, cursorX, cursorY, fontSize, atlas) => {
|
|
173
|
+
const { left, top, right, bottom, u0, v0, u1, v1 } = glyphQuadGeometry(g, cursorX, cursorY, fontSize, atlas);
|
|
174
|
+
// Two triangles, six vertices, (x, y, u, v) each.
|
|
175
|
+
buf.set([
|
|
176
|
+
left, top, u0, v0,
|
|
177
|
+
right, top, u1, v0,
|
|
178
|
+
left, bottom, u0, v1,
|
|
179
|
+
right, top, u1, v0,
|
|
180
|
+
right, bottom, u1, v1,
|
|
181
|
+
left, bottom, u0, v1,
|
|
182
|
+
], offset);
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Module-level scratch buffers — reused across every `drawText`
|
|
186
|
+
* invocation so the text hot path allocates zero `Float32Array`s after
|
|
187
|
+
* warmup.
|
|
188
|
+
*
|
|
189
|
+
* `scratchGlyphBuf` starts at 512 floats (21 chars worth of glyph
|
|
190
|
+
* quads); longer strings grow to the next power of 2. `scratchMat3` is
|
|
191
|
+
* a fixed mat3 (column-major), no grow needed.
|
|
192
|
+
*
|
|
193
|
+
* Safe for single-threaded WebGL — `drawText` is not reentrant, calls
|
|
194
|
+
* are serialised through the editor render loop. Multiple WebGL2Target
|
|
195
|
+
* instances share the buffer, which is fine.
|
|
196
|
+
*/
|
|
197
|
+
let scratchGlyphBuf = new Float32Array(512);
|
|
198
|
+
const scratchMat3 = new Float32Array(9);
|
|
199
|
+
const ensureGlyphBufCapacity = (n) => {
|
|
200
|
+
if (scratchGlyphBuf.length >= n)
|
|
201
|
+
return;
|
|
202
|
+
let cap = scratchGlyphBuf.length;
|
|
203
|
+
while (cap < n)
|
|
204
|
+
cap *= 2;
|
|
205
|
+
scratchGlyphBuf = new Float32Array(cap);
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Write the column-major mat3 the shader expects into a caller-owned
|
|
209
|
+
* scratch buffer. The editor affine maps (worldX, worldY) → screen
|
|
210
|
+
* pixels, then we scale pixels into clip space (-1..1) with a y flip so
|
|
211
|
+
* positive y goes down on the screen.
|
|
212
|
+
*/
|
|
213
|
+
const writeAffineToClipMat3 = (out, t, w, h) => {
|
|
214
|
+
const sx = 2 / w;
|
|
215
|
+
const sy = -2 / h;
|
|
216
|
+
out[0] = t.a * sx;
|
|
217
|
+
out[1] = t.b * sy;
|
|
218
|
+
out[2] = 0;
|
|
219
|
+
out[3] = t.c * sx;
|
|
220
|
+
out[4] = t.d * sy;
|
|
221
|
+
out[5] = 0;
|
|
222
|
+
out[6] = t.e * sx - 1;
|
|
223
|
+
out[7] = t.f * sy + 1;
|
|
224
|
+
out[8] = 1;
|
|
225
|
+
};
|
|
226
|
+
const VERTEX_SRC = `#version 300 es
|
|
227
|
+
in vec2 aPos;
|
|
228
|
+
in vec2 aUV;
|
|
229
|
+
uniform mat3 uTransform;
|
|
230
|
+
out vec2 vUV;
|
|
231
|
+
void main() {
|
|
232
|
+
vec3 p = uTransform * vec3(aPos, 1.0);
|
|
233
|
+
gl_Position = vec4(p.xy, 0.0, 1.0);
|
|
234
|
+
vUV = aUV;
|
|
235
|
+
}`;
|
|
236
|
+
/**
|
|
237
|
+
* Standard MSDF fragment shader: sample the 3-channel SDF, take the
|
|
238
|
+
* median of (r, g, b) to recover a single signed distance, and use
|
|
239
|
+
* `smoothstep` to antialias the 0.5 isoline. `pxRange` controls how
|
|
240
|
+
* wide the AA band is in screen pixels — without it the smoothstep
|
|
241
|
+
* collapses to a hard edge at high zoom and over-blurs at low zoom.
|
|
242
|
+
*
|
|
243
|
+
* The 0.5 isoline is the canonical inside/outside boundary for MSDF
|
|
244
|
+
* (the generator centres the distance field on 0.5 in u8 encoding:
|
|
245
|
+
* 0 = deep outside, 128 = on the edge, 255 = deep inside).
|
|
246
|
+
*/
|
|
247
|
+
const FRAGMENT_SRC = `#version 300 es
|
|
248
|
+
precision mediump float;
|
|
249
|
+
uniform vec3 uColor;
|
|
250
|
+
uniform float uOpacity;
|
|
251
|
+
uniform float uPxRange;
|
|
252
|
+
uniform sampler2D uAtlas;
|
|
253
|
+
in vec2 vUV;
|
|
254
|
+
out vec4 fragColor;
|
|
255
|
+
|
|
256
|
+
float median(float r, float g, float b) {
|
|
257
|
+
return max(min(r, g), min(max(r, g), b));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
void main() {
|
|
261
|
+
vec3 msd = texture(uAtlas, vUV).rgb;
|
|
262
|
+
float sd = median(msd.r, msd.g, msd.b);
|
|
263
|
+
// Convert signed distance to screen-space AA: fwidth(vUV) tracks how
|
|
264
|
+
// much UV changes per screen pixel, multiplied by pxRange gives the
|
|
265
|
+
// screen-pixel cover of one SDF step.
|
|
266
|
+
float dx = fwidth(sd) * 0.5;
|
|
267
|
+
float alpha = smoothstep(0.5 - dx, 0.5 + dx, sd);
|
|
268
|
+
if (alpha < 0.001) discard;
|
|
269
|
+
// Premultiplied output to match the context's premultipliedAlpha
|
|
270
|
+
// contract + blendFunc(ONE, 1-SRC_ALPHA).
|
|
271
|
+
float a = alpha * uOpacity;
|
|
272
|
+
fragColor = vec4(uColor * a, a);
|
|
273
|
+
}`;
|
|
274
|
+
/**
|
|
275
|
+
* Asserts a WebGL resource handle is non-null. Creation APIs are typed
|
|
276
|
+
* non-null but return `null` on context loss; surface that as a throw.
|
|
277
|
+
*/
|
|
278
|
+
const glReq = (v) => {
|
|
279
|
+
if (v === null)
|
|
280
|
+
throw new Error("packages/renderer-canvas: WebGL resource creation failed");
|
|
281
|
+
return v;
|
|
282
|
+
};
|
|
283
|
+
const compile = (gl, type, src) => {
|
|
284
|
+
const sh = glReq(gl.createShader(type));
|
|
285
|
+
gl.shaderSource(sh, src);
|
|
286
|
+
gl.compileShader(sh);
|
|
287
|
+
if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {
|
|
288
|
+
const log = gl.getShaderInfoLog(sh);
|
|
289
|
+
gl.deleteShader(sh);
|
|
290
|
+
throw new Error(`MSDF shader compile failed: ${log}`);
|
|
291
|
+
}
|
|
292
|
+
return sh;
|
|
293
|
+
};
|
|
294
|
+
const link = (gl, vert, frag) => {
|
|
295
|
+
const program = gl.createProgram();
|
|
296
|
+
gl.attachShader(program, vert);
|
|
297
|
+
gl.attachShader(program, frag);
|
|
298
|
+
gl.linkProgram(program);
|
|
299
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
300
|
+
const log = gl.getProgramInfoLog(program);
|
|
301
|
+
gl.deleteProgram(program);
|
|
302
|
+
throw new Error(`MSDF program link failed: ${log}`);
|
|
303
|
+
}
|
|
304
|
+
return program;
|
|
305
|
+
};
|
|
306
|
+
//# sourceMappingURL=webgl2-msdf-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgl2-msdf-text.js","sourceRoot":"","sources":["../src/webgl2-msdf-text.ts"],"names":[],"mappings":"AAwBA,MAAM,OAAO,gBAAgB;IAYE;IAXZ,OAAO,CAAe;IACtB,GAAG,CAAc;IACjB,UAAU,CAAuB;IACjC,MAAM,CAAuB;IAC7B,QAAQ,CAAuB;IAC/B,UAAU,CAAuB;IACjC,QAAQ,CAAuB;IAC/B,MAAM,CAAuB;IAC7B,IAAI,CAAS;IACb,GAAG,CAAS;IAE7B,YAA6B,EAA0B;QAA1B,OAAE,GAAF,EAAE,CAAwB;QACrD,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;QAC3D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IACrE,CAAC;IAED;;;;;;;;;OASG;IACH,QAAQ,CACN,IAAY,EACZ,CAAS,EACT,CAAS,EACT,QAAgB,EAChB,KAAiB,EACjB,KAAsB,EACtB,WAA8C;IAC9C;;;;;OAKG;IACH,WAAW,GAAG,CAAC;IACf,wEAAwE;IACxE,MAAM,GAAG,CAAC;QAEV,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAEhC,iEAAiE;QACjE,0DAA0D;QAC1D,4BAA4B;QAC5B,MAAM,gBAAgB,GAAG,CAAC,CAAC;QAC3B,MAAM,eAAe,GAAG,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,gBAAgB,GAAG,eAAe,CAAC;QAChE,0DAA0D;QAC1D,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,GAAG,GAAG,eAAe,CAAC;QAC5B,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,EAAE,KAAK,SAAS;gBAAE,SAAS;YAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC/C,IAAI,CAAC,KAAK;gBAAE,MAAM,CAAC,mCAAmC;YACtD,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;YAChE,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,MAAM,IAAI,SAAS,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YACpE,WAAW,IAAI,gBAAgB,GAAG,eAAe,CAAC;YAClD,MAAM,IAAI,SAAS,CAAC;QACtB,CAAC;QACD,IAAI,WAAW,KAAK,CAAC;YAAE,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,kCAAkC;QAE5E,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACnB,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC;QAC9E,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7D,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5D,kEAAkE;QAClE,+DAA+D;QAC/D,kEAAkE;QAClE,oBAAoB;QACpB,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QAC1B,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC;YACvC,GAAG,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC;QACvD,CAAC;QACD,qBAAqB,CAAC,WAAW,EAAE,GAAG,EAAE,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAC/E,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;QACzD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAC/C,iEAAiE;QACjE,iEAAiE;QACjE,uCAAuC;QACvC,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;QACrD,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QACpE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrC,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;QAC9B,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACnC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC7B,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,WAAW,GAAG,eAAe,CAAC,CAAC;QAC9D,OAAO,MAAM,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,OAAO;QACL,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,CAAa,EACb,OAAe,EACf,OAAe,EACf,QAAgB,EAChB,KAA6D,EAU7D,EAAE;IACF,MAAM,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC,UAAU,CAAC;IACzC,mEAAmE;IACnE,iEAAiE;IACjE,mEAAmE;IACnE,sEAAsE;IACtE,sEAAsE;IACtE,sEAAsE;IACtE,6DAA6D;IAC7D,yBAAyB;IACzB,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC;IAC1E,uDAAuD;IACvD,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,GAAG,mBAAmB,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;IACpE,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,GAAG,mBAAmB,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;IACpE,qEAAqE;IACrE,oCAAoC;IACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,mBAAmB,GAAG,QAAQ,CAAC;IAC9D,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC;IAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC;IAC5C,kEAAkE;IAClE,kEAAkE;IAClE,oDAAoD;IACpD,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,CAAC,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACxD,MAAM,GAAG,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACpE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC;IACvB,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC;IACvB,kEAAkE;IAClE,oEAAoE;IACpE,iEAAiE;IACjE,sEAAsE;IACtE,mEAAmE;IACnE,4BAA4B;IAC5B,EAAE;IACF,mEAAmE;IACnE,+DAA+D;IAC/D,MAAM,KAAK,GAAG,GAAG,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;IAChD,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;IAChD,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,WAAW,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;IAC9D,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,WAAW,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;IAC9D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AACtD,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACrB,GAAiB,EACjB,MAAc,EACd,CAAa,EACb,OAAe,EACf,OAAe,EACf,QAAgB,EAChB,KAAiB,EACX,EAAE;IACR,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,iBAAiB,CACpE,CAAC,EACD,OAAO,EACP,OAAO,EACP,QAAQ,EACR,KAAK,CACN,CAAC;IACF,kDAAkD;IAClD,GAAG,CAAC,GAAG,CACL;QACE,IAAI,EAAG,GAAG,EAAK,EAAE,EAAE,EAAE;QACrB,KAAK,EAAE,GAAG,EAAK,EAAE,EAAE,EAAE;QACrB,IAAI,EAAG,MAAM,EAAE,EAAE,EAAE,EAAE;QACrB,KAAK,EAAE,GAAG,EAAK,EAAE,EAAE,EAAE;QACrB,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE;QACrB,IAAI,EAAG,MAAM,EAAE,EAAE,EAAE,EAAE;KACtB,EACD,MAAM,CACP,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,IAAI,eAAe,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AAC5C,MAAM,WAAW,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;AAExC,MAAM,sBAAsB,GAAG,CAAC,CAAS,EAAQ,EAAE;IACjD,IAAI,eAAe,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO;IACxC,IAAI,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC;IACjC,OAAO,GAAG,GAAG,CAAC;QAAE,GAAG,IAAI,CAAC,CAAC;IACzB,eAAe,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,qBAAqB,GAAG,CAC5B,GAAiB,EACjB,CAAY,EACZ,CAAS,EACT,CAAS,EACH,EAAE;IACR,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAClB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAClB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAClB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACX,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAClB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAClB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACX,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG;;;;;;;;;EASjB,CAAC;AAEH;;;;;;;;;;GAUG;AACH,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BnB,CAAC;AAEH;;;GAGG;AACH,MAAM,KAAK,GAAG,CAAI,CAAW,EAAK,EAAE;IAClC,IAAI,CAAC,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC5F,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,EAA0B,EAAE,IAAY,EAAE,GAAW,EAAe,EAAE;IACrF,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IACxC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACzB,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACrB,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACpC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,CACX,EAA0B,EAC1B,IAAiB,EACjB,IAAiB,EACH,EAAE;IAChB,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;IACnC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/B,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/B,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACxB,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;QACrD,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC1C,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { LineCap, LineJoin } from "@oh-just-another/renderer-core";
|
|
2
|
+
import type { Transform, Vec2 } from "@oh-just-another/types";
|
|
3
|
+
/**
|
|
4
|
+
* GPU-side stroke pipeline for the WebGL2 backend. Builds a single
|
|
5
|
+
* triangle list per call (joins + caps included), uploads once, and
|
|
6
|
+
* draws via the host's solid-color program. Independent of the
|
|
7
|
+
* fill / text / image pipelines — they each manage their own VBO.
|
|
8
|
+
*
|
|
9
|
+
* Supports the full Canvas2D / SVG join + cap matrix:
|
|
10
|
+
* joins: "miter" (default), "bevel", "round"
|
|
11
|
+
* caps: "butt" (default), "square", "round"
|
|
12
|
+
*
|
|
13
|
+
* One TRIANGLES list rather than a strip + extra primitives: round
|
|
14
|
+
* joins / caps need fan triangles glued on top of the strip, and a
|
|
15
|
+
* single TRIANGLES list avoids re-binding the buffer per join while
|
|
16
|
+
* keeping heterogeneous join geometry easy to author.
|
|
17
|
+
*/
|
|
18
|
+
/** Two-vertex pair per polyline vertex (left + right side of the band). */
|
|
19
|
+
interface SideOffset {
|
|
20
|
+
ox: number;
|
|
21
|
+
oy: number;
|
|
22
|
+
}
|
|
23
|
+
export interface StrokeStyle {
|
|
24
|
+
readonly width: number;
|
|
25
|
+
readonly color: readonly [number, number, number];
|
|
26
|
+
readonly opacity: number;
|
|
27
|
+
readonly join: LineJoin;
|
|
28
|
+
readonly cap: LineCap;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Compute one miter offset at the hinge between two unit normals.
|
|
32
|
+
* Returns `{ ox, oy }` along the bisector, clamped to MITER_LIMIT.
|
|
33
|
+
* Exported so `webgl2-target.ts` can reuse it for closed-polyline seam
|
|
34
|
+
* vertices.
|
|
35
|
+
*/
|
|
36
|
+
export declare const miterOffset: (n1x: number, n1y: number, n2x: number, n2y: number, half: number) => SideOffset;
|
|
37
|
+
/**
|
|
38
|
+
* Build the stroke geometry for a polyline + style, upload to the
|
|
39
|
+
* caller's dynamic VBO, and draw. Identity uTransform — vertices are
|
|
40
|
+
* pre-projected into clip space here.
|
|
41
|
+
*
|
|
42
|
+
* The caller passes its solid program + cached `aPos` attribute
|
|
43
|
+
* location + its dynamic VBO. This function binds & sets up the
|
|
44
|
+
* attribute itself so it's self-contained — no implicit dependency on
|
|
45
|
+
* the previous draw's GL state.
|
|
46
|
+
*/
|
|
47
|
+
export declare const drawPolylineStroke: (gl: WebGL2RenderingContext, polyline: readonly Vec2[], style: StrokeStyle, transform: Transform, size: {
|
|
48
|
+
width: number;
|
|
49
|
+
height: number;
|
|
50
|
+
}, program: WebGLProgram, uTransformLoc: WebGLUniformLocation, uColorLoc: WebGLUniformLocation, uOpacityLoc: WebGLUniformLocation, dynamicVbo: WebGLBuffer, aPosLoc: number, identityMat3: Float32Array) => void;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=webgl2-stroke.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgl2-stroke.d.ts","sourceRoot":"","sources":["../src/webgl2-stroke.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;;;GAcG;AAEH,2EAA2E;AAC3E,UAAU,UAAU;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE;AA+D/C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACvB;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACtB,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,MAAM,EACX,MAAM,MAAM,KACX,UAaF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAC7B,IAAI,sBAAsB,EAC1B,UAAU,SAAS,IAAI,EAAE,EACzB,OAAO,WAAW,EAClB,WAAW,SAAS,EACpB,MAAM;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACvC,SAAS,YAAY,EACrB,eAAe,oBAAoB,EACnC,WAAW,oBAAoB,EAC/B,aAAa,oBAAoB,EACjC,YAAY,WAAW,EACvB,SAAS,MAAM,EACf,cAAc,YAAY,KACzB,IA4KF,CAAC"}
|