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.
- package/dist/html2canvas-pro.esm.js +2509 -3036
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +2517 -3040
- package/dist/html2canvas-pro.js.map +1 -1
- package/dist/html2canvas-pro.min.js +6 -2
- package/dist/lib/__tests__/index.js +57 -122
- package/dist/lib/__tests__/index.js.map +1 -1
- package/dist/lib/core/__mocks__/cache-storage.js +2 -5
- package/dist/lib/core/__mocks__/cache-storage.js.map +1 -1
- package/dist/lib/core/__mocks__/context.js +7 -10
- package/dist/lib/core/__mocks__/context.js.map +1 -1
- package/dist/lib/core/__mocks__/logger.js +9 -17
- package/dist/lib/core/__mocks__/logger.js.map +1 -1
- package/dist/lib/core/__tests__/cache-storage.js +153 -351
- package/dist/lib/core/__tests__/cache-storage.js.map +1 -1
- package/dist/lib/core/__tests__/logger.js +12 -13
- package/dist/lib/core/__tests__/logger.js.map +1 -1
- package/dist/lib/core/bitwise.js +1 -1
- package/dist/lib/core/bitwise.js.map +1 -1
- package/dist/lib/core/cache-storage.js +92 -155
- package/dist/lib/core/cache-storage.js.map +1 -1
- package/dist/lib/core/context.js +8 -10
- package/dist/lib/core/context.js.map +1 -1
- package/dist/lib/core/debugger.js +5 -5
- package/dist/lib/core/debugger.js.map +1 -1
- package/dist/lib/core/features.js +65 -68
- package/dist/lib/core/features.js.map +1 -1
- package/dist/lib/core/logger.js +21 -56
- package/dist/lib/core/logger.js.map +1 -1
- package/dist/lib/css/index.js +98 -103
- package/dist/lib/css/index.js.map +1 -1
- package/dist/lib/css/layout/__mocks__/bounds.js +1 -1
- package/dist/lib/css/layout/__mocks__/bounds.js.map +1 -1
- package/dist/lib/css/layout/bounds.js +20 -21
- package/dist/lib/css/layout/bounds.js.map +1 -1
- package/dist/lib/css/layout/text.js +50 -58
- package/dist/lib/css/layout/text.js.map +1 -1
- package/dist/lib/css/property-descriptors/__tests__/background-tests.js +24 -29
- package/dist/lib/css/property-descriptors/__tests__/background-tests.js.map +1 -1
- package/dist/lib/css/property-descriptors/__tests__/font-family.js +14 -20
- package/dist/lib/css/property-descriptors/__tests__/font-family.js.map +1 -1
- package/dist/lib/css/property-descriptors/__tests__/paint-order.js +61 -83
- package/dist/lib/css/property-descriptors/__tests__/paint-order.js.map +1 -1
- package/dist/lib/css/property-descriptors/__tests__/text-shadow.js +75 -87
- package/dist/lib/css/property-descriptors/__tests__/text-shadow.js.map +1 -1
- package/dist/lib/css/property-descriptors/__tests__/transform-tests.js +9 -13
- package/dist/lib/css/property-descriptors/__tests__/transform-tests.js.map +1 -1
- package/dist/lib/css/property-descriptors/background-clip.js +3 -3
- package/dist/lib/css/property-descriptors/background-clip.js.map +1 -1
- package/dist/lib/css/property-descriptors/background-color.js +1 -1
- package/dist/lib/css/property-descriptors/background-image.js +6 -6
- package/dist/lib/css/property-descriptors/background-image.js.map +1 -1
- package/dist/lib/css/property-descriptors/background-origin.js +3 -3
- package/dist/lib/css/property-descriptors/background-origin.js.map +1 -1
- package/dist/lib/css/property-descriptors/background-position.js +6 -6
- package/dist/lib/css/property-descriptors/background-position.js.map +1 -1
- package/dist/lib/css/property-descriptors/background-repeat.js +7 -9
- package/dist/lib/css/property-descriptors/background-repeat.js.map +1 -1
- package/dist/lib/css/property-descriptors/background-size.js +5 -7
- package/dist/lib/css/property-descriptors/background-size.js.map +1 -1
- package/dist/lib/css/property-descriptors/border-color.js +3 -3
- package/dist/lib/css/property-descriptors/border-color.js.map +1 -1
- package/dist/lib/css/property-descriptors/border-radius.js +5 -7
- package/dist/lib/css/property-descriptors/border-radius.js.map +1 -1
- package/dist/lib/css/property-descriptors/border-style.js +4 -4
- package/dist/lib/css/property-descriptors/border-style.js.map +1 -1
- package/dist/lib/css/property-descriptors/border-width.js +5 -5
- package/dist/lib/css/property-descriptors/border-width.js.map +1 -1
- package/dist/lib/css/property-descriptors/box-shadow.js +10 -10
- package/dist/lib/css/property-descriptors/box-shadow.js.map +1 -1
- package/dist/lib/css/property-descriptors/color.js +1 -1
- package/dist/lib/css/property-descriptors/content.js +2 -2
- package/dist/lib/css/property-descriptors/content.js.map +1 -1
- package/dist/lib/css/property-descriptors/counter-increment.js +10 -10
- package/dist/lib/css/property-descriptors/counter-increment.js.map +1 -1
- package/dist/lib/css/property-descriptors/counter-reset.js +9 -9
- package/dist/lib/css/property-descriptors/counter-reset.js.map +1 -1
- package/dist/lib/css/property-descriptors/direction.js +1 -1
- package/dist/lib/css/property-descriptors/direction.js.map +1 -1
- package/dist/lib/css/property-descriptors/display.js +4 -4
- package/dist/lib/css/property-descriptors/display.js.map +1 -1
- package/dist/lib/css/property-descriptors/duration.js +4 -4
- package/dist/lib/css/property-descriptors/duration.js.map +1 -1
- package/dist/lib/css/property-descriptors/float.js +1 -1
- package/dist/lib/css/property-descriptors/float.js.map +1 -1
- package/dist/lib/css/property-descriptors/font-family.js +6 -6
- package/dist/lib/css/property-descriptors/font-family.js.map +1 -1
- package/dist/lib/css/property-descriptors/font-size.js +1 -1
- package/dist/lib/css/property-descriptors/font-style.js +1 -1
- package/dist/lib/css/property-descriptors/font-style.js.map +1 -1
- package/dist/lib/css/property-descriptors/font-variant.js +3 -3
- package/dist/lib/css/property-descriptors/font-variant.js.map +1 -1
- package/dist/lib/css/property-descriptors/font-weight.js +2 -2
- package/dist/lib/css/property-descriptors/font-weight.js.map +1 -1
- package/dist/lib/css/property-descriptors/letter-spacing.js +1 -1
- package/dist/lib/css/property-descriptors/letter-spacing.js.map +1 -1
- package/dist/lib/css/property-descriptors/line-break.js +1 -1
- package/dist/lib/css/property-descriptors/line-break.js.map +1 -1
- package/dist/lib/css/property-descriptors/line-height.js +3 -3
- package/dist/lib/css/property-descriptors/line-height.js.map +1 -1
- package/dist/lib/css/property-descriptors/list-style-image.js +2 -2
- package/dist/lib/css/property-descriptors/list-style-image.js.map +1 -1
- package/dist/lib/css/property-descriptors/list-style-position.js +1 -1
- package/dist/lib/css/property-descriptors/list-style-position.js.map +1 -1
- package/dist/lib/css/property-descriptors/list-style-type.js +1 -1
- package/dist/lib/css/property-descriptors/list-style-type.js.map +1 -1
- package/dist/lib/css/property-descriptors/margin.js +3 -3
- package/dist/lib/css/property-descriptors/margin.js.map +1 -1
- package/dist/lib/css/property-descriptors/object-fit.js +4 -4
- package/dist/lib/css/property-descriptors/object-fit.js.map +1 -1
- package/dist/lib/css/property-descriptors/opacity.js +2 -2
- package/dist/lib/css/property-descriptors/opacity.js.map +1 -1
- package/dist/lib/css/property-descriptors/overflow-wrap.js +1 -1
- package/dist/lib/css/property-descriptors/overflow-wrap.js.map +1 -1
- package/dist/lib/css/property-descriptors/overflow.js +3 -3
- package/dist/lib/css/property-descriptors/overflow.js.map +1 -1
- package/dist/lib/css/property-descriptors/padding.js +3 -3
- package/dist/lib/css/property-descriptors/padding.js.map +1 -1
- package/dist/lib/css/property-descriptors/paint-order.js +6 -6
- package/dist/lib/css/property-descriptors/paint-order.js.map +1 -1
- package/dist/lib/css/property-descriptors/position.js +1 -1
- package/dist/lib/css/property-descriptors/position.js.map +1 -1
- package/dist/lib/css/property-descriptors/quotes.js +11 -11
- package/dist/lib/css/property-descriptors/quotes.js.map +1 -1
- package/dist/lib/css/property-descriptors/rotate.js +3 -3
- package/dist/lib/css/property-descriptors/rotate.js.map +1 -1
- package/dist/lib/css/property-descriptors/text-align.js +1 -1
- package/dist/lib/css/property-descriptors/text-align.js.map +1 -1
- package/dist/lib/css/property-descriptors/text-decoration-color.js +1 -1
- package/dist/lib/css/property-descriptors/text-decoration-line.js +4 -4
- package/dist/lib/css/property-descriptors/text-decoration-line.js.map +1 -1
- package/dist/lib/css/property-descriptors/text-shadow.js +10 -10
- package/dist/lib/css/property-descriptors/text-shadow.js.map +1 -1
- package/dist/lib/css/property-descriptors/text-transform.js +1 -1
- package/dist/lib/css/property-descriptors/text-transform.js.map +1 -1
- package/dist/lib/css/property-descriptors/transform-origin.js +6 -6
- package/dist/lib/css/property-descriptors/transform-origin.js.map +1 -1
- package/dist/lib/css/property-descriptors/transform.js +15 -15
- package/dist/lib/css/property-descriptors/transform.js.map +1 -1
- package/dist/lib/css/property-descriptors/visibility.js +1 -1
- package/dist/lib/css/property-descriptors/visibility.js.map +1 -1
- package/dist/lib/css/property-descriptors/webkit-text-stroke-color.js +1 -1
- package/dist/lib/css/property-descriptors/webkit-text-stroke-width.js +3 -3
- package/dist/lib/css/property-descriptors/webkit-text-stroke-width.js.map +1 -1
- package/dist/lib/css/property-descriptors/word-break.js +1 -1
- package/dist/lib/css/property-descriptors/word-break.js.map +1 -1
- package/dist/lib/css/property-descriptors/z-index.js +3 -3
- package/dist/lib/css/property-descriptors/z-index.js.map +1 -1
- package/dist/lib/css/syntax/__tests__/tokernizer-tests.js +17 -25
- package/dist/lib/css/syntax/__tests__/tokernizer-tests.js.map +1 -1
- package/dist/lib/css/syntax/parser.js +50 -55
- package/dist/lib/css/syntax/parser.js.map +1 -1
- package/dist/lib/css/syntax/tokenizer.js +205 -214
- package/dist/lib/css/syntax/tokenizer.js.map +1 -1
- package/dist/lib/css/types/__tests__/color-tests.js +103 -167
- package/dist/lib/css/types/__tests__/color-tests.js.map +1 -1
- package/dist/lib/css/types/__tests__/image-tests.js +192 -217
- package/dist/lib/css/types/__tests__/image-tests.js.map +1 -1
- package/dist/lib/css/types/angle.js +13 -13
- package/dist/lib/css/types/angle.js.map +1 -1
- package/dist/lib/css/types/color-spaces/a98.js +18 -22
- package/dist/lib/css/types/color-spaces/a98.js.map +1 -1
- package/dist/lib/css/types/color-spaces/p3.js +17 -22
- package/dist/lib/css/types/color-spaces/p3.js.map +1 -1
- package/dist/lib/css/types/color-spaces/pro-photo.js +17 -21
- package/dist/lib/css/types/color-spaces/pro-photo.js.map +1 -1
- package/dist/lib/css/types/color-spaces/rec2020.js +15 -19
- package/dist/lib/css/types/color-spaces/rec2020.js.map +1 -1
- package/dist/lib/css/types/color-spaces/srgb.js +17 -23
- package/dist/lib/css/types/color-spaces/srgb.js.map +1 -1
- package/dist/lib/css/types/color-utilities.js +80 -103
- package/dist/lib/css/types/color-utilities.js.map +1 -1
- package/dist/lib/css/types/color.js +72 -66
- package/dist/lib/css/types/color.js.map +1 -1
- package/dist/lib/css/types/functions/-prefix-linear-gradient.js +11 -11
- package/dist/lib/css/types/functions/-prefix-linear-gradient.js.map +1 -1
- package/dist/lib/css/types/functions/-prefix-radial-gradient.js +16 -16
- package/dist/lib/css/types/functions/-prefix-radial-gradient.js.map +1 -1
- package/dist/lib/css/types/functions/-webkit-gradient.js +26 -26
- package/dist/lib/css/types/functions/-webkit-gradient.js.map +1 -1
- package/dist/lib/css/types/functions/__tests__/radial-gradient.js +57 -65
- package/dist/lib/css/types/functions/__tests__/radial-gradient.js.map +1 -1
- package/dist/lib/css/types/functions/counter.js +59 -65
- package/dist/lib/css/types/functions/counter.js.map +1 -1
- package/dist/lib/css/types/functions/gradient.js +51 -52
- package/dist/lib/css/types/functions/gradient.js.map +1 -1
- package/dist/lib/css/types/functions/linear-gradient.js +10 -10
- package/dist/lib/css/types/functions/linear-gradient.js.map +1 -1
- package/dist/lib/css/types/functions/radial-gradient.js +17 -17
- package/dist/lib/css/types/functions/radial-gradient.js.map +1 -1
- package/dist/lib/css/types/image.js +14 -14
- package/dist/lib/css/types/image.js.map +1 -1
- package/dist/lib/css/types/length-percentage.js +19 -27
- package/dist/lib/css/types/length-percentage.js.map +1 -1
- package/dist/lib/css/types/length.js +1 -3
- package/dist/lib/css/types/length.js.map +1 -1
- package/dist/lib/css/types/time.js +2 -2
- package/dist/lib/css/types/time.js.map +1 -1
- package/dist/lib/dom/__mocks__/document-cloner.js +7 -8
- package/dist/lib/dom/__mocks__/document-cloner.js.map +1 -1
- package/dist/lib/dom/document-cloner.js +195 -219
- package/dist/lib/dom/document-cloner.js.map +1 -1
- package/dist/lib/dom/element-container.js +8 -9
- package/dist/lib/dom/element-container.js.map +1 -1
- package/dist/lib/dom/elements/li-element-container.js +6 -24
- package/dist/lib/dom/elements/li-element-container.js.map +1 -1
- package/dist/lib/dom/elements/ol-element-container.js +7 -25
- package/dist/lib/dom/elements/ol-element-container.js.map +1 -1
- package/dist/lib/dom/elements/select-element-container.js +7 -25
- package/dist/lib/dom/elements/select-element-container.js.map +1 -1
- package/dist/lib/dom/elements/textarea-element-container.js +6 -24
- package/dist/lib/dom/elements/textarea-element-container.js.map +1 -1
- package/dist/lib/dom/node-parser.js +42 -46
- package/dist/lib/dom/node-parser.js.map +1 -1
- package/dist/lib/dom/replaced-elements/canvas-element-container.js +8 -26
- package/dist/lib/dom/replaced-elements/canvas-element-container.js.map +1 -1
- package/dist/lib/dom/replaced-elements/iframe-element-container.js +17 -35
- package/dist/lib/dom/replaced-elements/iframe-element-container.js.map +1 -1
- package/dist/lib/dom/replaced-elements/image-element-container.js +9 -27
- package/dist/lib/dom/replaced-elements/image-element-container.js.map +1 -1
- package/dist/lib/dom/replaced-elements/input-element-container.js +47 -59
- package/dist/lib/dom/replaced-elements/input-element-container.js.map +1 -1
- package/dist/lib/dom/replaced-elements/svg-element-container.js +14 -32
- package/dist/lib/dom/replaced-elements/svg-element-container.js.map +1 -1
- package/dist/lib/dom/text-container.js +7 -8
- package/dist/lib/dom/text-container.js.map +1 -1
- package/dist/lib/index.js +101 -156
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/invariant.js +1 -1
- package/dist/lib/invariant.js.map +1 -1
- package/dist/lib/render/background.js +44 -47
- package/dist/lib/render/background.js.map +1 -1
- package/dist/lib/render/bezier-curve.js +18 -19
- package/dist/lib/render/bezier-curve.js.map +1 -1
- package/dist/lib/render/border.js +9 -9
- package/dist/lib/render/border.js.map +1 -1
- package/dist/lib/render/bound-curves.js +35 -36
- package/dist/lib/render/bound-curves.js.map +1 -1
- package/dist/lib/render/box-sizing.js +11 -11
- package/dist/lib/render/box-sizing.js.map +1 -1
- package/dist/lib/render/canvas/canvas-renderer.js +639 -918
- package/dist/lib/render/canvas/canvas-renderer.js.map +1 -1
- package/dist/lib/render/canvas/foreignobject-renderer.js +35 -101
- package/dist/lib/render/canvas/foreignobject-renderer.js.map +1 -1
- package/dist/lib/render/effects.js +12 -17
- package/dist/lib/render/effects.js.map +1 -1
- package/dist/lib/render/font-metrics.js +17 -18
- package/dist/lib/render/font-metrics.js.map +1 -1
- package/dist/lib/render/path.js +4 -4
- package/dist/lib/render/path.js.map +1 -1
- package/dist/lib/render/renderer.js +3 -4
- package/dist/lib/render/renderer.js.map +1 -1
- package/dist/lib/render/stacking-context.js +71 -73
- package/dist/lib/render/stacking-context.js.map +1 -1
- package/dist/lib/render/vector.js +6 -7
- package/dist/lib/render/vector.js.map +1 -1
- package/dist/types/dom/replaced-elements/input-element-container.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/eslint.config.js +35 -0
- package/jest.config.cjs +5 -0
- package/karma.conf.cjs +295 -0
- 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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
105
|
-
var _this = this;
|
|
51
|
+
applyEffects(effects) {
|
|
106
52
|
while (this._activeEffects.length) {
|
|
107
53
|
this.popEffect();
|
|
108
54
|
}
|
|
109
|
-
effects.forEach(
|
|
110
|
-
}
|
|
111
|
-
|
|
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
|
-
|
|
72
|
+
}
|
|
73
|
+
popEffect() {
|
|
128
74
|
this._activeEffects.pop();
|
|
129
75
|
this.ctx.restore();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
|
|
178
|
-
letters.reduce(
|
|
179
|
-
|
|
180
|
-
return left +
|
|
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
|
-
|
|
185
|
-
|
|
186
|
-
.filter(
|
|
105
|
+
}
|
|
106
|
+
createFontStyle(styles) {
|
|
107
|
+
const fontVariant = styles.fontVariant
|
|
108
|
+
.filter((variant) => variant === 'normal' || variant === 'small-caps')
|
|
187
109
|
.join('');
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
?
|
|
191
|
-
:
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
272
|
-
_this.ctx.lineWidth = 0;
|
|
273
|
-
_this.ctx.lineJoin = 'miter';
|
|
274
|
-
break;
|
|
166
|
+
});
|
|
275
167
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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
|
-
|
|
287
|
-
|
|
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
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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
|
-
|
|
335
|
-
|
|
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
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
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
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
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
|
-
|
|
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
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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
|
-
|
|
487
|
+
}
|
|
488
|
+
path(paths) {
|
|
665
489
|
this.ctx.beginPath();
|
|
666
490
|
this.formatPath(paths);
|
|
667
491
|
this.ctx.closePath();
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
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
|
-
|
|
497
|
+
this.ctx.moveTo(start.x, start.y);
|
|
675
498
|
}
|
|
676
499
|
else {
|
|
677
|
-
|
|
500
|
+
this.ctx.lineTo(start.x, start.y);
|
|
678
501
|
}
|
|
679
502
|
if ((0, bezier_curve_1.isBezierCurve)(point)) {
|
|
680
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
697
|
-
|
|
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
|
-
|
|
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
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
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
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
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
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
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.
|
|
876
|
-
this.ctx.
|
|
877
|
-
|
|
878
|
-
|
|
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
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
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
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
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
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
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
|
-
|
|
969
|
-
|
|
656
|
+
this.mask(borderBoxArea);
|
|
657
|
+
this.ctx.clip();
|
|
658
|
+
this.path(shadowPaintingArea);
|
|
970
659
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
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
|
-
|
|
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 (
|
|
980
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1115
|
-
|
|
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(
|
|
838
|
+
? fontFamilies.filter((fontFamily) => iOSBrokenFonts.indexOf(fontFamily) === -1)
|
|
1118
839
|
: fontFamilies;
|
|
1119
840
|
};
|
|
1120
841
|
//# sourceMappingURL=canvas-renderer.js.map
|