@postermywall/fabricjs-2 6.4.1-pmw-22 → 6.4.2-pmw-22

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/index.js +123 -95
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.min.js +1 -1
  5. package/dist/index.min.js.map +1 -1
  6. package/dist/index.min.mjs +1 -1
  7. package/dist/index.min.mjs.map +1 -1
  8. package/dist/index.mjs +123 -95
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/index.node.cjs +123 -95
  11. package/dist/index.node.cjs.map +1 -1
  12. package/dist/index.node.mjs +123 -95
  13. package/dist/index.node.mjs.map +1 -1
  14. package/dist/package.json.min.mjs +1 -1
  15. package/dist/package.json.mjs +1 -1
  16. package/dist/src/canvas/DOMManagers/CanvasDOMManager.min.mjs +1 -1
  17. package/dist/src/canvas/DOMManagers/CanvasDOMManager.min.mjs.map +1 -1
  18. package/dist/src/canvas/DOMManagers/CanvasDOMManager.mjs +0 -1
  19. package/dist/src/canvas/DOMManagers/CanvasDOMManager.mjs.map +1 -1
  20. package/dist/src/canvas/SelectableCanvas.min.mjs +1 -1
  21. package/dist/src/canvas/SelectableCanvas.min.mjs.map +1 -1
  22. package/dist/src/canvas/SelectableCanvas.mjs +0 -1
  23. package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
  24. package/dist/src/config.d.ts +5 -1
  25. package/dist/src/config.d.ts.map +1 -1
  26. package/dist/src/config.min.mjs +1 -1
  27. package/dist/src/config.min.mjs.map +1 -1
  28. package/dist/src/config.mjs +6 -2
  29. package/dist/src/config.mjs.map +1 -1
  30. package/dist/src/parser/constants.d.ts +0 -1
  31. package/dist/src/parser/constants.d.ts.map +1 -1
  32. package/dist/src/parser/constants.min.mjs +1 -1
  33. package/dist/src/parser/constants.min.mjs.map +1 -1
  34. package/dist/src/parser/constants.mjs +1 -2
  35. package/dist/src/parser/constants.mjs.map +1 -1
  36. package/dist/src/shapes/Line.min.mjs +1 -1
  37. package/dist/src/shapes/Line.min.mjs.map +1 -1
  38. package/dist/src/shapes/Line.mjs +0 -1
  39. package/dist/src/shapes/Line.mjs.map +1 -1
  40. package/dist/src/shapes/Path.min.mjs +1 -1
  41. package/dist/src/shapes/Path.min.mjs.map +1 -1
  42. package/dist/src/shapes/Path.mjs +7 -1
  43. package/dist/src/shapes/Path.mjs.map +1 -1
  44. package/dist/src/shapes/Text/StyledText.min.mjs +1 -1
  45. package/dist/src/shapes/Text/StyledText.min.mjs.map +1 -1
  46. package/dist/src/shapes/Text/StyledText.mjs +0 -1
  47. package/dist/src/shapes/Text/StyledText.mjs.map +1 -1
  48. package/dist/src/util/misc/boundingBoxFromPoints.d.ts.map +1 -1
  49. package/dist/src/util/misc/boundingBoxFromPoints.min.mjs +1 -1
  50. package/dist/src/util/misc/boundingBoxFromPoints.min.mjs.map +1 -1
  51. package/dist/src/util/misc/boundingBoxFromPoints.mjs +17 -30
  52. package/dist/src/util/misc/boundingBoxFromPoints.mjs.map +1 -1
  53. package/dist/src/util/path/index.d.ts.map +1 -1
  54. package/dist/src/util/path/index.min.mjs +1 -1
  55. package/dist/src/util/path/index.min.mjs.map +1 -1
  56. package/dist/src/util/path/index.mjs +51 -47
  57. package/dist/src/util/path/index.mjs.map +1 -1
  58. package/dist/src/util/path/regex.d.ts +2 -1
  59. package/dist/src/util/path/regex.d.ts.map +1 -1
  60. package/dist/src/util/path/regex.min.mjs +1 -1
  61. package/dist/src/util/path/regex.min.mjs.map +1 -1
  62. package/dist/src/util/path/regex.mjs +41 -16
  63. package/dist/src/util/path/regex.mjs.map +1 -1
  64. package/dist/src/util/path/typedefs.d.ts +1 -0
  65. package/dist/src/util/path/typedefs.d.ts.map +1 -1
  66. package/dist-extensions/src/config.d.ts +5 -1
  67. package/dist-extensions/src/config.d.ts.map +1 -1
  68. package/dist-extensions/src/parser/constants.d.ts +0 -1
  69. package/dist-extensions/src/parser/constants.d.ts.map +1 -1
  70. package/dist-extensions/src/util/misc/boundingBoxFromPoints.d.ts.map +1 -1
  71. package/dist-extensions/src/util/path/index.d.ts.map +1 -1
  72. package/dist-extensions/src/util/path/regex.d.ts +2 -1
  73. package/dist-extensions/src/util/path/regex.d.ts.map +1 -1
  74. package/dist-extensions/src/util/path/typedefs.d.ts +1 -0
  75. package/dist-extensions/src/util/path/typedefs.d.ts.map +1 -1
  76. package/package.json +1 -1
  77. package/src/config.ts +6 -2
  78. package/src/parser/constants.ts +0 -2
  79. package/src/shapes/Path.ts +1 -1
  80. package/src/util/misc/boundingBoxFromPoints.ts +15 -24
  81. package/src/util/path/__snapshots__/index.spec.ts.snap +462 -0
  82. package/src/util/path/index.spec.ts +107 -1
  83. package/src/util/path/index.ts +56 -51
  84. package/src/util/path/regex.ts +29 -22
  85. package/src/util/path/typedefs.ts +22 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## [next]
