fabric 6.4.1 → 6.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.
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
@@ -159,9 +159,13 @@ class BaseConfiguration {
159
159
  _defineProperty(this, "forceGLPutImageData", false);
160
160
  /**
161
161
  * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better
162
- * @default true
162
+ * With the standard behaviour of fabric to translate all curves in absolute commands and by not subtracting the starting point from
163
+ * the curve is very hard to hit any cache.
164
+ * Enable only if you know why it could be useful.
165
+ * Candidate for removal/simplification
166
+ * @default false
163
167
  */
164
- _defineProperty(this, "cachesBoundsOfCurve", true);
168
+ _defineProperty(this, "cachesBoundsOfCurve", false);
165
169
  /**
166
170
  * Map of font files
167
171
  * Map<fontFamily, pathToFile> of font files
@@ -457,7 +461,7 @@ class Cache {
457
461
  }
458
462
  const cache = new Cache();
459
463
 
460
- var version = "6.4.1";
464
+ var version = "6.4.2";
461
465
 
462
466
  // use this syntax so babel plugin see this import here
463
467
  const VERSION = version;
@@ -4341,36 +4345,25 @@ const stopEvent = e => {
4341
4345
  * @return {Object} Object with left, top, width, height properties
4342
4346
  */
4343
4347
  const makeBoundingBoxFromPoints = points => {
4344
- if (points.length === 0) {
4345
- return {
4346
- left: 0,
4347
- top: 0,
4348
- width: 0,
4349
- height: 0
4350
- };
4348
+ let left = 0,
4349
+ top = 0,
4350
+ width = 0,
4351
+ height = 0;
4352
+ for (let i = 0, len = points.length; i < len; i++) {
4353
+ const {
4354
+ x,
4355
+ y
4356
+ } = points[i];
4357
+ if (x > width || !i) width = x;
4358
+ if (x < left || !i) left = x;
4359
+ if (y > height || !i) height = y;
4360
+ if (y < top || !i) top = y;
4351
4361
  }
4352
- const {
4353
- min,
4354
- max
4355
- } = points.reduce((_ref, curr) => {
4356
- let {
4357
- min,
4358
- max
4359
- } = _ref;
4360
- return {
4361
- min: min.min(curr),
4362
- max: max.max(curr)
4363
- };
4364
- }, {
4365
- min: new Point(points[0]),
4366
- max: new Point(points[0])
4367
- });
4368
- const size = max.subtract(min);
4369
4362
  return {
4370
- left: min.x,
4371
- top: min.y,
4372
- width: size.x,
4373
- height: size.y
4363
+ left,
4364
+ top,
4365
+ width: width - left,
4366
+ height: height - top
4374
4367
  };
4375
4368
  };
4376
4369
 
@@ -4869,10 +4862,9 @@ function getSvgRegex(arr) {
4869
4862
  return new RegExp('^(' + arr.join('|') + ')\\b', 'i');
4870
4863
  }
4871
4864
 
4872
- var _templateObject$2, _templateObject2$1;
4873
- const reNum = String.raw(_templateObject$2 || (_templateObject$2 = _taggedTemplateLiteral(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"], ["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"])));
4865
+ var _templateObject$1;
4866
+ const reNum = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"], ["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"])));
4874
4867
  const svgNS = 'http://www.w3.org/2000/svg';
4875
- String.raw(_templateObject2$1 || (_templateObject2$1 = _taggedTemplateLiteral(["(?:s+,?s*|,s*|$)"], ["(?:\\s+,?\\s*|,\\s*|$)"])));
4876
4868
  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+(.*)');
4877
4869
  const svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', 'image', 'text'],
4878
4870
  svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],
@@ -10538,11 +10530,11 @@ const cleanupSvgAttribute = attributeValue => attributeValue.replace(regex$1, '
10538
10530
  // replace annoying commas and arbitrary whitespace with single spaces
10539
10531
  .replace(/,/gi, ' ').replace(/\s+/gi, ' ');
10540
10532
 
10541
- var _templateObject$1, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
10533
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
10542
10534
 
10543
10535
  // == begin transform regexp
10544
10536
  const p$1 = "(".concat(reNum, ")");
10545
- const skewX = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(skewX)(", ")"], ["(skewX)\\(", "\\)"])), p$1);
10537
+ const skewX = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(skewX)(", ")"], ["(skewX)\\(", "\\)"])), p$1);
10546
10538
  const skewY = String.raw(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["(skewY)(", ")"], ["(skewY)\\(", "\\)"])), p$1);
10547
10539
  const rotate = String.raw(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["(rotate)(", "(?: ", " ", ")?)"], ["(rotate)\\(", "(?: ", " ", ")?\\)"])), p$1, p$1, p$1);
10548
10540
  const scale = String.raw(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["(scale)(", "(?: ", ")?)"], ["(scale)\\(", "(?: ", ")?\\)"])), p$1, p$1);
