fabric 7.3.1 → 7.4.0

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 (314) hide show
  1. package/CHANGELOG.md +40 -27
  2. package/dist/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.126.0}/helpers/defineProperty.mjs +1 -1
  3. package/{dist-extensions/_virtual/_@oxc-project_runtime@0.122.0 → dist/_virtual/_@oxc-project_runtime@0.126.0}/helpers/toPrimitive.mjs +1 -1
  4. package/dist/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.126.0}/helpers/toPropertyKey.mjs +1 -1
  5. package/{dist-extensions/_virtual/_@oxc-project_runtime@0.122.0 → dist/_virtual/_@oxc-project_runtime@0.126.0}/helpers/typeof.mjs +1 -1
  6. package/dist/index.js +88 -66
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.min.js +35 -35
  9. package/dist/index.min.js.map +1 -1
  10. package/dist/index.min.mjs +37 -37
  11. package/dist/index.min.mjs.map +1 -1
  12. package/dist/index.mjs +88 -66
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/index.node.cjs +83 -62
  15. package/dist/index.node.cjs.map +1 -1
  16. package/dist/index.node.mjs +83 -62
  17. package/dist/index.node.mjs.map +1 -1
  18. package/dist/package.min.mjs +1 -1
  19. package/dist/package.mjs +1 -1
  20. package/dist/src/Collection.min.mjs +1 -1
  21. package/dist/src/Collection.mjs +1 -1
  22. package/dist/src/LayoutManager/LayoutManager.min.mjs +1 -1
  23. package/dist/src/LayoutManager/LayoutManager.mjs +1 -1
  24. package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.min.mjs +1 -1
  25. package/dist/src/LayoutManager/LayoutStrategies/ClipPathLayout.mjs +1 -1
  26. package/dist/src/LayoutManager/LayoutStrategies/FitContentLayout.min.mjs +1 -1
  27. package/dist/src/LayoutManager/LayoutStrategies/FitContentLayout.mjs +1 -1
  28. package/dist/src/LayoutManager/LayoutStrategies/FixedLayout.min.mjs +1 -1
  29. package/dist/src/LayoutManager/LayoutStrategies/FixedLayout.mjs +1 -1
  30. package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.min.mjs +1 -1
  31. package/dist/src/LayoutManager/LayoutStrategies/LayoutStrategy.mjs +1 -1
  32. package/dist/src/Observable.min.mjs +1 -1
  33. package/dist/src/Observable.mjs +1 -1
  34. package/dist/src/Pattern/Pattern.min.mjs +1 -1
  35. package/dist/src/Pattern/Pattern.mjs +1 -1
  36. package/dist/src/Shadow.min.mjs +1 -1
  37. package/dist/src/Shadow.mjs +1 -1
  38. package/dist/src/brushes/BaseBrush.min.mjs +1 -1
  39. package/dist/src/brushes/BaseBrush.mjs +1 -1
  40. package/dist/src/brushes/CircleBrush.min.mjs +1 -1
  41. package/dist/src/brushes/CircleBrush.mjs +1 -1
  42. package/dist/src/brushes/PencilBrush.min.mjs +1 -1
  43. package/dist/src/brushes/PencilBrush.mjs +1 -1
  44. package/dist/src/brushes/SprayBrush.min.mjs +1 -1
  45. package/dist/src/brushes/SprayBrush.mjs +1 -1
  46. package/dist/src/cache.min.mjs +1 -1
  47. package/dist/src/cache.mjs +1 -1
  48. package/dist/src/canvas/Canvas.min.mjs +1 -1
  49. package/dist/src/canvas/Canvas.mjs +1 -1
  50. package/dist/src/canvas/DOMManagers/CanvasDOMManager.min.mjs +1 -1
  51. package/dist/src/canvas/DOMManagers/CanvasDOMManager.mjs +1 -1
  52. package/dist/src/canvas/DOMManagers/StaticCanvasDOMManager.min.mjs +1 -1
  53. package/dist/src/canvas/DOMManagers/StaticCanvasDOMManager.mjs +1 -1
  54. package/dist/src/canvas/SelectableCanvas.min.mjs +1 -1
  55. package/dist/src/canvas/SelectableCanvas.mjs +1 -1
  56. package/dist/src/canvas/StaticCanvas.d.ts +1 -1
  57. package/dist/src/canvas/StaticCanvas.d.ts.map +1 -1
  58. package/dist/src/canvas/StaticCanvas.min.mjs +5 -5
  59. package/dist/src/canvas/StaticCanvas.min.mjs.map +1 -1
  60. package/dist/src/canvas/StaticCanvas.mjs +4 -4
  61. package/dist/src/canvas/StaticCanvas.mjs.map +1 -1
  62. package/dist/src/canvas/TextEditingManager.min.mjs +1 -1
  63. package/dist/src/canvas/TextEditingManager.mjs +1 -1
  64. package/dist/src/color/Color.min.mjs +1 -1
  65. package/dist/src/color/Color.mjs +1 -1
  66. package/dist/src/config.min.mjs +1 -1
  67. package/dist/src/config.mjs +1 -1
  68. package/dist/src/controls/Control.min.mjs +1 -1
  69. package/dist/src/controls/Control.mjs +1 -1
  70. package/dist/src/filters/BaseFilter.min.mjs +1 -1
  71. package/dist/src/filters/BaseFilter.mjs +1 -1
  72. package/dist/src/filters/BlendColor.min.mjs +1 -1
  73. package/dist/src/filters/BlendColor.mjs +1 -1
  74. package/dist/src/filters/BlendImage.min.mjs +1 -1
  75. package/dist/src/filters/BlendImage.mjs +1 -1
  76. package/dist/src/filters/Blur.min.mjs +1 -1
  77. package/dist/src/filters/Blur.mjs +1 -1
  78. package/dist/src/filters/Brightness.min.mjs +1 -1
  79. package/dist/src/filters/Brightness.mjs +1 -1
  80. package/dist/src/filters/Canvas2dFilterBackend.min.mjs +1 -1
  81. package/dist/src/filters/Canvas2dFilterBackend.mjs +1 -1
  82. package/dist/src/filters/ColorMatrix.min.mjs +1 -1
  83. package/dist/src/filters/ColorMatrix.mjs +1 -1
  84. package/dist/src/filters/ColorMatrixFilters.min.mjs +1 -1
  85. package/dist/src/filters/ColorMatrixFilters.mjs +1 -1
  86. package/dist/src/filters/Composed.min.mjs +1 -1
  87. package/dist/src/filters/Composed.mjs +1 -1
  88. package/dist/src/filters/Contrast.min.mjs +1 -1
  89. package/dist/src/filters/Contrast.mjs +1 -1
  90. package/dist/src/filters/Convolute.min.mjs +1 -1
  91. package/dist/src/filters/Convolute.min.mjs.map +1 -1
  92. package/dist/src/filters/Convolute.mjs +1 -1
  93. package/dist/src/filters/Gamma.min.mjs +1 -1
  94. package/dist/src/filters/Gamma.mjs +1 -1
  95. package/dist/src/filters/Grayscale.min.mjs +1 -1
  96. package/dist/src/filters/Grayscale.mjs +1 -1
  97. package/dist/src/filters/HueRotation.min.mjs +1 -1
  98. package/dist/src/filters/HueRotation.mjs +1 -1
  99. package/dist/src/filters/Invert.min.mjs +1 -1
  100. package/dist/src/filters/Invert.mjs +1 -1
  101. package/dist/src/filters/Noise.min.mjs +1 -1
  102. package/dist/src/filters/Noise.mjs +1 -1
  103. package/dist/src/filters/Pixelate.min.mjs +1 -1
  104. package/dist/src/filters/Pixelate.mjs +1 -1
  105. package/dist/src/filters/RemoveColor.min.mjs +1 -1
  106. package/dist/src/filters/RemoveColor.mjs +1 -1
  107. package/dist/src/filters/Resize.min.mjs +2 -2
  108. package/dist/src/filters/Resize.min.mjs.map +1 -1
  109. package/dist/src/filters/Resize.mjs +2 -2
  110. package/dist/src/filters/Resize.mjs.map +1 -1
  111. package/dist/src/filters/Saturation.min.mjs +1 -1
  112. package/dist/src/filters/Saturation.mjs +1 -1
  113. package/dist/src/filters/Vibrance.min.mjs +1 -1
  114. package/dist/src/filters/Vibrance.mjs +1 -1
  115. package/dist/src/filters/WebGLFilterBackend.min.mjs +1 -1
  116. package/dist/src/filters/WebGLFilterBackend.mjs +1 -1
  117. package/dist/src/gradient/Gradient.d.ts.map +1 -1
  118. package/dist/src/gradient/Gradient.min.mjs +4 -4
  119. package/dist/src/gradient/Gradient.min.mjs.map +1 -1
  120. package/dist/src/gradient/Gradient.mjs +6 -2
  121. package/dist/src/gradient/Gradient.mjs.map +1 -1
  122. package/dist/src/gradient/typedefs.d.ts +7 -7
  123. package/dist/src/parser/applyViewboxTransform.d.ts.map +1 -1
  124. package/dist/src/parser/applyViewboxTransform.min.mjs +1 -1
  125. package/dist/src/parser/applyViewboxTransform.min.mjs.map +1 -1
  126. package/dist/src/parser/applyViewboxTransform.mjs +2 -4
  127. package/dist/src/parser/applyViewboxTransform.mjs.map +1 -1
  128. package/dist/src/shapes/ActiveSelection.min.mjs +1 -1
  129. package/dist/src/shapes/ActiveSelection.mjs +1 -1
  130. package/dist/src/shapes/Circle.min.mjs +2 -2
  131. package/dist/src/shapes/Circle.min.mjs.map +1 -1
  132. package/dist/src/shapes/Circle.mjs +1 -1
  133. package/dist/src/shapes/Ellipse.min.mjs +1 -1
  134. package/dist/src/shapes/Ellipse.mjs +1 -1
  135. package/dist/src/shapes/Group.min.mjs +1 -1
  136. package/dist/src/shapes/Group.mjs +1 -1
  137. package/dist/src/shapes/IText/DraggableTextDelegate.min.mjs +1 -1
  138. package/dist/src/shapes/IText/DraggableTextDelegate.mjs +1 -1
  139. package/dist/src/shapes/IText/IText.d.ts.map +1 -1
  140. package/dist/src/shapes/IText/IText.min.mjs +1 -1
  141. package/dist/src/shapes/IText/IText.min.mjs.map +1 -1
  142. package/dist/src/shapes/IText/IText.mjs +3 -3
  143. package/dist/src/shapes/IText/IText.mjs.map +1 -1
  144. package/dist/src/shapes/IText/ITextBehavior.min.mjs +1 -1
  145. package/dist/src/shapes/IText/ITextBehavior.mjs +1 -1
  146. package/dist/src/shapes/IText/ITextClickBehavior.min.mjs +1 -1
  147. package/dist/src/shapes/IText/ITextClickBehavior.mjs +1 -1
  148. package/dist/src/shapes/Image.min.mjs +1 -1
  149. package/dist/src/shapes/Image.mjs +1 -1
  150. package/dist/src/shapes/Line.min.mjs +1 -1
  151. package/dist/src/shapes/Line.mjs +1 -1
  152. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
  153. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs +2 -2
  154. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs.map +1 -1
  155. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs +11 -26
  156. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs.map +1 -1
  157. package/dist/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
  158. package/dist/src/shapes/Object/InteractiveObject.min.mjs +1 -1
  159. package/dist/src/shapes/Object/InteractiveObject.min.mjs.map +1 -1
  160. package/dist/src/shapes/Object/InteractiveObject.mjs +7 -6
  161. package/dist/src/shapes/Object/InteractiveObject.mjs.map +1 -1
  162. package/dist/src/shapes/Object/Object.min.mjs +1 -1
  163. package/dist/src/shapes/Object/Object.mjs +1 -1
  164. package/dist/src/shapes/Object/ObjectGeometry.d.ts.map +1 -1
  165. package/dist/src/shapes/Object/ObjectGeometry.min.mjs +1 -1
  166. package/dist/src/shapes/Object/ObjectGeometry.min.mjs.map +1 -1
  167. package/dist/src/shapes/Object/ObjectGeometry.mjs +6 -2
  168. package/dist/src/shapes/Object/ObjectGeometry.mjs.map +1 -1
  169. package/dist/src/shapes/Object/types/FabricObjectProps.d.ts +1 -1
  170. package/dist/src/shapes/Path.min.mjs +1 -1
  171. package/dist/src/shapes/Path.mjs +1 -1
  172. package/dist/src/shapes/Polygon.min.mjs +1 -1
  173. package/dist/src/shapes/Polygon.mjs +1 -1
  174. package/dist/src/shapes/Polyline.min.mjs +1 -1
  175. package/dist/src/shapes/Polyline.mjs +1 -1
  176. package/dist/src/shapes/Rect.min.mjs +1 -1
  177. package/dist/src/shapes/Rect.mjs +1 -1
  178. package/dist/src/shapes/Text/StyledText.min.mjs +1 -1
  179. package/dist/src/shapes/Text/StyledText.mjs +1 -1
  180. package/dist/src/shapes/Text/Text.d.ts +4 -4
  181. package/dist/src/shapes/Text/Text.min.mjs +1 -1
  182. package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
  183. package/dist/src/shapes/Text/Text.mjs +3 -3
  184. package/dist/src/shapes/Text/Text.mjs.map +1 -1
  185. package/dist/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
  186. package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs +2 -2
  187. package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs.map +1 -1
  188. package/dist/src/shapes/Text/TextSVGExportMixin.mjs +14 -7
  189. package/dist/src/shapes/Text/TextSVGExportMixin.mjs.map +1 -1
  190. package/dist/src/shapes/Textbox.d.ts.map +1 -1
  191. package/dist/src/shapes/Textbox.min.mjs +2 -2
  192. package/dist/src/shapes/Textbox.min.mjs.map +1 -1
  193. package/dist/src/shapes/Textbox.mjs +2 -3
  194. package/dist/src/shapes/Textbox.mjs.map +1 -1
  195. package/dist/src/shapes/Triangle.min.mjs +1 -1
  196. package/dist/src/shapes/Triangle.mjs +1 -1
  197. package/dist/src/util/animation/AnimationBase.min.mjs +1 -1
  198. package/dist/src/util/animation/AnimationBase.mjs +1 -1
  199. package/dist/src/util/animation/easing.min.mjs +1 -1
  200. package/dist/src/util/animation/easing.min.mjs.map +1 -1
  201. package/dist/src/util/animation/easing.mjs +1 -1
  202. package/dist/src/util/animation/easing.mjs.map +1 -1
  203. package/dist/src/util/internals/applyCanvasTransform.d.ts +1 -1
  204. package/dist/src/util/internals/applyCanvasTransform.min.mjs.map +1 -1
  205. package/dist/src/util/internals/applyCanvasTransform.mjs +1 -1
  206. package/dist/src/util/internals/applyCanvasTransform.mjs.map +1 -1
  207. package/dist/src/util/internals/svgExportCheck.d.ts +4 -0
  208. package/dist/src/util/internals/svgExportCheck.d.ts.map +1 -0
  209. package/dist/src/util/internals/svgExportCheck.min.mjs +2 -0
  210. package/dist/src/util/internals/svgExportCheck.min.mjs.map +1 -0
  211. package/dist/src/util/internals/svgExportCheck.mjs +12 -0
  212. package/dist/src/util/internals/svgExportCheck.mjs.map +1 -0
  213. package/dist/src/util/misc/matrix.d.ts +14 -0
  214. package/dist/src/util/misc/matrix.d.ts.map +1 -1
  215. package/dist/src/util/misc/matrix.min.mjs +1 -1
  216. package/dist/src/util/misc/matrix.min.mjs.map +1 -1
  217. package/dist/src/util/misc/matrix.mjs +15 -1
  218. package/dist/src/util/misc/matrix.mjs.map +1 -1
  219. package/dist/src/util/misc/mergeClipPaths.d.ts +1 -1
  220. package/dist/src/util/misc/mergeClipPaths.min.mjs.map +1 -1
  221. package/dist/src/util/misc/mergeClipPaths.mjs +1 -1
  222. package/dist/src/util/misc/mergeClipPaths.mjs.map +1 -1
  223. package/dist/src/util/misc/objectEnlive.min.mjs.map +1 -1
  224. package/dist/src/util/misc/objectEnlive.mjs +1 -1
  225. package/dist/src/util/misc/objectEnlive.mjs.map +1 -1
  226. package/dist/src/util/misc/projectStroke/StrokeLineJoinProjections.min.mjs +1 -1
  227. package/dist/src/util/misc/projectStroke/StrokeLineJoinProjections.min.mjs.map +1 -1
  228. package/dist/src/util/misc/projectStroke/StrokeLineJoinProjections.mjs +1 -1
  229. package/dist/src/util/misc/svgParsing.d.ts +2 -2
  230. package/dist/src/util/misc/svgParsing.d.ts.map +1 -1
  231. package/dist/src/util/misc/svgParsing.min.mjs +1 -1
  232. package/dist/src/util/misc/svgParsing.min.mjs.map +1 -1
  233. package/dist/src/util/misc/svgParsing.mjs +8 -3
  234. package/dist/src/util/misc/svgParsing.mjs.map +1 -1
  235. package/dist/src/util/path/index.d.ts.map +1 -1
  236. package/dist/src/util/path/index.min.mjs +1 -1
  237. package/dist/src/util/path/index.min.mjs.map +1 -1
  238. package/dist/src/util/path/index.mjs +2 -1
  239. package/dist/src/util/path/index.mjs.map +1 -1
  240. package/dist/src/util/path/regex.min.mjs.map +1 -1
  241. package/dist/src/util/path/regex.mjs +1 -1
  242. package/dist/src/util/path/regex.mjs.map +1 -1
  243. package/dist-extensions/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.126.0}/helpers/defineProperty.mjs +1 -1
  244. package/{dist/_virtual/_@oxc-project_runtime@0.122.0 → dist-extensions/_virtual/_@oxc-project_runtime@0.126.0}/helpers/toPrimitive.mjs +1 -1
  245. package/dist-extensions/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.126.0}/helpers/toPropertyKey.mjs +1 -1
  246. package/{dist/_virtual/_@oxc-project_runtime@0.122.0 → dist-extensions/_virtual/_@oxc-project_runtime@0.126.0}/helpers/typeof.mjs +1 -1
  247. package/dist-extensions/aligning_guidelines/index.mjs +1 -1
  248. package/dist-extensions/cropping_controls/croppingHandlers.mjs +1 -7
  249. package/dist-extensions/cropping_controls/croppingHandlers.mjs.map +1 -1
  250. package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -1
  251. package/dist-extensions/fabric-extensions.min.js +1 -1
  252. package/dist-extensions/fabric-extensions.min.js.map +1 -1
  253. package/dist-extensions/src/canvas/StaticCanvas.d.ts +1 -1
  254. package/dist-extensions/src/canvas/StaticCanvas.d.ts.map +1 -1
  255. package/dist-extensions/src/gradient/Gradient.d.ts.map +1 -1
  256. package/dist-extensions/src/gradient/typedefs.d.ts +7 -7
  257. package/dist-extensions/src/parser/applyViewboxTransform.d.ts.map +1 -1
  258. package/dist-extensions/src/shapes/IText/IText.d.ts.map +1 -1
  259. package/dist-extensions/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
  260. package/dist-extensions/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
  261. package/dist-extensions/src/shapes/Object/ObjectGeometry.d.ts.map +1 -1
  262. package/dist-extensions/src/shapes/Object/types/FabricObjectProps.d.ts +1 -1
  263. package/dist-extensions/src/shapes/Text/Text.d.ts +4 -4
  264. package/dist-extensions/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
  265. package/dist-extensions/src/shapes/Textbox.d.ts.map +1 -1
  266. package/dist-extensions/src/util/internals/applyCanvasTransform.d.ts +1 -1
  267. package/dist-extensions/src/util/internals/svgExportCheck.d.ts +4 -0
  268. package/dist-extensions/src/util/internals/svgExportCheck.d.ts.map +1 -0
  269. package/dist-extensions/src/util/misc/matrix.d.ts +14 -0
  270. package/dist-extensions/src/util/misc/matrix.d.ts.map +1 -1
  271. package/dist-extensions/src/util/misc/mergeClipPaths.d.ts +1 -1
  272. package/dist-extensions/src/util/misc/svgParsing.d.ts +2 -2
  273. package/dist-extensions/src/util/misc/svgParsing.d.ts.map +1 -1
  274. package/dist-extensions/src/util/path/index.d.ts.map +1 -1
  275. package/extensions/cropping_controls/croppingHandlers.ts +13 -19
  276. package/package.json +10 -10
  277. package/src/LayoutManager/README.md +3 -3
  278. package/src/canvas/StaticCanvas.spec.ts +19 -0
  279. package/src/canvas/StaticCanvas.ts +7 -3
  280. package/src/filters/Resize.ts +1 -1
  281. package/src/gradient/Gradient.spec.ts +60 -1
  282. package/src/gradient/Gradient.ts +9 -2
  283. package/src/gradient/typedefs.ts +7 -7
  284. package/src/parser/applyViewboxTransform.ts +2 -4
  285. package/src/shapes/IText/IText.ts +1 -2
  286. package/src/shapes/IText/ITextBehavior.test.ts +6 -6
  287. package/src/shapes/Object/FabricObject.spec.ts +3 -2
  288. package/src/shapes/Object/FabricObjectSVGExportMixin.ts +47 -37
  289. package/src/shapes/Object/InteractiveObject.ts +13 -3
  290. package/src/shapes/Object/Object-interactivity.spec.ts +126 -7
  291. package/src/shapes/Object/ObjectGeometry.spec.ts +10 -1
  292. package/src/shapes/Object/ObjectGeometry.ts +10 -3
  293. package/src/shapes/Object/objectSvgExport.spec.ts +27 -0
  294. package/src/shapes/Object/types/FabricObjectProps.ts +1 -1
  295. package/src/shapes/Text/Text.spec.ts +25 -0
  296. package/src/shapes/Text/Text.ts +5 -5
  297. package/src/shapes/Text/TextSVGExportMixin.ts +25 -11
  298. package/src/shapes/Textbox.ts +1 -2
  299. package/src/util/animation/animations.spec.ts +1 -1
  300. package/src/util/animation/easing.ts +1 -1
  301. package/src/util/internals/applyCanvasTransform.ts +1 -1
  302. package/src/util/internals/svgExportCheck.ts +20 -0
  303. package/src/util/misc/matrix.spec.ts +52 -0
  304. package/src/util/misc/matrix.ts +16 -0
  305. package/src/util/misc/mergeClipPaths.ts +1 -1
  306. package/src/util/misc/objectEnlive.ts +1 -1
  307. package/src/util/misc/svgParsing.ts +22 -10
  308. package/src/util/path/index.ts +3 -2
  309. package/src/util/path/regex.ts +1 -1
  310. package/src/util/typeAssertions.spec.ts +1 -1
  311. /package/dist/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.126.0}/helpers/defineProperty.min.mjs +0 -0
  312. /package/dist/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.126.0}/helpers/toPrimitive.min.mjs +0 -0
  313. /package/dist/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.126.0}/helpers/toPropertyKey.min.mjs +0 -0
  314. /package/dist/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.126.0}/helpers/typeof.min.mjs +0 -0