4
4
 
5
+ ## [6.4.2]
6
+
7
+ - Fix(): path parsing performance [#10123](https://github.com/fabricjs/fabric.js/pull/10123)
8
+
5
9
  ## [6.4.1]
6
10
 
7
11
  - fix(): Package.json had wrong path to types for extensions [#10115](https://github.com/fabricjs/fabric.js/pull/10115)
package/dist/index.js CHANGED
@@ -179,9 +179,13 @@
179
179
  _defineProperty(this, "forceGLPutImageData", false);
180
180
  /**
181
181
  * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better
182
- * @default true
182
+ * With the standard behaviour of fabric to translate all curves in absolute commands and by not subtracting the starting point from
183
+ * the curve is very hard to hit any cache.
184
+ * Enable only if you know why it could be useful.
185
+ * Candidate for removal/simplification
186
+ * @default false
183
187
  */
184
- _defineProperty(this, "cachesBoundsOfCurve", true);
188
+ _defineProperty(this, "cachesBoundsOfCurve", false);
185
189
  /**
186
190
  * Map of font files
187
191
  * Map<fontFamily, pathToFile> of font files
@@ -424,7 +428,7 @@
424
428
  }
425
429
  const cache = new Cache();
426
430
 
427
- var version = "6.4.1-pmw-22";
431
+ var version = "6.4.2-pmw-22";
428
432
 
429
433
  // use this syntax so babel plugin see this import here
430
434
  const VERSION = version;
@@ -4318,36 +4322,25 @@
4318
4322
  * @return {Object} Object with left, top, width, height properties
4319
4323
  */
4320
4324
  const makeBoundingBoxFromPoints = points => {
4321
- if (points.length === 0) {
4322
- return {
4323
- left: 0,
4324
- top: 0,
4325
- width: 0,
4326
- height: 0
4327
- };
4325
+ let left = 0,
4326
+ top = 0,
4327
+ width = 0,
4328
+ height = 0;
4329
+ for (let i = 0, len = points.length; i < len; i++) {
4330
+ const {
4331
+ x,
4332
+ y
4333
+ } = points[i];
4334
+ if (x > width || !i) width = x;
4335
+ if (x < left || !i) left = x;
4336
+ if (y > height || !i) height = y;
4337
+ if (y < top || !i) top = y;
4328
4338
  }
4329
- const {
4330
- min,
4331
- max
4332
- } = points.reduce((_ref, curr) => {
4333
- let {
4334
- min,
4335
- max
4336
- } = _ref;
4337
- return {
4338
- min: min.min(curr),
4339
- max: max.max(curr)
4340
- };
4341
- }, {
4342
- min: new Point(points[0]),
4343
- max: new Point(points[0])
4344
- });
4345
- const size = max.subtract(min);
4346
4339
  return {
4347
- left: min.x,
4348
- top: min.y,
4349
- width: size.x,
4350
- height: size.y
4340
+ left,
4341
+ top,
4342
+ width: width - left,
4343
+ height: height - top
4351
4344
  };
4352
4345
  };
4353
4346
 
@@ -4846,10 +4839,9 @@
4846
4839
  return new RegExp('^(' + arr.join('|') + ')\\b', 'i');
4847
4840
  }
4848
4841
 
4849
- var _templateObject$2, _templateObject2$1;
4850
- const reNum = String.raw(_templateObject$2 || (_templateObject$2 = _taggedTemplateLiteral(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"], ["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"])));
4842
+ var _templateObject$1;
4843
+ const reNum = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"], ["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"])));
4851
4844
  const svgNS = 'http://www.w3.org/2000/svg';
4852
- String.raw(_templateObject2$1 || (_templateObject2$1 = _taggedTemplateLiteral(["(?:s+,?s*|,s*|$)"], ["(?:\\s+,?\\s*|,\\s*|$)"])));
4853
4845
  const reFontDeclaration = new RegExp('(normal|italic)?\\s*(normal|small-caps)?\\s*' + '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' + reNum + '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' + reNum + '))?\\s+(.*)');
4854
4846
  const svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', 'image', 'text'],
4855
4847
  svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],
@@ -10614,11 +10606,11 @@
10614
10606
  // replace annoying commas and arbitrary whitespace with single spaces
10615
10607
  .replace(/,/gi, ' ').replace(/\s+/gi, ' ');
10616
10608
 
10617
- var _templateObject$1, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
10609
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
10618
10610
 
10619
10611
  // == begin transform regexp
10620
10612
  const p$1 = "(".concat(reNum, ")");
10621
- const skewX = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(skewX)(", ")"], ["(skewX)\\(", "\\)"])), p$1);
10613
+ const skewX = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(skewX)(", ")"], ["(skewX)\\(", "\\)"])), p$1);
10622
10614
  const skewY = String.raw(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["(skewY)(", ")"], ["(skewY)\\(", "\\)"])), p$1);
10623
10615
  const rotate = String.raw(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["(rotate)(", "(?: ", " ", ")?)"], ["(rotate)\\(", "(?: ", " ", ")?\\)"])), p$1, p$1, p$1);
