html2canvas-pro 1.5.13 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/.eslintrc.old +27 -0
  2. package/README.md +20 -0
  3. package/dist/html2canvas-pro.esm.js +2616 -3010
  4. package/dist/html2canvas-pro.esm.js.map +1 -1
  5. package/dist/html2canvas-pro.js +2616 -3010
  6. package/dist/html2canvas-pro.js.map +1 -1
  7. package/dist/html2canvas-pro.min.js +6 -2
  8. package/dist/lib/__tests__/index.js +57 -122
  9. package/dist/lib/__tests__/index.js.map +1 -1
  10. package/dist/lib/core/__mocks__/cache-storage.js +2 -5
  11. package/dist/lib/core/__mocks__/cache-storage.js.map +1 -1
  12. package/dist/lib/core/__mocks__/context.js +7 -10
  13. package/dist/lib/core/__mocks__/context.js.map +1 -1
  14. package/dist/lib/core/__mocks__/logger.js +9 -17
  15. package/dist/lib/core/__mocks__/logger.js.map +1 -1
  16. package/dist/lib/core/__tests__/cache-storage.js +153 -351
  17. package/dist/lib/core/__tests__/cache-storage.js.map +1 -1
  18. package/dist/lib/core/__tests__/logger.js +12 -13
  19. package/dist/lib/core/__tests__/logger.js.map +1 -1
  20. package/dist/lib/core/bitwise.js +1 -1
  21. package/dist/lib/core/bitwise.js.map +1 -1
  22. package/dist/lib/core/cache-storage.js +92 -155
  23. package/dist/lib/core/cache-storage.js.map +1 -1
  24. package/dist/lib/core/context.js +8 -10
  25. package/dist/lib/core/context.js.map +1 -1
  26. package/dist/lib/core/debugger.js +5 -5
  27. package/dist/lib/core/debugger.js.map +1 -1
  28. package/dist/lib/core/features.js +65 -68
  29. package/dist/lib/core/features.js.map +1 -1
  30. package/dist/lib/core/logger.js +21 -56
  31. package/dist/lib/core/logger.js.map +1 -1
  32. package/dist/lib/css/index.js +98 -103
  33. package/dist/lib/css/index.js.map +1 -1
  34. package/dist/lib/css/layout/__mocks__/bounds.js +1 -1
  35. package/dist/lib/css/layout/__mocks__/bounds.js.map +1 -1
  36. package/dist/lib/css/layout/bounds.js +30 -19
  37. package/dist/lib/css/layout/bounds.js.map +1 -1
  38. package/dist/lib/css/layout/text.js +50 -58
  39. package/dist/lib/css/layout/text.js.map +1 -1
  40. package/dist/lib/css/property-descriptors/__tests__/background-tests.js +24 -29
  41. package/dist/lib/css/property-descriptors/__tests__/background-tests.js.map +1 -1
  42. package/dist/lib/css/property-descriptors/__tests__/font-family.js +14 -20
  43. package/dist/lib/css/property-descriptors/__tests__/font-family.js.map +1 -1
  44. package/dist/lib/css/property-descriptors/__tests__/paint-order.js +61 -83
  45. package/dist/lib/css/property-descriptors/__tests__/paint-order.js.map +1 -1
  46. package/dist/lib/css/property-descriptors/__tests__/text-shadow.js +75 -87
  47. package/dist/lib/css/property-descriptors/__tests__/text-shadow.js.map +1 -1
  48. package/dist/lib/css/property-descriptors/__tests__/transform-tests.js +9 -13
  49. package/dist/lib/css/property-descriptors/__tests__/transform-tests.js.map +1 -1
  50. package/dist/lib/css/property-descriptors/background-clip.js +3 -3
  51. package/dist/lib/css/property-descriptors/background-clip.js.map +1 -1
  52. package/dist/lib/css/property-descriptors/background-color.js +1 -1
  53. package/dist/lib/css/property-descriptors/background-image.js +6 -6
  54. package/dist/lib/css/property-descriptors/background-image.js.map +1 -1
  55. package/dist/lib/css/property-descriptors/background-origin.js +3 -3
  56. package/dist/lib/css/property-descriptors/background-origin.js.map +1 -1
  57. package/dist/lib/css/property-descriptors/background-position.js +17 -4
  58. package/dist/lib/css/property-descriptors/background-position.js.map +1 -1
  59. package/dist/lib/css/property-descriptors/background-repeat.js +7 -9
  60. package/dist/lib/css/property-descriptors/background-repeat.js.map +1 -1
  61. package/dist/lib/css/property-descriptors/background-size.js +5 -7
  62. package/dist/lib/css/property-descriptors/background-size.js.map +1 -1
  63. package/dist/lib/css/property-descriptors/border-color.js +3 -3
  64. package/dist/lib/css/property-descriptors/border-color.js.map +1 -1
  65. package/dist/lib/css/property-descriptors/border-radius.js +5 -7
  66. package/dist/lib/css/property-descriptors/border-radius.js.map +1 -1
  67. package/dist/lib/css/property-descriptors/border-style.js +4 -4
  68. package/dist/lib/css/property-descriptors/border-style.js.map +1 -1
  69. package/dist/lib/css/property-descriptors/border-width.js +5 -5
  70. package/dist/lib/css/property-descriptors/border-width.js.map +1 -1
  71. package/dist/lib/css/property-descriptors/box-shadow.js +10 -10
  72. package/dist/lib/css/property-descriptors/box-shadow.js.map +1 -1
  73. package/dist/lib/css/property-descriptors/color.js +1 -1
  74. package/dist/lib/css/property-descriptors/content.js +2 -2
  75. package/dist/lib/css/property-descriptors/content.js.map +1 -1
  76. package/dist/lib/css/property-descriptors/counter-increment.js +10 -10
  77. package/dist/lib/css/property-descriptors/counter-increment.js.map +1 -1
  78. package/dist/lib/css/property-descriptors/counter-reset.js +9 -9
  79. package/dist/lib/css/property-descriptors/counter-reset.js.map +1 -1
  80. package/dist/lib/css/property-descriptors/direction.js +1 -1
  81. package/dist/lib/css/property-descriptors/direction.js.map +1 -1
  82. package/dist/lib/css/property-descriptors/display.js +4 -4
  83. package/dist/lib/css/property-descriptors/display.js.map +1 -1
  84. package/dist/lib/css/property-descriptors/duration.js +4 -4
  85. package/dist/lib/css/property-descriptors/duration.js.map +1 -1
  86. package/dist/lib/css/property-descriptors/float.js +1 -1
  87. package/dist/lib/css/property-descriptors/float.js.map +1 -1
  88. package/dist/lib/css/property-descriptors/font-family.js +6 -6
  89. package/dist/lib/css/property-descriptors/font-family.js.map +1 -1
  90. package/dist/lib/css/property-descriptors/font-size.js +1 -1
  91. package/dist/lib/css/property-descriptors/font-style.js +1 -1
  92. package/dist/lib/css/property-descriptors/font-style.js.map +1 -1
  93. package/dist/lib/css/property-descriptors/font-variant.js +3 -3
  94. package/dist/lib/css/property-descriptors/font-variant.js.map +1 -1
  95. package/dist/lib/css/property-descriptors/font-weight.js +2 -2
  96. package/dist/lib/css/property-descriptors/font-weight.js.map +1 -1
  97. package/dist/lib/css/property-descriptors/letter-spacing.js +1 -1
  98. package/dist/lib/css/property-descriptors/letter-spacing.js.map +1 -1
  99. package/dist/lib/css/property-descriptors/line-break.js +1 -1
  100. package/dist/lib/css/property-descriptors/line-break.js.map +1 -1
  101. package/dist/lib/css/property-descriptors/line-height.js +3 -3
  102. package/dist/lib/css/property-descriptors/line-height.js.map +1 -1
  103. package/dist/lib/css/property-descriptors/list-style-image.js +2 -2
  104. package/dist/lib/css/property-descriptors/list-style-image.js.map +1 -1
  105. package/dist/lib/css/property-descriptors/list-style-position.js +1 -1
  106. package/dist/lib/css/property-descriptors/list-style-position.js.map +1 -1
  107. package/dist/lib/css/property-descriptors/list-style-type.js +1 -1
  108. package/dist/lib/css/property-descriptors/list-style-type.js.map +1 -1
  109. package/dist/lib/css/property-descriptors/margin.js +3 -3
  110. package/dist/lib/css/property-descriptors/margin.js.map +1 -1
  111. package/dist/lib/css/property-descriptors/object-fit.js +4 -4
  112. package/dist/lib/css/property-descriptors/object-fit.js.map +1 -1
  113. package/dist/lib/css/property-descriptors/opacity.js +2 -2
  114. package/dist/lib/css/property-descriptors/opacity.js.map +1 -1
  115. package/dist/lib/css/property-descriptors/overflow-wrap.js +1 -1
  116. package/dist/lib/css/property-descriptors/overflow-wrap.js.map +1 -1
  117. package/dist/lib/css/property-descriptors/overflow.js +3 -3
  118. package/dist/lib/css/property-descriptors/overflow.js.map +1 -1
  119. package/dist/lib/css/property-descriptors/padding.js +3 -3
  120. package/dist/lib/css/property-descriptors/padding.js.map +1 -1
  121. package/dist/lib/css/property-descriptors/paint-order.js +6 -6
  122. package/dist/lib/css/property-descriptors/paint-order.js.map +1 -1
  123. package/dist/lib/css/property-descriptors/position.js +1 -1
  124. package/dist/lib/css/property-descriptors/position.js.map +1 -1
  125. package/dist/lib/css/property-descriptors/quotes.js +11 -11
  126. package/dist/lib/css/property-descriptors/quotes.js.map +1 -1
  127. package/dist/lib/css/property-descriptors/rotate.js +3 -3
  128. package/dist/lib/css/property-descriptors/rotate.js.map +1 -1
  129. package/dist/lib/css/property-descriptors/text-align.js +1 -1
  130. package/dist/lib/css/property-descriptors/text-align.js.map +1 -1
  131. package/dist/lib/css/property-descriptors/text-decoration-color.js +1 -1
  132. package/dist/lib/css/property-descriptors/text-decoration-line.js +4 -4
  133. package/dist/lib/css/property-descriptors/text-decoration-line.js.map +1 -1
  134. package/dist/lib/css/property-descriptors/text-shadow.js +10 -10
  135. package/dist/lib/css/property-descriptors/text-shadow.js.map +1 -1
  136. package/dist/lib/css/property-descriptors/text-transform.js +1 -1
  137. package/dist/lib/css/property-descriptors/text-transform.js.map +1 -1
  138. package/dist/lib/css/property-descriptors/transform-origin.js +6 -6
  139. package/dist/lib/css/property-descriptors/transform-origin.js.map +1 -1
  140. package/dist/lib/css/property-descriptors/transform.js +15 -15
  141. package/dist/lib/css/property-descriptors/transform.js.map +1 -1
  142. package/dist/lib/css/property-descriptors/visibility.js +1 -1
  143. package/dist/lib/css/property-descriptors/visibility.js.map +1 -1
  144. package/dist/lib/css/property-descriptors/webkit-text-stroke-color.js +1 -1
  145. package/dist/lib/css/property-descriptors/webkit-text-stroke-width.js +3 -3
  146. package/dist/lib/css/property-descriptors/webkit-text-stroke-width.js.map +1 -1
  147. package/dist/lib/css/property-descriptors/word-break.js +1 -1
  148. package/dist/lib/css/property-descriptors/word-break.js.map +1 -1
  149. package/dist/lib/css/property-descriptors/z-index.js +3 -3
  150. package/dist/lib/css/property-descriptors/z-index.js.map +1 -1
  151. package/dist/lib/css/syntax/__tests__/tokernizer-tests.js +17 -25
  152. package/dist/lib/css/syntax/__tests__/tokernizer-tests.js.map +1 -1
  153. package/dist/lib/css/syntax/parser.js +50 -55
  154. package/dist/lib/css/syntax/parser.js.map +1 -1
  155. package/dist/lib/css/syntax/tokenizer.js +205 -214
  156. package/dist/lib/css/syntax/tokenizer.js.map +1 -1
  157. package/dist/lib/css/types/__tests__/color-tests.js +103 -167
  158. package/dist/lib/css/types/__tests__/color-tests.js.map +1 -1
  159. package/dist/lib/css/types/__tests__/image-tests.js +192 -217
  160. package/dist/lib/css/types/__tests__/image-tests.js.map +1 -1
  161. package/dist/lib/css/types/angle.js +13 -13
  162. package/dist/lib/css/types/angle.js.map +1 -1
  163. package/dist/lib/css/types/color-spaces/a98.js +18 -22
  164. package/dist/lib/css/types/color-spaces/a98.js.map +1 -1
  165. package/dist/lib/css/types/color-spaces/p3.js +17 -22
  166. package/dist/lib/css/types/color-spaces/p3.js.map +1 -1
  167. package/dist/lib/css/types/color-spaces/pro-photo.js +17 -21
  168. package/dist/lib/css/types/color-spaces/pro-photo.js.map +1 -1
  169. package/dist/lib/css/types/color-spaces/rec2020.js +15 -19
  170. package/dist/lib/css/types/color-spaces/rec2020.js.map +1 -1
  171. package/dist/lib/css/types/color-spaces/srgb.js +17 -23
  172. package/dist/lib/css/types/color-spaces/srgb.js.map +1 -1
  173. package/dist/lib/css/types/color-utilities.js +80 -103
  174. package/dist/lib/css/types/color-utilities.js.map +1 -1
  175. package/dist/lib/css/types/color.js +72 -66
  176. package/dist/lib/css/types/color.js.map +1 -1
  177. package/dist/lib/css/types/functions/-prefix-linear-gradient.js +11 -11
  178. package/dist/lib/css/types/functions/-prefix-linear-gradient.js.map +1 -1
  179. package/dist/lib/css/types/functions/-prefix-radial-gradient.js +16 -16
  180. package/dist/lib/css/types/functions/-prefix-radial-gradient.js.map +1 -1
  181. package/dist/lib/css/types/functions/-webkit-gradient.js +26 -26
  182. package/dist/lib/css/types/functions/-webkit-gradient.js.map +1 -1
  183. package/dist/lib/css/types/functions/__tests__/radial-gradient.js +57 -65
  184. package/dist/lib/css/types/functions/__tests__/radial-gradient.js.map +1 -1
  185. package/dist/lib/css/types/functions/counter.js +59 -65
  186. package/dist/lib/css/types/functions/counter.js.map +1 -1
  187. package/dist/lib/css/types/functions/gradient.js +51 -52
  188. package/dist/lib/css/types/functions/gradient.js.map +1 -1
  189. package/dist/lib/css/types/functions/linear-gradient.js +10 -10
  190. package/dist/lib/css/types/functions/linear-gradient.js.map +1 -1
  191. package/dist/lib/css/types/functions/radial-gradient.js +17 -17
  192. package/dist/lib/css/types/functions/radial-gradient.js.map +1 -1
  193. package/dist/lib/css/types/image.js +14 -14
  194. package/dist/lib/css/types/image.js.map +1 -1
  195. package/dist/lib/css/types/length-percentage.js +94 -12
  196. package/dist/lib/css/types/length-percentage.js.map +1 -1
  197. package/dist/lib/css/types/length.js +1 -3
  198. package/dist/lib/css/types/length.js.map +1 -1
  199. package/dist/lib/css/types/time.js +2 -2
  200. package/dist/lib/css/types/time.js.map +1 -1
  201. package/dist/lib/dom/__mocks__/document-cloner.js +7 -8
  202. package/dist/lib/dom/__mocks__/document-cloner.js.map +1 -1
  203. package/dist/lib/dom/document-cloner.js +195 -219
  204. package/dist/lib/dom/document-cloner.js.map +1 -1
  205. package/dist/lib/dom/element-container.js +8 -9
  206. package/dist/lib/dom/element-container.js.map +1 -1
  207. package/dist/lib/dom/elements/li-element-container.js +6 -24
  208. package/dist/lib/dom/elements/li-element-container.js.map +1 -1
  209. package/dist/lib/dom/elements/ol-element-container.js +7 -25
  210. package/dist/lib/dom/elements/ol-element-container.js.map +1 -1
  211. package/dist/lib/dom/elements/select-element-container.js +7 -25
  212. package/dist/lib/dom/elements/select-element-container.js.map +1 -1
  213. package/dist/lib/dom/elements/textarea-element-container.js +6 -24
  214. package/dist/lib/dom/elements/textarea-element-container.js.map +1 -1
  215. package/dist/lib/dom/node-parser.js +54 -45
  216. package/dist/lib/dom/node-parser.js.map +1 -1
  217. package/dist/lib/dom/replaced-elements/canvas-element-container.js +8 -26
  218. package/dist/lib/dom/replaced-elements/canvas-element-container.js.map +1 -1
  219. package/dist/lib/dom/replaced-elements/iframe-element-container.js +17 -35
  220. package/dist/lib/dom/replaced-elements/iframe-element-container.js.map +1 -1
  221. package/dist/lib/dom/replaced-elements/image-element-container.js +9 -27
  222. package/dist/lib/dom/replaced-elements/image-element-container.js.map +1 -1
  223. package/dist/lib/dom/replaced-elements/input-element-container.js +47 -59
  224. package/dist/lib/dom/replaced-elements/input-element-container.js.map +1 -1
  225. package/dist/lib/dom/replaced-elements/svg-element-container.js +14 -32
  226. package/dist/lib/dom/replaced-elements/svg-element-container.js.map +1 -1
  227. package/dist/lib/dom/text-container.js +7 -8
  228. package/dist/lib/dom/text-container.js.map +1 -1
  229. package/dist/lib/index.js +99 -156
  230. package/dist/lib/index.js.map +1 -1
  231. package/dist/lib/invariant.js +1 -1
  232. package/dist/lib/invariant.js.map +1 -1
  233. package/dist/lib/render/background.js +44 -47
  234. package/dist/lib/render/background.js.map +1 -1
  235. package/dist/lib/render/bezier-curve.js +18 -19
  236. package/dist/lib/render/bezier-curve.js.map +1 -1
  237. package/dist/lib/render/border.js +9 -9
  238. package/dist/lib/render/border.js.map +1 -1
  239. package/dist/lib/render/bound-curves.js +35 -36
  240. package/dist/lib/render/bound-curves.js.map +1 -1
  241. package/dist/lib/render/box-sizing.js +11 -11
  242. package/dist/lib/render/box-sizing.js.map +1 -1
  243. package/dist/lib/render/canvas/canvas-renderer.js +642 -915
  244. package/dist/lib/render/canvas/canvas-renderer.js.map +1 -1
  245. package/dist/lib/render/canvas/foreignobject-renderer.js +35 -101
  246. package/dist/lib/render/canvas/foreignobject-renderer.js.map +1 -1
  247. package/dist/lib/render/effects.js +12 -17
  248. package/dist/lib/render/effects.js.map +1 -1
  249. package/dist/lib/render/font-metrics.js +17 -18
  250. package/dist/lib/render/font-metrics.js.map +1 -1
  251. package/dist/lib/render/path.js +4 -4
  252. package/dist/lib/render/path.js.map +1 -1
  253. package/dist/lib/render/renderer.js +3 -4
  254. package/dist/lib/render/renderer.js.map +1 -1
  255. package/dist/lib/render/stacking-context.js +71 -70
  256. package/dist/lib/render/stacking-context.js.map +1 -1
  257. package/dist/lib/render/vector.js +6 -7
  258. package/dist/lib/render/vector.js.map +1 -1
  259. package/dist/types/css/types/length-percentage.d.ts +11 -1
  260. package/dist/types/dom/replaced-elements/input-element-container.d.ts +2 -0
  261. package/eslint.config.js +35 -0
  262. package/jest.config.cjs +5 -0
  263. package/karma.conf.cjs +295 -0
  264. package/package.json +19 -15
  265. package/test-punctuation.html +0 -77