@@ -1,2 +1,2 @@
1
- import{config as e}from"../../config.min.mjs";import{FILL as t}from"../../constants.min.mjs";import{toFixed as n}from"./toFixed.min.mjs";import{escapeXml as r}from"../lang_string.min.mjs";import{Color as i}from"../../color/Color.min.mjs";const a=e=>{let t=[`instantiated_by_use`,`style`,`id`,`class`];switch(e){case`linearGradient`:return t.concat([`x1`,`y1`,`x2`,`y2`,`gradientUnits`,`gradientTransform`]);case`radialGradient`:return t.concat([`gradientUnits`,`gradientTransform`,`cx`,`cy`,`r`,`fx`,`fy`,`fr`]);case`stop`:return t.concat([`offset`,`stop-color`,`stop-opacity`])}return t},o=(t,n=16)=>{let r=/\D{0,2}$/.exec(t),i=parseFloat(t),a=e.DPI;switch(r==null?void 0:r[0]){case`mm`:return i*a/25.4;case`cm`:return i*a/2.54;case`in`:return i*a;case`pt`:return i*a/72;case`pc`:return i*a/72*12;case`em`:return i*n;default:return i}},s=e=>{let[t,n]=e.trim().split(` `),[r,i]=(a=t)&&a!==`none`?[a.slice(1,4),a.slice(5,8)]:a===`none`?[a,a]:[`Mid`,`Mid`];var a;return{meetOrSlice:n||`meet`,alignX:r,alignY:i}},c=(e,t,n=!0)=>{let a,o;if(t)if(t.toLive)a=`url(#SVGID_${r(t.id)})`;else{let e=new i(t),n=e.getAlpha();a=e.toRgb(),n!==1&&(o=n.toString())}else a=`none`;return n?`${e}: ${a}; ${o?`${e}-opacity: ${o}; `:``}`:`${e}="${a}" ${o?`${e}-opacity="${o}" `:``}`},l=(r,{left:i,top:a,width:o,height:s},l=e.NUM_FRACTION_DIGITS)=>{let u=c(t,r,!1),[d,f,p,m]=[i,a,o,s].map(e=>n(e,l));return`<rect ${u} x="${d}" y="${f}" width="${p}" height="${m}"></rect>`};export{c as colorPropToSVG,l as createSVGRect,a as getSvgAttributes,s as parsePreserveAspectRatioAttribute,o as parseUnit};
1
+ import{config as e}from"../../config.min.mjs";import{FILL as t}from"../../constants.min.mjs";import{toFixed as n}from"./toFixed.min.mjs";import{escapeXml as r}from"../lang_string.min.mjs";import{isSafeSvgStyleValue as i}from"../internals/svgExportCheck.min.mjs";import{Color as a}from"../../color/Color.min.mjs";const o=e=>{let t=[`instantiated_by_use`,`style`,`id`,`class`];switch(e){case`linearGradient`:return t.concat([`x1`,`y1`,`x2`,`y2`,`gradientUnits`,`gradientTransform`]);case`radialGradient`:return t.concat([`gradientUnits`,`gradientTransform`,`cx`,`cy`,`r`,`fx`,`fy`,`fr`]);case`stop`:return t.concat([`offset`,`stop-color`,`stop-opacity`])}return t},s=(t,n=16)=>{let r=/\D{0,2}$/.exec(t),i=parseFloat(t),a=e.DPI;switch(r==null?void 0:r[0]){case`mm`:return i*a/25.4;case`cm`:return i*a/2.54;case`in`:return i*a;case`pt`:return i*a/72;case`pc`:return i*a/72*12;case`em`:return i*n;default:return i}},c=e=>{let[t,n]=e.trim().split(` `),[r,i]=(a=t)&&a!==`none`?[a.slice(1,4),a.slice(5,8)]:a===`none`?[a,a]:[`Mid`,`Mid`];var a;return{meetOrSlice:n||`meet`,alignX:r,alignY:i}},l=(e,t,n=!0)=>{let o,s;if(t)if(t.toLive)o=`url(#SVGID_${r(t.id)})`;else{let e=String(t);if(i(e)){let t=new a(e),n=t.getAlpha();o=t.toRgb(),n!==1&&(s=n.toString())}else o=new a(`black`).toRgb()}else o=`none`;return n?`${e}: ${o}; ${s?`${e}-opacity: ${s}; `:``}`:`${e}="${o}" ${s?`${e}-opacity="${s}" `:``}`},u=(r,{left:i,top:a,width:o,height:s},c=e.NUM_FRACTION_DIGITS)=>{let u=l(t,r,!1),[d,f,p,m]=[i,a,o,s].map(e=>n(e,c));return`<rect ${u} x="${d}" y="${f}" width="${p}" height="${m}"></rect>`};export{l as colorPropToSVG,u as createSVGRect,o as getSvgAttributes,c as parsePreserveAspectRatioAttribute,s as parseUnit};
2
2
  //# sourceMappingURL=svgParsing.min.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"svgParsing.min.mjs","names":[],"sources":["../../../../src/util/misc/svgParsing.ts"],"sourcesContent":["import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type { TBBox, SVGElementName, SupportedSVGUnit } from '../../typedefs';\nimport { escapeXml } from '../lang_string';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string,\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined,\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: any,\n inlineStyle = true,\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if (value.toLive) {\n colorValue = `url(#SVGID_${escapeXml(value.id)})`;\n } else {\n const color = new Color(value),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS,\n) => {\n const svgColor = colorPropToSVG(FILL, color, false);\n const [x, y, w, h] = [left, top, width, height].map((value) =>\n toFixed(value, precision),\n );\n return `<rect ${svgColor} x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\"></rect>`;\n};\n"],"mappings":"8OAYA,MAAa,EAAoB,GAAA,CAC/B,IAAM,EAAmB,CAAC,sBAAuB,QAAS,KAAM,QAAA,CAChE,OAAQ,EAAR,CACE,IAAK,iBACH,OAAO,EAAiB,OAAO,CAC7B,KACA,KACA,KACA,KACA,gBACA,oBAAA,CAAA,CAEJ,IAAK,iBACH,OAAO,EAAiB,OAAO,CAC7B,gBACA,oBACA,KACA,KACA,IACA,KACA,KACA,KAAA,CAAA,CAEJ,IAAK,OACH,OAAO,EAAiB,OAAO,CAAC,SAAU,aAAc,eAAA,CAAA,CAE5D,OAAO,GAUI,GAAa,EAAe,EAAA,KAAA,CACvC,IAAM,EAAO,WAAW,KAAK,EAAA,CAC3B,EAAS,WAAW,EAAA,CAChB,EAAM,EAAO,IACnB,OAAA,GAAA,KAAA,IAAA,GAAQ,EAAO,GAAf,CACE,IAAK,KACH,OAAQ,EAAS,EAAO,KAE1B,IAAK,KACH,OAAQ,EAAS,EAAO,KAE1B,IAAK,KACH,OAAO,EAAS,EAElB,IAAK,KACH,OAAQ,EAAS,EAAO,GAE1B,IAAK,KACH,OAAS,EAAS,EAAO,GAAM,GAEjC,IAAK,KACH,OAAO,EAAS,EAElB,QACE,OAAO,IA+BA,EACX,GAAA,CAEA,GAAA,CAAO,EAAW,GAAc,EAAU,MAAA,CAAO,MAAM,IAAA,CAAA,CAIhD,EAAQ,IAvBG,EAuBkB,IArBvB,IAAA,OACJ,CAAC,EAAM,MAAM,EAAG,EAAA,CAAiB,EAAM,MAAM,EAAG,EAAA,CAAA,CAC9C,IAAA,OACF,CAAC,EAAO,EAAA,CAEV,CAAC,MAAO,MAAA,CAPX,IAAc,EAwBlB,MAAO,CACL,YAAa,GAAc,OAC3B,OAAA,EACA,OAAA,EAAA,EAYS,GACX,EACA,EACA,EAAA,CAAc,IAAA,CAEd,IAAI,EACA,EACJ,GAAK,EAAA,GAEM,EAAM,OACf,EAAa,cAAc,EAAU,EAAM,GAAA,CAAA,OACtC,CACL,IAAM,EAAQ,IAAI,EAAM,EAAA,CACtB,EAAU,EAAM,UAAA,CAElB,EAAa,EAAM,OAAA,CACf,IAAY,IACd,EAAe,EAAQ,UAAA,OATzB,EAAa,OAYf,OAAI,EACK,GAAG,EAAA,IAAS,EAAA,IACjB,EAAe,GAAG,EAAA,YAAiB,EAAA,IAAmB,KAGjD,GAAG,EAAA,IAAS,EAAA,IACjB,EAAe,GAAG,EAAA,YAAiB,EAAA,IAAmB,MAK/C,GACX,EAAA,CACE,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,OAAA,GACpB,EAAY,EAAO,sBAAA,CAEnB,IAAM,EAAW,EAAe,EAAM,EAAA,CAAO,EAAA,CAAA,CACtC,EAAG,EAAG,EAAG,GAAK,CAAC,EAAM,EAAK,EAAO,EAAA,CAAQ,IAAK,GACnD,EAAQ,EAAO,EAAA,CAAA,CAEjB,MAAO,SAAS,EAAA,MAAe,EAAA,OAAS,EAAA,WAAa,EAAA,YAAc,EAAA,YAAA,OAAA,KAAA,eAAA,KAAA,cAAA,KAAA,iBAAA,KAAA,kCAAA,KAAA"}