10624
10616
  const scale = String.raw(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["(scale)(", "(?: ", ")?)"], ["(scale)\\(", "(?: ", ")?\\)"])), p$1, p$1);
@@ -12255,24 +12247,50 @@
12255
12247
  */
12256
12248
  const findScaleToCover = (source, destination) => Math.max(destination.width / source.width, destination.height / source.height);
12257
12249
 
12258
- var _templateObject;
12250
+ const commaWsp = "\\s*,?\\s*";
12259
12251
 
12260
12252
  /**
12261
12253
  * p for param
12262
12254
  * using "bad naming" here because it makes the regex much easier to read
12255
+ * p is a number that is preceded by an arbitary number of spaces, maybe 0,
12256
+ * a comma or not, and then possibly more spaces or not.
12263
12257
  */
12264
- const p = "(".concat(reNum, ")");
12265
- const reMoveToCommand = "(M) (?:".concat(p, " ").concat(p, " ?)+");
12266
- const reLineCommand = "(L) (?:".concat(p, " ").concat(p, " ?)+");
12267
- const reHorizontalLineCommand = "(H) (?:".concat(p, " ?)+");
12268
- const reVerticalLineCommand = "(V) (?:".concat(p, " ?)+");
12269
- const reClosePathCommand = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(Z)s*"], ["(Z)\\s*"])));
12270
- const reCubicCurveCommand = "(C) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
12271
- const reCubicCurveShortcutCommand = "(S) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
12272
- const reQuadraticCurveCommand = "(Q) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
12273
- const reQuadraticCurveShortcutCommand = "(T) (?:".concat(p, " ").concat(p, " ?)+");
12274
- const reArcCommand = "(A) (?:".concat(p, " ").concat(p, " ").concat(p, " ([01]) ?([01]) ").concat(p, " ").concat(p, " ?)+");
12275
- const rePathCommand = "(?:(?:".concat(reMoveToCommand, ")") + "|(?:".concat(reLineCommand, ")") + "|(?:".concat(reHorizontalLineCommand, ")") + "|(?:".concat(reVerticalLineCommand, ")") + "|(?:".concat(reClosePathCommand, ")") + "|(?:".concat(reCubicCurveCommand, ")") + "|(?:".concat(reCubicCurveShortcutCommand, ")") + "|(?:".concat(reQuadraticCurveCommand, ")") + "|(?:".concat(reQuadraticCurveShortcutCommand, ")") + "|(?:".concat(reArcCommand, "))");
12258
+ const p = "".concat(commaWsp, "(").concat(reNum, ")");
12259
+
12260
+ // const reMoveToCommand = `(M) ?(?:${p}${p} ?)+`;
12261
+
12262
+ // const reLineCommand = `(L) ?(?:${p}${p} ?)+`;
12263
+
12264
+ // const reHorizontalLineCommand = `(H) ?(?:${p} ?)+`;
12265
+
12266
+ // const reVerticalLineCommand = `(V) ?(?:${p} ?)+`;
12267
+
12268
+ // const reClosePathCommand = String.raw`(Z)\s*`;
12269
+
12270
+ // const reCubicCurveCommand = `(C) ?(?:${p}${p}${p}${p}${p}${p} ?)+`;
12271
+
12272
+ // const reCubicCurveShortcutCommand = `(S) ?(?:${p}${p}${p}${p} ?)+`;
12273
+
12274
+ // const reQuadraticCurveCommand = `(Q) ?(?:${p}${p}${p}${p} ?)+`;
12275
+
12276
+ // const reQuadraticCurveShortcutCommand = `(T) ?(?:${p}${p} ?)+`;
12277
+
12278
+ const reArcCommandPoints = "".concat(p).concat(p).concat(p).concat(commaWsp, "([01])").concat(commaWsp, "([01])").concat(p).concat(p);
12279
+ // const reArcCommand = `(A) ?(?:${reArcCommandPoints} ?)+`;
12280
+
12281
+ // export const rePathCommandGroups =
12282
+ // `(?:(?:${reMoveToCommand})` +
12283
+ // `|(?:${reLineCommand})` +
12284
+ // `|(?:${reHorizontalLineCommand})` +
12285
+ // `|(?:${reVerticalLineCommand})` +
12286
+ // `|(?:${reClosePathCommand})` +
12287
+ // `|(?:${reCubicCurveCommand})` +
12288
+ // `|(?:${reCubicCurveShortcutCommand})` +
12289
+ // `|(?:${reQuadraticCurveCommand})` +
12290
+ // `|(?:${reQuadraticCurveShortcutCommand})` +
12291
+ // `|(?:${reArcCommand}))`;
12292
+
12293
+ const rePathCommand = '[mzlhvcsqta][^mzlhvcsqta]*';
12276
12294
 
