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