@@ -11995,24 +11987,50 @@ const findScaleToFit = (source, destination) => Math.min(destination.width / sou
11995
11987
  */
11996
11988
  const findScaleToCover = (source, destination) => Math.max(destination.width / source.width, destination.height / source.height);
11997
11989
 
11998
- var _templateObject;
11990
+ const commaWsp = "\\s*,?\\s*";
11999
11991
 
12000
11992
  /**
12001
11993
  * p for param
12002
11994
  * using "bad naming" here because it makes the regex much easier to read
11995
+ * p is a number that is preceded by an arbitary number of spaces, maybe 0,
11996
+ * a comma or not, and then possibly more spaces or not.
12003
11997
  */
12004
- const p = "(".concat(reNum, ")");
12005
- const reMoveToCommand = "(M) (?:".concat(p, " ").concat(p, " ?)+");
12006
- const reLineCommand = "(L) (?:".concat(p, " ").concat(p, " ?)+");
12007
- const reHorizontalLineCommand = "(H) (?:".concat(p, " ?)+");
12008
- const reVerticalLineCommand = "(V) (?:".concat(p, " ?)+");
12009
- const reClosePathCommand = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(Z)s*"], ["(Z)\\s*"])));
12010
- const reCubicCurveCommand = "(C) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
12011
- const reCubicCurveShortcutCommand = "(S) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
12012
- const reQuadraticCurveCommand = "(Q) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
12013
- const reQuadraticCurveShortcutCommand = "(T) (?:".concat(p, " ").concat(p, " ?)+");
12014
- const reArcCommand = "(A) (?:".concat(p, " ").concat(p, " ").concat(p, " ([01]) ?([01]) ").concat(p, " ").concat(p, " ?)+");
12015
- const rePathCommand = "(?:(?:".concat(reMoveToCommand, ")") + "|(?:".concat(reLineCommand, ")") + "|(?:".concat(reHorizontalLineCommand, ")") + "|(?:".concat(reVerticalLineCommand, ")") + "|(?:".concat(reClosePathCommand, ")") + "|(?:".concat(reCubicCurveCommand, ")") + "|(?:".concat(reCubicCurveShortcutCommand, ")") + "|(?:".concat(reQuadraticCurveCommand, ")") + "|(?:".concat(reQuadraticCurveShortcutCommand, ")") + "|(?:".concat(reArcCommand, "))");
11998
+ const p = "".concat(commaWsp, "(").concat(reNum, ")");
11999
+
12000
+ // const reMoveToCommand = `(M) ?(?:${p}${p} ?)+`;
12001
+
12002
+ // const reLineCommand = `(L) ?(?:${p}${p} ?)+`;
12003
+
12004
+ // const reHorizontalLineCommand = `(H) ?(?:${p} ?)+`;
12005
+
12006
+ // const reVerticalLineCommand = `(V) ?(?:${p} ?)+`;
12007
+
12008
+ // const reClosePathCommand = String.raw`(Z)\s*`;
12009
+
12010
+ // const reCubicCurveCommand = `(C) ?(?:${p}${p}${p}${p}${p}${p} ?)+`;
12011
+
12012
+ // const reCubicCurveShortcutCommand = `(S) ?(?:${p}${p}${p}${p} ?)+`;
12013
+
12014
+ // const reQuadraticCurveCommand = `(Q) ?(?:${p}${p}${p}${p} ?)+`;
12015
+
12016
+ // const reQuadraticCurveShortcutCommand = `(T) ?(?:${p}${p} ?)+`;
12017
+
12018
+ const reArcCommandPoints = "".concat(p).concat(p).concat(p).concat(commaWsp, "([01])").concat(commaWsp, "([01])").concat(p).concat(p);
12019
+ // const reArcCommand = `(A) ?(?:${reArcCommandPoints} ?)+`;
12020
+
12021
+ // export const rePathCommandGroups =
12022
+ // `(?:(?:${reMoveToCommand})` +
12023
+ // `|(?:${reLineCommand})` +
12024
+ // `|(?:${reHorizontalLineCommand})` +
12025
+ // `|(?:${reVerticalLineCommand})` +
12026
+ // `|(?:${reClosePathCommand})` +
12027
+ // `|(?:${reCubicCurveCommand})` +
12028
+ // `|(?:${reCubicCurveShortcutCommand})` +
12029
+ // `|(?:${reQuadraticCurveCommand})` +
12030
+ // `|(?:${reQuadraticCurveShortcutCommand})` +
12031
+ // `|(?:${reArcCommand}))`;
12032
+
12033
+ const rePathCommand = '[mzlhvcsqta][^mzlhvcsqta]*';
12016
12034
 
12017
12035
  /**
12018
12036
  * Commands that may be repeated
@@ -12642,8 +12660,19 @@ const getPointOnPath = function (path, distance) {
12642
12660
  }
12643
12661
  };
12644
12662
  const rePathCmdAll = new RegExp(rePathCommand, 'gi');
12645
- const rePathCmd = new RegExp(rePathCommand, 'i');
12646
-
12663
+ const regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g');
12664
+ const reMyNum = new RegExp(reNum, 'gi');
12665
+ const commandLengths = {
12666
+ m: 2,
12667
+ l: 2,
12668
+ h: 1,
12669
+ v: 1,
12670
+ c: 6,
12671
+ s: 4,
12672
+ q: 4,
12673
+ t: 2,
12674
+ a: 7
12675
+ };
12647
12676
  /**
12648
12677
  *
12649
12678
  * @param {string} pathString
@@ -12656,52 +12685,45 @@ const rePathCmd = new RegExp(rePathCommand, 'i');
12656
12685
  * ];
12657
12686
  */
12658
12687
  const parsePath = pathString => {
12659
- // clean the string
12660
- // add spaces around the numbers
12661
- pathString = cleanupSvgAttribute(pathString);
12662
- const res = [];
12663
- for (let [matchStr] of pathString.matchAll(rePathCmdAll)) {
12664
- const chain = [];
12665
- let paramArr;
12666
- do {
12667
- paramArr = rePathCmd.exec(matchStr);
12668
- if (!paramArr) {
12669
- break;
12670
- }
12671
- // ignore undefined match groups
12672
- const filteredGroups = paramArr.filter(g => g);
12673
- // remove the first element from the match array since it's just the whole command
12674
- filteredGroups.shift();
12675
- // if we can't parse the number, just interpret it as a string
12676
- // (since it's probably the path command)
12677
- const command = filteredGroups.map(g => {
12678
- const numParse = Number.parseFloat(g);
12679
- if (Number.isNaN(numParse)) {
12680
- return g;
12681
- } else {
12682
- return numParse;
12683
- }
12684
- });
12685
- chain.push(command);
12686
- // stop now if it's a z command
12687
- if (filteredGroups.length <= 1) {
12688
- break;
12688
+ var _pathString$match;
12689
+ const chain = [];
12690
+ const all = (_pathString$match = pathString.match(rePathCmdAll)) !== null && _pathString$match !== void 0 ? _pathString$match : [];
12691
+ for (const matchStr of all) {
12692
+ // take match string and save the first letter as the command
12693
+ const commandLetter = matchStr[0];
12694
+ // in case of Z we have very little to do
12695
+ if (commandLetter === 'z' || commandLetter === 'Z') {
12696
+ chain.push([commandLetter]);
12697
+ continue;
12698
+ }
12699
+ const commandLength = commandLengths[commandLetter.toLowerCase()];
12700
+ let paramArr = [];
12701
+ if (commandLetter === 'a' || commandLetter === 'A') {
12702
+ // the arc command ha some peculariaties that requires a special regex other than numbers
12703
+ // it is possible to avoid using a space between the sweep and large arc flags, making them either
12704
+ // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum
12705
+ // reset the regexp
12706
+ regExpArcCommandPoints.lastIndex = 0;
12707
+ for (let out = null; out = regExpArcCommandPoints.exec(matchStr);) {
12708
+ paramArr.push(...out.slice(1));
12689
12709
  }
12690
- // remove the last part of the chained command
12691
- filteredGroups.shift();
12692
- // ` ?` is to support commands with optional spaces between flags
12693
- matchStr = matchStr.replace(new RegExp("".concat(filteredGroups.join(' ?'), " ?$")), '');
12694
- } while (paramArr);
12695
- // add the chain, convert multiple m's to l's in the process
12696
- chain.reverse().forEach((c, idx) => {
12697
- const transformed = repeatedCommands[c[0]];
12698
- if (idx > 0 && (transformed == 'l' || transformed == 'L')) {
12699
- c[0] = transformed;
12710
+ } else {
12711
+ paramArr = matchStr.match(reMyNum) || [];
12712
+ }
12713
+
12714
+ // inspect the length of paramArr, if is longer than commandLength
12715
+ // we are dealing with repeated commands
12716
+ for (let i = 0; i < paramArr.length; i += commandLength) {
12717
+ const newCommand = new Array(commandLength);
12718
+ const transformedCommand = repeatedCommands[commandLetter];
12719
+ newCommand[0] = i > 0 && transformedCommand ? transformedCommand : commandLetter;
12720
+ for (let j = 0; j < commandLength; j++) {
12721
+ newCommand[j + 1] = parseFloat(paramArr[i + j]);
12700
12722
  }
12701
- res.push(c);
12702
- });
12723
+ chain.push(newCommand);
12724
+ }
12703
12725
  }
12704
- return res;
12726
+ return chain;
12705
12727
  };
12706
12728
 
12707
12729
  /**
@@ -16625,7 +16647,13 @@ class Path extends FabricObject {
16625
16647
  // lineto, absolute
16626
16648
  x = command[1];
16627
16649
  y = command[2];
16628
- bounds.push(new Point(subpathStartX, subpathStartY), new Point(x, y));
16650
+ bounds.push({
16651
+ x: subpathStartX,
16652
+ y: subpathStartY
16653
+ }, {
16654
+ x,
16655
+ y
16656
+ });
16629
16657
  break;
16630
16658
  case 'M':
16631
16659
  // moveTo, absolute