html2canvas-pro 1.6.0 → 1.6.2

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