12277
12295
  /**
12278
12296
  * Commands that may be repeated
@@ -12902,8 +12920,19 @@
12902
12920
  }
12903
12921
  };
12904
12922
  const rePathCmdAll = new RegExp(rePathCommand, 'gi');
12905
- const rePathCmd = new RegExp(rePathCommand, 'i');
12906
-
12923
+ const regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g');
12924
+ const reMyNum = new RegExp(reNum, 'gi');
12925
+ const commandLengths = {
12926
+ m: 2,
12927
+ l: 2,
12928
+ h: 1,
12929
+ v: 1,
12930
+ c: 6,
12931
+ s: 4,
12932
+ q: 4,
12933
+ t: 2,
12934
+ a: 7
12935
+ };
12907
12936
  /**
12908
12937
  *
12909
12938
  * @param {string} pathString
@@ -12916,52 +12945,45 @@
12916
12945
  * ];
12917
12946
  */
12918
12947
  const parsePath = pathString => {
12919
- // clean the string
12920
- // add spaces around the numbers
12921
- pathString = cleanupSvgAttribute(pathString);
12922
- const res = [];
12923
- for (let [matchStr] of pathString.matchAll(rePathCmdAll)) {
12924
- const chain = [];
12925
- let paramArr;
12926
- do {
12927
- paramArr = rePathCmd.exec(matchStr);
12928
- if (!paramArr) {
12929
- break;
12948
+ var _pathString$match;
12949
+ const chain = [];
12950
+ const all = (_pathString$match = pathString.match(rePathCmdAll)) !== null && _pathString$match !== void 0 ? _pathString$match : [];
12951
+ for (const matchStr of all) {
12952
+ // take match string and save the first letter as the command
12953
+ const commandLetter = matchStr[0];
12954
+ // in case of Z we have very little to do
12955
+ if (commandLetter === 'z' || commandLetter === 'Z') {
12956
+ chain.push([commandLetter]);
12957
+ continue;
12958
+ }
12959
+ const commandLength = commandLengths[commandLetter.toLowerCase()];
12960
+ let paramArr = [];
12961
+ if (commandLetter === 'a' || commandLetter === 'A') {
12962
+ // the arc command ha some peculariaties that requires a special regex other than numbers
12963
+ // it is possible to avoid using a space between the sweep and large arc flags, making them either
12964
+ // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum
12965
+ // reset the regexp
12966
+ regExpArcCommandPoints.lastIndex = 0;
12967
+ for (let out = null; out = regExpArcCommandPoints.exec(matchStr);) {
12968
+ paramArr.push(...out.slice(1));
12930
12969
  }
12931
- // ignore undefined match groups
12932
- const filteredGroups = paramArr.filter(g => g);
12933
- // remove the first element from the match array since it's just the whole command
12934
- filteredGroups.shift();
12935
- // if we can't parse the number, just interpret it as a string
12936
- // (since it's probably the path command)
12937
- const command = filteredGroups.map(g => {
12938
- const numParse = Number.parseFloat(g);
12939
- if (Number.isNaN(numParse)) {
12940
- return g;
12941
- } else {
12942
- return numParse;
12943
- }
12944
- });
12945
- chain.push(command);
12946
- // stop now if it's a z command
12947
- if (filteredGroups.length <= 1) {
12948
- break;
12970
+ } else {
12971
+ paramArr = matchStr.match(reMyNum) || [];
12972
+ }
12973
+
12974
+ // inspect the length of paramArr, if is longer than commandLength
12975
+ // we are dealing with repeated commands
12976
+ for (let i = 0; i < paramArr.length; i += commandLength) {
12977
+ const newCommand = new Array(commandLength);
12978
+ const transformedCommand = repeatedCommands[commandLetter];
12979
+ newCommand[0] = i > 0 && transformedCommand ? transformedCommand : commandLetter;
12980
+ for (let j = 0; j < commandLength; j++) {
12981
+ newCommand[j + 1] = parseFloat(paramArr[i + j]);
12949
12982
  }
12950
- // remove the last part of the chained command
12951
- filteredGroups.shift();
12952
- // ` ?` is to support commands with optional spaces between flags
12953
- matchStr = matchStr.replace(new RegExp("".concat(filteredGroups.join(' ?'), " ?$")), '');
12954
- } while (paramArr);
12955
- // add the chain, convert multiple m's to l's in the process
12956
- chain.reverse().forEach((c, idx) => {
12957
- const transformed = repeatedCommands[c[0]];
12958
- if (idx > 0 && (transformed == 'l' || transformed == 'L')) {
12959
- c[0] = transformed;
12960
- }
12961
- res.push(c);
12962
- });
12983
+ chain.push(newCommand);
12984
+ }
12963
12985
  }
12964
- return res;
12986
+ return chain;
12965
12987
  };
12966
12988
 
12967
12989
  /**
@@ -16934,7 +16956,13 @@
16934
16956
  // lineto, absolute
16935
16957
  x = command[1];
16936
16958
  y = command[2];
16937
- bounds.push(new Point(subpathStartX, subpathStartY), new Point(x, y));
16959
+ bounds.push({
16960
+ x: subpathStartX,
16961
+ y: subpathStartY
16962
+ }, {
16963
+ x,
16964
+ y
16965
+ });
16938
16966
  break;
16939
16967
  case 'M':
16940
16968
  // moveTo, absolute