q5 4.4.1 → 4.4.2
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/deno.json +1 -1
- package/package.json +1 -1
- package/q5.d.ts +12 -17
- package/q5.js +206 -403
- package/q5.min.js +1 -1
package/q5.js
CHANGED
|
@@ -6202,15 +6202,7 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
6202
6202
|
shouldClear = false;
|
|
6203
6203
|
};
|
|
6204
6204
|
|
|
6205
|
-
let transformsBuffer,
|
|
6206
|
-
colorsBuffer,
|
|
6207
|
-
shapesVertBuff,
|
|
6208
|
-
imgVertBuff,
|
|
6209
|
-
polygonVertBuff,
|
|
6210
|
-
polyPtsBuffer,
|
|
6211
|
-
polyPtsBindGroup,
|
|
6212
|
-
charBuffer,
|
|
6213
|
-
textBuffer;
|
|
6205
|
+
let transformsBuffer, colorsBuffer, shapesVertBuff, imgVertBuff, charBuffer, textBuffer;
|
|
6214
6206
|
let mainBindGroup, lastTransformsBuffer, lastColorsBuffer;
|
|
6215
6207
|
|
|
6216
6208
|
$._render = () => {
|
|
@@ -6288,38 +6280,6 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
6288
6280
|
$._pass.setVertexBuffer(0, shapesVertBuff);
|
|
6289
6281
|
|
|
6290
6282
|
// prepare to render images and videos
|
|
6291
|
-
|
|
6292
|
-
if (polygonVertIdx) {
|
|
6293
|
-
let polygonVertSize = polygonVertIdx * 4; // 4 bytes per float
|
|
6294
|
-
if (!polygonVertBuff || polygonVertBuff.size < polygonVertSize) {
|
|
6295
|
-
if (polygonVertBuff) polygonVertBuff.destroy();
|
|
6296
|
-
polygonVertBuff = Q5.device.createBuffer({
|
|
6297
|
-
size: polygonVertSize * 2,
|
|
6298
|
-
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
|
|
6299
|
-
});
|
|
6300
|
-
}
|
|
6301
|
-
|
|
6302
|
-
Q5.device.queue.writeBuffer(polygonVertBuff, 0, polygonVertStack.subarray(0, polygonVertIdx));
|
|
6303
|
-
$._pass.setVertexBuffer(2, polygonVertBuff);
|
|
6304
|
-
|
|
6305
|
-
if (polyPtsIdx) {
|
|
6306
|
-
let polyPtsSize = polyPtsIdx * 4;
|
|
6307
|
-
if (!polyPtsBuffer || polyPtsBuffer.size < polyPtsSize) {
|
|
6308
|
-
if (polyPtsBuffer) polyPtsBuffer.destroy();
|
|
6309
|
-
polyPtsBuffer = Q5.device.createBuffer({
|
|
6310
|
-
size: Math.max(polyPtsSize * 2, 64),
|
|
6311
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
|
|
6312
|
-
});
|
|
6313
|
-
}
|
|
6314
|
-
Q5.device.queue.writeBuffer(polyPtsBuffer, 0, polyPtsStack.subarray(0, polyPtsIdx));
|
|
6315
|
-
|
|
6316
|
-
polyPtsBindGroup = Q5.device.createBindGroup({
|
|
6317
|
-
layout: polygonBindGroupLayout,
|
|
6318
|
-
entries: [{ binding: 0, resource: { buffer: polyPtsBuffer } }]
|
|
6319
|
-
});
|
|
6320
|
-
}
|
|
6321
|
-
}
|
|
6322
|
-
|
|
6323
6283
|
if (imgVertIdx) {
|
|
6324
6284
|
$._pass.setPipeline($._pipelines[2]); // images pipeline
|
|
6325
6285
|
|
|
@@ -6418,7 +6378,6 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
6418
6378
|
let drawVertOffset = 0,
|
|
6419
6379
|
imageVertOffset = 0,
|
|
6420
6380
|
textCharOffset = 0,
|
|
6421
|
-
polygonVertOffset = 0,
|
|
6422
6381
|
rectIdx = 0,
|
|
6423
6382
|
ellipseIdx = 0,
|
|
6424
6383
|
curPipelineIndex = -1;
|
|
@@ -6446,18 +6405,12 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
6446
6405
|
} else if (curPipelineIndex == 6) {
|
|
6447
6406
|
pass.setIndexBuffer(ellipseIndexBuffer, 'uint16');
|
|
6448
6407
|
pass.setBindGroup(1, ellipseBindGroup);
|
|
6449
|
-
} else if (curPipelineIndex == 7) {
|
|
6450
|
-
pass.setBindGroup(1, polyPtsBindGroup);
|
|
6451
6408
|
} else if ($._customBindHandlers[curPipelineIndex]) {
|
|
6452
6409
|
$._customBindHandlers[curPipelineIndex](pass);
|
|
6453
6410
|
}
|
|
6454
6411
|
}
|
|
6455
6412
|
|
|
6456
|
-
if (curPipelineIndex ==
|
|
6457
|
-
// draw a polygon
|
|
6458
|
-
pass.draw(v, 1, polygonVertOffset, 0);
|
|
6459
|
-
polygonVertOffset += v;
|
|
6460
|
-
} else if (curPipelineIndex == 6) {
|
|
6413
|
+
if (curPipelineIndex == 6) {
|
|
6461
6414
|
// draw an ellipse
|
|
6462
6415
|
pass.drawIndexed(18, v, 0, 0, ellipseIdx);
|
|
6463
6416
|
ellipseIdx += v;
|
|
@@ -6534,8 +6487,6 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
6534
6487
|
|
|
6535
6488
|
// reset
|
|
6536
6489
|
shapesVertIdx = 0;
|
|
6537
|
-
polygonVertIdx = 0;
|
|
6538
|
-
polyPtsIdx = 0;
|
|
6539
6490
|
imgVertIdx = 0;
|
|
6540
6491
|
// Remove video frames without creating new array
|
|
6541
6492
|
if (vidFrames > 0) {
|
|
@@ -6659,15 +6610,11 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
6659
6610
|
shapesVertIdx = i;
|
|
6660
6611
|
};
|
|
6661
6612
|
|
|
6662
|
-
let _strokeCap = '
|
|
6663
|
-
_strokeJoin = '
|
|
6613
|
+
let _strokeCap = 'butt', // SQUARE
|
|
6614
|
+
_strokeJoin = 'miter';
|
|
6664
6615
|
|
|
6665
6616
|
$.strokeCap = (x) => (_strokeCap = x);
|
|
6666
6617
|
$.strokeJoin = (x) => (_strokeJoin = x);
|
|
6667
|
-
$.lineMode = () => {
|
|
6668
|
-
_strokeCap = 'square';
|
|
6669
|
-
_strokeJoin = 'none';
|
|
6670
|
-
};
|
|
6671
6618
|
|
|
6672
6619
|
let curveSegments = 20;
|
|
6673
6620
|
$.curveDetail = (v) => (curveSegments = v);
|
|
@@ -6738,266 +6685,6 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
6738
6685
|
|
|
6739
6686
|
$.quadraticVertex = (cx, cy, x, y) => $.bezierVertex(cx, cy, x, y);
|
|
6740
6687
|
|
|
6741
|
-
function addQuad(x1, y1, x2, y2, x3, y3, x4, y4, ci, ti) {
|
|
6742
|
-
addVert(x1, y1, ci, ti); // v0
|
|
6743
|
-
addVert(x2, y2, ci, ti); // v1
|
|
6744
|
-
addVert(x4, y4, ci, ti); // v3
|
|
6745
|
-
addVert(x3, y3, ci, ti); // v2
|
|
6746
|
-
drawStack.push(shapesPL, 4);
|
|
6747
|
-
}
|
|
6748
|
-
|
|
6749
|
-
$.plane = (x, y, w, h) => {
|
|
6750
|
-
h ??= w;
|
|
6751
|
-
let [l, r, t, b] = calcBox(x, y, w, h, 'center');
|
|
6752
|
-
if (matrixDirty) saveMatrix();
|
|
6753
|
-
addQuad(l, t, r, t, r, b, l, b, fillIdx, matrixIdx);
|
|
6754
|
-
};
|
|
6755
|
-
|
|
6756
|
-
$.curve = (x1, y1, x2, y2, x3, y3, x4, y4) => {
|
|
6757
|
-
$.beginShape();
|
|
6758
|
-
$.curveVertex(x1, y1);
|
|
6759
|
-
$.curveVertex(x2, y2);
|
|
6760
|
-
$.curveVertex(x3, y3);
|
|
6761
|
-
$.curveVertex(x4, y4);
|
|
6762
|
-
$.endShape();
|
|
6763
|
-
};
|
|
6764
|
-
|
|
6765
|
-
$.bezier = (x1, y1, x2, y2, x3, y3, x4, y4) => {
|
|
6766
|
-
$.beginShape();
|
|
6767
|
-
$.vertex(x1, y1);
|
|
6768
|
-
$.bezierVertex(x2, y2, x3, y3, x4, y4);
|
|
6769
|
-
$.endShape();
|
|
6770
|
-
};
|
|
6771
|
-
|
|
6772
|
-
/* POLYGONS */
|
|
6773
|
-
|
|
6774
|
-
let polygonPL = 7;
|
|
6775
|
-
|
|
6776
|
-
$._polygonShaderCode =
|
|
6777
|
-
$._baseShaderCode +
|
|
6778
|
-
/* wgsl */ `
|
|
6779
|
-
struct VertexParams {
|
|
6780
|
-
@builtin(vertex_index) vertexIndex : u32,
|
|
6781
|
-
@location(0) pos: vec2f,
|
|
6782
|
-
@location(1) polyStart: f32,
|
|
6783
|
-
@location(2) polyCount: f32,
|
|
6784
|
-
@location(3) fillIndex: f32,
|
|
6785
|
-
@location(4) strokeIndex: f32,
|
|
6786
|
-
@location(5) strokeWeight: f32,
|
|
6787
|
-
@location(6) matrixIndex: f32
|
|
6788
|
-
}
|
|
6789
|
-
|
|
6790
|
-
struct FragParams {
|
|
6791
|
-
@builtin(position) position: vec4f,
|
|
6792
|
-
@location(0) localPos: vec2f,
|
|
6793
|
-
@location(1) @interpolate(flat) polyStart: u32,
|
|
6794
|
-
@location(2) @interpolate(flat) polyCount: u32,
|
|
6795
|
-
@location(3) @interpolate(flat) fillIndex: f32,
|
|
6796
|
-
@location(4) @interpolate(flat) strokeIndex: f32,
|
|
6797
|
-
@location(5) @interpolate(flat) strokeWeight: f32,
|
|
6798
|
-
@location(6) @interpolate(flat) isClosed: f32
|
|
6799
|
-
}
|
|
6800
|
-
|
|
6801
|
-
@group(0) @binding(0) var<uniform> q: Q5;
|
|
6802
|
-
@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
|
|
6803
|
-
@group(0) @binding(2) var<storage> colors : array<vec4f>;
|
|
6804
|
-
|
|
6805
|
-
@group(1) @binding(0) var<storage, read> polyPts: array<vec4f>;
|
|
6806
|
-
|
|
6807
|
-
fn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {
|
|
6808
|
-
var vert = vec4f(pos, 0.0, 1.0);
|
|
6809
|
-
vert = transforms[i32(matrixIndex)] * vert;
|
|
6810
|
-
vert.x /= q.halfWidth;
|
|
6811
|
-
vert.y /= q.halfHeight;
|
|
6812
|
-
return vert;
|
|
6813
|
-
}
|
|
6814
|
-
|
|
6815
|
-
fn getPolyColor(p: vec2f, start: u32, count: u32, fIdx: f32) -> vec4f {
|
|
6816
|
-
let uniformColor = colors[i32(fIdx)];
|
|
6817
|
-
if (uniformColor.a == 0.0) {
|
|
6818
|
-
return uniformColor;
|
|
6819
|
-
}
|
|
6820
|
-
|
|
6821
|
-
var sumWeight: f32 = 0.0;
|
|
6822
|
-
var sumColor = vec4f(0.0);
|
|
6823
|
-
for (var i: u32 = 0u; i < count; i = i + 1u) {
|
|
6824
|
-
let pt = polyPts[start + i];
|
|
6825
|
-
let d = distance(p, pt.xy);
|
|
6826
|
-
if (d < 0.1) {
|
|
6827
|
-
return colors[i32(pt.z)];
|
|
6828
|
-
}
|
|
6829
|
-
let w = 1.0 / (d * d * d);
|
|
6830
|
-
sumWeight += w;
|
|
6831
|
-
sumColor += colors[i32(pt.z)] * w;
|
|
6832
|
-
}
|
|
6833
|
-
return sumColor / sumWeight;
|
|
6834
|
-
}
|
|
6835
|
-
|
|
6836
|
-
fn sdPolygon(p: vec2f, start: u32, count: u32, isClosed: f32) -> f32 {
|
|
6837
|
-
var d: f32 = dot(p - polyPts[start].xy, p - polyPts[start].xy);
|
|
6838
|
-
var s: f32 = 1.0;
|
|
6839
|
-
var j: u32 = count - 1u;
|
|
6840
|
-
for (var i: u32 = 0u; i < count; i = i + 1u) {
|
|
6841
|
-
let vi = polyPts[start + i].xy;
|
|
6842
|
-
let vj = polyPts[start + j].xy;
|
|
6843
|
-
let e = vj - vi;
|
|
6844
|
-
let w = p - vi;
|
|
6845
|
-
let b = w - e * clamp(dot(w, e) / dot(e, e), 0.0, 1.0);
|
|
6846
|
-
let bSq = dot(b, b);
|
|
6847
|
-
if (isClosed != 0.0 || i != 0u) {
|
|
6848
|
-
if (bSq < d) { d = bSq; }
|
|
6849
|
-
}
|
|
6850
|
-
|
|
6851
|
-
let condX = p.y >= vi.y;
|
|
6852
|
-
let condY = p.y < vj.y;
|
|
6853
|
-
let condZ = e.x * w.y > e.y * w.x;
|
|
6854
|
-
if ((condX && condY && condZ) || (!condX && !condY && !condZ)) {
|
|
6855
|
-
s = -s;
|
|
6856
|
-
}
|
|
6857
|
-
j = i;
|
|
6858
|
-
}
|
|
6859
|
-
if (isClosed == 0.0) {
|
|
6860
|
-
return sqrt(d);
|
|
6861
|
-
}
|
|
6862
|
-
return s * sqrt(d);
|
|
6863
|
-
}
|
|
6864
|
-
|
|
6865
|
-
@vertex
|
|
6866
|
-
fn vertexMain(v: VertexParams) -> FragParams {
|
|
6867
|
-
var f: FragParams;
|
|
6868
|
-
|
|
6869
|
-
// manually apply transform
|
|
6870
|
-
var vert = vec4f(v.pos, 0.0, 1.0);
|
|
6871
|
-
vert = transforms[i32(v.matrixIndex)] * vert;
|
|
6872
|
-
vert.x /= q.halfWidth;
|
|
6873
|
-
vert.y /= q.halfHeight;
|
|
6874
|
-
|
|
6875
|
-
f.position = vert;
|
|
6876
|
-
f.localPos = v.pos;
|
|
6877
|
-
f.polyStart = u32(v.polyStart + 0.1);
|
|
6878
|
-
f.polyCount = u32(abs(v.polyCount) + 0.1);
|
|
6879
|
-
f.isClosed = step(0.0, v.polyCount);
|
|
6880
|
-
f.fillIndex = v.fillIndex;
|
|
6881
|
-
f.strokeIndex = v.strokeIndex;
|
|
6882
|
-
f.strokeWeight = v.strokeWeight;
|
|
6883
|
-
return f;
|
|
6884
|
-
}
|
|
6885
|
-
|
|
6886
|
-
@fragment
|
|
6887
|
-
fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
6888
|
-
let fill = getPolyColor(f.localPos, f.polyStart, f.polyCount, f.fillIndex);
|
|
6889
|
-
let stroke = colors[i32(f.strokeIndex)];
|
|
6890
|
-
|
|
6891
|
-
// f.isClosed is derived from the sign of v.polyCount (used for fill closure)
|
|
6892
|
-
let distFill = sdPolygon(f.localPos, f.polyStart, f.polyCount, f.isClosed);
|
|
6893
|
-
|
|
6894
|
-
// encode stroke-closure in the sign of strokeWeight; use absolute stroke weight for width
|
|
6895
|
-
let isClosedStroke = step(0.0, f.strokeWeight);
|
|
6896
|
-
let strokeW = abs(f.strokeWeight);
|
|
6897
|
-
let distStroke = sdPolygon(f.localPos, f.polyStart, f.polyCount, isClosedStroke);
|
|
6898
|
-
|
|
6899
|
-
// compute AA using gradients from both distances (conservative)
|
|
6900
|
-
let dpdx_fill = dpdx(distFill);
|
|
6901
|
-
let dpdy_fill = dpdy(distFill);
|
|
6902
|
-
let gradFill = sqrt(dpdx_fill * dpdx_fill + dpdy_fill * dpdy_fill);
|
|
6903
|
-
|
|
6904
|
-
let dpdx_stroke = dpdx(distStroke);
|
|
6905
|
-
let dpdy_stroke = dpdy(distStroke);
|
|
6906
|
-
let gradStroke = sqrt(dpdx_stroke * dpdx_stroke + dpdy_stroke * dpdy_stroke);
|
|
6907
|
-
|
|
6908
|
-
let aa = clamp(max(gradFill, gradStroke) * 1.5, 0.001, 2.0);
|
|
6909
|
-
|
|
6910
|
-
let halfStroke = strokeW * 0.5;
|
|
6911
|
-
|
|
6912
|
-
var outFragColor: vec4f;
|
|
6913
|
-
|
|
6914
|
-
if (fill.a != 0.0 && strokeW == 0.0) {
|
|
6915
|
-
let fillAlpha = 1.0 - smoothstep(-aa, aa, distFill);
|
|
6916
|
-
if (fillAlpha <= 0.0) { discard; }
|
|
6917
|
-
outFragColor = vec4f(fill.rgb, fill.a * fillAlpha);
|
|
6918
|
-
} else if (fill.a != 0.0) {
|
|
6919
|
-
let fillAlpha = 1.0 - smoothstep(-aa, aa, distFill);
|
|
6920
|
-
let strokeDist = abs(distStroke) - halfStroke;
|
|
6921
|
-
let strokeAlphaMask = 1.0 - smoothstep(-aa, aa, strokeDist);
|
|
6922
|
-
|
|
6923
|
-
if (fillAlpha <= 0.0 && strokeAlphaMask <= 0.0) { discard; }
|
|
6924
|
-
|
|
6925
|
-
let sA = stroke.a * strokeAlphaMask;
|
|
6926
|
-
let fA = fill.a * fillAlpha;
|
|
6927
|
-
let outAlpha = sA + fA * (1.0 - sA);
|
|
6928
|
-
let outCol = stroke.rgb * sA + fill.rgb * fA * (1.0 - sA);
|
|
6929
|
-
outFragColor = vec4f(outCol / max(outAlpha, 1e-5), outAlpha);
|
|
6930
|
-
} else {
|
|
6931
|
-
let strokeDist = abs(distStroke) - halfStroke;
|
|
6932
|
-
let strokeAlpha = 1.0 - smoothstep(-aa, aa, strokeDist);
|
|
6933
|
-
|
|
6934
|
-
if (strokeAlpha <= 0.0) { discard; }
|
|
6935
|
-
outFragColor = vec4f(stroke.rgb, stroke.a * strokeAlpha);
|
|
6936
|
-
}
|
|
6937
|
-
return outFragColor;
|
|
6938
|
-
}
|
|
6939
|
-
`;
|
|
6940
|
-
|
|
6941
|
-
let polygonShader = Q5.device.createShaderModule({
|
|
6942
|
-
label: 'polygonShader',
|
|
6943
|
-
code: $._polygonShaderCode
|
|
6944
|
-
});
|
|
6945
|
-
|
|
6946
|
-
let polygonVertStack = new Float32Array($._isGraphics ? 1000 : 1e7),
|
|
6947
|
-
polygonVertIdx = 0;
|
|
6948
|
-
let polyPtsStack = new Float32Array($._isGraphics ? 1000 : 1e7),
|
|
6949
|
-
polyPtsIdx = 0;
|
|
6950
|
-
|
|
6951
|
-
let polygonVertBuffLayout = {
|
|
6952
|
-
arrayStride: 32, // 8 floats * 4 bytes
|
|
6953
|
-
attributes: [
|
|
6954
|
-
{ format: 'float32x2', offset: 0, shaderLocation: 0 },
|
|
6955
|
-
{ format: 'float32', offset: 8, shaderLocation: 1 },
|
|
6956
|
-
{ format: 'float32', offset: 12, shaderLocation: 2 },
|
|
6957
|
-
{ format: 'float32', offset: 16, shaderLocation: 3 },
|
|
6958
|
-
{ format: 'float32', offset: 20, shaderLocation: 4 },
|
|
6959
|
-
{ format: 'float32', offset: 24, shaderLocation: 5 },
|
|
6960
|
-
{ format: 'float32', offset: 28, shaderLocation: 6 }
|
|
6961
|
-
]
|
|
6962
|
-
};
|
|
6963
|
-
|
|
6964
|
-
let polygonBindGroupLayout = Q5.device.createBindGroupLayout({
|
|
6965
|
-
entries: [{ binding: 0, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'read-only-storage' } }]
|
|
6966
|
-
});
|
|
6967
|
-
|
|
6968
|
-
let polygonPipelineLayout = Q5.device.createPipelineLayout({
|
|
6969
|
-
label: 'polygonPipelineLayout',
|
|
6970
|
-
bindGroupLayouts: [mainLayout, polygonBindGroupLayout]
|
|
6971
|
-
});
|
|
6972
|
-
|
|
6973
|
-
$._pipelineConfigs[7] = {
|
|
6974
|
-
label: 'polygonPipeline',
|
|
6975
|
-
layout: polygonPipelineLayout,
|
|
6976
|
-
vertex: { module: polygonShader, entryPoint: 'vertexMain', buffers: [null, null, polygonVertBuffLayout] },
|
|
6977
|
-
fragment: {
|
|
6978
|
-
module: polygonShader,
|
|
6979
|
-
entryPoint: 'fragMain',
|
|
6980
|
-
targets: [{ format: 'bgra8unorm', blend: $.blendConfigs['source-over'] }]
|
|
6981
|
-
},
|
|
6982
|
-
primitive: { topology: 'triangle-list' },
|
|
6983
|
-
multisample: { count: 4 }
|
|
6984
|
-
};
|
|
6985
|
-
$._pipelines[7] = Q5.device.createRenderPipeline($._pipelineConfigs[7]);
|
|
6986
|
-
|
|
6987
|
-
const addPolygonVert = (x, y, start, count, fIdx, sIdx, sWeight, mIdx) => {
|
|
6988
|
-
let v = polygonVertStack,
|
|
6989
|
-
i = polygonVertIdx;
|
|
6990
|
-
v[i++] = x;
|
|
6991
|
-
v[i++] = y;
|
|
6992
|
-
v[i++] = start;
|
|
6993
|
-
v[i++] = count;
|
|
6994
|
-
v[i++] = fIdx;
|
|
6995
|
-
v[i++] = sIdx;
|
|
6996
|
-
v[i++] = sWeight;
|
|
6997
|
-
v[i++] = mIdx;
|
|
6998
|
-
polygonVertIdx = i;
|
|
6999
|
-
};
|
|
7000
|
-
|
|
7001
6688
|
$.endShape = (close) => {
|
|
7002
6689
|
if (curveVertices.length > 0) {
|
|
7003
6690
|
let points = [...curveVertices];
|
|
@@ -7054,98 +6741,185 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
7054
6741
|
if (matrixDirty) saveMatrix();
|
|
7055
6742
|
let ti = matrixIdx;
|
|
7056
6743
|
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
let isClosedForStroke = false;
|
|
7060
|
-
let firstX = sv[0],
|
|
7061
|
-
firstY = sv[1];
|
|
7062
|
-
let lastX = sv[(shapeVertCount - 1) * 3],
|
|
7063
|
-
lastY = sv[(shapeVertCount - 1) * 3 + 1];
|
|
7064
|
-
|
|
7065
|
-
if (firstX === lastX && firstY === lastY) {
|
|
7066
|
-
isClosedPath = true;
|
|
7067
|
-
isClosedForStroke = true;
|
|
7068
|
-
} else if (close || doFill) {
|
|
7069
|
-
sv.push(firstX, firstY, sv[2]);
|
|
6744
|
+
if (doFill) {
|
|
6745
|
+
sv.push(sv[0], sv[1], sv[2]);
|
|
7070
6746
|
shapeVertCount++;
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
6747
|
+
|
|
6748
|
+
if (shapeVertCount == 5) {
|
|
6749
|
+
// Quads
|
|
6750
|
+
addVert(sv[0], sv[1], sv[2], ti);
|
|
6751
|
+
addVert(sv[3], sv[4], sv[5], ti);
|
|
6752
|
+
addVert(sv[9], sv[10], sv[11], ti);
|
|
6753
|
+
addVert(sv[6], sv[7], sv[8], ti);
|
|
6754
|
+
drawStack.push(shapesPL, 4);
|
|
6755
|
+
} else {
|
|
6756
|
+
// Triangulation fan
|
|
6757
|
+
for (let i = 1; i < shapeVertCount - 1; i++) {
|
|
6758
|
+
let v0 = 0,
|
|
6759
|
+
v1 = i * 3,
|
|
6760
|
+
v2 = (i + 1) * 3;
|
|
6761
|
+
addVert(sv[v0], sv[v0 + 1], sv[v0 + 2], ti);
|
|
6762
|
+
addVert(sv[v1], sv[v1 + 1], sv[v1 + 2], ti);
|
|
6763
|
+
addVert(sv[v2], sv[v2 + 1], sv[v2 + 2], ti);
|
|
6764
|
+
}
|
|
6765
|
+
drawStack.push(shapesPL, (shapeVertCount - 2) * 3);
|
|
6766
|
+
}
|
|
7074
6767
|
}
|
|
7075
6768
|
|
|
7076
|
-
|
|
6769
|
+
if (doStroke && sw > 0) {
|
|
6770
|
+
let numSegments = shapeVertCount - 1;
|
|
6771
|
+
if (!close && doFill) numSegments--;
|
|
7077
6772
|
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
6773
|
+
if (_strokeJoin == 'round' || hswScaled < 2) {
|
|
6774
|
+
for (let i = 0; i < numSegments; i++) {
|
|
6775
|
+
let p0x = sv[i * 3],
|
|
6776
|
+
p0y = sv[i * 3 + 1],
|
|
6777
|
+
p1x = sv[(i + 1) * 3],
|
|
6778
|
+
p1y = sv[(i + 1) * 3 + 1];
|
|
7081
6779
|
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
for (let i = 0; i < polyCount; i++) {
|
|
7085
|
-
polyPtsStack[polyPtsIdx++] = sv[i * 3];
|
|
7086
|
-
polyPtsStack[polyPtsIdx++] = sv[i * 3 + 1];
|
|
7087
|
-
polyPtsStack[polyPtsIdx++] = sv[i * 3 + 2];
|
|
7088
|
-
polyPtsStack[polyPtsIdx++] = ti;
|
|
7089
|
-
}
|
|
6780
|
+
// Skip zero-length segments
|
|
6781
|
+
if (p0x === p1x && p0y === p1y) continue;
|
|
7090
6782
|
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
for (let i = 0; i < shapeVertCount; i++) {
|
|
7096
|
-
let vx = sv[i * 3],
|
|
7097
|
-
vy = sv[i * 3 + 1];
|
|
7098
|
-
if (vx < minX) minX = vx;
|
|
7099
|
-
if (vx > maxX) maxX = vx;
|
|
7100
|
-
if (vy < minY) minY = vy;
|
|
7101
|
-
if (vy > maxY) maxY = vy;
|
|
7102
|
-
}
|
|
7103
|
-
let padding = sw * 0.5 + 1.0; // padding for stroke and AA
|
|
7104
|
-
minX -= padding;
|
|
7105
|
-
minY -= padding;
|
|
7106
|
-
maxX += padding;
|
|
7107
|
-
maxY += padding;
|
|
7108
|
-
|
|
7109
|
-
// single SDF pass: encode fill-closure in polyCount sign, stroke-closure in strokeWeight sign
|
|
7110
|
-
let passedCount = doFill ? polyCount : -polyCount;
|
|
7111
|
-
let strokeWeightSigned = isClosedForStroke ? sw : -sw;
|
|
7112
|
-
addPolygonVert(minX, minY, polyStart, passedCount, fi, si, strokeWeightSigned, ti);
|
|
7113
|
-
addPolygonVert(maxX, minY, polyStart, passedCount, fi, si, strokeWeightSigned, ti);
|
|
7114
|
-
addPolygonVert(minX, maxY, polyStart, passedCount, fi, si, strokeWeightSigned, ti);
|
|
7115
|
-
|
|
7116
|
-
addPolygonVert(maxX, minY, polyStart, passedCount, fi, si, strokeWeightSigned, ti);
|
|
7117
|
-
addPolygonVert(maxX, maxY, polyStart, passedCount, fi, si, strokeWeightSigned, ti);
|
|
7118
|
-
addPolygonVert(minX, maxY, polyStart, passedCount, fi, si, strokeWeightSigned, ti);
|
|
7119
|
-
|
|
7120
|
-
drawStack.push(polygonPL, 6);
|
|
7121
|
-
} else {
|
|
7122
|
-
if (doFill) {
|
|
7123
|
-
if (shapeVertCount == 5) {
|
|
7124
|
-
// Quads
|
|
7125
|
-
addVert(sv[0], sv[1], sv[2], ti);
|
|
7126
|
-
addVert(sv[3], sv[4], sv[5], ti);
|
|
7127
|
-
addVert(sv[9], sv[10], sv[11], ti);
|
|
7128
|
-
addVert(sv[6], sv[7], sv[8], ti);
|
|
7129
|
-
drawStack.push(shapesPL, 4);
|
|
7130
|
-
} else {
|
|
7131
|
-
// Triangulation fan
|
|
7132
|
-
for (let i = 1; i < shapeVertCount - 1; i++) {
|
|
7133
|
-
let v0 = 0,
|
|
7134
|
-
v1 = i * 3,
|
|
7135
|
-
v2 = (i + 1) * 3;
|
|
7136
|
-
addVert(sv[v0], sv[v0 + 1], sv[v0 + 2], ti);
|
|
7137
|
-
addVert(sv[v1], sv[v1 + 1], sv[v1 + 2], ti);
|
|
7138
|
-
addVert(sv[v2], sv[v2 + 1], sv[v2 + 2], ti);
|
|
6783
|
+
if (hswScaled < 2) {
|
|
6784
|
+
$.line(p0x, p0y, p1x, p1y);
|
|
6785
|
+
} else {
|
|
6786
|
+
addCapsule(p0x, p0y, p1x, p1y, sw * 0.5, 0, strokeIdx);
|
|
7139
6787
|
}
|
|
7140
|
-
drawStack.push(shapesPL, (shapeVertCount - 2) * 3);
|
|
7141
6788
|
}
|
|
7142
|
-
}
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
for (let i = 0; i <
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
6789
|
+
} else {
|
|
6790
|
+
let cx = 0,
|
|
6791
|
+
cy = 0;
|
|
6792
|
+
for (let i = 0; i < shapeVertCount - 1; i++) {
|
|
6793
|
+
cx += sv[i * 3];
|
|
6794
|
+
cy += sv[i * 3 + 1];
|
|
6795
|
+
}
|
|
6796
|
+
cx /= Math.max(1, shapeVertCount - 1);
|
|
6797
|
+
cy /= Math.max(1, shapeVertCount - 1);
|
|
6798
|
+
|
|
6799
|
+
let signedArea = 0,
|
|
6800
|
+
sign = 1;
|
|
6801
|
+
for (let i = 0; i < shapeVertCount - 1; i++) {
|
|
6802
|
+
let j = i + 1;
|
|
6803
|
+
signedArea += sv[i * 3] * sv[j * 3 + 1] - sv[j * 3] * sv[i * 3 + 1];
|
|
6804
|
+
}
|
|
6805
|
+
sign = signedArea < 0 ? -1 : 1;
|
|
6806
|
+
|
|
6807
|
+
let strokeI = doStroke ? strokeIdx : 0,
|
|
6808
|
+
baseWeight = doStroke ? sw : 0,
|
|
6809
|
+
exp = baseWeight * 0.5;
|
|
6810
|
+
|
|
6811
|
+
// Compute quads on-the-fly per edge without storing per-vertex arrays/objects
|
|
6812
|
+
for (let i = 0; i < numSegments; i++) {
|
|
6813
|
+
let j = i + 1,
|
|
6814
|
+
iprev = i === 0 ? shapeVertCount - 2 : i - 1,
|
|
6815
|
+
inext = i === shapeVertCount - 1 ? 1 : i + 1,
|
|
6816
|
+
ivx = sv[i * 3],
|
|
6817
|
+
ivy = sv[i * 3 + 1],
|
|
6818
|
+
ipx = sv[iprev * 3],
|
|
6819
|
+
ipy = sv[iprev * 3 + 1],
|
|
6820
|
+
inx = sv[inext * 3],
|
|
6821
|
+
iny = sv[inext * 3 + 1],
|
|
6822
|
+
idir1x = ivx - ipx,
|
|
6823
|
+
idir1y = ivy - ipy,
|
|
6824
|
+
il1 = idir1x * idir1x + idir1y * idir1y;
|
|
6825
|
+
if (il1 <= 0) {
|
|
6826
|
+
idir1x = 1;
|
|
6827
|
+
idir1y = 0;
|
|
6828
|
+
} else {
|
|
6829
|
+
let iinv = 1.0 / Math.sqrt(il1);
|
|
6830
|
+
idir1x *= iinv;
|
|
6831
|
+
idir1y *= iinv;
|
|
6832
|
+
}
|
|
6833
|
+
let idir2x = inx - ivx,
|
|
6834
|
+
idir2y = iny - ivy,
|
|
6835
|
+
il2 = idir2x * idir2x + idir2y * idir2y;
|
|
6836
|
+
if (il2 <= 0) {
|
|
6837
|
+
idir2x = 1;
|
|
6838
|
+
idir2y = 0;
|
|
6839
|
+
} else {
|
|
6840
|
+
let iinv2 = 1.0 / Math.sqrt(il2);
|
|
6841
|
+
idir2x *= iinv2;
|
|
6842
|
+
idir2y *= iinv2;
|
|
6843
|
+
}
|
|
6844
|
+
let in1x = idir1y * sign,
|
|
6845
|
+
in1y = -idir1x * sign,
|
|
6846
|
+
in2x = idir2y * sign,
|
|
6847
|
+
in2y = -idir2x * sign,
|
|
6848
|
+
imx = in1x + in2x,
|
|
6849
|
+
imy = in1y + in2y,
|
|
6850
|
+
iml = imx * imx + imy * imy;
|
|
6851
|
+
if (iml < 1e-6) {
|
|
6852
|
+
imx = in1x;
|
|
6853
|
+
imy = in1y;
|
|
6854
|
+
} else {
|
|
6855
|
+
let iinvm = 1.0 / Math.sqrt(iml);
|
|
6856
|
+
imx *= iinvm;
|
|
6857
|
+
imy *= iinvm;
|
|
6858
|
+
}
|
|
6859
|
+
let imiterDot = imx * in2x + imy * in2y,
|
|
6860
|
+
imiterExpansion = imiterDot !== 0 ? exp / imiterDot : exp;
|
|
6861
|
+
if (imiterExpansion > exp * 3.0) imiterExpansion = exp * 3.0;
|
|
6862
|
+
let inner_ix = ivx - imx * imiterExpansion,
|
|
6863
|
+
inner_iy = ivy - imy * imiterExpansion,
|
|
6864
|
+
outer_ix = ivx + imx * imiterExpansion,
|
|
6865
|
+
outer_iy = ivy + imy * imiterExpansion;
|
|
6866
|
+
|
|
6867
|
+
// compute miter for vertex j
|
|
6868
|
+
let jprev = j === 0 ? shapeVertCount - 2 : j - 1,
|
|
6869
|
+
jnext = j === shapeVertCount - 1 ? 1 : j + 1,
|
|
6870
|
+
jvx = sv[j * 3],
|
|
6871
|
+
jvy = sv[j * 3 + 1],
|
|
6872
|
+
jpx = sv[jprev * 3],
|
|
6873
|
+
jpy = sv[jprev * 3 + 1],
|
|
6874
|
+
jnx = sv[jnext * 3],
|
|
6875
|
+
jny = sv[jnext * 3 + 1];
|
|
6876
|
+
|
|
6877
|
+
let jdir1x = jvx - jpx,
|
|
6878
|
+
jdir1y = jvy - jpy,
|
|
6879
|
+
jl1 = jdir1x * jdir1x + jdir1y * jdir1y;
|
|
6880
|
+
if (jl1 <= 0) {
|
|
6881
|
+
jdir1x = 1;
|
|
6882
|
+
jdir1y = 0;
|
|
6883
|
+
} else {
|
|
6884
|
+
let jinv = 1.0 / Math.sqrt(jl1);
|
|
6885
|
+
jdir1x *= jinv;
|
|
6886
|
+
jdir1y *= jinv;
|
|
6887
|
+
}
|
|
6888
|
+
let jdir2x = jnx - jvx,
|
|
6889
|
+
jdir2y = jny - jvy,
|
|
6890
|
+
jl2 = jdir2x * jdir2x + jdir2y * jdir2y;
|
|
6891
|
+
if (jl2 <= 0) {
|
|
6892
|
+
jdir2x = 1;
|
|
6893
|
+
jdir2y = 0;
|
|
6894
|
+
} else {
|
|
6895
|
+
let jinv2 = 1.0 / Math.sqrt(jl2);
|
|
6896
|
+
jdir2x *= jinv2;
|
|
6897
|
+
jdir2y *= jinv2;
|
|
6898
|
+
}
|
|
6899
|
+
let jn1x = jdir1y * sign,
|
|
6900
|
+
jn1y = -jdir1x * sign,
|
|
6901
|
+
jn2x = jdir2y * sign,
|
|
6902
|
+
jn2y = -jdir2x * sign,
|
|
6903
|
+
jmx = jn1x + jn2x,
|
|
6904
|
+
jmy = jn1y + jn2y,
|
|
6905
|
+
jml = jmx * jmx + jmy * jmy;
|
|
6906
|
+
if (jml < 1e-6) {
|
|
6907
|
+
jmx = jn1x;
|
|
6908
|
+
jmy = jn1y;
|
|
6909
|
+
} else {
|
|
6910
|
+
let jinvm = 1.0 / Math.sqrt(jml);
|
|
6911
|
+
jmx *= jinvm;
|
|
6912
|
+
jmy *= jinvm;
|
|
6913
|
+
}
|
|
6914
|
+
let jmiterDot = jmx * jn2x + jmy * jn2y,
|
|
6915
|
+
mExp = jmiterDot !== 0 ? exp / jmiterDot : exp;
|
|
6916
|
+
if (mExp > exp * 3.0) mExp = exp * 3.0;
|
|
6917
|
+
let inner_jx = jvx - jmx * mExp,
|
|
6918
|
+
inner_jy = jvy - jmy * mExp,
|
|
6919
|
+
outer_jx = jvx + jmx * mExp,
|
|
6920
|
+
outer_jy = jvy + jmy * mExp;
|
|
6921
|
+
|
|
6922
|
+
addQuad(inner_ix, inner_iy, inner_jx, inner_jy, outer_jx, outer_jy, outer_ix, outer_iy, strokeI, ti);
|
|
7149
6923
|
}
|
|
7150
6924
|
}
|
|
7151
6925
|
}
|
|
@@ -7172,6 +6946,37 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
7172
6946
|
$.endShape(true);
|
|
7173
6947
|
};
|
|
7174
6948
|
|
|
6949
|
+
$.curve = (x1, y1, x2, y2, x3, y3, x4, y4) => {
|
|
6950
|
+
$.beginShape();
|
|
6951
|
+
$.curveVertex(x1, y1);
|
|
6952
|
+
$.curveVertex(x2, y2);
|
|
6953
|
+
$.curveVertex(x3, y3);
|
|
6954
|
+
$.curveVertex(x4, y4);
|
|
6955
|
+
$.endShape();
|
|
6956
|
+
};
|
|
6957
|
+
|
|
6958
|
+
$.bezier = (x1, y1, x2, y2, x3, y3, x4, y4) => {
|
|
6959
|
+
$.beginShape();
|
|
6960
|
+
$.vertex(x1, y1);
|
|
6961
|
+
$.bezierVertex(x2, y2, x3, y3, x4, y4);
|
|
6962
|
+
$.endShape();
|
|
6963
|
+
};
|
|
6964
|
+
|
|
6965
|
+
function addQuad(x1, y1, x2, y2, x3, y3, x4, y4, ci, ti) {
|
|
6966
|
+
addVert(x1, y1, ci, ti); // v0
|
|
6967
|
+
addVert(x2, y2, ci, ti); // v1
|
|
6968
|
+
addVert(x4, y4, ci, ti); // v3
|
|
6969
|
+
addVert(x3, y3, ci, ti); // v2
|
|
6970
|
+
drawStack.push(shapesPL, 4);
|
|
6971
|
+
}
|
|
6972
|
+
|
|
6973
|
+
$.plane = (x, y, w, h) => {
|
|
6974
|
+
h ??= w;
|
|
6975
|
+
let [l, r, t, b] = calcBox(x, y, w, h, 'center');
|
|
6976
|
+
if (matrixDirty) saveMatrix();
|
|
6977
|
+
addQuad(l, t, r, t, r, b, l, b, fillIdx, matrixIdx);
|
|
6978
|
+
};
|
|
6979
|
+
|
|
7175
6980
|
/* RECT */
|
|
7176
6981
|
|
|
7177
6982
|
let rectPL = 5;
|
|
@@ -9121,8 +8926,6 @@ fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
|
9121
8926
|
transformsBuffer?.destroy();
|
|
9122
8927
|
colorsBuffer?.destroy();
|
|
9123
8928
|
shapesVertBuff?.destroy();
|
|
9124
|
-
polygonVertBuff?.destroy();
|
|
9125
|
-
polyPtsBuffer?.destroy();
|
|
9126
8929
|
imgVertBuff?.destroy();
|
|
9127
8930
|
charBuffer?.destroy();
|
|
9128
8931
|
textBuffer?.destroy();
|