@@ -1,114 +1,60 @@
1
1
  "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = function (d, b) {
4
- extendStatics = Object.setPrototypeOf ||
5
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
- return extendStatics(d, b);
8
- };
9
- return function (d, b) {
10
- if (typeof b !== "function" && b !== null)
11
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
- extendStatics(d, b);
13
- function __() { this.constructor = d; }
14
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
- };
16
- })();
17
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
- return new (P || (P = Promise))(function (resolve, reject) {
20
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
21
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
22
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
23
- step((generator = generator.apply(thisArg, _arguments || [])).next());
24
- });
25
- };
26
- var __generator = (this && this.__generator) || function (thisArg, body) {
27
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
28
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
29
- function verb(n) { return function (v) { return step([n, v]); }; }
30
- function step(op) {
31
- if (f) throw new TypeError("Generator is already executing.");
32
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
33
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
34
- if (y = 0, t) op = [op[0] & 2, t.value];
35
- switch (op[0]) {
36
- case 0: case 1: t = op; break;
37
- case 4: _.label++; return { value: op[1], done: false };
38
- case 5: _.label++; y = op[1]; op = [0]; continue;
39
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
40
- default:
41
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
42
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
43
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
44
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
45
- if (t[2]) _.ops.pop();
46
- _.trys.pop(); continue;
47
- }
48
- op = body.call(thisArg, _);
49
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
50
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
- }
52
- };
53
2
  Object.defineProperty(exports, "__esModule", { value: true });
54
3
  exports.CanvasRenderer = void 0;
