ntk 7.6.0 → 7.6.1

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.
@@ -1106,10 +1106,23 @@ class RenderingContext2d {
1106
1106
  // a segment that is already at least r long
1107
1107
  if (dot >= 0 && r * r <= shortest) continue;
1108
1108
  const cross = ax * by - ay * bx;
1109
- // r·tan(φ/2) > min(|a|, |b|), squared. A non-positive denominator is
1110
- // the reversal the tangent is infinite at.
1111
- const denom = Math.sqrt(la * lb) + dot;
1112
- if (denom <= 0 || (r * cross) ** 2 > shortest * denom * denom) {
1109
+ // r·tan(φ/2) > min(|a|, |b|), squared. A non-positive denominator
1110
+ // is the reversal the tangent is infinite at — but near one the
1111
+ // denominator is pure cancellation (√(la·lb) and -dot agree to ~15
1112
+ // digits), so an exact double-back lands a few ulps to either side
1113
+ // of 0. The same-x bursts of issue #259 have cross exactly 0 too,
1114
+ // so when denom rounded positive neither test here fired and the
1115
+ // extruder met the reversal itself, normalizing a zero-length
1116
+ // tangent into NaN join vertices. Below its own noise floor denom
1117
+ // only means "within microradians of a reversal", where the true
1118
+ // tangent exceeds a million and no segment can hold the join: cut
1119
+ // unconditionally.
1120
+ const ab = Math.sqrt(la * lb);
1121
+ const denom = ab + dot;
1122
+ if (
1123
+ denom <= ab * 1e-12 ||
1124
+ (r * cross) ** 2 > shortest * denom * denom
1125
+ ) {
1113
1126
  (cuts ??= []).push(i);
1114
1127
  }
1115
1128
  }
@@ -1277,6 +1290,27 @@ class RenderingContext2d {
1277
1290
  for (const run of dashed.runs) extrudeRun(cleanRun(run), false);
1278
1291
  }
1279
1292
  }
1293
+ // Nothing non-finite may reach the server: FIXED encoding turns NaN
1294
+ // into 0, so one poisoned vertex renders as a wedge to the origin on a
1295
+ // real display — while the in-process server quietly drops it, which
1296
+ // is why no headless pixel test can see this for us (issue #259). The
1297
+ // cuts above are meant to keep the extruder off that path; this keeps
1298
+ // a future miss from being catastrophic. A sum is finite iff every
1299
+ // term is.
1300
+ let w = 0;
1301
+ for (let i = 0; i < tris.length; i += 6) {
1302
+ const sum =
1303
+ tris[i] +
1304
+ tris[i + 1] +
1305
+ tris[i + 2] +
1306
+ tris[i + 3] +
1307
+ tris[i + 4] +
1308
+ tris[i + 5];
1309
+ if (!Number.isFinite(sum)) continue;
1310
+ if (w < i) for (let k = 0; k < 6; k++) tris[w + k] = tris[i + k];
1311
+ w += 6;
1312
+ }
1313
+ if (w < tris.length) tris.length = w;
1280
1314
  if (!tris.length) return;
1281
1315
 
1282
1316
  const op = this._op();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ntk",
3
- "version": "7.6.0",
3
+ "version": "7.6.1",
4
4
  "description": "Desktop UI toolkit for X11 with canvas-like 2d and OpenGL rendering",
5
5
  "author": "Andrey Sidorov <sidorares@yandex.ru>",
6
6
  "license": "MIT",