1
+ {"version":3,"file":"svgParsing.min.mjs","names":[],"sources":["../../../../src/util/misc/svgParsing.ts"],"sourcesContent":["import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type {\n TBBox,\n SVGElementName,\n SupportedSVGUnit,\n TFiller,\n} from '../../typedefs';\nimport { isSafeSvgStyleValue } from '../internals/svgExportCheck';\nimport { escapeXml } from '../lang_string';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string,\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined,\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: string | TFiller | null,\n inlineStyle = true,\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if ((value as TFiller).toLive) {\n colorValue = `url(#SVGID_${escapeXml((value as TFiller).id)})`;\n } else {\n const rawValue = String(value);\n if (!isSafeSvgStyleValue(rawValue)) {\n colorValue = new Color('black').toRgb();\n } else {\n const color = new Color(rawValue),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n }\n\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS,\n) => {\n const svgColor = colorPropToSVG(FILL, color, false);\n const [x, y, w, h] = [left, top, width, height].map((value) =>\n toFixed(value, precision),\n );\n return `<rect ${svgColor} x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\"></rect>`;\n};\n"],"mappings":"wTAkBA,MAAa,EAAoB,GAAA,CAC/B,IAAM,EAAmB,CAAC,sBAAuB,QAAS,KAAM,QAAA,CAChE,OAAQ,EAAR,CACE,IAAK,iBACH,OAAO,EAAiB,OAAO,CAC7B,KACA,KACA,KACA,KACA,gBACA,oBAAA,CAAA,CAEJ,IAAK,iBACH,OAAO,EAAiB,OAAO,CAC7B,gBACA,oBACA,KACA,KACA,IACA,KACA,KACA,KAAA,CAAA,CAEJ,IAAK,OACH,OAAO,EAAiB,OAAO,CAAC,SAAU,aAAc,eAAA,CAAA,CAE5D,OAAO,GAUI,GAAa,EAAe,EAAA,KAAA,CACvC,IAAM,EAAO,WAAW,KAAK,EAAA,CAC3B,EAAS,WAAW,EAAA,CAChB,EAAM,EAAO,IACnB,OAAA,GAAA,KAAA,IAAA,GAAQ,EAAO,GAAf,CACE,IAAK,KACH,OAAQ,EAAS,EAAO,KAE1B,IAAK,KACH,OAAQ,EAAS,EAAO,KAE1B,IAAK,KACH,OAAO,EAAS,EAElB,IAAK,KACH,OAAQ,EAAS,EAAO,GAE1B,IAAK,KACH,OAAS,EAAS,EAAO,GAAM,GAEjC,IAAK,KACH,OAAO,EAAS,EAElB,QACE,OAAO,IA+BA,EACX,GAAA,CAEA,GAAA,CAAO,EAAW,GAAc,EAAU,MAAA,CAAO,MAAM,IAAA,CAAA,CAIhD,EAAQ,IAvBG,EAuBkB,IArBvB,IAAA,OACJ,CAAC,EAAM,MAAM,EAAG,EAAA,CAAiB,EAAM,MAAM,EAAG,EAAA,CAAA,CAC9C,IAAA,OACF,CAAC,EAAO,EAAA,CAEV,CAAC,MAAO,MAAA,CAPX,IAAc,EAwBlB,MAAO,CACL,YAAa,GAAc,OAC3B,OAAA,EACA,OAAA,EAAA,EAYS,GACX,EACA,EACA,EAAA,CAAc,IAAA,CAEd,IAAI,EACA,EACJ,GAAK,EAAA,GAEO,EAAkB,OAC5B,EAAa,cAAc,EAAW,EAAkB,GAAA,CAAA,OACnD,CACL,IAAM,EAAW,OAAO,EAAA,CACxB,GAAK,EAAoB,EAAA,CAElB,CACL,IAAM,EAAQ,IAAI,EAAM,EAAA,CACtB,EAAU,EAAM,UAAA,CAElB,EAAa,EAAM,OAAA,CACf,IAAY,IACd,EAAe,EAAQ,UAAA,OAPzB,EAAa,IAAI,EAAM,QAAA,CAAS,OAAA,MANlC,EAAa,OAkBf,OAAI,EACK,GAAG,EAAA,IAAS,EAAA,IACjB,EAAe,GAAG,EAAA,YAAiB,EAAA,IAAmB,KAGjD,GAAG,EAAA,IAAS,EAAA,IACjB,EAAe,GAAG,EAAA,YAAiB,EAAA,IAAmB,MAK/C,GACX,EAAA,CACE,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,OAAA,GACpB,EAAY,EAAO,sBAAA,CAEnB,IAAM,EAAW,EAAe,EAAM,EAAA,CAAO,EAAA,CAAA,CACtC,EAAG,EAAG,EAAG,GAAK,CAAC,EAAM,EAAK,EAAO,EAAA,CAAQ,IAAK,GACnD,EAAQ,EAAO,EAAA,CAAA,CAEjB,MAAO,SAAS,EAAA,MAAe,EAAA,OAAS,EAAA,WAAa,EAAA,YAAc,EAAA,YAAA,OAAA,KAAA,eAAA,KAAA,cAAA,KAAA,iBAAA,KAAA,kCAAA,KAAA"}
@@ -2,6 +2,7 @@ import { config } from "../../config.mjs";
2
2
  import { FILL } from "../../constants.mjs";
3
3
  import { toFixed } from "./toFixed.mjs";
4
4
  import { escapeXml } from "../lang_string.mjs";
5
+ import { isSafeSvgStyleValue } from "../internals/svgExportCheck.mjs";
5
6
  import { Color } from "../../color/Color.mjs";
6
7
  //#region src/util/misc/svgParsing.ts