55
- var stacking_context_1 = require("../stacking-context");
56
- var color_utilities_1 = require("../../css/types/color-utilities");
57
- var path_1 = require("../path");
58
- var bound_curves_1 = require("../bound-curves");
59
- var bezier_curve_1 = require("../bezier-curve");
60
- var vector_1 = require("../vector");
61
- var image_1 = require("../../css/types/image");
62
- var border_1 = require("../border");
63
- var background_1 = require("../background");
64
- var parser_1 = require("../../css/syntax/parser");
65
- var text_1 = require("../../css/layout/text");
66
- var image_element_container_1 = require("../../dom/replaced-elements/image-element-container");
67
- var box_sizing_1 = require("../box-sizing");
68
- var canvas_element_container_1 = require("../../dom/replaced-elements/canvas-element-container");
69
- var svg_element_container_1 = require("../../dom/replaced-elements/svg-element-container");
70
- var effects_1 = require("../effects");
71
- var bitwise_1 = require("../../core/bitwise");
72
- var gradient_1 = require("../../css/types/functions/gradient");
73
- var length_percentage_1 = require("../../css/types/length-percentage");
74
- var font_metrics_1 = require("../font-metrics");
75
- var bounds_1 = require("../../css/layout/bounds");
76
- var line_height_1 = require("../../css/property-descriptors/line-height");
77
- var input_element_container_1 = require("../../dom/replaced-elements/input-element-container");
78
- var textarea_element_container_1 = require("../../dom/elements/textarea-element-container");
79
- var select_element_container_1 = require("../../dom/elements/select-element-container");
80
- var iframe_element_container_1 = require("../../dom/replaced-elements/iframe-element-container");
81
- var renderer_1 = require("../renderer");
82
- var MASK_OFFSET = 10000;
83
- var CanvasRenderer = /** @class */ (function (_super) {
84
- __extends(CanvasRenderer, _super);
85
- function CanvasRenderer(context, options) {
86
- var _this = _super.call(this, context, options) || this;
87
- _this._activeEffects = [];
88
- _this.canvas = options.canvas ? options.canvas : document.createElement('canvas');
89
- _this.ctx = _this.canvas.getContext('2d');
4
+ const stacking_context_1 = require("../stacking-context");
5
+ const color_utilities_1 = require("../../css/types/color-utilities");
6
+ const path_1 = require("../path");
7
+ const bound_curves_1 = require("../bound-curves");
8
+ const bezier_curve_1 = require("../bezier-curve");
9
+ const vector_1 = require("../vector");
10
+ const image_1 = require("../../css/types/image");
11
+ const border_1 = require("../border");
12
+ const background_1 = require("../background");
13
+ const parser_1 = require("../../css/syntax/parser");
14
+ const text_1 = require("../../css/layout/text");
15
+ const image_element_container_1 = require("../../dom/replaced-elements/image-element-container");
16
+ const box_sizing_1 = require("../box-sizing");
17
+ const canvas_element_container_1 = require("../../dom/replaced-elements/canvas-element-container");
18
+ const svg_element_container_1 = require("../../dom/replaced-elements/svg-element-container");
19
+ const effects_1 = require("../effects");
20
+ const bitwise_1 = require("../../core/bitwise");
21
+ const gradient_1 = require("../../css/types/functions/gradient");
22
+ const length_percentage_1 = require("../../css/types/length-percentage");
23
+ const font_metrics_1 = require("../font-metrics");
24
+ const bounds_1 = require("../../css/layout/bounds");
25
+ const line_height_1 = require("../../css/property-descriptors/line-height");
26
+ const input_element_container_1 = require("../../dom/replaced-elements/input-element-container");
27
+ const textarea_element_container_1 = require("../../dom/elements/textarea-element-container");
28
+ const select_element_container_1 = require("../../dom/elements/select-element-container");
29
+ const iframe_element_container_1 = require("../../dom/replaced-elements/iframe-element-container");
30
+ const renderer_1 = require("../renderer");
31
+ const MASK_OFFSET = 10000;
32
+ class CanvasRenderer extends renderer_1.Renderer {
33
+ constructor(context, options) {
34
+ super(context, options);
35
+ this._activeEffects = [];
36
+ this.canvas = options.canvas ? options.canvas : document.createElement('canvas');
37
+ this.ctx = this.canvas.getContext('2d');
90
38
  if (!options.canvas) {
91
- _this.canvas.width = Math.floor(options.width * options.scale);
92
- _this.canvas.height = Math.floor(options.height * options.scale);
93
- _this.canvas.style.width = "".concat(options.width, "px");
94
- _this.canvas.style.height = "".concat(options.height, "px");
39
+ this.canvas.width = Math.floor(options.width * options.scale);
40
+ this.canvas.height = Math.floor(options.height * options.scale);
41
+ this.canvas.style.width = `${options.width}px`;
42
+ this.canvas.style.height = `${options.height}px`;
95
43
  }
96
- _this.fontMetrics = new font_metrics_1.FontMetrics(document);
97
- _this.ctx.scale(_this.options.scale, _this.options.scale);
98
- _this.ctx.translate(-options.x, -options.y);
99
- _this.ctx.textBaseline = 'bottom';
100
- _this._activeEffects = [];
101
- _this.context.logger.debug("Canvas renderer initialized (".concat(options.width, "x").concat(options.height, ") with scale ").concat(options.scale));
102
- return _this;
44
+ this.fontMetrics = new font_metrics_1.FontMetrics(document);
45
+ this.ctx.scale(this.options.scale, this.options.scale);
46
+ this.ctx.translate(-options.x, -options.y);
47
+ this.ctx.textBaseline = 'bottom';
48
+ this._activeEffects = [];
49
+ this.context.logger.debug(`Canvas renderer initialized (${options.width}x${options.height}) with scale ${options.scale}`);
103
50
  }
104
- CanvasRenderer.prototype.applyEffects = function (effects) {
105
- var _this = this;
51
+ applyEffects(effects) {
106
52
  while (this._activeEffects.length) {
107
53
  this.popEffect();
108
54
  }
109
- effects.forEach(function (effect) { return _this.applyEffect(effect); });
110
- };
111
- CanvasRenderer.prototype.applyEffect = function (effect) {
55
+ effects.forEach((effect) => this.applyEffect(effect));
56
+ }
57
+ applyEffect(effect) {
112
58
  this.ctx.save();
113
59
  if ((0, effects_1.isOpacityEffect)(effect)) {
114
60
  this.ctx.globalAlpha = effect.opacity;
@@ -123,169 +69,143 @@ var CanvasRenderer = /** @class */ (function (_super) {
123
69
  this.ctx.clip();
124
70
  }
125
71
  this._activeEffects.push(effect);
126
- };
127
- CanvasRenderer.prototype.popEffect = function () {
72
+ }
73
+ popEffect() {
128
74
  this._activeEffects.pop();
129
75
  this.ctx.restore();
130
- };
131
- CanvasRenderer.prototype.renderStack = function (stack) {
132
- return __awaiter(this, void 0, void 0, function () {
133
- var styles;
134
- return __generator(this, function (_a) {
135
- switch (_a.label) {
136
- case 0:
137
- styles = stack.element.container.styles;
138
- if (!styles.isVisible()) return [3 /*break*/, 2];
139
- return [4 /*yield*/, this.renderStackContent(stack)];
140
- case 1:
141
- _a.sent();
142
- _a.label = 2;
143
- case 2: return [2 /*return*/];
144
- }
145
- });
146
- });
147
- };
148
- CanvasRenderer.prototype.renderNode = function (paint) {
149
- return __awaiter(this, void 0, void 0, function () {
150
- return __generator(this, function (_a) {
151
- switch (_a.label) {
152
- case 0:
153
- if ((0, bitwise_1.contains)(paint.container.flags, 16 /* FLAGS.DEBUG_RENDER */)) {
154
- debugger;
155
- }
156
- if (!paint.container.styles.isVisible()) return [3 /*break*/, 3];
157
- return [4 /*yield*/, this.renderNodeBackgroundAndBorders(paint)];
158
- case 1:
159
- _a.sent();
160
- return [4 /*yield*/, this.renderNodeContent(paint)];
161
- case 2:
162
- _a.sent();
163
- _a.label = 3;
164
- case 3: return [2 /*return*/];
165
- }
166
- });
167
- });
168
- };
169
- CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing, baseline) {
170
- var _this = this;
76
+ }
77
+ async renderStack(stack) {
78
+ const styles = stack.element.container.styles;
79
+ if (styles.isVisible()) {
80
+ await this.renderStackContent(stack);
81
+ }
82
+ }
83
+ async renderNode(paint) {
84
+ if ((0, bitwise_1.contains)(paint.container.flags, 16 /* FLAGS.DEBUG_RENDER */)) {
85
+ debugger;
86
+ }
87
+ if (paint.container.styles.isVisible()) {
88
+ await this.renderNodeBackgroundAndBorders(paint);
89
+ await this.renderNodeContent(paint);
90
+ }
91
+ }
92
+ renderTextWithLetterSpacing(text, letterSpacing, baseline) {
171
93
  if (letterSpacing === 0) {
172
- // Fixed an issue with characters moving up in non-Firefox.
173
- // https://github.com/niklasvh/html2canvas/issues/2107#issuecomment-692462900
174
- if (navigator.userAgent.indexOf('Firefox') === -1) {
175
- this.ctx.textBaseline = 'ideographic';
176
- this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
177
- }
178
- else {
179
- this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline);
180
- }
94
+ // Use alphabetic baseline for consistent text positioning across browsers
95
+ // Issue #129: text.bounds.top + text.bounds.height causes text to render too low
96
+ this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline);
181
97
  }
182
98
  else {
183
- var letters = (0, text_1.segmentGraphemes)(text.text);
184
- letters.reduce(function (left, letter) {
185
- _this.ctx.fillText(letter, left, text.bounds.top + baseline);
186
- return left + _this.ctx.measureText(letter).width;
99
+ const letters = (0, text_1.segmentGraphemes)(text.text);
100
+ letters.reduce((left, letter) => {
101
+ this.ctx.fillText(letter, left, text.bounds.top + baseline);
102
+ return left + this.ctx.measureText(letter).width;
187
103
  }, text.bounds.left);
188
104
  }
189
- };
190
- CanvasRenderer.prototype.createFontStyle = function (styles) {
191
- var fontVariant = styles.fontVariant
192
- .filter(function (variant) { return variant === 'normal' || variant === 'small-caps'; })
105
+ }
106
+ createFontStyle(styles) {
107
+ const fontVariant = styles.fontVariant
108
+ .filter((variant) => variant === 'normal' || variant === 'small-caps')
193
109
  .join('');
194
- var fontFamily = fixIOSSystemFonts(styles.fontFamily).join(', ');
195
- var fontSize = (0, parser_1.isDimensionToken)(styles.fontSize)
196
- ? "".concat(styles.fontSize.number).concat(styles.fontSize.unit)
197
- : "".concat(styles.fontSize.number, "px");
110
+ const fontFamily = fixIOSSystemFonts(styles.fontFamily).join(', ');
111
+ const fontSize = (0, parser_1.isDimensionToken)(styles.fontSize)
112
+ ? `${styles.fontSize.number}${styles.fontSize.unit}`
113
+ : `${styles.fontSize.number}px`;
198
114
  return [
199
115
  [styles.fontStyle, fontVariant, styles.fontWeight, fontSize, fontFamily].join(' '),
200
116
  fontFamily,
201
117
  fontSize
202
118
  ];
203
- };
204
- CanvasRenderer.prototype.renderTextNode = function (text, styles) {
205
- return __awaiter(this, void 0, void 0, function () {
206
- var font, paintOrder;
207
- var _this = this;
208
- return __generator(this, function (_a) {
209
- font = this.createFontStyle(styles)[0];
210
- this.ctx.font = font;
211
- this.ctx.direction = styles.direction === 1 /* DIRECTION.RTL */ ? 'rtl' : 'ltr';
212
- this.ctx.textAlign = 'left';
213
- this.ctx.textBaseline = 'alphabetic';
214
- paintOrder = styles.paintOrder;
215
- text.textBounds.forEach(function (text) {
216
- paintOrder.forEach(function (paintOrderLayer) {
217
- switch (paintOrderLayer) {
218
- case 0 /* PAINT_ORDER_LAYER.FILL */:
219
- _this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.color);
220
- _this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number);
221
- var textShadows = styles.textShadow;
222
- if (textShadows.length && text.text.trim().length) {
223
- textShadows
224
- .slice(0)
225
- .reverse()
226
- .forEach(function (textShadow) {
227
- _this.ctx.shadowColor = (0, color_utilities_1.asString)(textShadow.color);
228
- _this.ctx.shadowOffsetX = textShadow.offsetX.number * _this.options.scale;
229
- _this.ctx.shadowOffsetY = textShadow.offsetY.number * _this.options.scale;
230
- _this.ctx.shadowBlur = textShadow.blur.number;
231
- _this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number);
232
- });
233
- _this.ctx.shadowColor = '';
234
- _this.ctx.shadowOffsetX = 0;
235
- _this.ctx.shadowOffsetY = 0;
236
- _this.ctx.shadowBlur = 0;
237
- }
238
- if (styles.textDecorationLine.length) {
239
- _this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.textDecorationColor || styles.color);
240
- var decorationLineHeight_1 = 1;
241
- styles.textDecorationLine.forEach(function (textDecorationLine) {
242
- // Fix the issue where textDecorationLine exhibits x-axis positioning errors on high-resolution devices due to varying devicePixelRatio, corrected by using relative values of element heights.
243
- switch (textDecorationLine) {
244
- case 1 /* TEXT_DECORATION_LINE.UNDERLINE */:
245
- _this.ctx.fillRect(text.bounds.left, text.bounds.top + text.bounds.height - decorationLineHeight_1, text.bounds.width, decorationLineHeight_1);
246
- break;
247
- case 2 /* TEXT_DECORATION_LINE.OVERLINE */:
248
- _this.ctx.fillRect(text.bounds.left, text.bounds.top, text.bounds.width, decorationLineHeight_1);
249
- break;
250
- case 3 /* TEXT_DECORATION_LINE.LINE_THROUGH */:
251
- _this.ctx.fillRect(text.bounds.left, text.bounds.top + (text.bounds.height / 2 - decorationLineHeight_1 / 2), text.bounds.width, decorationLineHeight_1);
252
- break;
253
- }
254
- });
255
- }
256
- break;
257
- case 1 /* PAINT_ORDER_LAYER.STROKE */:
258
- if (styles.webkitTextStrokeWidth && text.text.trim().length) {
259
- _this.ctx.strokeStyle = (0, color_utilities_1.asString)(styles.webkitTextStrokeColor);
260
- _this.ctx.lineWidth = styles.webkitTextStrokeWidth;
261
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
262
- _this.ctx.lineJoin = !!window.chrome ? 'miter' : 'round';
263
- _this.ctx.strokeText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
119
+ }
120
+ async renderTextNode(text, styles) {
121
+ const [font] = this.createFontStyle(styles);
122
+ this.ctx.font = font;
123
+ this.ctx.direction = styles.direction === 1 /* DIRECTION.RTL */ ? 'rtl' : 'ltr';
124
+ this.ctx.textAlign = 'left';
125
+ this.ctx.textBaseline = 'alphabetic';
126
+ const paintOrder = styles.paintOrder;
127
+ text.textBounds.forEach((text) => {
128
+ paintOrder.forEach((paintOrderLayer) => {
129
+ switch (paintOrderLayer) {
130
+ case 0 /* PAINT_ORDER_LAYER.FILL */:
131
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.color);
132
+ this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number);
133
+ const textShadows = styles.textShadow;
134
+ if (textShadows.length && text.text.trim().length) {
135
+ textShadows
136
+ .slice(0)
137
+ .reverse()
138
+ .forEach((textShadow) => {
139
+ this.ctx.shadowColor = (0, color_utilities_1.asString)(textShadow.color);
140
+ this.ctx.shadowOffsetX = textShadow.offsetX.number * this.options.scale;
141
+ this.ctx.shadowOffsetY = textShadow.offsetY.number * this.options.scale;
142
+ this.ctx.shadowBlur = textShadow.blur.number;
143
+ this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number);
144
+ });
145
+ this.ctx.shadowColor = '';
146
+ this.ctx.shadowOffsetX = 0;
147
+ this.ctx.shadowOffsetY = 0;
148
+ this.ctx.shadowBlur = 0;
149
+ }
150
+ if (styles.textDecorationLine.length) {
151
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.textDecorationColor || styles.color);
152
+ const decorationLineHeight = 1;
153
+ styles.textDecorationLine.forEach((textDecorationLine) => {
154
+ // Fix the issue where textDecorationLine exhibits x-axis positioning errors on high-resolution devices due to varying devicePixelRatio, corrected by using relative values of element heights.
155
+ switch (textDecorationLine) {
156
+ case 1 /* TEXT_DECORATION_LINE.UNDERLINE */:
157
+ this.ctx.fillRect(text.bounds.left, text.bounds.top + text.bounds.height - decorationLineHeight, text.bounds.width, decorationLineHeight);
158
+ break;
159
+ case 2 /* TEXT_DECORATION_LINE.OVERLINE */:
160
+ this.ctx.fillRect(text.bounds.left, text.bounds.top, text.bounds.width, decorationLineHeight);
161
+ break;
162
+ case 3 /* TEXT_DECORATION_LINE.LINE_THROUGH */:
163
+ this.ctx.fillRect(text.bounds.left, text.bounds.top + (text.bounds.height / 2 - decorationLineHeight / 2), text.bounds.width, decorationLineHeight);
164
+ break;
264
165
  }
265
- _this.ctx.strokeStyle = '';
266
- _this.ctx.lineWidth = 0;
267
- _this.ctx.lineJoin = 'miter';
268
- break;
166
+ });
269
167
  }
270
- });
271
- });
272
- return [2 /*return*/];
168
+ break;
169
+ case 1 /* PAINT_ORDER_LAYER.STROKE */:
170
+ if (styles.webkitTextStrokeWidth && text.text.trim().length) {
171
+ this.ctx.strokeStyle = (0, color_utilities_1.asString)(styles.webkitTextStrokeColor);
172
+ this.ctx.lineWidth = styles.webkitTextStrokeWidth;
173
+ this.ctx.lineJoin = !!window.chrome ? 'miter' : 'round';
174
+ // Issue #110: Use baseline (fontSize) for consistent positioning with fill
175
+ // Previously used text.bounds.height which caused stroke to render too low
176
+ const baseline = styles.fontSize.number;
177
+ if (styles.letterSpacing === 0) {
178
+ this.ctx.strokeText(text.text, text.bounds.left, text.bounds.top + baseline);
179
+ }
180
+ else {
181
+ const letters = (0, text_1.segmentGraphemes)(text.text);
182
+ letters.reduce((left, letter) => {
183
+ this.ctx.strokeText(letter, left, text.bounds.top + baseline);
184
+ return left + this.ctx.measureText(letter).width;
185
+ }, text.bounds.left);
186
+ }
187
+ }
188
+ this.ctx.strokeStyle = '';
189
+ this.ctx.lineWidth = 0;
190
+ this.ctx.lineJoin = 'miter';
191
+ break;
192
+ }
273
193
  });
274
194
  });
275
- };
276
- CanvasRenderer.prototype.renderReplacedElement = function (container, curves, image) {
277
- var intrinsicWidth = image.naturalWidth || container.intrinsicWidth;
278
- var intrinsicHeight = image.naturalHeight || container.intrinsicHeight;
195
+ }
196
+ renderReplacedElement(container, curves, image) {
197
+ const intrinsicWidth = image.naturalWidth || container.intrinsicWidth;
198
+ const intrinsicHeight = image.naturalHeight || container.intrinsicHeight;
279
199
  if (image && intrinsicWidth > 0 && intrinsicHeight > 0) {
280
- var box = (0, box_sizing_1.contentBox)(container);
281
- var path = (0, bound_curves_1.calculatePaddingBoxPath)(curves);
200
+ const box = (0, box_sizing_1.contentBox)(container);
201
+ const path = (0, bound_curves_1.calculatePaddingBoxPath)(curves);
282
202
  this.path(path);
283
203
  this.ctx.save();
284
204
  this.ctx.clip();
285
- var sx = 0, sy = 0, sw = intrinsicWidth, sh = intrinsicHeight, dx = box.left, dy = box.top, dw = box.width, dh = box.height;
286
- var objectFit = container.styles.objectFit;
287
- var boxRatio = dw / dh;
288
- var imgRatio = sw / sh;
205
+ let sx = 0, sy = 0, sw = intrinsicWidth, sh = intrinsicHeight, dx = box.left, dy = box.top, dw = box.width, dh = box.height;
206
+ const { objectFit } = container.styles;
207
+ const boxRatio = dw / dh;
208
+ const imgRatio = sw / sh;
289
209
  if (objectFit === 2 /* OBJECT_FIT.CONTAIN */) {
290
210
  if (imgRatio > boxRatio) {
291
211
  dh = dw / imgRatio;
@@ -325,8 +245,8 @@ var CanvasRenderer = /** @class */ (function (_super) {
325
245
  }
326
246
  }
327
247
  else if (objectFit === 16 /* OBJECT_FIT.SCALE_DOWN */) {
328
- var containW = imgRatio > boxRatio ? dw : dh * imgRatio;
329
- var noneW = sw > dw ? sw : dw;
248
+ const containW = imgRatio > boxRatio ? dw : dh * imgRatio;
249
+ const noneW = sw > dw ? sw : dw;
330
250
  if (containW < noneW) {
331
251
  if (imgRatio > boxRatio) {
332
252
  dh = dw / imgRatio;
@@ -359,718 +279,525 @@ var CanvasRenderer = /** @class */ (function (_super) {
359
279
  this.ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
360
280
  this.ctx.restore();
361
281
  }
362
- };
363
- CanvasRenderer.prototype.renderNodeContent = function (paint) {
364
- return __awaiter(this, void 0, void 0, function () {
365
- var container, curves, styles, _i, _a, child, image, e_1, image, e_2, iframeRenderer, canvas, size, _b, font, fontFamily, fontSize, baseline, bounds, x, textBounds, img, image, url, e_3, font, bounds;
366
- return __generator(this, function (_c) {
367
- switch (_c.label) {
368
- case 0:
369
- this.applyEffects(paint.getEffects(4 /* EffectTarget.CONTENT */));
370
- container = paint.container;
371
- curves = paint.curves;
372
- styles = container.styles;
373
- _i = 0, _a = container.textNodes;
374
- _c.label = 1;
375
- case 1:
376
- if (!(_i < _a.length)) return [3 /*break*/, 4];
377
- child = _a[_i];
378
- return [4 /*yield*/, this.renderTextNode(child, styles)];
379
- case 2:
380
- _c.sent();
381
- _c.label = 3;
382
- case 3:
383
- _i++;
384
- return [3 /*break*/, 1];
385
- case 4:
386
- if (!(container instanceof image_element_container_1.ImageElementContainer)) return [3 /*break*/, 8];
387
- _c.label = 5;
388
- case 5:
389
- _c.trys.push([5, 7, , 8]);
390
- return [4 /*yield*/, this.context.cache.match(container.src)];
391
- case 6:
392
- image = _c.sent();
393
- this.renderReplacedElement(container, curves, image);
394
- return [3 /*break*/, 8];
395
- case 7:
396
- e_1 = _c.sent();
397
- this.context.logger.error("Error loading image ".concat(container.src));
398
- return [3 /*break*/, 8];
399
- case 8:
400
- if (container instanceof canvas_element_container_1.CanvasElementContainer) {
401
- this.renderReplacedElement(container, curves, container.canvas);
402
- }
403
- if (!(container instanceof svg_element_container_1.SVGElementContainer)) return [3 /*break*/, 12];
404
- _c.label = 9;
405
- case 9:
406
- _c.trys.push([9, 11, , 12]);
407
- return [4 /*yield*/, this.context.cache.match(container.svg)];
408
- case 10:
409
- image = _c.sent();
410
- this.renderReplacedElement(container, curves, image);
411
- return [3 /*break*/, 12];
412
- case 11:
413
- e_2 = _c.sent();
414
- this.context.logger.error("Error loading svg ".concat(container.svg.substring(0, 255)));
415
- return [3 /*break*/, 12];
416
- case 12:
417
- if (!(container instanceof iframe_element_container_1.IFrameElementContainer && container.tree)) return [3 /*break*/, 14];
418
- iframeRenderer = new CanvasRenderer(this.context, {
419
- scale: this.options.scale,
420
- backgroundColor: container.backgroundColor,
421
- x: 0,
422
- y: 0,
423
- width: container.width,
424
- height: container.height
425
- });
426
- return [4 /*yield*/, iframeRenderer.render(container.tree)];
427
- case 13:
428
- canvas = _c.sent();
429
- if (container.width && container.height) {
430
- this.ctx.drawImage(canvas, 0, 0, container.width, container.height, container.bounds.left, container.bounds.top, container.bounds.width, container.bounds.height);
431
- }
432
- _c.label = 14;
433
- case 14:
434
- if (container instanceof input_element_container_1.InputElementContainer) {
435
- size = Math.min(container.bounds.width, container.bounds.height);
436
- if (container.type === input_element_container_1.CHECKBOX) {
437
- if (container.checked) {
438
- this.ctx.save();
439
- this.path([
440
- new vector_1.Vector(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79),
441
- new vector_1.Vector(container.bounds.left + size * 0.16, container.bounds.top + size * 0.5549),
442
- new vector_1.Vector(container.bounds.left + size * 0.27347, container.bounds.top + size * 0.44071),
443
- new vector_1.Vector(container.bounds.left + size * 0.39694, container.bounds.top + size * 0.5649),
444
- new vector_1.Vector(container.bounds.left + size * 0.72983, container.bounds.top + size * 0.23),
445
- new vector_1.Vector(container.bounds.left + size * 0.84, container.bounds.top + size * 0.34085),
446
- new vector_1.Vector(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79)
447
- ]);
448
- this.ctx.fillStyle = (0, color_utilities_1.asString)(input_element_container_1.INPUT_COLOR);
449
- this.ctx.fill();
450
- this.ctx.restore();
451
- }
452
- }
453
- else if (container.type === input_element_container_1.RADIO) {
454
- if (container.checked) {
455
- this.ctx.save();
456
- this.ctx.beginPath();
457
- this.ctx.arc(container.bounds.left + size / 2, container.bounds.top + size / 2, size / 4, 0, Math.PI * 2, true);
458
- this.ctx.fillStyle = (0, color_utilities_1.asString)(input_element_container_1.INPUT_COLOR);
459
- this.ctx.fill();
460
- this.ctx.restore();
461
- }
462
- }
463
- }
464
- if (isTextInputElement(container) && container.value.length) {
465
- _b = this.createFontStyle(styles), font = _b[0], fontFamily = _b[1], fontSize = _b[2];
466
- baseline = this.fontMetrics.getMetrics(fontFamily, fontSize).baseline;
467
- this.ctx.font = font;
468
- this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.color);
469
- this.ctx.textBaseline = 'alphabetic';
470
- this.ctx.textAlign = canvasTextAlign(container.styles.textAlign);
471
- bounds = (0, box_sizing_1.contentBox)(container);
472
- x = 0;
473
- switch (container.styles.textAlign) {
474
- case 1 /* TEXT_ALIGN.CENTER */:
475
- x += bounds.width / 2;
476
- break;
477
- case 2 /* TEXT_ALIGN.RIGHT */:
478
- x += bounds.width;
479
- break;
480
- }
481
- textBounds = bounds.add(x, 0, 0, -bounds.height / 2 + 1);
482
- this.ctx.save();
483
- this.path([
484
- new vector_1.Vector(bounds.left, bounds.top),
485
- new vector_1.Vector(bounds.left + bounds.width, bounds.top),
486
- new vector_1.Vector(bounds.left + bounds.width, bounds.top + bounds.height),
487
- new vector_1.Vector(bounds.left, bounds.top + bounds.height)
488
- ]);
489
- this.ctx.clip();
490
- this.renderTextWithLetterSpacing(new text_1.TextBounds(container.value, textBounds), styles.letterSpacing, baseline);
491
- this.ctx.restore();
492
- this.ctx.textBaseline = 'alphabetic';
493
- this.ctx.textAlign = 'left';
494
- }
495
- if (!(0, bitwise_1.contains)(container.styles.display, 2048 /* DISPLAY.LIST_ITEM */)) return [3 /*break*/, 20];
496
- if (!(container.styles.listStyleImage !== null)) return [3 /*break*/, 19];
497
- img = container.styles.listStyleImage;
498
- if (!(img.type === 0 /* CSSImageType.URL */)) return [3 /*break*/, 18];
499
- image = void 0;
500
- url = img.url;
501
- _c.label = 15;
502
- case 15:
503
- _c.trys.push([15, 17, , 18]);
504
- return [4 /*yield*/, this.context.cache.match(url)];
505
- case 16:
506
- image = _c.sent();
507
- this.ctx.drawImage(image, container.bounds.left - (image.width + 10), container.bounds.top);
508
- return [3 /*break*/, 18];
509
- case 17:
510
- e_3 = _c.sent();
511
- this.context.logger.error("Error loading list-style-image ".concat(url));
512
- return [3 /*break*/, 18];
513
- case 18: return [3 /*break*/, 20];
514
- case 19:
515
- if (paint.listValue && container.styles.listStyleType !== -1 /* LIST_STYLE_TYPE.NONE */) {
516
- font = this.createFontStyle(styles)[0];
517
- this.ctx.font = font;
518
- this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.color);
519
- this.ctx.textBaseline = 'middle';
520
- this.ctx.textAlign = 'right';
521
- bounds = new bounds_1.Bounds(container.bounds.left, container.bounds.top + (0, length_percentage_1.getAbsoluteValue)(container.styles.paddingTop, container.bounds.width), container.bounds.width, (0, line_height_1.computeLineHeight)(styles.lineHeight, styles.fontSize.number) / 2 + 1);
522
- this.renderTextWithLetterSpacing(new text_1.TextBounds(paint.listValue, bounds), styles.letterSpacing, (0, line_height_1.computeLineHeight)(styles.lineHeight, styles.fontSize.number) / 2 + 2);
523
- this.ctx.textBaseline = 'bottom';
524
- this.ctx.textAlign = 'left';
525
- }
526
- _c.label = 20;
527
- case 20: return [2 /*return*/];
528
- }
282
+ }
283
+ async renderNodeContent(paint) {
284
+ this.applyEffects(paint.getEffects(4 /* EffectTarget.CONTENT */));
285
+ const container = paint.container;
286
+ const curves = paint.curves;
287
+ const styles = container.styles;
288
+ for (const child of container.textNodes) {
289
+ await this.renderTextNode(child, styles);
290
+ }
291
+ if (container instanceof image_element_container_1.ImageElementContainer) {
292
+ try {
293
+ const image = await this.context.cache.match(container.src);
294
+ this.renderReplacedElement(container, curves, image);
295
+ }
296
+ catch (e) {
297
+ this.context.logger.error(`Error loading image ${container.src}`);
298
+ }
299
+ }
300
+ if (container instanceof canvas_element_container_1.CanvasElementContainer) {
301
+ this.renderReplacedElement(container, curves, container.canvas);
302
+ }
303
+ if (container instanceof svg_element_container_1.SVGElementContainer) {
304
+ try {
305
+ const image = await this.context.cache.match(container.svg);
306
+ this.renderReplacedElement(container, curves, image);
307
+ }
308
+ catch (e) {
309
+ this.context.logger.error(`Error loading svg ${container.svg.substring(0, 255)}`);
310
+ }
311
+ }
312
+ if (container instanceof iframe_element_container_1.IFrameElementContainer && container.tree) {
313
+ const iframeRenderer = new CanvasRenderer(this.context, {
314
+ scale: this.options.scale,
315
+ backgroundColor: container.backgroundColor,
316
+ x: 0,
317
+ y: 0,
318
+ width: container.width,
319
+ height: container.height
529
320
  });
530
- });
531
- };
532
- CanvasRenderer.prototype.renderStackContent = function (stack) {
533
- return __awaiter(this, void 0, void 0, function () {
534
- var _i, _a, child, _b, _c, child, _d, _e, child, _f, _g, child, _h, _j, child, _k, _l, child, _m, _o, child;
535
- return __generator(this, function (_p) {
536
- switch (_p.label) {
537
- case 0:
538
- if ((0, bitwise_1.contains)(stack.element.container.flags, 16 /* FLAGS.DEBUG_RENDER */)) {
539
- debugger;
540
- }
541
- // https://www.w3.org/TR/css-position-3/#painting-order
542
- // 1. the background and borders of the element forming the stacking context.
543
- return [4 /*yield*/, this.renderNodeBackgroundAndBorders(stack.element)];
544
- case 1:
545
- // https://www.w3.org/TR/css-position-3/#painting-order
546
- // 1. the background and borders of the element forming the stacking context.
547
- _p.sent();
548
- _i = 0, _a = stack.negativeZIndex;
549
- _p.label = 2;
550
- case 2:
551
- if (!(_i < _a.length)) return [3 /*break*/, 5];
552
- child = _a[_i];
553
- return [4 /*yield*/, this.renderStack(child)];
554
- case 3:
555
- _p.sent();
556
- _p.label = 4;
557
- case 4:
558
- _i++;
559
- return [3 /*break*/, 2];
560
- case 5:
561
- // 3. For all its in-flow, non-positioned, block-level descendants in tree order:
562
- return [4 /*yield*/, this.renderNodeContent(stack.element)];
563
- case 6:
564
- // 3. For all its in-flow, non-positioned, block-level descendants in tree order:
565
- _p.sent();
566
- _b = 0, _c = stack.nonInlineLevel;
567
- _p.label = 7;
568
- case 7:
569
- if (!(_b < _c.length)) return [3 /*break*/, 10];
570
- child = _c[_b];
571
- return [4 /*yield*/, this.renderNode(child)];
572
- case 8:
573
- _p.sent();
574
- _p.label = 9;
575
- case 9:
576
- _b++;
577
- return [3 /*break*/, 7];
578
- case 10:
579
- _d = 0, _e = stack.nonPositionedFloats;
580
- _p.label = 11;
581
- case 11:
582
- if (!(_d < _e.length)) return [3 /*break*/, 14];
583
- child = _e[_d];
584
- return [4 /*yield*/, this.renderStack(child)];
585
- case 12:
586
- _p.sent();
587
- _p.label = 13;
588
- case 13:
589
- _d++;
590
- return [3 /*break*/, 11];
591
- case 14:
592
- _f = 0, _g = stack.nonPositionedInlineLevel;
593
- _p.label = 15;
594
- case 15:
595
- if (!(_f < _g.length)) return [3 /*break*/, 18];
596
- child = _g[_f];
597
- return [4 /*yield*/, this.renderStack(child)];
598
- case 16:
599
- _p.sent();
600
- _p.label = 17;
601
- case 17:
602
- _f++;
603
- return [3 /*break*/, 15];
604
- case 18:
605
- _h = 0, _j = stack.inlineLevel;
606
- _p.label = 19;
607
- case 19:
608
- if (!(_h < _j.length)) return [3 /*break*/, 22];
609
- child = _j[_h];
610
- return [4 /*yield*/, this.renderNode(child)];
611
- case 20:
612
- _p.sent();
613
- _p.label = 21;
614
- case 21:
615
- _h++;
616
- return [3 /*break*/, 19];
617
- case 22:
618
- _k = 0, _l = stack.zeroOrAutoZIndexOrTransformedOrOpacity;
619
- _p.label = 23;
620
- case 23:
621
- if (!(_k < _l.length)) return [3 /*break*/, 26];
622
- child = _l[_k];
623
- return [4 /*yield*/, this.renderStack(child)];
624
- case 24:
625
- _p.sent();
626
- _p.label = 25;
627
- case 25:
628
- _k++;
629
- return [3 /*break*/, 23];
630
- case 26:
631
- _m = 0, _o = stack.positiveZIndex;
632
- _p.label = 27;
633
- case 27:
634
- if (!(_m < _o.length)) return [3 /*break*/, 30];
635
- child = _o[_m];
636
- return [4 /*yield*/, this.renderStack(child)];
637
- case 28:
638
- _p.sent();
639
- _p.label = 29;
640
- case 29:
641
- _m++;
642
- return [3 /*break*/, 27];
643
- case 30: return [2 /*return*/];
321
+ const canvas = await iframeRenderer.render(container.tree);
322
+ if (container.width && container.height) {
323
+ this.ctx.drawImage(canvas, 0, 0, container.width, container.height, container.bounds.left, container.bounds.top, container.bounds.width, container.bounds.height);
324
+ }
325
+ }
326
+ if (container instanceof input_element_container_1.InputElementContainer) {
327
+ const size = Math.min(container.bounds.width, container.bounds.height);
328
+ if (container.type === input_element_container_1.CHECKBOX) {
329
+ if (container.checked) {
330
+ this.ctx.save();
331
+ this.path([
332
+ new vector_1.Vector(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79),
333
+ new vector_1.Vector(container.bounds.left + size * 0.16, container.bounds.top + size * 0.5549),
334
+ new vector_1.Vector(container.bounds.left + size * 0.27347, container.bounds.top + size * 0.44071),
335
+ new vector_1.Vector(container.bounds.left + size * 0.39694, container.bounds.top + size * 0.5649),
336
+ new vector_1.Vector(container.bounds.left + size * 0.72983, container.bounds.top + size * 0.23),
337
+ new vector_1.Vector(container.bounds.left + size * 0.84, container.bounds.top + size * 0.34085),
338
+ new vector_1.Vector(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79)
339
+ ]);
340
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(input_element_container_1.INPUT_COLOR);
341
+ this.ctx.fill();
342
+ this.ctx.restore();
644
343
  }
645
- });
646
- });
647
- };
648
- CanvasRenderer.prototype.mask = function (paths) {
344
+ }
345
+ else if (container.type === input_element_container_1.RADIO) {
346
+ if (container.checked) {
347
+ this.ctx.save();
348
+ this.ctx.beginPath();
349
+ this.ctx.arc(container.bounds.left + size / 2, container.bounds.top + size / 2, size / 4, 0, Math.PI * 2, true);
350
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(input_element_container_1.INPUT_COLOR);
351
+ this.ctx.fill();
352
+ this.ctx.restore();
353
+ }
354
+ }
355
+ }
356
+ if (isTextInputElement(container) && container.value.length) {
357
+ const [font, fontFamily, fontSize] = this.createFontStyle(styles);
358
+ const { baseline } = this.fontMetrics.getMetrics(fontFamily, fontSize);
359
+ this.ctx.font = font;
360
+ // Fix for Issue #92: Use placeholder color when rendering placeholder text
361
+ const isPlaceholder = container instanceof input_element_container_1.InputElementContainer && container.isPlaceholder;
362
+ this.ctx.fillStyle = isPlaceholder ? (0, color_utilities_1.asString)(input_element_container_1.PLACEHOLDER_COLOR) : (0, color_utilities_1.asString)(styles.color);
363
+ this.ctx.textBaseline = 'alphabetic';
364
+ this.ctx.textAlign = canvasTextAlign(container.styles.textAlign);
365
+ const bounds = (0, box_sizing_1.contentBox)(container);
366
+ let x = 0;
367
+ switch (container.styles.textAlign) {
368
+ case 1 /* TEXT_ALIGN.CENTER */:
369
+ x += bounds.width / 2;
370
+ break;
371
+ case 2 /* TEXT_ALIGN.RIGHT */:
372
+ x += bounds.width;
373
+ break;
374
+ }
375
+ // Fix for Issue #92: Position text vertically centered in single-line input
376
+ // Only apply vertical centering for InputElementContainer, not for textarea or select
377
+ let verticalOffset = 0;
378
+ if (container instanceof input_element_container_1.InputElementContainer) {
379
+ const fontSizeValue = (0, length_percentage_1.getAbsoluteValue)(styles.fontSize, 0);
380
+ verticalOffset = (bounds.height - fontSizeValue) / 2;
381
+ }
382
+ // Create text bounds with horizontal and vertical offsets
383
+ // Height is not modified as it doesn't affect text rendering position
384
+ const textBounds = bounds.add(x, verticalOffset, 0, 0);
385
+ this.ctx.save();
386
+ this.path([
387
+ new vector_1.Vector(bounds.left, bounds.top),
388
+ new vector_1.Vector(bounds.left + bounds.width, bounds.top),
389
+ new vector_1.Vector(bounds.left + bounds.width, bounds.top + bounds.height),
390
+ new vector_1.Vector(bounds.left, bounds.top + bounds.height)
391
+ ]);
392
+ this.ctx.clip();
393
+ this.renderTextWithLetterSpacing(new text_1.TextBounds(container.value, textBounds), styles.letterSpacing, baseline);
394
+ this.ctx.restore();
395
+ this.ctx.textBaseline = 'alphabetic';
396
+ this.ctx.textAlign = 'left';
397
+ }
398
+ if ((0, bitwise_1.contains)(container.styles.display, 2048 /* DISPLAY.LIST_ITEM */)) {
399
+ if (container.styles.listStyleImage !== null) {
400
+ const img = container.styles.listStyleImage;
401
+ if (img.type === 0 /* CSSImageType.URL */) {
402
+ let image;
403
+ const url = img.url;
404
+ try {
405
+ image = await this.context.cache.match(url);
406
+ this.ctx.drawImage(image, container.bounds.left - (image.width + 10), container.bounds.top);
407
+ }
408
+ catch (e) {
409
+ this.context.logger.error(`Error loading list-style-image ${url}`);
410
+ }
411
+ }
412
+ }
413
+ else if (paint.listValue && container.styles.listStyleType !== -1 /* LIST_STYLE_TYPE.NONE */) {
414
+ const [font] = this.createFontStyle(styles);
415
+ this.ctx.font = font;
416
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.color);
417
+ this.ctx.textBaseline = 'middle';
418
+ this.ctx.textAlign = 'right';
419
+ const bounds = new bounds_1.Bounds(container.bounds.left, container.bounds.top + (0, length_percentage_1.getAbsoluteValue)(container.styles.paddingTop, container.bounds.width), container.bounds.width, (0, line_height_1.computeLineHeight)(styles.lineHeight, styles.fontSize.number) / 2 + 1);
420
+ this.renderTextWithLetterSpacing(new text_1.TextBounds(paint.listValue, bounds), styles.letterSpacing, (0, line_height_1.computeLineHeight)(styles.lineHeight, styles.fontSize.number) / 2 + 2);
421
+ this.ctx.textBaseline = 'bottom';
422
+ this.ctx.textAlign = 'left';
423
+ }
424
+ }
425
+ }
426
+ async renderStackContent(stack) {
427
+ if ((0, bitwise_1.contains)(stack.element.container.flags, 16 /* FLAGS.DEBUG_RENDER */)) {
428
+ debugger;
429
+ }
430
+ // https://www.w3.org/TR/css-position-3/#painting-order
431
+ // 1. the background and borders of the element forming the stacking context.
432
+ await this.renderNodeBackgroundAndBorders(stack.element);
433
+ // 2. the child stacking contexts with negative stack levels (most negative first).
434
+ for (const child of stack.negativeZIndex) {
435
+ await this.renderStack(child);
436
+ }
437
+ // 3. For all its in-flow, non-positioned, block-level descendants in tree order:
438
+ await this.renderNodeContent(stack.element);
439
+ for (const child of stack.nonInlineLevel) {
440
+ await this.renderNode(child);
441
+ }
442
+ // 4. All non-positioned floating descendants, in tree order. For each one of these,
443
+ // treat the element as if it created a new stacking context, but any positioned descendants and descendants
444
+ // which actually create a new stacking context should be considered part of the parent stacking context,
445
+ // not this new one.
446
+ for (const child of stack.nonPositionedFloats) {
447
+ await this.renderStack(child);
448
+ }
449
+ // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
450
+ for (const child of stack.nonPositionedInlineLevel) {
451
+ await this.renderStack(child);
452
+ }
453
+ for (const child of stack.inlineLevel) {
454
+ await this.renderNode(child);
455
+ }
456
+ // 6. All positioned, opacity or transform descendants, in tree order that fall into the following categories:
457
+ // All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order.
458
+ // For those with 'z-index: auto', treat the element as if it created a new stacking context,
459
+ // but any positioned descendants and descendants which actually create a new stacking context should be
460
+ // considered part of the parent stacking context, not this new one. For those with 'z-index: 0',
461
+ // treat the stacking context generated atomically.
462
+ //
463
+ // All opacity descendants with opacity less than 1
464
+ //
465
+ // All transform descendants with transform other than none
466
+ for (const child of stack.zeroOrAutoZIndexOrTransformedOrOpacity) {
467
+ await this.renderStack(child);
468
+ }
469
+ // 7. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index
470
+ // order (smallest first) then tree order.
471
+ for (const child of stack.positiveZIndex) {
472
+ await this.renderStack(child);
473
+ }
474
+ }
475
+ mask(paths) {
649
476
  this.ctx.beginPath();
650
477
  this.ctx.moveTo(0, 0);
651
- this.ctx.lineTo(this.canvas.width, 0);
652
- this.ctx.lineTo(this.canvas.width, this.canvas.height);
653
- this.ctx.lineTo(0, this.canvas.height);
478
+ // Use logical dimensions (options.width/height) instead of canvas pixel dimensions
479
+ // because context has already been scaled by this.options.scale
480
+ // Fix for Issue #126: Using canvas pixel dimensions causes broken output
481
+ this.ctx.lineTo(this.options.width, 0);
482
+ this.ctx.lineTo(this.options.width, this.options.height);
483
+ this.ctx.lineTo(0, this.options.height);
654
484
  this.ctx.lineTo(0, 0);
655
485
  this.formatPath(paths.slice(0).reverse());
656
486
  this.ctx.closePath();
657
- };
658
- CanvasRenderer.prototype.path = function (paths) {
487
+ }
488
+ path(paths) {
659
489
  this.ctx.beginPath();
660
490
  this.formatPath(paths);
661
491
  this.ctx.closePath();
662
- };
663
- CanvasRenderer.prototype.formatPath = function (paths) {
664
- var _this = this;
665
- paths.forEach(function (point, index) {
666
- var start = (0, bezier_curve_1.isBezierCurve)(point) ? point.start : point;
492
+ }
493
+ formatPath(paths) {
494
+ paths.forEach((point, index) => {
495
+ const start = (0, bezier_curve_1.isBezierCurve)(point) ? point.start : point;
667
496
  if (index === 0) {
668
- _this.ctx.moveTo(start.x, start.y);
497
+ this.ctx.moveTo(start.x, start.y);
669
498
  }
670
499
  else {
671
- _this.ctx.lineTo(start.x, start.y);
500
+ this.ctx.lineTo(start.x, start.y);
672
501
  }
673
502
  if ((0, bezier_curve_1.isBezierCurve)(point)) {
674
- _this.ctx.bezierCurveTo(point.startControl.x, point.startControl.y, point.endControl.x, point.endControl.y, point.end.x, point.end.y);
503
+ this.ctx.bezierCurveTo(point.startControl.x, point.startControl.y, point.endControl.x, point.endControl.y, point.end.x, point.end.y);
675
504
  }
676
505
  });
677
- };
678
- CanvasRenderer.prototype.renderRepeat = function (path, pattern, offsetX, offsetY) {
506
+ }
507
+ renderRepeat(path, pattern, offsetX, offsetY) {
679
508
  this.path(path);
680
509
  this.ctx.fillStyle = pattern;
681
510
  this.ctx.translate(offsetX, offsetY);
682
511
  this.ctx.fill();
683
512
  this.ctx.translate(-offsetX, -offsetY);
684
- };
685
- CanvasRenderer.prototype.resizeImage = function (image, width, height) {
513
+ }
514
+ resizeImage(image, width, height) {
686
515
  // https://github.com/niklasvh/html2canvas/pull/2911
687
516
  // if (image.width === width && image.height === height) {
688
517
  // return image;
689
518
  // }
690
- var _a;
691
- var ownerDocument = (_a = this.canvas.ownerDocument) !== null && _a !== void 0 ? _a : document;
692
- var canvas = ownerDocument.createElement('canvas');
519
+ const ownerDocument = this.canvas.ownerDocument ?? document;
520
+ const canvas = ownerDocument.createElement('canvas');
693
521
  canvas.width = Math.max(1, width);
694
522
  canvas.height = Math.max(1, height);
695
- var ctx = canvas.getContext('2d');
523
+ const ctx = canvas.getContext('2d');
696
524
  ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, width, height);
697
525
  return canvas;
698
- };
699
- CanvasRenderer.prototype.renderBackgroundImage = function (container) {
700
- return __awaiter(this, void 0, void 0, function () {
701
- var index, _loop_1, this_1, _i, _a, backgroundImage;
702
- return __generator(this, function (_b) {
703
- switch (_b.label) {
704
- case 0:
705
- index = container.styles.backgroundImage.length - 1;
706
- _loop_1 = function (backgroundImage) {
707
- var image, url, e_4, imageWidth, imageHeight, _c, path, x, y, width, height, pattern, _d, path, x, y, width, height, _e, lineLength, x0, x1, y0, y1, canvas, ctx, gradient_2, pattern, _f, path, left, top_1, width, height, position, x, y, _g, rx, ry, radialGradient_1, midX, midY, f, invF;
708
- return __generator(this, function (_h) {
709
- switch (_h.label) {
710
- case 0:
711
- if (!(backgroundImage.type === 0 /* CSSImageType.URL */)) return [3 /*break*/, 5];
712
- image = void 0;
713
- url = backgroundImage.url;
714
- _h.label = 1;
715
- case 1:
716
- _h.trys.push([1, 3, , 4]);
717
- return [4 /*yield*/, this_1.context.cache.match(url)];
718
- case 2:
719
- image = _h.sent();
720
- return [3 /*break*/, 4];
721
- case 3:
722
- e_4 = _h.sent();
723
- this_1.context.logger.error("Error loading background-image ".concat(url));
724
- return [3 /*break*/, 4];
725
- case 4:
726
- if (image) {
727
- imageWidth = isNaN(image.width) || image.width === 0 ? 1 : image.width;
728
- imageHeight = isNaN(image.height) || image.height === 0 ? 1 : image.height;
729
- _c = (0, background_1.calculateBackgroundRendering)(container, index, [
730
- imageWidth,
731
- imageHeight,
732
- imageWidth / imageHeight
733
- ]), path = _c[0], x = _c[1], y = _c[2], width = _c[3], height = _c[4];
734
- pattern = this_1.ctx.createPattern(this_1.resizeImage(image, width, height), 'repeat');
735
- this_1.renderRepeat(path, pattern, x, y);
736
- }
737
- return [3 /*break*/, 6];
738
- case 5:
739
- if ((0, image_1.isLinearGradient)(backgroundImage)) {
740
- _d = (0, background_1.calculateBackgroundRendering)(container, index, [null, null, null]), path = _d[0], x = _d[1], y = _d[2], width = _d[3], height = _d[4];
741
- _e = (0, gradient_1.calculateGradientDirection)(backgroundImage.angle, width, height), lineLength = _e[0], x0 = _e[1], x1 = _e[2], y0 = _e[3], y1 = _e[4];
742
- canvas = document.createElement('canvas');
743
- canvas.width = width;
744
- canvas.height = height;
745
- ctx = canvas.getContext('2d');
746
- gradient_2 = ctx.createLinearGradient(x0, y0, x1, y1);
747
- (0, gradient_1.processColorStops)(backgroundImage.stops, lineLength || 1).forEach(function (colorStop) {
748
- return gradient_2.addColorStop(colorStop.stop, (0, color_utilities_1.asString)(colorStop.color));
749
- });
750
- ctx.fillStyle = gradient_2;
751
- ctx.fillRect(0, 0, width, height);
752
- if (width > 0 && height > 0) {
753
- pattern = this_1.ctx.createPattern(canvas, 'repeat');
754
- this_1.renderRepeat(path, pattern, x, y);
755
- }
756
- }
757
- else if ((0, image_1.isRadialGradient)(backgroundImage)) {
758
- _f = (0, background_1.calculateBackgroundRendering)(container, index, [
759
- null,
760
- null,
761
- null
762
- ]), path = _f[0], left = _f[1], top_1 = _f[2], width = _f[3], height = _f[4];
763
- position = backgroundImage.position.length === 0 ? [length_percentage_1.FIFTY_PERCENT] : backgroundImage.position;
764
- x = (0, length_percentage_1.getAbsoluteValue)(position[0], width);
765
- y = (0, length_percentage_1.getAbsoluteValue)(position[position.length - 1], height);
766
- _g = (0, gradient_1.calculateRadius)(backgroundImage, x, y, width, height), rx = _g[0], ry = _g[1];
767
- if (rx > 0 && ry > 0) {
768
- radialGradient_1 = this_1.ctx.createRadialGradient(left + x, top_1 + y, 0, left + x, top_1 + y, rx);
769
- (0, gradient_1.processColorStops)(backgroundImage.stops, rx * 2).forEach(function (colorStop) {
770
- return radialGradient_1.addColorStop(colorStop.stop, (0, color_utilities_1.asString)(colorStop.color));
771
- });
772
- this_1.path(path);
773
- this_1.ctx.fillStyle = radialGradient_1;
774
- if (rx !== ry) {
775
- midX = container.bounds.left + 0.5 * container.bounds.width;
776
- midY = container.bounds.top + 0.5 * container.bounds.height;
777
- f = ry / rx;
778
- invF = 1 / f;
779
- this_1.ctx.save();
780
- this_1.ctx.translate(midX, midY);
781
- this_1.ctx.transform(1, 0, 0, f, 0, 0);
782
- this_1.ctx.translate(-midX, -midY);
783
- this_1.ctx.fillRect(left, invF * (top_1 - midY) + midY, width, height * invF);
784
- this_1.ctx.restore();
785
- }
786
- else {
787
- this_1.ctx.fill();
788
- }
789
- }
790
- }
791
- _h.label = 6;
792
- case 6:
793
- index--;
794
- return [2 /*return*/];
795
- }
796
- });
797
- };
798
- this_1 = this;
799
- _i = 0, _a = container.styles.backgroundImage.slice(0).reverse();
800
- _b.label = 1;
801
- case 1:
802
- if (!(_i < _a.length)) return [3 /*break*/, 4];
803
- backgroundImage = _a[_i];
804
- return [5 /*yield**/, _loop_1(backgroundImage)];
805
- case 2:
806
- _b.sent();
807
- _b.label = 3;
808
- case 3:
809
- _i++;
810
- return [3 /*break*/, 1];
811
- case 4: return [2 /*return*/];
526
+ }
527
+ async renderBackgroundImage(container) {
528
+ let index = container.styles.backgroundImage.length - 1;
529
+ for (const backgroundImage of container.styles.backgroundImage.slice(0).reverse()) {
530
+ if (backgroundImage.type === 0 /* CSSImageType.URL */) {
531
+ let image;
532
+ const url = backgroundImage.url;
533
+ try {
534
+ image = await this.context.cache.match(url);
535
+ }
536
+ catch (e) {
537
+ this.context.logger.error(`Error loading background-image ${url}`);
538
+ }
539
+ if (image) {
540
+ const imageWidth = isNaN(image.width) || image.width === 0 ? 1 : image.width;
541
+ const imageHeight = isNaN(image.height) || image.height === 0 ? 1 : image.height;
542
+ const [path, x, y, width, height] = (0, background_1.calculateBackgroundRendering)(container, index, [
543
+ imageWidth,
544
+ imageHeight,
545
+ imageWidth / imageHeight
546
+ ]);
547
+ const pattern = this.ctx.createPattern(this.resizeImage(image, width, height), 'repeat');
548
+ this.renderRepeat(path, pattern, x, y);
812
549
  }
813
- });
814
- });
815
- };
816
- CanvasRenderer.prototype.renderSolidBorder = function (color, side, curvePoints) {
817
- return __awaiter(this, void 0, void 0, function () {
818
- return __generator(this, function (_a) {
819
- this.path((0, border_1.parsePathForBorder)(curvePoints, side));
820
- this.ctx.fillStyle = (0, color_utilities_1.asString)(color);
821
- this.ctx.fill();
822
- return [2 /*return*/];
823
- });
824
- });
825
- };
826
- CanvasRenderer.prototype.renderDoubleBorder = function (color, width, side, curvePoints) {
827
- return __awaiter(this, void 0, void 0, function () {
828
- var outerPaths, innerPaths;
829
- return __generator(this, function (_a) {
830
- switch (_a.label) {
831
- case 0:
832
- if (!(width < 3)) return [3 /*break*/, 2];
833
- return [4 /*yield*/, this.renderSolidBorder(color, side, curvePoints)];
834
- case 1:
835
- _a.sent();
836
- return [2 /*return*/];
837
- case 2:
838
- outerPaths = (0, border_1.parsePathForBorderDoubleOuter)(curvePoints, side);
839
- this.path(outerPaths);
840
- this.ctx.fillStyle = (0, color_utilities_1.asString)(color);
841
- this.ctx.fill();
842
- innerPaths = (0, border_1.parsePathForBorderDoubleInner)(curvePoints, side);
843
- this.path(innerPaths);
844
- this.ctx.fill();
845
- return [2 /*return*/];
550
+ }
551
+ else if ((0, image_1.isLinearGradient)(backgroundImage)) {
552
+ const [path, x, y, width, height] = (0, background_1.calculateBackgroundRendering)(container, index, [null, null, null]);
553
+ const [lineLength, x0, x1, y0, y1] = (0, gradient_1.calculateGradientDirection)(backgroundImage.angle, width, height);
554
+ const canvas = document.createElement('canvas');
555
+ canvas.width = width;
556
+ canvas.height = height;
557
+ const ctx = canvas.getContext('2d');
558
+ const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
559
+ (0, gradient_1.processColorStops)(backgroundImage.stops, lineLength || 1).forEach((colorStop) => gradient.addColorStop(colorStop.stop, (0, color_utilities_1.asString)(colorStop.color)));
560
+ ctx.fillStyle = gradient;
561
+ ctx.fillRect(0, 0, width, height);
562
+ if (width > 0 && height > 0) {
563
+ const pattern = this.ctx.createPattern(canvas, 'repeat');
564
+ this.renderRepeat(path, pattern, x, y);
846
565
  }
847
- });
848
- });
849
- };
850
- CanvasRenderer.prototype.renderNodeBackgroundAndBorders = function (paint) {
851
- return __awaiter(this, void 0, void 0, function () {
852
- var styles, hasBackground, borders, backgroundPaintingArea, side, _i, borders_1, border;
853
- var _this = this;
854
- return __generator(this, function (_a) {
855
- switch (_a.label) {
856
- case 0:
857
- this.applyEffects(paint.getEffects(2 /* EffectTarget.BACKGROUND_BORDERS */));
858
- styles = paint.container.styles;
859
- hasBackground = !(0, color_utilities_1.isTransparent)(styles.backgroundColor) || styles.backgroundImage.length;
860
- borders = [
861
- { style: styles.borderTopStyle, color: styles.borderTopColor, width: styles.borderTopWidth },
862
- { style: styles.borderRightStyle, color: styles.borderRightColor, width: styles.borderRightWidth },
863
- { style: styles.borderBottomStyle, color: styles.borderBottomColor, width: styles.borderBottomWidth },
864
- { style: styles.borderLeftStyle, color: styles.borderLeftColor, width: styles.borderLeftWidth }
865
- ];
866
- backgroundPaintingArea = calculateBackgroundCurvedPaintingArea((0, background_1.getBackgroundValueForIndex)(styles.backgroundClip, 0), paint.curves);
867
- if (!(hasBackground || styles.boxShadow.length)) return [3 /*break*/, 2];
566
+ }
567
+ else if ((0, image_1.isRadialGradient)(backgroundImage)) {
568
+ const [path, left, top, width, height] = (0, background_1.calculateBackgroundRendering)(container, index, [
569
+ null,
570
+ null,
571
+ null
572
+ ]);
573
+ const position = backgroundImage.position.length === 0 ? [length_percentage_1.FIFTY_PERCENT] : backgroundImage.position;
574
+ const x = (0, length_percentage_1.getAbsoluteValue)(position[0], width);
575
+ const y = (0, length_percentage_1.getAbsoluteValue)(position[position.length - 1], height);
576
+ const [rx, ry] = (0, gradient_1.calculateRadius)(backgroundImage, x, y, width, height);
577
+ if (rx > 0 && ry > 0) {
578
+ const radialGradient = this.ctx.createRadialGradient(left + x, top + y, 0, left + x, top + y, rx);
579
+ (0, gradient_1.processColorStops)(backgroundImage.stops, rx * 2).forEach((colorStop) => radialGradient.addColorStop(colorStop.stop, (0, color_utilities_1.asString)(colorStop.color)));
580
+ this.path(path);
581
+ this.ctx.fillStyle = radialGradient;
582
+ if (rx !== ry) {
583
+ // transforms for elliptical radial gradient
584
+ const midX = container.bounds.left + 0.5 * container.bounds.width;
585
+ const midY = container.bounds.top + 0.5 * container.bounds.height;
586
+ const f = ry / rx;
587
+ const invF = 1 / f;
868
588
  this.ctx.save();
869
- this.path(backgroundPaintingArea);
870
- this.ctx.clip();
871
- if (!(0, color_utilities_1.isTransparent)(styles.backgroundColor)) {
872
- this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.backgroundColor);
873
- this.ctx.fill();
874
- }
875
- return [4 /*yield*/, this.renderBackgroundImage(paint.container)];
876
- case 1:
877
- _a.sent();
589
+ this.ctx.translate(midX, midY);
590
+ this.ctx.transform(1, 0, 0, f, 0, 0);
591
+ this.ctx.translate(-midX, -midY);
592
+ this.ctx.fillRect(left, invF * (top - midY) + midY, width, height * invF);
878
593
  this.ctx.restore();
879
- styles.boxShadow
880
- .slice(0)
881
- .reverse()
882
- .forEach(function (shadow) {
883
- _this.ctx.save();
884
- var borderBoxArea = (0, bound_curves_1.calculateBorderBoxPath)(paint.curves);
885
- var maskOffset = shadow.inset ? 0 : MASK_OFFSET;
886
- var shadowPaintingArea = (0, path_1.transformPath)(borderBoxArea, -maskOffset + (shadow.inset ? 1 : -1) * shadow.spread.number, (shadow.inset ? 1 : -1) * shadow.spread.number, shadow.spread.number * (shadow.inset ? -2 : 2), shadow.spread.number * (shadow.inset ? -2 : 2));
887
- if (shadow.inset) {
888
- _this.path(borderBoxArea);
889
- _this.ctx.clip();
890
- _this.mask(shadowPaintingArea);
891
- }
892
- else {
893
- _this.mask(borderBoxArea);
894
- _this.ctx.clip();
895
- _this.path(shadowPaintingArea);
896
- }
897
- _this.ctx.shadowOffsetX = shadow.offsetX.number + maskOffset;
898
- _this.ctx.shadowOffsetY = shadow.offsetY.number;
899
- _this.ctx.shadowColor = (0, color_utilities_1.asString)(shadow.color);
900
- _this.ctx.shadowBlur = shadow.blur.number;
901
- _this.ctx.fillStyle = shadow.inset ? (0, color_utilities_1.asString)(shadow.color) : 'rgba(0,0,0,1)';
902
- _this.ctx.fill();
903
- _this.ctx.restore();
904
- });
905
- _a.label = 2;
906
- case 2:
907
- side = 0;
908
- _i = 0, borders_1 = borders;
909
- _a.label = 3;
910
- case 3:
911
- if (!(_i < borders_1.length)) return [3 /*break*/, 13];
912
- border = borders_1[_i];
913
- if (!(border.style !== 0 /* BORDER_STYLE.NONE */ && !(0, color_utilities_1.isTransparent)(border.color) && border.width > 0)) return [3 /*break*/, 11];
914
- if (!(border.style === 2 /* BORDER_STYLE.DASHED */)) return [3 /*break*/, 5];
915
- return [4 /*yield*/, this.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 2 /* BORDER_STYLE.DASHED */)];
916
- case 4:
917
- _a.sent();
918
- return [3 /*break*/, 11];
919
- case 5:
920
- if (!(border.style === 3 /* BORDER_STYLE.DOTTED */)) return [3 /*break*/, 7];
921
- return [4 /*yield*/, this.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 3 /* BORDER_STYLE.DOTTED */)];
922
- case 6:
923
- _a.sent();
924
- return [3 /*break*/, 11];
925
- case 7:
926
- if (!(border.style === 4 /* BORDER_STYLE.DOUBLE */)) return [3 /*break*/, 9];
927
- return [4 /*yield*/, this.renderDoubleBorder(border.color, border.width, side, paint.curves)];
928
- case 8:
929
- _a.sent();
930
- return [3 /*break*/, 11];
931
- case 9: return [4 /*yield*/, this.renderSolidBorder(border.color, side, paint.curves)];
932
- case 10:
933
- _a.sent();
934
- _a.label = 11;
935
- case 11:
936
- side++;
937
- _a.label = 12;
938
- case 12:
939
- _i++;
940
- return [3 /*break*/, 3];
941
- case 13: return [2 /*return*/];
594
+ }
595
+ else {
596
+ this.ctx.fill();
597
+ }
942
598
  }
943
- });
944
- });
945
- };
946
- CanvasRenderer.prototype.renderDashedDottedBorder = function (color, width, side, curvePoints, style) {
947
- return __awaiter(this, void 0, void 0, function () {
948
- var strokePaths, boxPaths, startX, startY, endX, endY, length, dashLength, spaceLength, useLineDash, multiplier, numberOfDashes, minSpace, maxSpace, path1, path2, path1, path2;
949
- return __generator(this, function (_a) {
599
+ }
600
+ index--;
601
+ }
602
+ }
603
+ async renderSolidBorder(color, side, curvePoints) {
604
+ this.path((0, border_1.parsePathForBorder)(curvePoints, side));
605
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(color);
606
+ this.ctx.fill();
607
+ }
608
+ async renderDoubleBorder(color, width, side, curvePoints) {
609
+ if (width < 3) {
610
+ await this.renderSolidBorder(color, side, curvePoints);
611
+ return;
612
+ }
613
+ const outerPaths = (0, border_1.parsePathForBorderDoubleOuter)(curvePoints, side);
614
+ this.path(outerPaths);
615
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(color);
616
+ this.ctx.fill();
617
+ const innerPaths = (0, border_1.parsePathForBorderDoubleInner)(curvePoints, side);
618
+ this.path(innerPaths);
619
+ this.ctx.fill();
620
+ }
621
+ async renderNodeBackgroundAndBorders(paint) {
622
+ this.applyEffects(paint.getEffects(2 /* EffectTarget.BACKGROUND_BORDERS */));
623
+ const styles = paint.container.styles;
624
+ const hasBackground = !(0, color_utilities_1.isTransparent)(styles.backgroundColor) || styles.backgroundImage.length;
625
+ const borders = [
626
+ { style: styles.borderTopStyle, color: styles.borderTopColor, width: styles.borderTopWidth },
627
+ { style: styles.borderRightStyle, color: styles.borderRightColor, width: styles.borderRightWidth },
628
+ { style: styles.borderBottomStyle, color: styles.borderBottomColor, width: styles.borderBottomWidth },
629
+ { style: styles.borderLeftStyle, color: styles.borderLeftColor, width: styles.borderLeftWidth }
630
+ ];
631
+ const backgroundPaintingArea = calculateBackgroundCurvedPaintingArea((0, background_1.getBackgroundValueForIndex)(styles.backgroundClip, 0), paint.curves);
632
+ if (hasBackground || styles.boxShadow.length) {
633
+ this.ctx.save();
634
+ this.path(backgroundPaintingArea);
635
+ this.ctx.clip();
636
+ if (!(0, color_utilities_1.isTransparent)(styles.backgroundColor)) {
637
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.backgroundColor);
638
+ this.ctx.fill();
639
+ }
640
+ await this.renderBackgroundImage(paint.container);
641
+ this.ctx.restore();
642
+ styles.boxShadow
643
+ .slice(0)
644
+ .reverse()
645
+ .forEach((shadow) => {
950
646
  this.ctx.save();
951
- strokePaths = (0, border_1.parsePathForBorderStroke)(curvePoints, side);
952
- boxPaths = (0, border_1.parsePathForBorder)(curvePoints, side);
953
- if (style === 2 /* BORDER_STYLE.DASHED */) {
954
- this.path(boxPaths);
647
+ const borderBoxArea = (0, bound_curves_1.calculateBorderBoxPath)(paint.curves);
648
+ const maskOffset = shadow.inset ? 0 : MASK_OFFSET;
649
+ const shadowPaintingArea = (0, path_1.transformPath)(borderBoxArea, -maskOffset + (shadow.inset ? 1 : -1) * shadow.spread.number, (shadow.inset ? 1 : -1) * shadow.spread.number, shadow.spread.number * (shadow.inset ? -2 : 2), shadow.spread.number * (shadow.inset ? -2 : 2));
650
+ if (shadow.inset) {
651
+ this.path(borderBoxArea);
955
652
  this.ctx.clip();
956
- }
957
- if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) {
958
- startX = boxPaths[0].start.x;
959
- startY = boxPaths[0].start.y;
653
+ this.mask(shadowPaintingArea);
960
654
  }
961
655
  else {
962
- startX = boxPaths[0].x;
963
- startY = boxPaths[0].y;
656
+ this.mask(borderBoxArea);
657
+ this.ctx.clip();
658
+ this.path(shadowPaintingArea);
964
659
  }
965
- if ((0, bezier_curve_1.isBezierCurve)(boxPaths[1])) {
966
- endX = boxPaths[1].end.x;
967
- endY = boxPaths[1].end.y;
660
+ this.ctx.shadowOffsetX = shadow.offsetX.number + maskOffset;
661
+ this.ctx.shadowOffsetY = shadow.offsetY.number;
662
+ this.ctx.shadowColor = (0, color_utilities_1.asString)(shadow.color);
663
+ this.ctx.shadowBlur = shadow.blur.number;
664
+ this.ctx.fillStyle = shadow.inset ? (0, color_utilities_1.asString)(shadow.color) : 'rgba(0,0,0,1)';
665
+ this.ctx.fill();
666
+ this.ctx.restore();
667
+ });
668
+ }
669
+ let side = 0;
670
+ for (const border of borders) {
671
+ if (border.style !== 0 /* BORDER_STYLE.NONE */ && !(0, color_utilities_1.isTransparent)(border.color) && border.width > 0) {
672
+ if (border.style === 2 /* BORDER_STYLE.DASHED */) {
673
+ await this.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 2 /* BORDER_STYLE.DASHED */);
968
674
  }
969
- else {
970
- endX = boxPaths[1].x;
971
- endY = boxPaths[1].y;
675
+ else if (border.style === 3 /* BORDER_STYLE.DOTTED */) {
676
+ await this.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 3 /* BORDER_STYLE.DOTTED */);
972
677
  }
973
- if (side === 0 || side === 2) {
974
- length = Math.abs(startX - endX);
678
+ else if (border.style === 4 /* BORDER_STYLE.DOUBLE */) {
679
+ await this.renderDoubleBorder(border.color, border.width, side, paint.curves);
975
680
  }
976
681
  else {
977
- length = Math.abs(startY - endY);
682
+ await this.renderSolidBorder(border.color, side, paint.curves);
978
683
  }
684
+ }
685
+ side++;
686
+ }
687
+ }
688
+ async renderDashedDottedBorder(color, width, side, curvePoints, style) {
689
+ this.ctx.save();
690
+ const strokePaths = (0, border_1.parsePathForBorderStroke)(curvePoints, side);
691
+ const boxPaths = (0, border_1.parsePathForBorder)(curvePoints, side);
692
+ if (style === 2 /* BORDER_STYLE.DASHED */) {
693
+ this.path(boxPaths);
694
+ this.ctx.clip();
695
+ }
696
+ let startX, startY, endX, endY;
697
+ if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) {
698
+ startX = boxPaths[0].start.x;
699
+ startY = boxPaths[0].start.y;
700
+ }
701
+ else {
702
+ startX = boxPaths[0].x;
703
+ startY = boxPaths[0].y;
704
+ }
705
+ if ((0, bezier_curve_1.isBezierCurve)(boxPaths[1])) {
706
+ endX = boxPaths[1].end.x;
707
+ endY = boxPaths[1].end.y;
708
+ }
709
+ else {
710
+ endX = boxPaths[1].x;
711
+ endY = boxPaths[1].y;
712
+ }
713
+ let length;
714
+ if (side === 0 || side === 2) {
715
+ length = Math.abs(startX - endX);
716
+ }
717
+ else {
718
+ length = Math.abs(startY - endY);
719
+ }
720
+ this.ctx.beginPath();
721
+ if (style === 3 /* BORDER_STYLE.DOTTED */) {
722
+ this.formatPath(strokePaths);
723
+ }
724
+ else {
725
+ this.formatPath(boxPaths.slice(0, 2));
726
+ }
727
+ let dashLength = width < 3 ? width * 3 : width * 2;
728
+ let spaceLength = width < 3 ? width * 2 : width;
729
+ if (style === 3 /* BORDER_STYLE.DOTTED */) {
730
+ dashLength = width;
731
+ spaceLength = width;
732
+ }
733
+ let useLineDash = true;
734
+ if (length <= dashLength * 2) {
735
+ useLineDash = false;
736
+ }
737
+ else if (length <= dashLength * 2 + spaceLength) {
738
+ const multiplier = length / (2 * dashLength + spaceLength);
739
+ dashLength *= multiplier;
740
+ spaceLength *= multiplier;
741
+ }
742
+ else {
743
+ const numberOfDashes = Math.floor((length + spaceLength) / (dashLength + spaceLength));
744
+ const minSpace = (length - numberOfDashes * dashLength) / (numberOfDashes - 1);
745
+ const maxSpace = (length - (numberOfDashes + 1) * dashLength) / numberOfDashes;
746
+ spaceLength =
747
+ maxSpace <= 0 || Math.abs(spaceLength - minSpace) < Math.abs(spaceLength - maxSpace)
748
+ ? minSpace
749
+ : maxSpace;
750
+ }
751
+ if (useLineDash) {
752
+ if (style === 3 /* BORDER_STYLE.DOTTED */) {
753
+ this.ctx.setLineDash([0, dashLength + spaceLength]);
754
+ }
755
+ else {
756
+ this.ctx.setLineDash([dashLength, spaceLength]);
757
+ }
758
+ }
759
+ if (style === 3 /* BORDER_STYLE.DOTTED */) {
760
+ this.ctx.lineCap = 'round';
761
+ this.ctx.lineWidth = width;
762
+ }
763
+ else {
764
+ this.ctx.lineWidth = width * 2 + 1.1;
765
+ }
766
+ this.ctx.strokeStyle = (0, color_utilities_1.asString)(color);
767
+ this.ctx.stroke();
768
+ this.ctx.setLineDash([]);
769
+ // dashed round edge gap
770
+ if (style === 2 /* BORDER_STYLE.DASHED */) {
771
+ if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) {
772
+ const path1 = boxPaths[3];
773
+ const path2 = boxPaths[0];
979
774
  this.ctx.beginPath();
980
- if (style === 3 /* BORDER_STYLE.DOTTED */) {
981
- this.formatPath(strokePaths);
982
- }
983
- else {
984
- this.formatPath(boxPaths.slice(0, 2));
985
- }
986
- dashLength = width < 3 ? width * 3 : width * 2;
987
- spaceLength = width < 3 ? width * 2 : width;
988
- if (style === 3 /* BORDER_STYLE.DOTTED */) {
989
- dashLength = width;
990
- spaceLength = width;
991
- }
992
- useLineDash = true;
993
- if (length <= dashLength * 2) {
994
- useLineDash = false;
995
- }
996
- else if (length <= dashLength * 2 + spaceLength) {
997
- multiplier = length / (2 * dashLength + spaceLength);
998
- dashLength *= multiplier;
999
- spaceLength *= multiplier;
1000
- }
1001
- else {
1002
- numberOfDashes = Math.floor((length + spaceLength) / (dashLength + spaceLength));
1003
- minSpace = (length - numberOfDashes * dashLength) / (numberOfDashes - 1);
1004
- maxSpace = (length - (numberOfDashes + 1) * dashLength) / numberOfDashes;
1005
- spaceLength =
1006
- maxSpace <= 0 || Math.abs(spaceLength - minSpace) < Math.abs(spaceLength - maxSpace)
1007
- ? minSpace
1008
- : maxSpace;
1009
- }
1010
- if (useLineDash) {
1011
- if (style === 3 /* BORDER_STYLE.DOTTED */) {
1012
- this.ctx.setLineDash([0, dashLength + spaceLength]);
1013
- }
1014
- else {
1015
- this.ctx.setLineDash([dashLength, spaceLength]);
1016
- }
1017
- }
1018
- if (style === 3 /* BORDER_STYLE.DOTTED */) {
1019
- this.ctx.lineCap = 'round';
1020
- this.ctx.lineWidth = width;
1021
- }
1022
- else {
1023
- this.ctx.lineWidth = width * 2 + 1.1;
1024
- }
1025
- this.ctx.strokeStyle = (0, color_utilities_1.asString)(color);
775
+ this.formatPath([new vector_1.Vector(path1.end.x, path1.end.y), new vector_1.Vector(path2.start.x, path2.start.y)]);
1026
776
  this.ctx.stroke();
1027
- this.ctx.setLineDash([]);
1028
- // dashed round edge gap
1029
- if (style === 2 /* BORDER_STYLE.DASHED */) {
1030
- if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) {
1031
- path1 = boxPaths[3];
1032
- path2 = boxPaths[0];
1033
- this.ctx.beginPath();
1034
- this.formatPath([new vector_1.Vector(path1.end.x, path1.end.y), new vector_1.Vector(path2.start.x, path2.start.y)]);
1035
- this.ctx.stroke();
1036
- }
1037
- if ((0, bezier_curve_1.isBezierCurve)(boxPaths[1])) {
1038
- path1 = boxPaths[1];
1039
- path2 = boxPaths[2];
1040
- this.ctx.beginPath();
1041
- this.formatPath([new vector_1.Vector(path1.end.x, path1.end.y), new vector_1.Vector(path2.start.x, path2.start.y)]);
1042
- this.ctx.stroke();
1043
- }
1044
- }
1045
- this.ctx.restore();
1046
- return [2 /*return*/];
1047
- });
1048
- });
1049
- };
1050
- CanvasRenderer.prototype.render = function (element) {
1051
- return __awaiter(this, void 0, void 0, function () {
1052
- var stack;
1053
- return __generator(this, function (_a) {
1054
- switch (_a.label) {
1055
- case 0:
1056
- if (this.options.backgroundColor) {
1057
- this.ctx.fillStyle = (0, color_utilities_1.asString)(this.options.backgroundColor);
1058
- this.ctx.fillRect(this.options.x, this.options.y, this.options.width, this.options.height);
1059
- }
1060
- stack = (0, stacking_context_1.parseStackingContexts)(element);
1061
- return [4 /*yield*/, this.renderStack(stack)];
1062
- case 1:
1063
- _a.sent();
1064
- this.applyEffects([]);
1065
- return [2 /*return*/, this.canvas];
1066
- }
1067
- });
1068
- });
1069
- };
1070
- return CanvasRenderer;
1071
- }(renderer_1.Renderer));
777
+ }
778
+ if ((0, bezier_curve_1.isBezierCurve)(boxPaths[1])) {
779
+ const path1 = boxPaths[1];
780
+ const path2 = boxPaths[2];
781
+ this.ctx.beginPath();
782
+ this.formatPath([new vector_1.Vector(path1.end.x, path1.end.y), new vector_1.Vector(path2.start.x, path2.start.y)]);
783
+ this.ctx.stroke();
784
+ }
785
+ }
786
+ this.ctx.restore();
787
+ }
788
+ async render(element) {
789
+ if (this.options.backgroundColor) {
790
+ this.ctx.fillStyle = (0, color_utilities_1.asString)(this.options.backgroundColor);
791
+ this.ctx.fillRect(this.options.x, this.options.y, this.options.width, this.options.height);
792
+ }
793
+ const stack = (0, stacking_context_1.parseStackingContexts)(element);
794
+ await this.renderStack(stack);
795
+ this.applyEffects([]);
796
+ return this.canvas;
797
+ }
798
+ }
1072
799
  exports.CanvasRenderer = CanvasRenderer;
1073
- var isTextInputElement = function (container) {
800
+ const isTextInputElement = (container) => {
1074
801
  if (container instanceof textarea_element_container_1.TextareaElementContainer) {
1075
802
  return true;
1076
803
  }
@@ -1082,7 +809,7 @@ var isTextInputElement = function (container) {
1082
809
  }
1083
810
  return false;
1084
811
  };
1085
- var calculateBackgroundCurvedPaintingArea = function (clip, curves) {
812
+ const calculateBackgroundCurvedPaintingArea = (clip, curves) => {
1086
813
  switch (clip) {
1087
814
  case 0 /* BACKGROUND_CLIP.BORDER_BOX */:
1088
815
  return (0, bound_curves_1.calculateBorderBoxPath)(curves);
@@ -1093,7 +820,7 @@ var calculateBackgroundCurvedPaintingArea = function (clip, curves) {
1093
820
  return (0, bound_curves_1.calculatePaddingBoxPath)(curves);
1094
821
  }
1095
822
  };
1096
- var canvasTextAlign = function (textAlign) {
823
+ const canvasTextAlign = (textAlign) => {
1097
824
  switch (textAlign) {
1098
825
  case 1 /* TEXT_ALIGN.CENTER */:
1099
826
  return 'center';
@@ -1105,10 +832,10 @@ var canvasTextAlign = function (textAlign) {
1105
832
  }
1106
833
  };
1107
834
  // see https://github.com/niklasvh/html2canvas/pull/2645
1108
- var iOSBrokenFonts = ['-apple-system', 'system-ui'];
1109
- var fixIOSSystemFonts = function (fontFamilies) {
835
+ const iOSBrokenFonts = ['-apple-system', 'system-ui'];
836
+ const fixIOSSystemFonts = (fontFamilies) => {
1110
837
  return /iPhone OS 15_(0|1)/.test(window.navigator.userAgent)
1111
- ? fontFamilies.filter(function (fontFamily) { return iOSBrokenFonts.indexOf(fontFamily) === -1; })
838
+ ? fontFamilies.filter((fontFamily) => iOSBrokenFonts.indexOf(fontFamily) === -1)
1112
839
  : fontFamilies;
1113
840
  };
1114
841
  //# sourceMappingURL=canvas-renderer.js.map