7
8
  /**
@@ -97,9 +98,13 @@ const colorPropToSVG = (prop, value, inlineStyle = true) => {
97
98
  if (!value) colorValue = "none";
98
99
  else if (value.toLive) colorValue = `url(#SVGID_${escapeXml(value.id)})`;
99
100
  else {
100
- const color = new Color(value), opacity = color.getAlpha();
101
- colorValue = color.toRgb();
102
- if (opacity !== 1) opacityValue = opacity.toString();
101
+ const rawValue = String(value);
102
+ if (!isSafeSvgStyleValue(rawValue)) colorValue = new Color("black").toRgb();
103
+ else {
104
+ const color = new Color(rawValue), opacity = color.getAlpha();
105
+ colorValue = color.toRgb();
106
+ if (opacity !== 1) opacityValue = opacity.toString();
107
+ }
103
108
  }
104
109
  if (inlineStyle) return `${prop}: ${colorValue}; ${opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ""}`;
105
110
  else return `${prop}="${colorValue}" ${opacityValue ? `${prop}-opacity="${opacityValue}" ` : ""}`;
@@ -1 +1 @@
1
- {"version":3,"file":"svgParsing.mjs","names":[],"sources":["../../../../src/util/misc/svgParsing.ts"],"sourcesContent":["import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type { TBBox, SVGElementName, SupportedSVGUnit } from '../../typedefs';\nimport { escapeXml } from '../lang_string';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string,\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined,\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: any,\n inlineStyle = true,\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if (value.toLive) {\n colorValue = `url(#SVGID_${escapeXml(value.id)})`;\n } else {\n const color = new Color(value),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS,\n) => {\n const svgColor = colorPropToSVG(FILL, color, false);\n const [x, y, w, h] = [left, top, width, height].map((value) =>\n toFixed(value, precision),\n );\n return `<rect ${svgColor} x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\"></rect>`;\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,oBAAoB,SAAyB;CACxD,MAAM,mBAAmB;EAAC;EAAuB;EAAS;EAAM;EAAQ;AACxE,SAAQ,MAAR;EACE,KAAK,iBACH,QAAO,iBAAiB,OAAO;GAC7B;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACJ,KAAK,iBACH,QAAO,iBAAiB,OAAO;GAC7B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACJ,KAAK,OACH,QAAO,iBAAiB,OAAO;GAAC;GAAU;GAAc;GAAe,CAAC;;AAE5E,QAAO;;;;;;;;;AAUT,MAAa,aAAa,OAAe,WAAA,OAAqC;CAC5E,MAAM,OAAO,WAAW,KAAK,MAAM,EACjC,SAAS,WAAW,MAAM;CAC5B,MAAM,MAAM,OAAO;AACnB,SAAA,SAAA,QAAA,SAAA,KAAA,IAAA,KAAA,IAAQ,KAAO,IAAf;EACE,KAAK,KACH,QAAQ,SAAS,MAAO;EAE1B,KAAK,KACH,QAAQ,SAAS,MAAO;EAE1B,KAAK,KACH,QAAO,SAAS;EAElB,KAAK,KACH,QAAQ,SAAS,MAAO;EAE1B,KAAK,KACH,QAAS,SAAS,MAAO,KAAM;EAEjC,KAAK,KACH,QAAO,SAAS;EAElB,QACE,QAAO;;;AAeb,MAAM,cAAc,UAA+B;AAEjD,KAAI,SAAS,UAAA,OACX,QAAO,CAAC,MAAM,MAAM,GAAG,EAAE,EAAe,MAAM,MAAM,GAAG,EAAE,CAAc;UAC9D,UAAA,OACT,QAAO,CAAC,OAAO,MAAM;AAEvB,QAAO,CAAC,OAAO,MAAM;;;;;;;;AASvB,MAAa,qCACX,cACsB;CACtB,MAAM,CAAC,WAAW,cAAc,UAAU,MAAM,CAAC,MAAM,IAAI;CAI3D,MAAM,CAAC,QAAQ,UAAU,WAAW,UAAU;AAC9C,QAAO;EACL,aAAa,cAAc;EAC3B;EACA;EACD;;;;;;;;;;AAWH,MAAa,kBACX,MACA,OACA,cAAc,SACX;CACH,IAAI;CACJ,IAAI;AACJ,KAAI,CAAC,MACH,cAAa;UACJ,MAAM,OACf,cAAa,cAAc,UAAU,MAAM,GAAG,CAAC;MAC1C;EACL,MAAM,QAAQ,IAAI,MAAM,MAAM,EAC5B,UAAU,MAAM,UAAU;AAE5B,eAAa,MAAM,OAAO;AAC1B,MAAI,YAAY,EACd,gBAAe,QAAQ,UAAU;;AAGrC,KAAI,YACF,QAAO,GAAG,KAAK,IAAI,WAAW,IAC5B,eAAe,GAAG,KAAK,YAAY,aAAa,MAAM;KAGxD,QAAO,GAAG,KAAK,IAAI,WAAW,IAC5B,eAAe,GAAG,KAAK,YAAY,aAAa,MAAM;;AAK5D,MAAa,iBACX,OACA,EAAE,MAAM,KAAK,OAAO,UACpB,YAAY,OAAO,wBAChB;CACH,MAAM,WAAW,eAAe,MAAM,OAAO,MAAM;CACnD,MAAM,CAAC,GAAG,GAAG,GAAG,KAAK;EAAC;EAAM;EAAK;EAAO;EAAO,CAAC,KAAK,UACnD,QAAQ,OAAO,UAAU,CAC1B;AACD,QAAO,SAAS,SAAS,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE"}
1
+ {"version":3,"file":"svgParsing.mjs","names":[],"sources":["../../../../src/util/misc/svgParsing.ts"],"sourcesContent":["import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type {\n TBBox,\n SVGElementName,\n SupportedSVGUnit,\n TFiller,\n} from '../../typedefs';\nimport { isSafeSvgStyleValue } from '../internals/svgExportCheck';\nimport { escapeXml } from '../lang_string';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string,\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined,\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: string | TFiller | null,\n inlineStyle = true,\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if ((value as TFiller).toLive) {\n colorValue = `url(#SVGID_${escapeXml((value as TFiller).id)})`;\n } else {\n const rawValue = String(value);\n if (!isSafeSvgStyleValue(rawValue)) {\n colorValue = new Color('black').toRgb();\n } else {\n const color = new Color(rawValue),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n }\n\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS,\n) => {\n const svgColor = colorPropToSVG(FILL, color, false);\n const [x, y, w, h] = [left, top, width, height].map((value) =>\n toFixed(value, precision),\n );\n return `<rect ${svgColor} x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\"></rect>`;\n};\n"],"mappings":";;;;;;;;;;;;AAkBA,MAAa,oBAAoB,SAAyB;CACxD,MAAM,mBAAmB;EAAC;EAAuB;EAAS;EAAM;EAAQ;AACxE,SAAQ,MAAR;EACE,KAAK,iBACH,QAAO,iBAAiB,OAAO;GAC7B;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACJ,KAAK,iBACH,QAAO,iBAAiB,OAAO;GAC7B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACJ,KAAK,OACH,QAAO,iBAAiB,OAAO;GAAC;GAAU;GAAc;GAAe,CAAC;;AAE5E,QAAO;;;;;;;;;AAUT,MAAa,aAAa,OAAe,WAAA,OAAqC;CAC5E,MAAM,OAAO,WAAW,KAAK,MAAM,EACjC,SAAS,WAAW,MAAM;CAC5B,MAAM,MAAM,OAAO;AACnB,SAAA,SAAA,QAAA,SAAA,KAAA,IAAA,KAAA,IAAQ,KAAO,IAAf;EACE,KAAK,KACH,QAAQ,SAAS,MAAO;EAE1B,KAAK,KACH,QAAQ,SAAS,MAAO;EAE1B,KAAK,KACH,QAAO,SAAS;EAElB,KAAK,KACH,QAAQ,SAAS,MAAO;EAE1B,KAAK,KACH,QAAS,SAAS,MAAO,KAAM;EAEjC,KAAK,KACH,QAAO,SAAS;EAElB,QACE,QAAO;;;AAeb,MAAM,cAAc,UAA+B;AAEjD,KAAI,SAAS,UAAA,OACX,QAAO,CAAC,MAAM,MAAM,GAAG,EAAE,EAAe,MAAM,MAAM,GAAG,EAAE,CAAc;UAC9D,UAAA,OACT,QAAO,CAAC,OAAO,MAAM;AAEvB,QAAO,CAAC,OAAO,MAAM;;;;;;;;AASvB,MAAa,qCACX,cACsB;CACtB,MAAM,CAAC,WAAW,cAAc,UAAU,MAAM,CAAC,MAAM,IAAI;CAI3D,MAAM,CAAC,QAAQ,UAAU,WAAW,UAAU;AAC9C,QAAO;EACL,aAAa,cAAc;EAC3B;EACA;EACD;;;;;;;;;;AAWH,MAAa,kBACX,MACA,OACA,cAAc,SACX;CACH,IAAI;CACJ,IAAI;AACJ,KAAI,CAAC,MACH,cAAa;UACH,MAAkB,OAC5B,cAAa,cAAc,UAAW,MAAkB,GAAG,CAAC;MACvD;EACL,MAAM,WAAW,OAAO,MAAM;AAC9B,MAAI,CAAC,oBAAoB,SAAS,CAChC,cAAa,IAAI,MAAM,QAAQ,CAAC,OAAO;OAClC;GACL,MAAM,QAAQ,IAAI,MAAM,SAAS,EAC/B,UAAU,MAAM,UAAU;AAE5B,gBAAa,MAAM,OAAO;AAC1B,OAAI,YAAY,EACd,gBAAe,QAAQ,UAAU;;;AAKvC,KAAI,YACF,QAAO,GAAG,KAAK,IAAI,WAAW,IAC5B,eAAe,GAAG,KAAK,YAAY,aAAa,MAAM;KAGxD,QAAO,GAAG,KAAK,IAAI,WAAW,IAC5B,eAAe,GAAG,KAAK,YAAY,aAAa,MAAM;;AAK5D,MAAa,iBACX,OACA,EAAE,MAAM,KAAK,OAAO,UACpB,YAAY,OAAO,wBAChB;CACH,MAAM,WAAW,eAAe,MAAM,OAAO,MAAM;CACnD,MAAM,CAAC,GAAG,GAAG,GAAG,KAAK;EAAC;EAAM;EAAK;EAAO;EAAO,CAAC,KAAK,UACnD,QAAQ,OAAO,UAAU,CAC1B;AACD,QAAO,SAAS,SAAS,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/util/path/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAW,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKnE,OAAO,KAAK,EAEV,gBAAgB,EAChB,gCAAgC,EAChC,gBAAgB,EAChB,WAAW,EAEX,eAAe,EAKf,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAsLpC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,WAAW,CAoFb;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAC3B,IAAI,MAAM,EACV,IAAI,MAAM,EACV,wCAAwC,iBAAiB,KACxD,gCAAgC,EAYlC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,gBAAgB,KAAG,eA4JxD,CAAC;AA0KF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,MAAM,eAAe,KACpB,gBAAgB,EAkGlB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,eAAe,EACrB,UAAU,MAAM,EAChB,QAAO,gBAAgB,EAA8B,KACpD,WAAW,GAAG,SAoChB,CAAC;AAgBF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GAAI,YAAY,MAAM,KAAG,gBA4C9C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAClC,QAAQ,KAAK,EAAE,EACf,mBAAc,KACb,eA0CF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,eAAe,EACrB,WAAW,MAAM,EACjB,YAAY,KAAK,KAChB,eA2BF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAChC,aAAa,MAAM,EACnB,QAAQ,MAAM,KACb,eAgBF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAI,UAAU,eAAe,EAAE,iBAAiB,MAAM,WAY7D,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/util/path/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAW,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKnE,OAAO,KAAK,EAEV,gBAAgB,EAChB,gCAAgC,EAChC,gBAAgB,EAChB,WAAW,EAEX,eAAe,EAKf,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAsLpC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,WAAW,CAoFb;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAC3B,IAAI,MAAM,EACV,IAAI,MAAM,EACV,wCAAwC,iBAAiB,KACxD,gCAAgC,EAYlC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,gBAAgB,KAAG,eA4JxD,CAAC;AA0KF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,MAAM,eAAe,KACpB,gBAAgB,EAkGlB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,eAAe,EACrB,UAAU,MAAM,EAChB,QAAO,gBAAgB,EAA8B,KACpD,WAAW,GAAG,SAoChB,CAAC;AAgBF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GAAI,YAAY,MAAM,KAAG,gBA6C9C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAClC,QAAQ,KAAK,EAAE,EACf,mBAAc,KACb,eA0CF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,eAAe,EACrB,WAAW,MAAM,EACjB,YAAY,KAAK,KAChB,eA2BF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAChC,aAAa,MAAM,EACnB,QAAQ,MAAM,KACb,eAgBF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAI,UAAU,eAAe,EAAE,iBAAiB,MAAM,WAY7D,CAAC"}
@@ -1,2 +1,2 @@
1
- import{config as e}from"../../config.min.mjs";import{cache as t}from"../../cache.min.mjs";import{PiBy180 as n,halfPI as r}from"../../constants.min.mjs";import{cos as i}from"../misc/cos.min.mjs";import{sin as a}from"../misc/sin.min.mjs";import{Point as o}from"../../Point.min.mjs";import{multiplyTransformMatrices as s,transformPoint as c}from"../misc/matrix.min.mjs";import{toFixed as l}from"../misc/toFixed.min.mjs";import{reNum as u}from"../../parser/constants.min.mjs";import{reArcCommandPoints as d,rePathCommand as f}from"./regex.min.mjs";const p={m:`l`,M:`L`},m=(e,t,n,r,o,s,c,l,u,d,f)=>{let p=i(e),m=a(e),h=i(t),g=a(t),_=n*o*h-r*s*g+c,v=r*o*h+n*s*g+l;return[`C`,d+u*(-n*o*m-r*s*p),f+u*(-r*o*m+n*s*p),_+u*(n*o*g+r*s*h),v+u*(r*o*g-n*s*h),_,v]},h=(e,t,n,r)=>{let i=Math.atan2(t,e),a=Math.atan2(r,n);return a>=i?a-i:2*Math.PI-(i-a)};function g(n,r,i,a,s,c,l,u){let d;if(e.cachesBoundsOfCurve&&(d=[...arguments].join(),t.boundsOfCurveCache[d]))return t.boundsOfCurveCache[d];let f=Math.sqrt,p=Math.abs,m=[],h=[[0,0],[0,0]],g=6*n-12*i+6*s,_=-3*n+9*i-9*s+3*l,v=3*i-3*n;for(let e=0;e<2;++e){if(e>0&&(g=6*r-12*a+6*c,_=-3*r+9*a-9*c+3*u,v=3*a-3*r),p(_)<1e-12){if(p(g)<1e-12)continue;let e=-v/g;0<e&&e<1&&m.push(e);continue}let t=g*g-4*v*_;if(t<0)continue;let n=f(t),i=(-g+n)/(2*_);0<i&&i<1&&m.push(i);let o=(-g-n)/(2*_);0<o&&o<1&&m.push(o)}let y=m.length,x=y,S=b(n,r,i,a,s,c,l,u);for(;y--;){let{x:e,y:t}=S(m[y]);h[0][y]=e,h[1][y]=t}h[0][x]=n,h[1][x]=r,h[0][x+1]=l,h[1][x+1]=u;let C=[new o(Math.min(...h[0]),Math.min(...h[1])),new o(Math.max(...h[0]),Math.max(...h[1]))];return e.cachesBoundsOfCurve&&(t.boundsOfCurveCache[d]=C),C}const _=(e,t,[r,o,s,c,l,u,d,f])=>{let p=((e,t,r,o,s,c,l)=>{if(r===0||o===0)return[];let u=0,d=0,f=0,p=Math.PI,g=l*n,_=a(g),v=i(g),y=.5*(-v*e-_*t),b=.5*(-v*t+_*e),x=r**2,S=o**2,C=b**2,w=y**2,T=x*S-x*C-S*w,E=Math.abs(r),D=Math.abs(o);if(T<0){let e=Math.sqrt(1-T/(x*S));E*=e,D*=e}else f=(s===c?-1:1)*Math.sqrt(T/(x*C+S*w));let O=f*E*b/D,k=-f*D*y/E,A=v*O-_*k+.5*e,j=_*O+v*k+.5*t,M=h(1,0,(y-O)/E,(b-k)/D),N=h((y-O)/E,(b-k)/D,(-y-O)/E,(-b-k)/D);c===0&&N>0?N-=2*p:c===1&&N<0&&(N+=2*p);let P=Math.ceil(Math.abs(N/p*2)),F=[],I=N/P,L=8/3*Math.sin(I/4)*Math.sin(I/4)/Math.sin(I/2),R=M+I;for(let e=0;e<P;e++)F[e]=m(M,R,v,_,E,D,A,j,L,u,d),u=F[e][5],d=F[e][6],M=R,R+=I;return F})(d-e,f-t,o,s,l,u,c);for(let n=0,r=p.length;n<r;n++)p[n][1]+=e,p[n][2]+=t,p[n][3]+=e,p[n][4]+=t,p[n][5]+=e,p[n][6]+=t;return p},v=e=>{let t=0,n=0,r=0,i=0,a=[],o,s=0,c=0;for(let l of e){let e=[...l],u;switch(e[0]){case`l`:e[1]+=t,e[2]+=n;case`L`:t=e[1],n=e[2],u=[`L`,t,n];break;case`h`:e[1]+=t;case`H`:t=e[1],u=[`L`,t,n];break;case`v`:e[1]+=n;case`V`:n=e[1],u=[`L`,t,n];break;case`m`:e[1]+=t,e[2]+=n;case`M`:t=e[1],n=e[2],r=e[1],i=e[2],u=[`M`,t,n];break;case`c`:e[1]+=t,e[2]+=n,e[3]+=t,e[4]+=n,e[5]+=t,e[6]+=n;case`C`:s=e[3],c=e[4],t=e[5],n=e[6],u=[`C`,e[1],e[2],s,c,t,n];break;case`s`:e[1]+=t,e[2]+=n,e[3]+=t,e[4]+=n;case`S`:o===`C`?(s=2*t-s,c=2*n-c):(s=t,c=n),t=e[3],n=e[4],u=[`C`,s,c,e[1],e[2],t,n],s=u[3],c=u[4];break;case`q`:e[1]+=t,e[2]+=n,e[3]+=t,e[4]+=n;case`Q`:s=e[1],c=e[2],t=e[3],n=e[4],u=[`Q`,s,c,t,n];break;case`t`:e[1]+=t,e[2]+=n;case`T`:o===`Q`?(s=2*t-s,c=2*n-c):(s=t,c=n),t=e[1],n=e[2],u=[`Q`,s,c,t,n];break;case`a`:e[6]+=t,e[7]+=n;case`A`:_(t,n,e).forEach(e=>a.push(e)),t=e[6],n=e[7];break;case`z`:case`Z`:t=r,n=i,u=[`Z`]}u?(a.push(u),o=u[0]):o=``}return a},y=(e,t,n,r)=>Math.sqrt((n-e)**2+(r-t)**2),b=(e,t,n,r,i,a,s,c)=>l=>{let u=l**3,d=(e=>3*e**2*(1-e))(l),f=(e=>3*e*(1-e)**2)(l),p=(e=>(1-e)**3)(l);return new o(s*u+i*d+n*f+e*p,c*u+a*d+r*f+t*p)},x=e=>e**2,S=e=>2*e*(1-e),C=e=>(1-e)**2,w=(e,t,n,r,i,a,o,s)=>c=>{let l=x(c),u=S(c),d=C(c),f=3*(d*(n-e)+u*(i-n)+l*(o-i)),p=3*(d*(r-t)+u*(a-r)+l*(s-a));return Math.atan2(p,f)},T=(e,t,n,r,i,a)=>s=>{let c=x(s),l=S(s),u=C(s);return new o(i*c+n*l+e*u,a*c+r*l+t*u)},E=(e,t,n,r,i,a)=>o=>{let s=1-o,c=2*(s*(n-e)+o*(i-n)),l=2*(s*(r-t)+o*(a-r));return Math.atan2(l,c)},D=(e,t,n)=>{let r=new o(t,n),i=0;for(let t=1;t<=100;t+=1){let n=e(t/100);i+=y(r.x,r.y,n.x,n.y),r=n}return i},O=(e,t)=>{let n,r=0,i=0,a={x:e.x,y:e.y},o={...a},s=.01,c=0,l=e.iterator,u=e.angleFinder;for(;i<t&&s>1e-4;)o=l(r),c=r,n=y(a.x,a.y,o.x,o.y),n+i>t?(r-=s,s/=2):(a=o,r+=s,i+=n);return{...o,angle:u(c)}},k=e=>{let t,n,r=0,i=0,a=0,o=0,s=0,c=[];for(let l of e){let e={x:i,y:a,command:l[0],length:0};switch(l[0]){case`M`:n=e,n.x=o=i=l[1],n.y=s=a=l[2];break;case`L`:n=e,n.length=y(i,a,l[1],l[2]),i=l[1],a=l[2];break;case`C`:t=b(i,a,l[1],l[2],l[3],l[4],l[5],l[6]),n=e,n.iterator=t,n.angleFinder=w(i,a,l[1],l[2],l[3],l[4],l[5],l[6]),n.length=D(t,i,a),i=l[5],a=l[6];break;case`Q`:t=T(i,a,l[1],l[2],l[3],l[4]),n=e,n.iterator=t,n.angleFinder=E(i,a,l[1],l[2],l[3],l[4]),n.length=D(t,i,a),i=l[3],a=l[4];break;case`Z`:n=e,n.destX=o,n.destY=s,n.length=y(i,a,o,s),i=o,a=s}r+=n.length,c.push(n)}return c.push({length:r,x:i,y:a}),c},A=(e,t,n=k(e))=>{let r=0;for(;t-n[r].length>0&&r<n.length-2;)t-=n[r].length,r++;let i=n[r],a=t/i.length,s=e[r];switch(i.command){case`M`:return{x:i.x,y:i.y,angle:0};case`Z`:return{...new o(i.x,i.y).lerp(new o(i.destX,i.destY),a),angle:Math.atan2(i.destY-i.y,i.destX-i.x)};case`L`:return{...new o(i.x,i.y).lerp(new o(s[1],s[2]),a),angle:Math.atan2(s[2]-i.y,s[1]-i.x)};case`C`:case`Q`:return O(i,t)}},j=new RegExp(f,`gi`),M=new RegExp(d,`g`),N=new RegExp(u,`gi`),P={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},F=e=>{var t;let n=[],r=(t=e.match(j))==null?[]:t;for(let e of r){let t=e[0];if(t===`z`||t===`Z`){n.push([t]);continue}let r=P[t.toLowerCase()],i=[];if(t===`a`||t===`A`){M.lastIndex=0;for(let t=null;t=M.exec(e);)i.push(...t.slice(1))}else i=e.match(N)||[];for(let e=0;e<i.length;e+=r){let a=Array(r),o=p[t];a[0]=e>0&&o?o:t;for(let t=0;t<r;t++)a[t+1]=parseFloat(i[e+t]);n.push(a)}}return n},I=(e,t=0)=>{let n=new o(e[0]),r=new o(e[1]),i=1,a=0,s=[],c=e.length,l=c>2,u;for(l&&(i=e[2].x<r.x?-1:e[2].x===r.x?0:1,a=e[2].y<r.y?-1:e[2].y===r.y?0:1),s.push([`M`,n.x-i*t,n.y-a*t]),u=1;u<c;u++){if(!n.eq(r)){let e=n.midPointFrom(r);s.push([`Q`,n.x,n.y,e.x,e.y])}n=e[u],u+1<e.length&&(r=e[u+1])}return l&&(i=n.x>e[u-2].x?1:n.x===e[u-2].x?0:-1,a=n.y>e[u-2].y?1:n.y===e[u-2].y?0:-1),s.push([`L`,n.x+i*t,n.y+a*t]),s},L=(e,t,n)=>(n&&(t=s(t,[1,0,0,1,-n.x,-n.y])),e.map(e=>{let n=[...e];for(let r=1;r<e.length-1;r+=2){let{x:i,y:a}=c({x:e[r],y:e[r+1]},t);n[r]=i,n[r+1]=a}return n})),R=(e,t)=>{let n=2*Math.PI/e,s=-r;e%2==0&&(s+=n/2);let c=Array(e+1);for(let r=0;r<e;r++){let e=r*n+s,{x:l,y:u}=new o(i(e),a(e)).scalarMultiply(t);c[r]=[r===0?`M`:`L`,l,u]}return c[e]=[`Z`],c},z=(e,t)=>e.map(e=>e.map((e,n)=>n===0||t===void 0?e:l(e,t)).join(` `)).join(` `);export{g as getBoundsOfCurve,k as getPathSegmentsInfo,A as getPointOnPath,R as getRegularPolygonPath,I as getSmoothPathFromPoints,z as joinPath,v as makePathSimpler,F as parsePath,L as transformPath};
1
+ import{config as e}from"../../config.min.mjs";import{cache as t}from"../../cache.min.mjs";import{PiBy180 as n,halfPI as r}from"../../constants.min.mjs";import{cos as i}from"../misc/cos.min.mjs";import{sin as a}from"../misc/sin.min.mjs";import{Point as o}from"../../Point.min.mjs";import{multiplyTransformMatrices as s,transformPoint as c}from"../misc/matrix.min.mjs";import{toFixed as l}from"../misc/toFixed.min.mjs";import{reNum as u}from"../../parser/constants.min.mjs";import{reArcCommandPoints as d,rePathCommand as f}from"./regex.min.mjs";const p={m:`l`,M:`L`},m=(e,t,n,r,o,s,c,l,u,d,f)=>{let p=i(e),m=a(e),h=i(t),g=a(t),_=n*o*h-r*s*g+c,v=r*o*h+n*s*g+l;return[`C`,d+u*(-n*o*m-r*s*p),f+u*(-r*o*m+n*s*p),_+u*(n*o*g+r*s*h),v+u*(r*o*g-n*s*h),_,v]},h=(e,t,n,r)=>{let i=Math.atan2(t,e),a=Math.atan2(r,n);return a>=i?a-i:2*Math.PI-(i-a)};function g(n,r,i,a,s,c,l,u){let d;if(e.cachesBoundsOfCurve&&(d=[...arguments].join(),t.boundsOfCurveCache[d]))return t.boundsOfCurveCache[d];let f=Math.sqrt,p=Math.abs,m=[],h=[[0,0],[0,0]],g=6*n-12*i+6*s,_=-3*n+9*i-9*s+3*l,v=3*i-3*n;for(let e=0;e<2;++e){if(e>0&&(g=6*r-12*a+6*c,_=-3*r+9*a-9*c+3*u,v=3*a-3*r),p(_)<1e-12){if(p(g)<1e-12)continue;let e=-v/g;0<e&&e<1&&m.push(e);continue}let t=g*g-4*v*_;if(t<0)continue;let n=f(t),i=(-g+n)/(2*_);0<i&&i<1&&m.push(i);let o=(-g-n)/(2*_);0<o&&o<1&&m.push(o)}let y=m.length,x=y,S=b(n,r,i,a,s,c,l,u);for(;y--;){let{x:e,y:t}=S(m[y]);h[0][y]=e,h[1][y]=t}h[0][x]=n,h[1][x]=r,h[0][x+1]=l,h[1][x+1]=u;let C=[new o(Math.min(...h[0]),Math.min(...h[1])),new o(Math.max(...h[0]),Math.max(...h[1]))];return e.cachesBoundsOfCurve&&(t.boundsOfCurveCache[d]=C),C}const _=(e,t,[r,o,s,c,l,u,d,f])=>{let p=((e,t,r,o,s,c,l)=>{if(r===0||o===0)return[];let u=0,d=0,f=0,p=Math.PI,g=l*n,_=a(g),v=i(g),y=.5*(-v*e-_*t),b=.5*(-v*t+_*e),x=r**2,S=o**2,C=b**2,w=y**2,T=x*S-x*C-S*w,E=Math.abs(r),D=Math.abs(o);if(T<0){let e=Math.sqrt(1-T/(x*S));E*=e,D*=e}else f=(s===c?-1:1)*Math.sqrt(T/(x*C+S*w));let O=f*E*b/D,k=-f*D*y/E,A=v*O-_*k+.5*e,j=_*O+v*k+.5*t,M=h(1,0,(y-O)/E,(b-k)/D),N=h((y-O)/E,(b-k)/D,(-y-O)/E,(-b-k)/D);c===0&&N>0?N-=2*p:c===1&&N<0&&(N+=2*p);let P=Math.ceil(Math.abs(N/p*2)),F=[],I=N/P,L=8/3*Math.sin(I/4)*Math.sin(I/4)/Math.sin(I/2),R=M+I;for(let e=0;e<P;e++)F[e]=m(M,R,v,_,E,D,A,j,L,u,d),u=F[e][5],d=F[e][6],M=R,R+=I;return F})(d-e,f-t,o,s,l,u,c);for(let n=0,r=p.length;n<r;n++)p[n][1]+=e,p[n][2]+=t,p[n][3]+=e,p[n][4]+=t,p[n][5]+=e,p[n][6]+=t;return p},v=e=>{let t=0,n=0,r=0,i=0,a=[],o,s=0,c=0;for(let l of e){let e=[...l],u;switch(e[0]){case`l`:e[1]+=t,e[2]+=n;case`L`:t=e[1],n=e[2],u=[`L`,t,n];break;case`h`:e[1]+=t;case`H`:t=e[1],u=[`L`,t,n];break;case`v`:e[1]+=n;case`V`:n=e[1],u=[`L`,t,n];break;case`m`:e[1]+=t,e[2]+=n;case`M`:t=e[1],n=e[2],r=e[1],i=e[2],u=[`M`,t,n];break;case`c`:e[1]+=t,e[2]+=n,e[3]+=t,e[4]+=n,e[5]+=t,e[6]+=n;case`C`:s=e[3],c=e[4],t=e[5],n=e[6],u=[`C`,e[1],e[2],s,c,t,n];break;case`s`:e[1]+=t,e[2]+=n,e[3]+=t,e[4]+=n;case`S`:o===`C`?(s=2*t-s,c=2*n-c):(s=t,c=n),t=e[3],n=e[4],u=[`C`,s,c,e[1],e[2],t,n],s=u[3],c=u[4];break;case`q`:e[1]+=t,e[2]+=n,e[3]+=t,e[4]+=n;case`Q`:s=e[1],c=e[2],t=e[3],n=e[4],u=[`Q`,s,c,t,n];break;case`t`:e[1]+=t,e[2]+=n;case`T`:o===`Q`?(s=2*t-s,c=2*n-c):(s=t,c=n),t=e[1],n=e[2],u=[`Q`,s,c,t,n];break;case`a`:e[6]+=t,e[7]+=n;case`A`:_(t,n,e).forEach(e=>a.push(e)),t=e[6],n=e[7];break;case`z`:case`Z`:t=r,n=i,u=[`Z`]}u?(a.push(u),o=u[0]):o=``}return a},y=(e,t,n,r)=>Math.sqrt((n-e)**2+(r-t)**2),b=(e,t,n,r,i,a,s,c)=>l=>{let u=l**3,d=(e=>3*e**2*(1-e))(l),f=(e=>3*e*(1-e)**2)(l),p=(e=>(1-e)**3)(l);return new o(s*u+i*d+n*f+e*p,c*u+a*d+r*f+t*p)},x=e=>e**2,S=e=>2*e*(1-e),C=e=>(1-e)**2,w=(e,t,n,r,i,a,o,s)=>c=>{let l=x(c),u=S(c),d=C(c),f=3*(d*(n-e)+u*(i-n)+l*(o-i)),p=3*(d*(r-t)+u*(a-r)+l*(s-a));return Math.atan2(p,f)},T=(e,t,n,r,i,a)=>s=>{let c=x(s),l=S(s),u=C(s);return new o(i*c+n*l+e*u,a*c+r*l+t*u)},E=(e,t,n,r,i,a)=>o=>{let s=1-o,c=2*(s*(n-e)+o*(i-n)),l=2*(s*(r-t)+o*(a-r));return Math.atan2(l,c)},D=(e,t,n)=>{let r=new o(t,n),i=0;for(let t=1;t<=100;t+=1){let n=e(t/100);i+=y(r.x,r.y,n.x,n.y),r=n}return i},O=(e,t)=>{let n,r=0,i=0,a={x:e.x,y:e.y},o={...a},s=.01,c=0,l=e.iterator,u=e.angleFinder;for(;i<t&&s>1e-4;)o=l(r),c=r,n=y(a.x,a.y,o.x,o.y),n+i>t?(r-=s,s/=2):(a=o,r+=s,i+=n);return{...o,angle:u(c)}},k=e=>{let t,n,r=0,i=0,a=0,o=0,s=0,c=[];for(let l of e){let e={x:i,y:a,command:l[0],length:0};switch(l[0]){case`M`:n=e,n.x=o=i=l[1],n.y=s=a=l[2];break;case`L`:n=e,n.length=y(i,a,l[1],l[2]),i=l[1],a=l[2];break;case`C`:t=b(i,a,l[1],l[2],l[3],l[4],l[5],l[6]),n=e,n.iterator=t,n.angleFinder=w(i,a,l[1],l[2],l[3],l[4],l[5],l[6]),n.length=D(t,i,a),i=l[5],a=l[6];break;case`Q`:t=T(i,a,l[1],l[2],l[3],l[4]),n=e,n.iterator=t,n.angleFinder=E(i,a,l[1],l[2],l[3],l[4]),n.length=D(t,i,a),i=l[3],a=l[4];break;case`Z`:n=e,n.destX=o,n.destY=s,n.length=y(i,a,o,s),i=o,a=s}r+=n.length,c.push(n)}return c.push({length:r,x:i,y:a}),c},A=(e,t,n=k(e))=>{let r=0;for(;t-n[r].length>0&&r<n.length-2;)t-=n[r].length,r++;let i=n[r],a=t/i.length,s=e[r];switch(i.command){case`M`:return{x:i.x,y:i.y,angle:0};case`Z`:return{...new o(i.x,i.y).lerp(new o(i.destX,i.destY),a),angle:Math.atan2(i.destY-i.y,i.destX-i.x)};case`L`:return{...new o(i.x,i.y).lerp(new o(s[1],s[2]),a),angle:Math.atan2(s[2]-i.y,s[1]-i.x)};case`C`:case`Q`:return O(i,t)}},j=new RegExp(f,`gi`),M=new RegExp(d,`g`),N=new RegExp(u,`gi`),P={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},F=e=>{var t;let n=[],r=(t=e.match(j))==null?[]:t;for(let e of r){let t=e[0];if(t===`z`||t===`Z`){n.push([t]);continue}let r=P[t.toLowerCase()],i=[];if(t===`a`||t===`A`){let t;for(M.lastIndex=0;t=M.exec(e);)i.push(...t.slice(1))}else i=e.match(N)||[];for(let e=0;e<i.length;e+=r){let a=Array(r),o=p[t];a[0]=e>0&&o?o:t;for(let t=0;t<r;t++)a[t+1]=parseFloat(i[e+t]);n.push(a)}}return n},I=(e,t=0)=>{let n=new o(e[0]),r=new o(e[1]),i=1,a=0,s=[],c=e.length,l=c>2,u;for(l&&(i=e[2].x<r.x?-1:e[2].x===r.x?0:1,a=e[2].y<r.y?-1:e[2].y===r.y?0:1),s.push([`M`,n.x-i*t,n.y-a*t]),u=1;u<c;u++){if(!n.eq(r)){let e=n.midPointFrom(r);s.push([`Q`,n.x,n.y,e.x,e.y])}n=e[u],u+1<e.length&&(r=e[u+1])}return l&&(i=n.x>e[u-2].x?1:n.x===e[u-2].x?0:-1,a=n.y>e[u-2].y?1:n.y===e[u-2].y?0:-1),s.push([`L`,n.x+i*t,n.y+a*t]),s},L=(e,t,n)=>(n&&(t=s(t,[1,0,0,1,-n.x,-n.y])),e.map(e=>{let n=[...e];for(let r=1;r<e.length-1;r+=2){let{x:i,y:a}=c({x:e[r],y:e[r+1]},t);n[r]=i,n[r+1]=a}return n})),R=(e,t)=>{let n=2*Math.PI/e,s=-r;e%2==0&&(s+=n/2);let c=Array(e+1);for(let r=0;r<e;r++){let e=r*n+s,{x:l,y:u}=new o(i(e),a(e)).scalarMultiply(t);c[r]=[r===0?`M`:`L`,l,u]}return c[e]=[`Z`],c},z=(e,t)=>e.map(e=>e.map((e,n)=>n===0||t===void 0?e:l(e,t)).join(` `)).join(` `);export{g as getBoundsOfCurve,k as getPathSegmentsInfo,A as getPointOnPath,R as getRegularPolygonPath,I as getSmoothPathFromPoints,z as joinPath,v as makePathSimpler,F as parsePath,L as transformPath};
2
2
  //# sourceMappingURL=index.min.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.min.mjs","names":[],"sources":["../../../../src/util/path/index.ts"],"sourcesContent":["import { cache } from '../../cache';\nimport { config } from '../../config';\nimport { halfPI, PiBy180 } from '../../constants';\nimport type { TMat2D, TRadian, TRectBounds } from '../../typedefs';\nimport { cos } from '../misc/cos';\nimport { multiplyTransformMatrices, transformPoint } from '../misc/matrix';\nimport { sin } from '../misc/sin';\nimport { toFixed } from '../misc/toFixed';\nimport type {\n TCurveInfo,\n TComplexPathData,\n TParsedAbsoluteCubicCurveCommand,\n TPathSegmentInfo,\n TPointAngle,\n TSimpleParsedCommand,\n TSimplePathData,\n TPathSegmentCommandInfo,\n TComplexParsedCommand,\n TPathSegmentInfoCommon,\n TEndPathInfo,\n TParsedArcCommand,\n TComplexParsedCommandType,\n} from './typedefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { reArcCommandPoints, rePathCommand } from './regex';\nimport { reNum } from '../../parser/constants';\n\n/**\n * Commands that may be repeated\n */\nconst repeatedCommands: Record<string, 'l' | 'L'> = {\n m: 'l',\n M: 'L',\n};\n\n/**\n * Convert an arc of a rotated ellipse to a Bezier Curve\n * @param {TRadian} theta1 start of the arc\n * @param {TRadian} theta2 end of the arc\n * @param cosTh cosine of the angle of rotation\n * @param sinTh sine of the angle of rotation\n * @param rx x-axis radius (before rotation)\n * @param ry y-axis radius (before rotation)\n * @param cx1 center x of the ellipse\n * @param cy1 center y of the ellipse\n * @param mT\n * @param fromX starting point of arc x\n * @param fromY starting point of arc y\n */\nconst segmentToBezier = (\n theta1: TRadian,\n theta2: TRadian,\n cosTh: number,\n sinTh: number,\n rx: number,\n ry: number,\n cx1: number,\n cy1: number,\n mT: number,\n fromX: number,\n fromY: number,\n): TParsedAbsoluteCubicCurveCommand => {\n const costh1 = cos(theta1),\n sinth1 = sin(theta1),\n costh2 = cos(theta2),\n sinth2 = sin(theta2),\n toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1,\n toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1,\n cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1),\n cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1),\n cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2),\n cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2);\n\n return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];\n};\n\n/**\n * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp}\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n * @param toX\n * @param toY\n * @param rx\n * @param ry\n * @param {number} large 0 or 1 flag\n * @param {number} sweep 0 or 1 flag\n * @param rotateX\n */\nconst arcToSegments = (\n toX: number,\n toY: number,\n rx: number,\n ry: number,\n large: number,\n sweep: number,\n rotateX: TRadian,\n): TParsedAbsoluteCubicCurveCommand[] => {\n if (rx === 0 || ry === 0) {\n return [];\n }\n let fromX = 0,\n fromY = 0,\n root = 0;\n const PI = Math.PI,\n theta = rotateX * PiBy180,\n sinTheta = sin(theta),\n cosTh = cos(theta),\n px = 0.5 * (-cosTh * toX - sinTheta * toY),\n py = 0.5 * (-cosTh * toY + sinTheta * toX),\n rx2 = rx ** 2,\n ry2 = ry ** 2,\n py2 = py ** 2,\n px2 = px ** 2,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2;\n let _rx = Math.abs(rx);\n let _ry = Math.abs(ry);\n\n if (pl < 0) {\n const s = Math.sqrt(1 - pl / (rx2 * ry2));\n _rx *= s;\n _ry *= s;\n } else {\n root =\n (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));\n }\n\n const cx = (root * _rx * py) / _ry,\n cy = (-root * _ry * px) / _rx,\n cx1 = cosTh * cx - sinTheta * cy + toX * 0.5,\n cy1 = sinTheta * cx + cosTh * cy + toY * 0.5;\n let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry);\n let dtheta = calcVectorAngle(\n (px - cx) / _rx,\n (py - cy) / _ry,\n (-px - cx) / _rx,\n (-py - cy) / _ry,\n );\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n } else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n const segments = Math.ceil(Math.abs((dtheta / PI) * 2)),\n result = [],\n mDelta = dtheta / segments,\n mT =\n ((8 / 3) * Math.sin(mDelta / 4) * Math.sin(mDelta / 4)) /\n Math.sin(mDelta / 2);\n let th3 = mTheta + mDelta;\n\n for (let i = 0; i < segments; i++) {\n result[i] = segmentToBezier(\n mTheta,\n th3,\n cosTh,\n sinTheta,\n _rx,\n _ry,\n cx1,\n cy1,\n mT,\n fromX,\n fromY,\n );\n fromX = result[i][5];\n fromY = result[i][6];\n mTheta = th3;\n th3 += mDelta;\n }\n return result;\n};\n\n/**\n * @private\n * Calculate the angle between two vectors\n * @param ux u endpoint x\n * @param uy u endpoint y\n * @param vx v endpoint x\n * @param vy v endpoint y\n */\nconst calcVectorAngle = (\n ux: number,\n uy: number,\n vx: number,\n vy: number,\n): TRadian => {\n const ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n } else {\n return 2 * Math.PI - (ta - tb);\n }\n};\n\n// functions for the Cubic beizer\n// taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\nconst CB1 = (t: number) => t ** 3;\nconst CB2 = (t: number) => 3 * t ** 2 * (1 - t);\nconst CB3 = (t: number) => 3 * t * (1 - t) ** 2;\nconst CB4 = (t: number) => (1 - t) ** 3;\n\n/**\n * Calculate bounding box of a cubic Bezier curve\n * Taken from http://jsbin.com/ivomiq/56/edit (no credits available)\n * TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n * @param {number} begx starting point\n * @param {number} begy\n * @param {number} cp1x first control point\n * @param {number} cp1y\n * @param {number} cp2x second control point\n * @param {number} cp2y\n * @param {number} endx end of bezier\n * @param {number} endy\n * @return {TRectBounds} the rectangular bounds\n */\nexport function getBoundsOfCurve(\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n): TRectBounds {\n let argsString: string;\n if (config.cachesBoundsOfCurve) {\n // eslint-disable-next-line\n argsString = [...arguments].join();\n if (cache.boundsOfCurveCache[argsString]) {\n return cache.boundsOfCurveCache[argsString];\n }\n }\n\n const sqrt = Math.sqrt,\n abs = Math.abs,\n tvalues = [],\n bounds: [[x: number, y: number], [x: number, y: number]] = [\n [0, 0],\n [0, 0],\n ];\n\n let b = 6 * begx - 12 * cp1x + 6 * cp2x;\n let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx;\n let c = 3 * cp1x - 3 * begx;\n\n for (let i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * begy - 12 * cp1y + 6 * cp2y;\n a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy;\n c = 3 * cp1y - 3 * begy;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n const t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n const b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n const sqrtb2ac = sqrt(b2ac);\n const t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n const t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n let j = tvalues.length;\n const jlen = j;\n const iterator = getPointOnCubicBezierIterator(\n begx,\n begy,\n cp1x,\n cp1y,\n cp2x,\n cp2y,\n endx,\n endy,\n );\n while (j--) {\n const { x, y } = iterator(tvalues[j]);\n bounds[0][j] = x;\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = begx;\n bounds[1][jlen] = begy;\n bounds[0][jlen + 1] = endx;\n bounds[1][jlen + 1] = endy;\n const result: TRectBounds = [\n new Point(Math.min(...bounds[0]), Math.min(...bounds[1])),\n new Point(Math.max(...bounds[0]), Math.max(...bounds[1])),\n ];\n if (config.cachesBoundsOfCurve) {\n cache.boundsOfCurveCache[argsString!] = result;\n }\n return result;\n}\n\n/**\n * Converts arc to a bunch of cubic Bezier curves\n * @param {number} fx starting point x\n * @param {number} fy starting point y\n * @param {TParsedArcCommand} coords Arc command\n */\nexport const fromArcToBeziers = (\n fx: number,\n fy: number,\n [_, rx, ry, rot, large, sweep, tx, ty]: TParsedArcCommand,\n): TParsedAbsoluteCubicCurveCommand[] => {\n const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (let i = 0, len = segsNorm.length; i < len; i++) {\n segsNorm[i][1] += fx;\n segsNorm[i][2] += fy;\n segsNorm[i][3] += fx;\n segsNorm[i][4] += fy;\n segsNorm[i][5] += fx;\n segsNorm[i][6] += fy;\n }\n return segsNorm;\n};\n\n/**\n * This function takes a parsed SVG path and makes it simpler for fabricJS logic.\n * Simplification consist of:\n * - All commands converted to absolute (lowercase to uppercase)\n * - S converted to C\n * - T converted to Q\n * - A converted to C\n * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path`\n * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path`\n * TODO: figure out how to remove the type assertions in a nice way\n */\nexport const makePathSimpler = (path: TComplexPathData): TSimplePathData => {\n // x and y represent the last point of the path, AKA the previous command point.\n // we add them to each relative command to make it an absolute comment.\n // we also swap the v V h H with L, because are easier to transform.\n let x = 0,\n y = 0;\n // x1 and y1 represent the last point of the subpath. the subpath is started with\n // m or M command. When a z or Z command is drawn, x and y need to be resetted to\n // the last x1 and y1.\n let x1 = 0,\n y1 = 0;\n // previous will host the letter of the previous command, to handle S and T.\n // controlX and controlY will host the previous reflected control point\n const destinationPath: TSimplePathData = [];\n let previous,\n // placeholders\n controlX = 0,\n controlY = 0;\n for (const parsedCommand of path) {\n const current: TComplexParsedCommand = [...parsedCommand];\n let converted: TSimpleParsedCommand | undefined;\n switch (\n current[0] // first letter\n ) {\n case 'l': // lineto, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'L':\n x = current[1];\n y = current[2];\n converted = ['L', x, y];\n break;\n case 'h': // horizontal lineto, relative\n current[1] += x;\n // falls through\n case 'H':\n x = current[1];\n converted = ['L', x, y];\n break;\n case 'v': // vertical lineto, relative\n current[1] += y;\n // falls through\n case 'V':\n y = current[1];\n converted = ['L', x, y];\n break;\n case 'm': // moveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'M':\n x = current[1];\n y = current[2];\n x1 = current[1];\n y1 = current[2];\n converted = ['M', x, y];\n break;\n case 'c': // bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n current[5] += x;\n current[6] += y;\n // falls through\n case 'C':\n controlX = current[3];\n controlY = current[4];\n x = current[5];\n y = current[6];\n converted = ['C', current[1], current[2], controlX, controlY, x, y];\n break;\n case 's': // shorthand cubic bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'S':\n // would be sScC but since we are swapping sSc for C, we check just that.\n if (previous === 'C') {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[3];\n y = current[4];\n converted = ['C', controlX, controlY, current[1], current[2], x, y];\n // converted[3] and converted[4] are NOW the second control point.\n // we keep it for the next reflection.\n controlX = converted[3];\n controlY = converted[4];\n break;\n case 'q': // quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'Q':\n controlX = current[1];\n controlY = current[2];\n x = current[3];\n y = current[4];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 't': // shorthand quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'T':\n if (previous === 'Q') {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[1];\n y = current[2];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 'a':\n current[6] += x;\n current[7] += y;\n // falls through\n case 'A':\n fromArcToBeziers(x, y, current).forEach((b) => destinationPath.push(b));\n x = current[6];\n y = current[7];\n break;\n case 'z':\n case 'Z':\n x = x1;\n y = y1;\n converted = ['Z'];\n break;\n default:\n }\n if (converted) {\n destinationPath.push(converted);\n previous = converted[0];\n } else {\n previous = '';\n }\n }\n return destinationPath;\n};\n\n// todo verify if we can just use the point class here\n/**\n * Calc length from point x1,y1 to x2,y2\n * @param {number} x1 starting point x\n * @param {number} y1 starting point y\n * @param {number} x2 starting point x\n * @param {number} y2 starting point y\n * @return {number} length of segment\n */\nconst calcLineLength = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): number => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n\n/**\n * Get an iterator that takes a percentage and returns a point\n * @param {number} begx\n * @param {number} begy\n * @param {number} cp1x\n * @param {number} cp1y\n * @param {number} cp2x\n * @param {number} cp2y\n * @param {number} endx\n * @param {number} endy\n */\nconst getPointOnCubicBezierIterator =\n (\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n ) =>\n (pct: number) => {\n const c1 = CB1(pct),\n c2 = CB2(pct),\n c3 = CB3(pct),\n c4 = CB4(pct);\n return new Point(\n endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4,\n endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4,\n );\n };\n\nconst QB1 = (t: number) => t ** 2;\nconst QB2 = (t: number) => 2 * t * (1 - t);\nconst QB3 = (t: number) => (1 - t) ** 2;\n\nconst getTangentCubicIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n p4x: number,\n p4y: number,\n ) =>\n (pct: number) => {\n const qb1 = QB1(pct),\n qb2 = QB2(pct),\n qb3 = QB3(pct),\n tangentX =\n 3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)),\n tangentY =\n 3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y));\n return Math.atan2(tangentY, tangentX);\n };\n\nconst getPointOnQuadraticBezierIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const c1 = QB1(pct),\n c2 = QB2(pct),\n c3 = QB3(pct);\n return new Point(\n p3x * c1 + p2x * c2 + p1x * c3,\n p3y * c1 + p2y * c2 + p1y * c3,\n );\n };\n\nconst getTangentQuadraticIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const invT = 1 - pct,\n tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)),\n tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y));\n return Math.atan2(tangentY, tangentX);\n };\n\n// this will run over a path segment (a cubic or quadratic segment) and approximate it\n// with 100 segments. This will good enough to calculate the length of the curve\nconst pathIterator = (\n iterator: (pct: number) => Point,\n x1: number,\n y1: number,\n) => {\n let tempP = new Point(x1, y1),\n tmpLen = 0;\n for (let perc = 1; perc <= 100; perc += 1) {\n const p = iterator(perc / 100);\n tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n tempP = p;\n }\n return tmpLen;\n};\n\n/**\n * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1\n * that correspond to that pixels run over the path.\n * The percentage will be then used to find the correct point on the canvas for the path.\n * @param {Array} segInfo fabricJS collection of information on a parsed path\n * @param {number} distance from starting point, in pixels.\n * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point;\n */\nconst findPercentageForDistance = (\n segInfo: TCurveInfo<'Q' | 'C'>,\n distance: number,\n): TPointAngle => {\n let perc = 0,\n tmpLen = 0,\n tempP: XY = { x: segInfo.x, y: segInfo.y },\n p: XY = { ...tempP },\n nextLen: number,\n nextStep = 0.01,\n lastPerc = 0;\n // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100\n // the path\n const iterator = segInfo.iterator,\n angleFinder = segInfo.angleFinder;\n while (tmpLen < distance && nextStep > 0.0001) {\n p = iterator(perc);\n lastPerc = perc;\n nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);\n // compare tmpLen each cycle with distance, decide next perc to test.\n if (nextLen + tmpLen > distance) {\n // we discard this step and we make smaller steps.\n perc -= nextStep;\n nextStep /= 2;\n } else {\n tempP = p;\n perc += nextStep;\n tmpLen += nextLen;\n }\n }\n return { ...p, angle: angleFinder(lastPerc) };\n};\n\n/**\n * Run over a parsed and simplified path and extract some information (length of each command and starting point)\n * @param {TSimplePathData} path parsed path commands\n * @return {TPathSegmentInfo[]} path commands information\n */\nexport const getPathSegmentsInfo = (\n path: TSimplePathData,\n): TPathSegmentInfo[] => {\n let totalLength = 0,\n //x2 and y2 are the coords of segment start\n //x1 and y1 are the coords of the current point\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n iterator,\n tempInfo: TPathSegmentInfo;\n const info: TPathSegmentInfo[] = [];\n for (const current of path) {\n const basicInfo: TPathSegmentInfoCommon<keyof TPathSegmentCommandInfo> = {\n x: x1,\n y: y1,\n command: current[0],\n length: 0,\n };\n switch (\n current[0] //first letter\n ) {\n case 'M':\n tempInfo = <TPathSegmentInfoCommon<'M'>>basicInfo;\n tempInfo.x = x2 = x1 = current[1];\n tempInfo.y = y2 = y1 = current[2];\n break;\n case 'L':\n tempInfo = <TPathSegmentInfoCommon<'L'>>basicInfo;\n tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n x1 = current[1];\n y1 = current[2];\n break;\n case 'C':\n iterator = getPointOnCubicBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo = <TCurveInfo<'C'>>basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentCubicIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n\n x1 = current[5];\n y1 = current[6];\n break;\n case 'Q':\n iterator = getPointOnQuadraticBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo = <TCurveInfo<'Q'>>basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentQuadraticIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[3];\n y1 = current[4];\n break;\n case 'Z':\n // we add those in order to ease calculations later\n tempInfo = <TEndPathInfo>basicInfo;\n tempInfo.destX = x2;\n tempInfo.destY = y2;\n tempInfo.length = calcLineLength(x1, y1, x2, y2);\n x1 = x2;\n y1 = y2;\n break;\n }\n totalLength += tempInfo.length;\n info.push(tempInfo);\n }\n info.push({ length: totalLength, x: x1, y: y1 });\n return info;\n};\n\n/**\n * Get the point on the path that is distance along the path\n * @param path\n * @param distance\n * @param infos\n */\nexport const getPointOnPath = (\n path: TSimplePathData,\n distance: number,\n infos: TPathSegmentInfo[] = getPathSegmentsInfo(path),\n): TPointAngle | undefined => {\n let i = 0;\n while (distance - infos[i].length > 0 && i < infos.length - 2) {\n distance -= infos[i].length;\n i++;\n }\n const segInfo = infos[i],\n segPercent = distance / segInfo.length,\n segment = path[i];\n\n switch (segInfo.command) {\n case 'M':\n return { x: segInfo.x, y: segInfo.y, angle: 0 };\n case 'Z':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segInfo.destX, segInfo.destY),\n segPercent,\n ),\n angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x),\n };\n case 'L':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segment[1]!, segment[2]!),\n segPercent,\n ),\n angle: Math.atan2(segment[2]! - segInfo.y, segment[1]! - segInfo.x),\n };\n case 'C':\n return findPercentageForDistance(segInfo, distance);\n case 'Q':\n return findPercentageForDistance(segInfo, distance);\n default:\n // throw Error('Invalid command');\n }\n};\n\nconst rePathCmdAll = new RegExp(rePathCommand, 'gi');\nconst regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g');\nconst reMyNum = new RegExp(reNum, 'gi');\nconst commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7,\n} as const;\n/**\n *\n * @param {string} pathString\n * @return {TComplexPathData} An array of SVG path commands\n * @example <caption>Usage</caption>\n * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [\n * ['M', 3, 4],\n * ['Q', 3, 5, 2, 1, 4, 0],\n * ['Q', 9, 12, 2, 1, 4, 0],\n * ];\n */\nexport const parsePath = (pathString: string): TComplexPathData => {\n const chain: TComplexPathData = [];\n const all = pathString.match(rePathCmdAll) ?? [];\n for (const matchStr of all) {\n // take match string and save the first letter as the command\n const commandLetter = matchStr[0] as TComplexParsedCommandType;\n // in case of Z we have very little to do\n if (commandLetter === 'z' || commandLetter === 'Z') {\n chain.push([commandLetter]);\n continue;\n }\n const commandLength =\n commandLengths[\n commandLetter.toLowerCase() as keyof typeof commandLengths\n ];\n\n let paramArr = [];\n if (commandLetter === 'a' || commandLetter === 'A') {\n // the arc command ha some peculariaties that requires a special regex other than numbers\n // it is possible to avoid using a space between the sweep and large arc flags, making them either\n // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum\n // reset the regexp\n regExpArcCommandPoints.lastIndex = 0;\n for (let out = null; (out = regExpArcCommandPoints.exec(matchStr)); ) {\n paramArr.push(...out.slice(1));\n }\n } else {\n paramArr = matchStr.match(reMyNum) || [];\n }\n\n // inspect the length of paramArr, if is longer than commandLength\n // we are dealing with repeated commands\n for (let i = 0; i < paramArr.length; i += commandLength) {\n const newCommand = new Array(commandLength) as TComplexParsedCommand;\n const transformedCommand = repeatedCommands[commandLetter];\n newCommand[0] =\n i > 0 && transformedCommand ? transformedCommand : commandLetter;\n for (let j = 0; j < commandLength; j++) {\n newCommand[j + 1] = parseFloat(paramArr[i + j]);\n }\n chain.push(newCommand);\n }\n }\n return chain;\n};\n\n/**\n *\n * Converts points to a smooth SVG path\n * @param {XY[]} points Array of points\n * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value.\n * @return {(string|number)[][]} An array of SVG path commands\n */\nexport const getSmoothPathFromPoints = (\n points: Point[],\n correction = 0,\n): TSimplePathData => {\n let p1 = new Point(points[0]),\n p2 = new Point(points[1]),\n multSignX = 1,\n multSignY = 0;\n const path: TSimplePathData = [],\n len = points.length,\n manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push([\n 'M',\n p1.x - multSignX * correction,\n p1.y - multSignY * correction,\n ]);\n let i;\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n const midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]);\n }\n p1 = points[i];\n if (i + 1 < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push([\n 'L',\n p1.x + multSignX * correction,\n p1.y + multSignY * correction,\n ]);\n return path;\n};\n\n/**\n * Transform a path by transforming each segment.\n * it has to be a simplified path or it won't work.\n * WARNING: this depends from pathOffset for correct operation\n * @param {TSimplePathData} path fabricJS parsed and simplified path commands\n * @param {TMat2D} transform matrix that represent the transformation\n * @param {Point} [pathOffset] `Path.pathOffset`\n * @returns {TSimplePathData} the transformed path\n */\nexport const transformPath = (\n path: TSimplePathData,\n transform: TMat2D,\n pathOffset: Point,\n): TSimplePathData => {\n if (pathOffset) {\n transform = multiplyTransformMatrices(transform, [\n 1,\n 0,\n 0,\n 1,\n -pathOffset.x,\n -pathOffset.y,\n ]);\n }\n return path.map((pathSegment) => {\n const newSegment: TSimpleParsedCommand = [...pathSegment];\n for (let i = 1; i < pathSegment.length - 1; i += 2) {\n // TODO: is there a way to get around casting to any?\n const { x, y } = transformPoint(\n {\n x: pathSegment[i] as number,\n y: pathSegment[i + 1] as number,\n },\n transform,\n );\n newSegment[i] = x;\n newSegment[i + 1] = y;\n }\n return newSegment;\n });\n};\n\n/**\n * Returns an array of path commands to create a regular polygon\n * @param {number} numVertexes\n * @param {number} radius\n * @returns {TSimplePathData} An array of SVG path commands\n */\nexport const getRegularPolygonPath = (\n numVertexes: number,\n radius: number,\n): TSimplePathData => {\n const interiorAngle = (Math.PI * 2) / numVertexes;\n // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom\n // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn\n let rotationAdjustment = -halfPI;\n if (numVertexes % 2 === 0) {\n rotationAdjustment += interiorAngle / 2;\n }\n const d = new Array(numVertexes + 1);\n for (let i = 0; i < numVertexes; i++) {\n const rad = i * interiorAngle + rotationAdjustment;\n const { x, y } = new Point(cos(rad), sin(rad)).scalarMultiply(radius);\n d[i] = [i === 0 ? 'M' : 'L', x, y];\n }\n d[numVertexes] = ['Z'];\n return d;\n};\n\n/**\n * Join path commands to go back to svg format\n * @param {TSimplePathData} pathData fabricJS parsed path commands\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {String} joined path 'M 0 0 L 20 30'\n */\nexport const joinPath = (pathData: TSimplePathData, fractionDigits?: number) =>\n pathData\n .map((segment) => {\n return segment\n .map((arg, i) => {\n if (i === 0) return arg;\n return fractionDigits === undefined\n ? arg\n : toFixed(arg, fractionDigits);\n })\n .join(' ');\n })\n .join(' ');\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.min.mjs","names":[],"sources":["../../../../src/util/path/index.ts"],"sourcesContent":["import { cache } from '../../cache';\nimport { config } from '../../config';\nimport { halfPI, PiBy180 } from '../../constants';\nimport type { TMat2D, TRadian, TRectBounds } from '../../typedefs';\nimport { cos } from '../misc/cos';\nimport { multiplyTransformMatrices, transformPoint } from '../misc/matrix';\nimport { sin } from '../misc/sin';\nimport { toFixed } from '../misc/toFixed';\nimport type {\n TCurveInfo,\n TComplexPathData,\n TParsedAbsoluteCubicCurveCommand,\n TPathSegmentInfo,\n TPointAngle,\n TSimpleParsedCommand,\n TSimplePathData,\n TPathSegmentCommandInfo,\n TComplexParsedCommand,\n TPathSegmentInfoCommon,\n TEndPathInfo,\n TParsedArcCommand,\n TComplexParsedCommandType,\n} from './typedefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { reArcCommandPoints, rePathCommand } from './regex';\nimport { reNum } from '../../parser/constants';\n\n/**\n * Commands that may be repeated\n */\nconst repeatedCommands: Record<string, 'l' | 'L'> = {\n m: 'l',\n M: 'L',\n};\n\n/**\n * Convert an arc of a rotated ellipse to a Bezier Curve\n * @param {TRadian} theta1 start of the arc\n * @param {TRadian} theta2 end of the arc\n * @param cosTh cosine of the angle of rotation\n * @param sinTh sine of the angle of rotation\n * @param rx x-axis radius (before rotation)\n * @param ry y-axis radius (before rotation)\n * @param cx1 center x of the ellipse\n * @param cy1 center y of the ellipse\n * @param mT\n * @param fromX starting point of arc x\n * @param fromY starting point of arc y\n */\nconst segmentToBezier = (\n theta1: TRadian,\n theta2: TRadian,\n cosTh: number,\n sinTh: number,\n rx: number,\n ry: number,\n cx1: number,\n cy1: number,\n mT: number,\n fromX: number,\n fromY: number,\n): TParsedAbsoluteCubicCurveCommand => {\n const costh1 = cos(theta1),\n sinth1 = sin(theta1),\n costh2 = cos(theta2),\n sinth2 = sin(theta2),\n toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1,\n toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1,\n cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1),\n cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1),\n cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2),\n cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2);\n\n return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];\n};\n\n/**\n * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp}\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n * @param toX\n * @param toY\n * @param rx\n * @param ry\n * @param {number} large 0 or 1 flag\n * @param {number} sweep 0 or 1 flag\n * @param rotateX\n */\nconst arcToSegments = (\n toX: number,\n toY: number,\n rx: number,\n ry: number,\n large: number,\n sweep: number,\n rotateX: TRadian,\n): TParsedAbsoluteCubicCurveCommand[] => {\n if (rx === 0 || ry === 0) {\n return [];\n }\n let fromX = 0,\n fromY = 0,\n root = 0;\n const PI = Math.PI,\n theta = rotateX * PiBy180,\n sinTheta = sin(theta),\n cosTh = cos(theta),\n px = 0.5 * (-cosTh * toX - sinTheta * toY),\n py = 0.5 * (-cosTh * toY + sinTheta * toX),\n rx2 = rx ** 2,\n ry2 = ry ** 2,\n py2 = py ** 2,\n px2 = px ** 2,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2;\n let _rx = Math.abs(rx);\n let _ry = Math.abs(ry);\n\n if (pl < 0) {\n const s = Math.sqrt(1 - pl / (rx2 * ry2));\n _rx *= s;\n _ry *= s;\n } else {\n root =\n (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));\n }\n\n const cx = (root * _rx * py) / _ry,\n cy = (-root * _ry * px) / _rx,\n cx1 = cosTh * cx - sinTheta * cy + toX * 0.5,\n cy1 = sinTheta * cx + cosTh * cy + toY * 0.5;\n let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry);\n let dtheta = calcVectorAngle(\n (px - cx) / _rx,\n (py - cy) / _ry,\n (-px - cx) / _rx,\n (-py - cy) / _ry,\n );\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n } else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n const segments = Math.ceil(Math.abs((dtheta / PI) * 2)),\n result = [],\n mDelta = dtheta / segments,\n mT =\n ((8 / 3) * Math.sin(mDelta / 4) * Math.sin(mDelta / 4)) /\n Math.sin(mDelta / 2);\n let th3 = mTheta + mDelta;\n\n for (let i = 0; i < segments; i++) {\n result[i] = segmentToBezier(\n mTheta,\n th3,\n cosTh,\n sinTheta,\n _rx,\n _ry,\n cx1,\n cy1,\n mT,\n fromX,\n fromY,\n );\n fromX = result[i][5];\n fromY = result[i][6];\n mTheta = th3;\n th3 += mDelta;\n }\n return result;\n};\n\n/**\n * @private\n * Calculate the angle between two vectors\n * @param ux u endpoint x\n * @param uy u endpoint y\n * @param vx v endpoint x\n * @param vy v endpoint y\n */\nconst calcVectorAngle = (\n ux: number,\n uy: number,\n vx: number,\n vy: number,\n): TRadian => {\n const ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n } else {\n return 2 * Math.PI - (ta - tb);\n }\n};\n\n// functions for the Cubic beizer\n// taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\nconst CB1 = (t: number) => t ** 3;\nconst CB2 = (t: number) => 3 * t ** 2 * (1 - t);\nconst CB3 = (t: number) => 3 * t * (1 - t) ** 2;\nconst CB4 = (t: number) => (1 - t) ** 3;\n\n/**\n * Calculate bounding box of a cubic Bezier curve\n * Taken from http://jsbin.com/ivomiq/56/edit (no credits available)\n * TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n * @param {number} begx starting point\n * @param {number} begy\n * @param {number} cp1x first control point\n * @param {number} cp1y\n * @param {number} cp2x second control point\n * @param {number} cp2y\n * @param {number} endx end of bezier\n * @param {number} endy\n * @return {TRectBounds} the rectangular bounds\n */\nexport function getBoundsOfCurve(\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n): TRectBounds {\n let argsString: string;\n if (config.cachesBoundsOfCurve) {\n // eslint-disable-next-line\n argsString = [...arguments].join();\n if (cache.boundsOfCurveCache[argsString]) {\n return cache.boundsOfCurveCache[argsString];\n }\n }\n\n const sqrt = Math.sqrt,\n abs = Math.abs,\n tvalues = [],\n bounds: [[x: number, y: number], [x: number, y: number]] = [\n [0, 0],\n [0, 0],\n ];\n\n let b = 6 * begx - 12 * cp1x + 6 * cp2x;\n let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx;\n let c = 3 * cp1x - 3 * begx;\n\n for (let i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * begy - 12 * cp1y + 6 * cp2y;\n a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy;\n c = 3 * cp1y - 3 * begy;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n const t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n const b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n const sqrtb2ac = sqrt(b2ac);\n const t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n const t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n let j = tvalues.length;\n const jlen = j;\n const iterator = getPointOnCubicBezierIterator(\n begx,\n begy,\n cp1x,\n cp1y,\n cp2x,\n cp2y,\n endx,\n endy,\n );\n while (j--) {\n const { x, y } = iterator(tvalues[j]);\n bounds[0][j] = x;\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = begx;\n bounds[1][jlen] = begy;\n bounds[0][jlen + 1] = endx;\n bounds[1][jlen + 1] = endy;\n const result: TRectBounds = [\n new Point(Math.min(...bounds[0]), Math.min(...bounds[1])),\n new Point(Math.max(...bounds[0]), Math.max(...bounds[1])),\n ];\n if (config.cachesBoundsOfCurve) {\n cache.boundsOfCurveCache[argsString!] = result;\n }\n return result;\n}\n\n/**\n * Converts arc to a bunch of cubic Bezier curves\n * @param {number} fx starting point x\n * @param {number} fy starting point y\n * @param {TParsedArcCommand} coords Arc command\n */\nexport const fromArcToBeziers = (\n fx: number,\n fy: number,\n [_, rx, ry, rot, large, sweep, tx, ty]: TParsedArcCommand,\n): TParsedAbsoluteCubicCurveCommand[] => {\n const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (let i = 0, len = segsNorm.length; i < len; i++) {\n segsNorm[i][1] += fx;\n segsNorm[i][2] += fy;\n segsNorm[i][3] += fx;\n segsNorm[i][4] += fy;\n segsNorm[i][5] += fx;\n segsNorm[i][6] += fy;\n }\n return segsNorm;\n};\n\n/**\n * This function takes a parsed SVG path and makes it simpler for fabricJS logic.\n * Simplification consist of:\n * - All commands converted to absolute (lowercase to uppercase)\n * - S converted to C\n * - T converted to Q\n * - A converted to C\n * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path`\n * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path`\n * TODO: figure out how to remove the type assertions in a nice way\n */\nexport const makePathSimpler = (path: TComplexPathData): TSimplePathData => {\n // x and y represent the last point of the path, AKA the previous command point.\n // we add them to each relative command to make it an absolute comment.\n // we also swap the v V h H with L, because are easier to transform.\n let x = 0,\n y = 0;\n // x1 and y1 represent the last point of the subpath. the subpath is started with\n // m or M command. When a z or Z command is drawn, x and y need to be reset to\n // the last x1 and y1.\n let x1 = 0,\n y1 = 0;\n // previous will host the letter of the previous command, to handle S and T.\n // controlX and controlY will host the previous reflected control point\n const destinationPath: TSimplePathData = [];\n let previous,\n // placeholders\n controlX = 0,\n controlY = 0;\n for (const parsedCommand of path) {\n const current: TComplexParsedCommand = [...parsedCommand];\n let converted: TSimpleParsedCommand | undefined;\n switch (\n current[0] // first letter\n ) {\n case 'l': // lineto, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'L':\n x = current[1];\n y = current[2];\n converted = ['L', x, y];\n break;\n case 'h': // horizontal lineto, relative\n current[1] += x;\n // falls through\n case 'H':\n x = current[1];\n converted = ['L', x, y];\n break;\n case 'v': // vertical lineto, relative\n current[1] += y;\n // falls through\n case 'V':\n y = current[1];\n converted = ['L', x, y];\n break;\n case 'm': // moveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'M':\n x = current[1];\n y = current[2];\n x1 = current[1];\n y1 = current[2];\n converted = ['M', x, y];\n break;\n case 'c': // bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n current[5] += x;\n current[6] += y;\n // falls through\n case 'C':\n controlX = current[3];\n controlY = current[4];\n x = current[5];\n y = current[6];\n converted = ['C', current[1], current[2], controlX, controlY, x, y];\n break;\n case 's': // shorthand cubic bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'S':\n // would be sScC but since we are swapping sSc for C, we check just that.\n if (previous === 'C') {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[3];\n y = current[4];\n converted = ['C', controlX, controlY, current[1], current[2], x, y];\n // converted[3] and converted[4] are NOW the second control point.\n // we keep it for the next reflection.\n controlX = converted[3];\n controlY = converted[4];\n break;\n case 'q': // quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'Q':\n controlX = current[1];\n controlY = current[2];\n x = current[3];\n y = current[4];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 't': // shorthand quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'T':\n if (previous === 'Q') {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[1];\n y = current[2];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 'a':\n current[6] += x;\n current[7] += y;\n // falls through\n case 'A':\n fromArcToBeziers(x, y, current).forEach((b) => destinationPath.push(b));\n x = current[6];\n y = current[7];\n break;\n case 'z':\n case 'Z':\n x = x1;\n y = y1;\n converted = ['Z'];\n break;\n default:\n }\n if (converted) {\n destinationPath.push(converted);\n previous = converted[0];\n } else {\n previous = '';\n }\n }\n return destinationPath;\n};\n\n// todo verify if we can just use the point class here\n/**\n * Calc length from point x1,y1 to x2,y2\n * @param {number} x1 starting point x\n * @param {number} y1 starting point y\n * @param {number} x2 starting point x\n * @param {number} y2 starting point y\n * @return {number} length of segment\n */\nconst calcLineLength = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): number => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n\n/**\n * Get an iterator that takes a percentage and returns a point\n * @param {number} begx\n * @param {number} begy\n * @param {number} cp1x\n * @param {number} cp1y\n * @param {number} cp2x\n * @param {number} cp2y\n * @param {number} endx\n * @param {number} endy\n */\nconst getPointOnCubicBezierIterator =\n (\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n ) =>\n (pct: number) => {\n const c1 = CB1(pct),\n c2 = CB2(pct),\n c3 = CB3(pct),\n c4 = CB4(pct);\n return new Point(\n endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4,\n endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4,\n );\n };\n\nconst QB1 = (t: number) => t ** 2;\nconst QB2 = (t: number) => 2 * t * (1 - t);\nconst QB3 = (t: number) => (1 - t) ** 2;\n\nconst getTangentCubicIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n p4x: number,\n p4y: number,\n ) =>\n (pct: number) => {\n const qb1 = QB1(pct),\n qb2 = QB2(pct),\n qb3 = QB3(pct),\n tangentX =\n 3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)),\n tangentY =\n 3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y));\n return Math.atan2(tangentY, tangentX);\n };\n\nconst getPointOnQuadraticBezierIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const c1 = QB1(pct),\n c2 = QB2(pct),\n c3 = QB3(pct);\n return new Point(\n p3x * c1 + p2x * c2 + p1x * c3,\n p3y * c1 + p2y * c2 + p1y * c3,\n );\n };\n\nconst getTangentQuadraticIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const invT = 1 - pct,\n tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)),\n tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y));\n return Math.atan2(tangentY, tangentX);\n };\n\n// this will run over a path segment (a cubic or quadratic segment) and approximate it\n// with 100 segments. This will good enough to calculate the length of the curve\nconst pathIterator = (\n iterator: (pct: number) => Point,\n x1: number,\n y1: number,\n) => {\n let tempP = new Point(x1, y1),\n tmpLen = 0;\n for (let perc = 1; perc <= 100; perc += 1) {\n const p = iterator(perc / 100);\n tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n tempP = p;\n }\n return tmpLen;\n};\n\n/**\n * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1\n * that correspond to that pixels run over the path.\n * The percentage will be then used to find the correct point on the canvas for the path.\n * @param {Array} segInfo fabricJS collection of information on a parsed path\n * @param {number} distance from starting point, in pixels.\n * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point;\n */\nconst findPercentageForDistance = (\n segInfo: TCurveInfo<'Q' | 'C'>,\n distance: number,\n): TPointAngle => {\n let perc = 0,\n tmpLen = 0,\n tempP: XY = { x: segInfo.x, y: segInfo.y },\n p: XY = { ...tempP },\n nextLen: number,\n nextStep = 0.01,\n lastPerc = 0;\n // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100\n // the path\n const iterator = segInfo.iterator,\n angleFinder = segInfo.angleFinder;\n while (tmpLen < distance && nextStep > 0.0001) {\n p = iterator(perc);\n lastPerc = perc;\n nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);\n // compare tmpLen each cycle with distance, decide next perc to test.\n if (nextLen + tmpLen > distance) {\n // we discard this step and we make smaller steps.\n perc -= nextStep;\n nextStep /= 2;\n } else {\n tempP = p;\n perc += nextStep;\n tmpLen += nextLen;\n }\n }\n return { ...p, angle: angleFinder(lastPerc) };\n};\n\n/**\n * Run over a parsed and simplified path and extract some information (length of each command and starting point)\n * @param {TSimplePathData} path parsed path commands\n * @return {TPathSegmentInfo[]} path commands information\n */\nexport const getPathSegmentsInfo = (\n path: TSimplePathData,\n): TPathSegmentInfo[] => {\n let totalLength = 0,\n //x2 and y2 are the coords of segment start\n //x1 and y1 are the coords of the current point\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n iterator,\n tempInfo: TPathSegmentInfo;\n const info: TPathSegmentInfo[] = [];\n for (const current of path) {\n const basicInfo: TPathSegmentInfoCommon<keyof TPathSegmentCommandInfo> = {\n x: x1,\n y: y1,\n command: current[0],\n length: 0,\n };\n switch (\n current[0] //first letter\n ) {\n case 'M':\n tempInfo = <TPathSegmentInfoCommon<'M'>>basicInfo;\n tempInfo.x = x2 = x1 = current[1];\n tempInfo.y = y2 = y1 = current[2];\n break;\n case 'L':\n tempInfo = <TPathSegmentInfoCommon<'L'>>basicInfo;\n tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n x1 = current[1];\n y1 = current[2];\n break;\n case 'C':\n iterator = getPointOnCubicBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo = <TCurveInfo<'C'>>basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentCubicIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n\n x1 = current[5];\n y1 = current[6];\n break;\n case 'Q':\n iterator = getPointOnQuadraticBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo = <TCurveInfo<'Q'>>basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentQuadraticIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[3];\n y1 = current[4];\n break;\n case 'Z':\n // we add those in order to ease calculations later\n tempInfo = <TEndPathInfo>basicInfo;\n tempInfo.destX = x2;\n tempInfo.destY = y2;\n tempInfo.length = calcLineLength(x1, y1, x2, y2);\n x1 = x2;\n y1 = y2;\n break;\n }\n totalLength += tempInfo.length;\n info.push(tempInfo);\n }\n info.push({ length: totalLength, x: x1, y: y1 });\n return info;\n};\n\n/**\n * Get the point on the path that is distance along the path\n * @param path\n * @param distance\n * @param infos\n */\nexport const getPointOnPath = (\n path: TSimplePathData,\n distance: number,\n infos: TPathSegmentInfo[] = getPathSegmentsInfo(path),\n): TPointAngle | undefined => {\n let i = 0;\n while (distance - infos[i].length > 0 && i < infos.length - 2) {\n distance -= infos[i].length;\n i++;\n }\n const segInfo = infos[i],\n segPercent = distance / segInfo.length,\n segment = path[i];\n\n switch (segInfo.command) {\n case 'M':\n return { x: segInfo.x, y: segInfo.y, angle: 0 };\n case 'Z':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segInfo.destX, segInfo.destY),\n segPercent,\n ),\n angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x),\n };\n case 'L':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segment[1]!, segment[2]!),\n segPercent,\n ),\n angle: Math.atan2(segment[2]! - segInfo.y, segment[1]! - segInfo.x),\n };\n case 'C':\n return findPercentageForDistance(segInfo, distance);\n case 'Q':\n return findPercentageForDistance(segInfo, distance);\n default:\n // throw Error('Invalid command');\n }\n};\n\nconst rePathCmdAll = new RegExp(rePathCommand, 'gi');\nconst regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g');\nconst reMyNum = new RegExp(reNum, 'gi');\nconst commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7,\n} as const;\n/**\n *\n * @param {string} pathString\n * @return {TComplexPathData} An array of SVG path commands\n * @example <caption>Usage</caption>\n * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [\n * ['M', 3, 4],\n * ['Q', 3, 5, 2, 1, 4, 0],\n * ['Q', 9, 12, 2, 1, 4, 0],\n * ];\n */\nexport const parsePath = (pathString: string): TComplexPathData => {\n const chain: TComplexPathData = [];\n const all = pathString.match(rePathCmdAll) ?? [];\n for (const matchStr of all) {\n // take match string and save the first letter as the command\n const commandLetter = matchStr[0] as TComplexParsedCommandType;\n // in case of Z we have very little to do\n if (commandLetter === 'z' || commandLetter === 'Z') {\n chain.push([commandLetter]);\n continue;\n }\n const commandLength =\n commandLengths[\n commandLetter.toLowerCase() as keyof typeof commandLengths\n ];\n\n let paramArr = [];\n if (commandLetter === 'a' || commandLetter === 'A') {\n // the arc command ha some peculariaties that requires a special regex other than numbers\n // it is possible to avoid using a space between the sweep and large arc flags, making them either\n // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum\n // reset the regexp\n regExpArcCommandPoints.lastIndex = 0;\n let out: RegExpExecArray | null;\n while ((out = regExpArcCommandPoints.exec(matchStr))) {\n paramArr.push(...out.slice(1));\n }\n } else {\n paramArr = matchStr.match(reMyNum) || [];\n }\n\n // inspect the length of paramArr, if is longer than commandLength\n // we are dealing with repeated commands\n for (let i = 0; i < paramArr.length; i += commandLength) {\n const newCommand = new Array(commandLength) as TComplexParsedCommand;\n const transformedCommand = repeatedCommands[commandLetter];\n newCommand[0] =\n i > 0 && transformedCommand ? transformedCommand : commandLetter;\n for (let j = 0; j < commandLength; j++) {\n newCommand[j + 1] = parseFloat(paramArr[i + j]);\n }\n chain.push(newCommand);\n }\n }\n return chain;\n};\n\n/**\n *\n * Converts points to a smooth SVG path\n * @param {XY[]} points Array of points\n * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value.\n * @return {(string|number)[][]} An array of SVG path commands\n */\nexport const getSmoothPathFromPoints = (\n points: Point[],\n correction = 0,\n): TSimplePathData => {\n let p1 = new Point(points[0]),\n p2 = new Point(points[1]),\n multSignX = 1,\n multSignY = 0;\n const path: TSimplePathData = [],\n len = points.length,\n manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push([\n 'M',\n p1.x - multSignX * correction,\n p1.y - multSignY * correction,\n ]);\n let i;\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n const midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]);\n }\n p1 = points[i];\n if (i + 1 < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push([\n 'L',\n p1.x + multSignX * correction,\n p1.y + multSignY * correction,\n ]);\n return path;\n};\n\n/**\n * Transform a path by transforming each segment.\n * it has to be a simplified path or it won't work.\n * WARNING: this depends from pathOffset for correct operation\n * @param {TSimplePathData} path fabricJS parsed and simplified path commands\n * @param {TMat2D} transform matrix that represent the transformation\n * @param {Point} [pathOffset] `Path.pathOffset`\n * @returns {TSimplePathData} the transformed path\n */\nexport const transformPath = (\n path: TSimplePathData,\n transform: TMat2D,\n pathOffset: Point,\n): TSimplePathData => {\n if (pathOffset) {\n transform = multiplyTransformMatrices(transform, [\n 1,\n 0,\n 0,\n 1,\n -pathOffset.x,\n -pathOffset.y,\n ]);\n }\n return path.map((pathSegment) => {\n const newSegment: TSimpleParsedCommand = [...pathSegment];\n for (let i = 1; i < pathSegment.length - 1; i += 2) {\n // TODO: is there a way to get around casting to any?\n const { x, y } = transformPoint(\n {\n x: pathSegment[i] as number,\n y: pathSegment[i + 1] as number,\n },\n transform,\n );\n newSegment[i] = x;\n newSegment[i + 1] = y;\n }\n return newSegment;\n });\n};\n\n/**\n * Returns an array of path commands to create a regular polygon\n * @param {number} numVertexes\n * @param {number} radius\n * @returns {TSimplePathData} An array of SVG path commands\n */\nexport const getRegularPolygonPath = (\n numVertexes: number,\n radius: number,\n): TSimplePathData => {\n const interiorAngle = (Math.PI * 2) / numVertexes;\n // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom\n // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn\n let rotationAdjustment = -halfPI;\n if (numVertexes % 2 === 0) {\n rotationAdjustment += interiorAngle / 2;\n }\n const d = new Array(numVertexes + 1);\n for (let i = 0; i < numVertexes; i++) {\n const rad = i * interiorAngle + rotationAdjustment;\n const { x, y } = new Point(cos(rad), sin(rad)).scalarMultiply(radius);\n d[i] = [i === 0 ? 'M' : 'L', x, y];\n }\n d[numVertexes] = ['Z'];\n return d;\n};\n\n/**\n * Join path commands to go back to svg format\n * @param {TSimplePathData} pathData fabricJS parsed path commands\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {String} joined path 'M 0 0 L 20 30'\n */\nexport const joinPath = (pathData: TSimplePathData, fractionDigits?: number) =>\n pathData\n .map((segment) => {\n return segment\n .map((arg, i) => {\n if (i === 0) return arg;\n return fractionDigits === undefined\n ? arg\n : toFixed(arg, fractionDigits);\n })\n .join(' ');\n })\n .join(' ');\n"],"mappings":"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"}
@@ -566,7 +566,8 @@ const parsePath = (pathString) => {
566
566
  let paramArr = [];
567
567
  if (commandLetter === "a" || commandLetter === "A") {
568
568
  regExpArcCommandPoints.lastIndex = 0;
569
- for (let out = null; out = regExpArcCommandPoints.exec(matchStr);) paramArr.push(...out.slice(1));
569
+ let out;
570
+ while (out = regExpArcCommandPoints.exec(matchStr)) paramArr.push(...out.slice(1));
570
571
  } else paramArr = matchStr.match(reMyNum) || [];
571
572
  for (let i = 0; i < paramArr.length; i += commandLength) {
572
573
  const newCommand = new Array(commandLength);