dompdf.js 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +5 -0
- package/README.md +168 -79
- package/dist/dom/element-container.d.ts +4 -2
- package/dist/dompdf.esm.js +607 -455
- package/dist/dompdf.esm.js.map +1 -1
- package/dist/dompdf.js +607 -455
- package/dist/dompdf.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/lib/__tests__/index.js.map +1 -1
- package/dist/lib/css/property-descriptors/border-style.js.map +1 -1
- package/dist/lib/css/types/color.js.map +1 -1
- package/dist/lib/dom/element-container.js +3 -1
- package/dist/lib/dom/element-container.js.map +1 -1
- package/dist/lib/dom/node-parser.js +15 -7
- package/dist/lib/dom/node-parser.js.map +1 -1
- package/dist/lib/dom/replaced-elements/iframe-element-container.js.map +1 -1
- package/dist/lib/index.js +107 -42
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/render/canvas/foreignobject-renderer.js.map +1 -1
- package/dist/lib/render/canvas/pdf-renderer.js +268 -464
- package/dist/lib/render/canvas/pdf-renderer.js.map +1 -1
- package/dist/lib/render/page-format-map.js +54 -0
- package/dist/lib/render/page-format-map.js.map +1 -0
- package/dist/lib/render/paginate.js +172 -0
- package/dist/lib/render/paginate.js.map +1 -0
- package/dist/render/canvas/pdf-renderer.d.ts +41 -16
- package/dist/render/page-format-map.d.ts +4 -0
- package/dist/render/paginate.d.ts +3 -0
- package/dist/types/dom/element-container.d.ts +4 -2
- package/dist/types/index.d.ts +1 -3
- package/dist/types/render/canvas/pdf-renderer.d.ts +41 -16
- package/dist/types/render/page-format-map.d.ts +4 -0
- package/dist/types/render/paginate.d.ts +3 -0
- package/package.json +3 -2
- package/dist/lib/render/canvas/canvas-renderer2.js +0 -1415
- package/dist/lib/render/canvas/canvas-renderer2.js.map +0 -1
- package/dist/render/canvas/canvas-renderer2.d.ts +0 -81
- package/dist/types/render/canvas/canvas-renderer2.d.ts +0 -81
|
@@ -52,78 +52,89 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
52
52
|
};
|
|
53
53
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
54
|
exports.CanvasRenderer = void 0;
|
|
55
|
-
var jspdf_1 = require("jspdf");
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
var
|
|
59
|
-
var
|
|
60
|
-
var
|
|
61
|
-
var
|
|
62
|
-
|
|
63
|
-
var
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
var
|
|
67
|
-
var
|
|
68
|
-
var
|
|
69
|
-
var
|
|
70
|
-
var
|
|
71
|
-
var
|
|
72
|
-
var
|
|
73
|
-
var
|
|
74
|
-
var
|
|
75
|
-
var
|
|
76
|
-
var
|
|
77
|
-
var
|
|
78
|
-
var
|
|
79
|
-
var
|
|
80
|
-
var effects_1 = require("../effects"); // 效果相关
|
|
81
|
-
var font_metrics_1 = require("../font-metrics"); // 字体度量
|
|
82
|
-
var renderer_1 = require("../renderer"); // 渲染器基类
|
|
83
|
-
var stacking_context_1 = require("../stacking-context"); // 堆叠上下文
|
|
84
|
-
var vector_1 = require("../vector"); // 向量
|
|
85
|
-
// 遮罩偏移常量
|
|
86
|
-
// const MASK_OFFSET = 10000;
|
|
87
|
-
// Canvas渲染器类,继承自Renderer
|
|
55
|
+
var jspdf_1 = require("jspdf");
|
|
56
|
+
var bitwise_1 = require("../../core/bitwise");
|
|
57
|
+
var bounds_1 = require("../../css/layout/bounds");
|
|
58
|
+
var text_1 = require("../../css/layout/text");
|
|
59
|
+
var line_height_1 = require("../../css/property-descriptors/line-height");
|
|
60
|
+
var parser_1 = require("../../css/syntax/parser");
|
|
61
|
+
var color_1 = require("../../css/types/color");
|
|
62
|
+
var length_percentage_1 = require("../../css/types/length-percentage");
|
|
63
|
+
var select_element_container_1 = require("../../dom/elements/select-element-container");
|
|
64
|
+
var textarea_element_container_1 = require("../../dom/elements/textarea-element-container");
|
|
65
|
+
var canvas_element_container_1 = require("../../dom/replaced-elements/canvas-element-container");
|
|
66
|
+
var iframe_element_container_1 = require("../../dom/replaced-elements/iframe-element-container");
|
|
67
|
+
var image_element_container_1 = require("../../dom/replaced-elements/image-element-container");
|
|
68
|
+
var input_element_container_1 = require("../../dom/replaced-elements/input-element-container");
|
|
69
|
+
var svg_element_container_1 = require("../../dom/replaced-elements/svg-element-container");
|
|
70
|
+
var background_1 = require("../background");
|
|
71
|
+
var bezier_curve_1 = require("../bezier-curve");
|
|
72
|
+
var border_1 = require("../border");
|
|
73
|
+
var bound_curves_1 = require("../bound-curves");
|
|
74
|
+
var box_sizing_1 = require("../box-sizing");
|
|
75
|
+
var effects_1 = require("../effects");
|
|
76
|
+
var font_metrics_1 = require("../font-metrics");
|
|
77
|
+
var renderer_1 = require("../renderer");
|
|
78
|
+
var stacking_context_1 = require("../stacking-context");
|
|
79
|
+
var vector_1 = require("../vector");
|
|
88
80
|
var CanvasRenderer = /** @class */ (function (_super) {
|
|
89
81
|
__extends(CanvasRenderer, _super);
|
|
90
|
-
// 构造函数
|
|
91
82
|
function CanvasRenderer(context, options) {
|
|
92
|
-
var _this = this;
|
|
93
|
-
|
|
94
|
-
_this =
|
|
95
|
-
_this._activeEffects = []; // 活动效果数组
|
|
83
|
+
var _this = _super.call(this, context, options) || this;
|
|
84
|
+
_this._activeEffects = [];
|
|
85
|
+
_this.totalPages = 1;
|
|
96
86
|
_this.canvas = options.canvas ? options.canvas : document.createElement('canvas');
|
|
97
87
|
_this.ctx = _this.canvas.getContext('2d');
|
|
98
|
-
// 计算页面尺寸并转换为 pt 单位 (1pt = 1/72 inch, 1px = 1/96 inch)
|
|
99
88
|
var pxToPt = function (px) { return px * (72 / 96); };
|
|
100
|
-
//
|
|
101
89
|
var pageWidth = pxToPt(options.width);
|
|
102
90
|
var pageHeight = pxToPt(options.height);
|
|
103
|
-
//
|
|
91
|
+
// const enc =
|
|
92
|
+
// this.options.encryption &&
|
|
93
|
+
// (this.options.encryption.userPassword ||
|
|
94
|
+
// this.options.encryption.ownerPassword ||
|
|
95
|
+
// (this.options.encryption.userPermissions && this.options.encryption.userPermissions.length))
|
|
96
|
+
// ? this.options.encryption
|
|
97
|
+
// : [];
|
|
98
|
+
var encOptions = _this.options.encryption
|
|
99
|
+
? {
|
|
100
|
+
userPassword: _this.options.encryption.userPassword,
|
|
101
|
+
ownerPassword: _this.options.encryption.ownerPassword,
|
|
102
|
+
userPermissions: _this.options.encryption.userPermissions
|
|
103
|
+
}
|
|
104
|
+
: undefined;
|
|
104
105
|
_this.jspdfCtx = new jspdf_1.jsPDF({
|
|
105
106
|
orientation: pageWidth > pageHeight ? 'landscape' : 'portrait',
|
|
106
107
|
unit: 'pt',
|
|
107
|
-
format: [
|
|
108
|
-
hotfixes: [
|
|
108
|
+
format: options.pagination && options.format ? options.format : [pageHeight, pageWidth],
|
|
109
|
+
hotfixes: ['px_scaling'],
|
|
110
|
+
putOnlyUsedFonts: options.putOnlyUsedFonts,
|
|
111
|
+
compress: options.compress,
|
|
112
|
+
precision: options.precision,
|
|
113
|
+
floatPrecision: options.floatPrecision,
|
|
114
|
+
encryption: encOptions
|
|
109
115
|
});
|
|
110
|
-
//
|
|
116
|
+
// orientation: pageWidth > pageHeight ? 'landscape' : 'portrait',
|
|
117
|
+
// unit: 'pt',
|
|
118
|
+
// format: options.pagination && options.format ? options.format : [pageHeight, pageWidth],
|
|
119
|
+
// hotfixes: ['px_scaling'],
|
|
120
|
+
// putOnlyUsedFonts: options.putOnlyUsedFonts,
|
|
121
|
+
// compress: options.compress,
|
|
122
|
+
// precision: options.precision,
|
|
123
|
+
// floatPrecision: options.floatPrecision,
|
|
124
|
+
// encryption: enc
|
|
125
|
+
// });
|
|
111
126
|
_this.context2dCtx = _this.jspdfCtx.context2d;
|
|
112
127
|
_this.context2dCtx.scale(0.75, 0.75);
|
|
113
128
|
_this.context2dCtx.translate(-options.x, -options.y);
|
|
114
|
-
// 确保字体已加载并注册到 jsPDF
|
|
115
129
|
if (options.fontConfig) {
|
|
116
130
|
try {
|
|
117
131
|
_this.loadFont();
|
|
118
132
|
}
|
|
119
133
|
catch (error) {
|
|
120
134
|
console.warn('Failed to set font:', error);
|
|
121
|
-
// 如果设置失败,使用默认字体
|
|
122
135
|
_this.jspdfCtx.setFont('Helvetica');
|
|
123
136
|
}
|
|
124
137
|
}
|
|
125
|
-
// this.jspdfCtx.setFont('SourceHanSansSC-Normal-Min');
|
|
126
|
-
// 将 pxToPt 保存为实例属性,以便其他方法使用
|
|
127
138
|
_this.pxToPt = pxToPt;
|
|
128
139
|
if (!options.canvas) {
|
|
129
140
|
_this.canvas.width = 10;
|
|
@@ -132,9 +143,6 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
132
143
|
_this.canvas.style.height = "10px";
|
|
133
144
|
}
|
|
134
145
|
_this.fontMetrics = new font_metrics_1.FontMetrics(document);
|
|
135
|
-
// this.ctx.scale(this.options.scale, this.options.scale);
|
|
136
|
-
// this.ctx.translate(-options.x, -options.y);
|
|
137
|
-
// this.ctx.textBaseline = 'bottom';
|
|
138
146
|
_this.context2dCtx.textBaseline = 'bottom';
|
|
139
147
|
_this._activeEffects = [];
|
|
140
148
|
_this.context.logger.debug("Canvas renderer initialized (".concat(options.width, "x").concat(options.height, ") with scale ").concat(options.scale));
|
|
@@ -144,67 +152,23 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
144
152
|
return __awaiter(this, void 0, void 0, function () {
|
|
145
153
|
var fontData;
|
|
146
154
|
return __generator(this, function (_a) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (!this.options.fontConfig.fontBase64) return [3 /*break*/, 1];
|
|
150
|
-
// 直接使用 Base64 编码
|
|
151
|
-
fontData = this.options.fontConfig.fontBase64;
|
|
152
|
-
return [3 /*break*/, 3];
|
|
153
|
-
case 1:
|
|
154
|
-
if (!this.options.fontConfig.fontUrl) return [3 /*break*/, 3];
|
|
155
|
-
return [4 /*yield*/, this.loadFontFromURL(this.options.fontConfig.fontUrl)];
|
|
156
|
-
case 2:
|
|
157
|
-
fontData = _a.sent();
|
|
158
|
-
_a.label = 3;
|
|
159
|
-
case 3:
|
|
160
|
-
// console.log('fontData',fontData)
|
|
161
|
-
// 将字体添加到 jsPDF
|
|
162
|
-
this.addFontToJsPDF(fontData);
|
|
163
|
-
return [2 /*return*/];
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
};
|
|
168
|
-
CanvasRenderer.prototype.loadFontFromURL = function (url) {
|
|
169
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
170
|
-
var response, blob;
|
|
171
|
-
return __generator(this, function (_a) {
|
|
172
|
-
switch (_a.label) {
|
|
173
|
-
case 0: return [4 /*yield*/, fetch(url, {
|
|
174
|
-
mode: 'no-cors',
|
|
175
|
-
headers: {
|
|
176
|
-
'Content-Type': 'font/ttf'
|
|
177
|
-
}
|
|
178
|
-
})];
|
|
179
|
-
case 1:
|
|
180
|
-
response = _a.sent();
|
|
181
|
-
return [4 /*yield*/, response.blob()];
|
|
182
|
-
case 2:
|
|
183
|
-
blob = _a.sent();
|
|
184
|
-
// const fontUrl = URL.createObjectURL(blob);
|
|
185
|
-
// console.log('response', blob, fontUrl)
|
|
186
|
-
// 注意:no-cors 模式下无法读取响应内容!
|
|
187
|
-
// const blob = await response.blob();
|
|
188
|
-
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
189
|
-
var reader = new FileReader();
|
|
190
|
-
reader.onload = function () { return resolve(reader.result.split(',')[1]); }; // 提取 Base64 数据
|
|
191
|
-
reader.onerror = function () { return reject(new Error('字体文件读取失败')); };
|
|
192
|
-
reader.readAsDataURL(blob);
|
|
193
|
-
})];
|
|
155
|
+
if (this.options.fontConfig.fontBase64) {
|
|
156
|
+
fontData = this.options.fontConfig.fontBase64;
|
|
194
157
|
}
|
|
158
|
+
this.addFontToJsPDF(fontData);
|
|
159
|
+
return [2 /*return*/];
|
|
195
160
|
});
|
|
196
161
|
});
|
|
197
162
|
};
|
|
198
163
|
CanvasRenderer.prototype.addFontToJsPDF = function (fontData) {
|
|
199
|
-
var
|
|
164
|
+
var fontFamily = this.options.fontConfig.fontFamily;
|
|
200
165
|
if (!fontFamily) {
|
|
201
166
|
return;
|
|
202
167
|
}
|
|
203
|
-
this.jspdfCtx.addFileToVFS("".concat(fontFamily, ".ttf"), fontData);
|
|
204
|
-
this.jspdfCtx.addFont("".concat(fontFamily, ".ttf"), fontFamily,
|
|
205
|
-
this.jspdfCtx.setFont(fontFamily);
|
|
168
|
+
this.jspdfCtx.addFileToVFS("".concat(fontFamily, ".ttf"), fontData);
|
|
169
|
+
this.jspdfCtx.addFont("".concat(fontFamily, ".ttf"), fontFamily, 'normal');
|
|
170
|
+
this.jspdfCtx.setFont(fontFamily);
|
|
206
171
|
};
|
|
207
|
-
// 应用效果数组
|
|
208
172
|
CanvasRenderer.prototype.applyEffects = function (effects) {
|
|
209
173
|
var _this = this;
|
|
210
174
|
while (this._activeEffects.length) {
|
|
@@ -212,46 +176,29 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
212
176
|
}
|
|
213
177
|
effects.forEach(function (effect) { return _this.applyEffect(effect); });
|
|
214
178
|
};
|
|
215
|
-
// 应用单个效果
|
|
216
179
|
CanvasRenderer.prototype.applyEffect = function (effect) {
|
|
217
180
|
this.ctx.save();
|
|
218
|
-
// this.context2dCtx.save()
|
|
219
181
|
if ((0, effects_1.isOpacityEffect)(effect)) {
|
|
220
182
|
this.ctx.globalAlpha = effect.opacity;
|
|
221
|
-
// this.context2dCtx.globalAlpha = effect.opacity
|
|
222
183
|
}
|
|
223
184
|
if ((0, effects_1.isTransformEffect)(effect)) {
|
|
224
185
|
this.ctx.translate(effect.offsetX, effect.offsetY);
|
|
225
186
|
this.ctx.transform(effect.matrix[0], effect.matrix[1], effect.matrix[2], effect.matrix[3], effect.matrix[4], effect.matrix[5]);
|
|
226
187
|
this.ctx.translate(-effect.offsetX, -effect.offsetY);
|
|
227
|
-
// this.context2dCtx.translate(effect.offsetX, effect.offsetY);
|
|
228
|
-
// this.context2dCtx.transform(
|
|
229
|
-
// effect.matrix[0],
|
|
230
|
-
// effect.matrix[1],
|
|
231
|
-
// effect.matrix[2],
|
|
232
|
-
// effect.matrix[3],
|
|
233
|
-
// effect.matrix[4],
|
|
234
|
-
// effect.matrix[5]
|
|
235
|
-
// );
|
|
236
|
-
// this.context2dCtx.translate(-effect.offsetX, -effect.offsetY);
|
|
237
188
|
}
|
|
238
189
|
if ((0, effects_1.isClipEffect)(effect)) {
|
|
239
190
|
this.path(effect.path);
|
|
240
191
|
this.ctx.clip();
|
|
241
|
-
// this.context2dCtx.clip()
|
|
242
192
|
}
|
|
243
193
|
this._activeEffects.push(effect);
|
|
244
194
|
};
|
|
245
|
-
// 移除最后应用的效果
|
|
246
195
|
CanvasRenderer.prototype.popEffect = function () {
|
|
247
196
|
this._activeEffects.pop();
|
|
248
|
-
// this.ctx.restore();
|
|
249
197
|
this.context2dCtx.restore();
|
|
250
198
|
if (this.options.fontConfig && this.options.fontConfig.fontFamily) {
|
|
251
199
|
this.jspdfCtx.setFont(this.options.fontConfig.fontFamily);
|
|
252
200
|
}
|
|
253
201
|
};
|
|
254
|
-
// 渲染堆叠上下文
|
|
255
202
|
CanvasRenderer.prototype.renderStack = function (stack) {
|
|
256
203
|
return __awaiter(this, void 0, void 0, function () {
|
|
257
204
|
var styles;
|
|
@@ -263,13 +210,12 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
263
210
|
return [4 /*yield*/, this.renderStackContent(stack)];
|
|
264
211
|
case 1:
|
|
265
212
|
_a.sent();
|
|
266
|
-
|
|
213
|
+
_a.label = 2;
|
|
267
214
|
case 2: return [2 /*return*/];
|
|
268
215
|
}
|
|
269
216
|
});
|
|
270
217
|
});
|
|
271
218
|
};
|
|
272
|
-
// 渲染节点
|
|
273
219
|
CanvasRenderer.prototype.renderNode = function (paint) {
|
|
274
220
|
return __awaiter(this, void 0, void 0, function () {
|
|
275
221
|
return __generator(this, function (_a) {
|
|
@@ -291,27 +237,19 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
291
237
|
});
|
|
292
238
|
});
|
|
293
239
|
};
|
|
294
|
-
// 渲染带有字母间距的文本
|
|
295
240
|
CanvasRenderer.prototype.renderTextWithLetterSpacing = function (text, letterSpacing, baseline) {
|
|
296
241
|
var _this = this;
|
|
297
242
|
if (letterSpacing === 0) {
|
|
298
|
-
// console.log(text.text, text.bounds.left,'绘制文字-没有letterSpacing')
|
|
299
|
-
// this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline);
|
|
300
243
|
this.context2dCtx.fillText(text.text, text.bounds.left, text.bounds.top + baseline);
|
|
301
244
|
}
|
|
302
245
|
else {
|
|
303
246
|
var letters = (0, text_1.segmentGraphemes)(text.text);
|
|
304
247
|
letters.reduce(function (left, letter) {
|
|
305
|
-
// console.log(left, letter,'绘制文字')
|
|
306
|
-
// this.ctx.fillText(letter, left, text.bounds.top + baseline);
|
|
307
|
-
// this.context2dCtx.fillText(letter, left - leftMargin, text.bounds.top + baseline - topMargin);
|
|
308
|
-
// 使用jspdf绘制文字
|
|
309
248
|
_this.context2dCtx.fillText(letter, left, text.bounds.top + baseline);
|
|
310
249
|
return left + _this.ctx.measureText(letter).width;
|
|
311
250
|
}, text.bounds.left);
|
|
312
251
|
}
|
|
313
252
|
};
|
|
314
|
-
// 创建字体样式
|
|
315
253
|
CanvasRenderer.prototype.createFontStyle = function (styles) {
|
|
316
254
|
var fontVariant = styles.fontVariant
|
|
317
255
|
.filter(function (variant) { return variant === 'normal' || variant === 'small-caps'; })
|
|
@@ -326,19 +264,16 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
326
264
|
fontSize
|
|
327
265
|
];
|
|
328
266
|
};
|
|
329
|
-
// 添加一个新的颜色转换函数
|
|
330
267
|
CanvasRenderer.prototype.convertColor = function (color) {
|
|
331
|
-
// 如果是透明色,返回白色
|
|
332
268
|
if ((0, color_1.isTransparent)(color)) {
|
|
333
269
|
return '#FFFFFF';
|
|
334
270
|
}
|
|
335
|
-
// 将 rgba 转换为 rgb
|
|
336
|
-
// 从32位整数中提取RGB分量
|
|
337
271
|
var r = 0xff & (color >> 24);
|
|
338
272
|
var g = 0xff & (color >> 16);
|
|
339
273
|
var b = 0xff & (color >> 8);
|
|
340
|
-
return "#".concat(r.toString(16).padStart(2, '0')).concat(g.toString(16).padStart(2, '0')).concat(b
|
|
341
|
-
|
|
274
|
+
return "#".concat(r.toString(16).padStart(2, '0')).concat(g.toString(16).padStart(2, '0')).concat(b
|
|
275
|
+
.toString(16)
|
|
276
|
+
.padStart(2, '0'));
|
|
342
277
|
return (0, color_1.asString)(color);
|
|
343
278
|
};
|
|
344
279
|
CanvasRenderer.prototype.renderTextNode = function (text, styles) {
|
|
@@ -347,15 +282,12 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
347
282
|
var _this = this;
|
|
348
283
|
return __generator(this, function (_c) {
|
|
349
284
|
_a = this.createFontStyle(styles), font = _a[0], fontFamily = _a[1], fontSize = _a[2];
|
|
350
|
-
// ,
|
|
351
|
-
// 设置 CanvasRenderingContext2D 的字体样式
|
|
352
285
|
this.ctx.font = font;
|
|
353
|
-
|
|
354
|
-
this.context2dCtx.font = this.options.fontConfig.fontFamily; // 通常不需要显式设置,jsPDF 会处理
|
|
286
|
+
this.context2dCtx.font = this.options.fontConfig.fontFamily;
|
|
355
287
|
this.ctx.direction = styles.direction === 1 /* DIRECTION.RTL */ ? 'rtl' : 'ltr';
|
|
356
|
-
this.context2dCtx.direction = styles.direction === 1 /* DIRECTION.RTL */ ? 'rtl' : 'ltr';
|
|
288
|
+
this.context2dCtx.direction = styles.direction === 1 /* DIRECTION.RTL */ ? 'rtl' : 'ltr';
|
|
357
289
|
this.ctx.textAlign = 'left';
|
|
358
|
-
this.context2dCtx.textAlign = 'left';
|
|
290
|
+
this.context2dCtx.textAlign = 'left';
|
|
359
291
|
fontSizePt = styles.fontSize.number;
|
|
360
292
|
this.jspdfCtx.setFontSize(fontSizePt);
|
|
361
293
|
_b = this.fontMetrics.getMetrics(fontFamily, fontSize), baseline = _b.baseline, middle = _b.middle;
|
|
@@ -364,15 +296,9 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
364
296
|
paintOrder.forEach(function (paintOrderLayer) {
|
|
365
297
|
switch (paintOrderLayer) {
|
|
366
298
|
case 0 /* PAINT_ORDER_LAYER.FILL */:
|
|
367
|
-
// 设置 CanvasRenderingContext2D 的填充样式
|
|
368
|
-
// this.ctx.fillStyle = asString(styles.color);
|
|
369
|
-
// 设置 jsPDF context2d 的填充样式
|
|
370
299
|
_this.context2dCtx.fillStyle = (0, color_1.asString)(styles.color);
|
|
371
300
|
_this.renderTextWithLetterSpacing(textItem, styles.letterSpacing, baseline);
|
|
372
301
|
if (styles.textDecorationLine.length) {
|
|
373
|
-
// 设置 CanvasRenderingContext2D 的填充样式
|
|
374
|
-
// this.ctx.fillStyle = asString(styles.textDecorationColor || styles.color);
|
|
375
|
-
// 设置 jsPDF context2d 的填充样式
|
|
376
302
|
_this.context2dCtx.fillStyle = (0, color_1.asString)(styles.textDecorationColor || styles.color);
|
|
377
303
|
styles.textDecorationLine.forEach(function (textDecorationLine) {
|
|
378
304
|
var x = textItem.bounds.left;
|
|
@@ -380,18 +306,15 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
380
306
|
var y_underline = Math.round(textItem.bounds.top + baseline);
|
|
381
307
|
var y_overline = Math.round(textItem.bounds.top);
|
|
382
308
|
var y_line_through = Math.ceil(textItem.bounds.top + middle);
|
|
383
|
-
var thickness = 1;
|
|
309
|
+
var thickness = 1;
|
|
384
310
|
switch (textDecorationLine) {
|
|
385
311
|
case 1 /* TEXT_DECORATION_LINE.UNDERLINE */:
|
|
386
|
-
// this.ctx.fillRect(x, y_underline, width, thickness);
|
|
387
312
|
_this.context2dCtx.fillRect(x, y_underline, width, thickness);
|
|
388
313
|
break;
|
|
389
314
|
case 2 /* TEXT_DECORATION_LINE.OVERLINE */:
|
|
390
|
-
// this.ctx.fillRect(x, y_overline, width, thickness);
|
|
391
315
|
_this.context2dCtx.fillRect(x, y_overline, width, thickness);
|
|
392
316
|
break;
|
|
393
317
|
case 3 /* TEXT_DECORATION_LINE.LINE_THROUGH */:
|
|
394
|
-
// this.ctx.fillRect(x, y_line_through, width, thickness);
|
|
395
318
|
_this.context2dCtx.fillRect(x, y_line_through, width, thickness);
|
|
396
319
|
break;
|
|
397
320
|
}
|
|
@@ -400,24 +323,10 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
400
323
|
break;
|
|
401
324
|
case 1 /* PAINT_ORDER_LAYER.STROKE */:
|
|
402
325
|
if (styles.webkitTextStrokeWidth && textItem.text.trim().length) {
|
|
403
|
-
// 设置 CanvasRenderingContext2D 的描边样式
|
|
404
|
-
// this.ctx.strokeStyle = asString(styles.webkitTextStrokeColor);
|
|
405
|
-
// this.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
406
|
-
// this.ctx.lineJoin = !!(window as any).chrome ? 'miter' : 'round';
|
|
407
|
-
// 设置 jsPDF context2d 的描边样式
|
|
408
326
|
_this.context2dCtx.strokeStyle = (0, color_1.asString)(styles.webkitTextStrokeColor);
|
|
409
327
|
_this.context2dCtx.lineWidth = styles.webkitTextStrokeWidth;
|
|
410
|
-
// this.context2dCtx.lineJoin = ...; // 根据 jsPDF API 调整
|
|
411
|
-
// CanvasRenderingContext2D 描边
|
|
412
|
-
// this.ctx.strokeText(textItem.text, textItem.bounds.left, textItem.bounds.top + baseline);
|
|
413
|
-
// jsPDF context2d 描边
|
|
414
328
|
_this.context2dCtx.strokeText(textItem.text, textItem.bounds.left, textItem.bounds.top + baseline);
|
|
415
329
|
}
|
|
416
|
-
// 清除 CanvasRenderingContext2D 的描边样式
|
|
417
|
-
// this.ctx.strokeStyle = '';
|
|
418
|
-
// this.ctx.lineWidth = 0;
|
|
419
|
-
// this.ctx.lineJoin = 'miter';
|
|
420
|
-
// 清除 jsPDF context2d 的描边样式
|
|
421
330
|
_this.context2dCtx.strokeStyle = '';
|
|
422
331
|
_this.context2dCtx.lineWidth = 0;
|
|
423
332
|
_this.context2dCtx.lineJoin = 'miter';
|
|
@@ -438,31 +347,14 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
438
347
|
this.ctx.clip();
|
|
439
348
|
this.ctx.drawImage(image, 0, 0, container.intrinsicWidth, container.intrinsicHeight, box.left, box.top, box.width, box.height);
|
|
440
349
|
this.ctx.restore();
|
|
441
|
-
// this.context2dCtx.save();
|
|
442
|
-
// this.context2dCtx.clip();
|
|
443
|
-
// this.context2dCtx.drawImage(
|
|
444
|
-
// image,
|
|
445
|
-
// 0,
|
|
446
|
-
// 0,
|
|
447
|
-
// container.intrinsicWidth,
|
|
448
|
-
// container.intrinsicHeight,
|
|
449
|
-
// box.left,
|
|
450
|
-
// box.top,
|
|
451
|
-
// box.width,
|
|
452
|
-
// box.height
|
|
453
|
-
// );
|
|
454
|
-
// this.context2dCtx.restore();
|
|
455
350
|
}
|
|
456
351
|
};
|
|
457
|
-
// 渲染节点内容
|
|
458
|
-
// 渲染节点内容的异步方法
|
|
459
352
|
CanvasRenderer.prototype.renderNodeContent = function (paint) {
|
|
460
353
|
return __awaiter(this, void 0, void 0, function () {
|
|
461
|
-
var container, curves, styles, _i, _a, child, image, bounds, x, y, width, height, e_1, bounds, x, y, width, height, dataURL, image, bounds, x, y, width, height, canvas, ctx, dataURL, e_2,
|
|
354
|
+
var container, curves, styles, _i, _a, child, image, bounds, x, y, width, height, e_1, bounds, x, y, width, height, dataURL, image, bounds, x, y, width, height, canvas, ctx, dataURL, e_2, size, _b, fontFamily, fontSize, baseline, bounds, x, textBounds, img, image, url, e_3, fontFamily, bounds;
|
|
462
355
|
return __generator(this, function (_c) {
|
|
463
356
|
switch (_c.label) {
|
|
464
357
|
case 0:
|
|
465
|
-
// 应用内容效果
|
|
466
358
|
this.applyEffects(paint.getEffects(4 /* EffectTarget.CONTENT */));
|
|
467
359
|
container = paint.container;
|
|
468
360
|
curves = paint.curves;
|
|
@@ -487,18 +379,14 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
487
379
|
return [4 /*yield*/, this.context.cache.match(container.src)];
|
|
488
380
|
case 6:
|
|
489
381
|
image = _c.sent();
|
|
490
|
-
// 渲染到 Canvas
|
|
491
382
|
this.renderReplacedElement(container, curves, image);
|
|
492
|
-
// 添加到 PDF
|
|
493
383
|
try {
|
|
494
384
|
bounds = (0, box_sizing_1.contentBox)(container);
|
|
495
385
|
x = this.pxToPt(bounds.left - this.options.x);
|
|
496
386
|
y = this.pxToPt(bounds.top - this.options.y);
|
|
497
387
|
width = this.pxToPt(bounds.width);
|
|
498
388
|
height = this.pxToPt(bounds.height);
|
|
499
|
-
|
|
500
|
-
this.jspdfCtx.addImage(image, 'JPEG', // 默认使用 JPEG 格式
|
|
501
|
-
x, y, width, height);
|
|
389
|
+
this.addImagePdf(image, 'JPEG', x, y, width, height);
|
|
502
390
|
}
|
|
503
391
|
catch (err) {
|
|
504
392
|
this.context.logger.error("Error adding image to PDF: ".concat(err));
|
|
@@ -510,9 +398,7 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
510
398
|
return [3 /*break*/, 8];
|
|
511
399
|
case 8:
|
|
512
400
|
if (container instanceof canvas_element_container_1.CanvasElementContainer) {
|
|
513
|
-
// 渲染到 Canvas
|
|
514
401
|
this.renderReplacedElement(container, curves, container.canvas);
|
|
515
|
-
// 添加到 PDF
|
|
516
402
|
try {
|
|
517
403
|
bounds = (0, box_sizing_1.contentBox)(container);
|
|
518
404
|
x = this.pxToPt(bounds.left - this.options.x);
|
|
@@ -520,8 +406,7 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
520
406
|
width = this.pxToPt(bounds.width);
|
|
521
407
|
height = this.pxToPt(bounds.height);
|
|
522
408
|
dataURL = container.canvas.toDataURL('image/png', 0.95);
|
|
523
|
-
|
|
524
|
-
this.jspdfCtx.addImage(dataURL, 'PNG', x, y, width, height);
|
|
409
|
+
this.addImagePdf(dataURL, 'PNG', x, y, width, height);
|
|
525
410
|
}
|
|
526
411
|
catch (err) {
|
|
527
412
|
this.context.logger.error("Error adding canvas to PDF: ".concat(err));
|
|
@@ -534,9 +419,7 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
534
419
|
return [4 /*yield*/, this.context.cache.match(container.svg)];
|
|
535
420
|
case 10:
|
|
536
421
|
image = _c.sent();
|
|
537
|
-
// 渲染到 Canvas
|
|
538
422
|
this.renderReplacedElement(container, curves, image);
|
|
539
|
-
// 添加到 PDF
|
|
540
423
|
try {
|
|
541
424
|
bounds = (0, box_sizing_1.contentBox)(container);
|
|
542
425
|
x = this.pxToPt(bounds.left - this.options.x);
|
|
@@ -548,13 +431,10 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
548
431
|
canvas.height = container.intrinsicHeight || image.height;
|
|
549
432
|
ctx = canvas.getContext('2d');
|
|
550
433
|
if (ctx) {
|
|
551
|
-
// 设置白色背景或保持透明
|
|
552
434
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
553
|
-
// 绘制SVG图像
|
|
554
435
|
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
555
436
|
dataURL = canvas.toDataURL('image/png');
|
|
556
|
-
|
|
557
|
-
this.jspdfCtx.addImage(dataURL, 'PNG', x, y, width, height);
|
|
437
|
+
this.addImagePdf(dataURL, 'PNG', x, y, width, height);
|
|
558
438
|
}
|
|
559
439
|
}
|
|
560
440
|
catch (err) {
|
|
@@ -566,42 +446,12 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
566
446
|
this.context.logger.error("Error loading svg ".concat(e_2));
|
|
567
447
|
return [3 /*break*/, 12];
|
|
568
448
|
case 12:
|
|
569
|
-
if (
|
|
570
|
-
iframeRenderer = new CanvasRenderer(this.context, {
|
|
571
|
-
scale: this.options.scale,
|
|
572
|
-
fontConfig: this.options.fontConfig,
|
|
573
|
-
backgroundColor: container.backgroundColor,
|
|
574
|
-
x: 0,
|
|
575
|
-
y: 0,
|
|
576
|
-
width: container.width,
|
|
577
|
-
height: container.height
|
|
578
|
-
});
|
|
579
|
-
return [4 /*yield*/, iframeRenderer.render(container.tree)];
|
|
580
|
-
case 13:
|
|
581
|
-
canvas = _c.sent();
|
|
582
|
-
if (container.width && container.height) {
|
|
583
|
-
// this.ctx.drawImage(
|
|
584
|
-
// canvas,
|
|
585
|
-
// 0,
|
|
586
|
-
// 0,
|
|
587
|
-
// container.width,
|
|
588
|
-
// container.height,
|
|
589
|
-
// container.bounds.left,
|
|
590
|
-
// container.bounds.top,
|
|
591
|
-
// container.bounds.width,
|
|
592
|
-
// container.bounds.height
|
|
593
|
-
// );
|
|
594
|
-
this.context2dCtx.drawImage(canvas, 0, 0, container.width, container.height, container.bounds.left, container.bounds.top, container.bounds.width, container.bounds.height);
|
|
449
|
+
if (container instanceof iframe_element_container_1.IFrameElementContainer && container.tree) {
|
|
595
450
|
}
|
|
596
|
-
_c.label = 14;
|
|
597
|
-
case 14:
|
|
598
|
-
// 处理Input元素
|
|
599
451
|
if (container instanceof input_element_container_1.InputElementContainer) {
|
|
600
452
|
size = Math.min(container.bounds.width, container.bounds.height);
|
|
601
|
-
// 渲染复选框
|
|
602
453
|
if (container.type === input_element_container_1.CHECKBOX) {
|
|
603
454
|
if (container.checked) {
|
|
604
|
-
// this.ctx.save();
|
|
605
455
|
this.context2dCtx.save();
|
|
606
456
|
this.path([
|
|
607
457
|
new vector_1.Vector(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79),
|
|
@@ -612,9 +462,6 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
612
462
|
new vector_1.Vector(container.bounds.left + size * 0.84, container.bounds.top + size * 0.34085),
|
|
613
463
|
new vector_1.Vector(container.bounds.left + size * 0.39363, container.bounds.top + size * 0.79)
|
|
614
464
|
]);
|
|
615
|
-
// this.ctx.fillStyle = this.convertColor(INPUT_COLOR);
|
|
616
|
-
// this.ctx.fill();
|
|
617
|
-
// this.ctx.restore();
|
|
618
465
|
this.context2dCtx.fillStyle = this.convertColor(input_element_container_1.INPUT_COLOR);
|
|
619
466
|
this.context2dCtx.fill();
|
|
620
467
|
this.context2dCtx.restore();
|
|
@@ -623,47 +470,25 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
623
470
|
}
|
|
624
471
|
}
|
|
625
472
|
}
|
|
626
|
-
// 渲染单选框
|
|
627
473
|
else if (container.type === input_element_container_1.RADIO) {
|
|
628
474
|
if (container.checked) {
|
|
629
|
-
// this.ctx.save();
|
|
630
|
-
// this.ctx.beginPath();
|
|
631
|
-
// this.ctx.arc(
|
|
632
|
-
// container.bounds.left + size / 2,
|
|
633
|
-
// container.bounds.top + size / 2,
|
|
634
|
-
// size / 4,
|
|
635
|
-
// 0,
|
|
636
|
-
// Math.PI * 2,
|
|
637
|
-
// true
|
|
638
|
-
// );
|
|
639
|
-
// this.ctx.fillStyle = this.convertColor(INPUT_COLOR);
|
|
640
|
-
// this.ctx.fill();
|
|
641
|
-
// this.ctx.restore();
|
|
642
475
|
this.context2dCtx.save();
|
|
643
476
|
this.context2dCtx.beginPath();
|
|
644
477
|
this.context2dCtx.arc(container.bounds.left + size / 2, container.bounds.top + size / 2, size / 4, 0, Math.PI * 2, true);
|
|
645
478
|
this.context2dCtx.fillStyle = this.convertColor(input_element_container_1.INPUT_COLOR);
|
|
646
479
|
this.context2dCtx.fill();
|
|
647
480
|
this.context2dCtx.restore();
|
|
648
|
-
// 在 restore 之后重新设置字体
|
|
649
481
|
}
|
|
650
482
|
}
|
|
651
483
|
}
|
|
652
|
-
// 处理文本输入元素
|
|
653
484
|
if (isTextInputElement(container) && container.value.length) {
|
|
654
485
|
_b = this.createFontStyle(styles), fontFamily = _b[0], fontSize = _b[1];
|
|
655
486
|
baseline = this.fontMetrics.getMetrics(fontFamily, fontSize).baseline;
|
|
656
|
-
// this.ctx.font = fontFamily;
|
|
657
|
-
// this.ctx.fillStyle = this.convertColor(styles.color);
|
|
658
|
-
// this.context2dCtx.font = fontFamily;
|
|
659
487
|
this.context2dCtx.fillStyle = this.convertColor(styles.color);
|
|
660
|
-
// this.ctx.textBaseline = 'alphabetic';
|
|
661
|
-
// this.ctx.textAlign = canvasTextAlign(container.styles.textAlign);
|
|
662
488
|
this.context2dCtx.textBaseline = 'alphabetic';
|
|
663
489
|
this.context2dCtx.textAlign = canvasTextAlign(container.styles.textAlign);
|
|
664
490
|
bounds = (0, box_sizing_1.contentBox)(container);
|
|
665
491
|
x = 0;
|
|
666
|
-
// 根据文本对齐方式调整x坐标
|
|
667
492
|
switch (container.styles.textAlign) {
|
|
668
493
|
case 1 /* TEXT_ALIGN.CENTER */:
|
|
669
494
|
x += bounds.width / 2;
|
|
@@ -673,7 +498,6 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
673
498
|
break;
|
|
674
499
|
}
|
|
675
500
|
textBounds = bounds.add(x, 0, 0, -bounds.height / 2 + 1);
|
|
676
|
-
// this.ctx.save();
|
|
677
501
|
this.context2dCtx.save();
|
|
678
502
|
this.path([
|
|
679
503
|
new vector_1.Vector(bounds.left, bounds.top),
|
|
@@ -681,56 +505,45 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
681
505
|
new vector_1.Vector(bounds.left + bounds.width, bounds.top + bounds.height),
|
|
682
506
|
new vector_1.Vector(bounds.left, bounds.top + bounds.height)
|
|
683
507
|
]);
|
|
684
|
-
// this.ctx.clip();
|
|
685
508
|
this.context2dCtx.clip();
|
|
686
509
|
this.renderTextWithLetterSpacing(new text_1.TextBounds(container.value, textBounds), styles.letterSpacing, baseline);
|
|
687
|
-
// this.ctx.restore();
|
|
688
|
-
// this.ctx.textBaseline = 'alphabetic';
|
|
689
|
-
// this.ctx.textAlign = 'left';
|
|
690
510
|
this.context2dCtx.restore();
|
|
691
511
|
this.context2dCtx.textBaseline = 'alphabetic';
|
|
692
512
|
this.context2dCtx.textAlign = 'left';
|
|
693
513
|
}
|
|
694
|
-
if (!(0, bitwise_1.contains)(container.styles.display, 2048 /* DISPLAY.LIST_ITEM */)) return [3 /*break*/,
|
|
695
|
-
if (!(container.styles.listStyleImage !== null)) return [3 /*break*/,
|
|
514
|
+
if (!(0, bitwise_1.contains)(container.styles.display, 2048 /* DISPLAY.LIST_ITEM */)) return [3 /*break*/, 18];
|
|
515
|
+
if (!(container.styles.listStyleImage !== null)) return [3 /*break*/, 17];
|
|
696
516
|
img = container.styles.listStyleImage;
|
|
697
|
-
if (!(img.type === 0 /* CSSImageType.URL */)) return [3 /*break*/,
|
|
517
|
+
if (!(img.type === 0 /* CSSImageType.URL */)) return [3 /*break*/, 16];
|
|
698
518
|
image = void 0;
|
|
699
519
|
url = img.url;
|
|
700
|
-
_c.label =
|
|
701
|
-
case
|
|
702
|
-
_c.trys.push([
|
|
520
|
+
_c.label = 13;
|
|
521
|
+
case 13:
|
|
522
|
+
_c.trys.push([13, 15, , 16]);
|
|
703
523
|
return [4 /*yield*/, this.context.cache.match(url)];
|
|
704
|
-
case
|
|
524
|
+
case 14:
|
|
705
525
|
image = _c.sent();
|
|
706
|
-
// this.ctx.drawImage(image, container.bounds.left - (image.width + 10), container.bounds.top);
|
|
707
526
|
this.context2dCtx.drawImage(image, container.bounds.left - (image.width + 10), container.bounds.top);
|
|
708
|
-
return [3 /*break*/,
|
|
709
|
-
case
|
|
527
|
+
return [3 /*break*/, 16];
|
|
528
|
+
case 15:
|
|
710
529
|
e_3 = _c.sent();
|
|
711
530
|
this.context.logger.error("Error loading list-style-image ".concat(url));
|
|
712
|
-
return [3 /*break*/,
|
|
713
|
-
case
|
|
714
|
-
case
|
|
531
|
+
return [3 /*break*/, 16];
|
|
532
|
+
case 16: return [3 /*break*/, 18];
|
|
533
|
+
case 17:
|
|
715
534
|
if (paint.listValue && container.styles.listStyleType !== -1 /* LIST_STYLE_TYPE.NONE */) {
|
|
716
535
|
fontFamily = this.createFontStyle(styles)[0];
|
|
717
|
-
// this.ctx.font = fontFamily;
|
|
718
|
-
// this.ctx.fillStyle = this.convertColor(styles.color);
|
|
719
536
|
this.context2dCtx.font = fontFamily;
|
|
720
537
|
this.context2dCtx.fillStyle = this.convertColor(styles.color);
|
|
721
|
-
// this.ctx.textBaseline = 'middle';
|
|
722
|
-
// this.ctx.textAlign = 'right';
|
|
723
538
|
this.context2dCtx.textBaseline = 'middle';
|
|
724
539
|
this.context2dCtx.textAlign = 'right';
|
|
725
540
|
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);
|
|
726
541
|
this.renderTextWithLetterSpacing(new text_1.TextBounds(paint.listValue, bounds), styles.letterSpacing, (0, line_height_1.computeLineHeight)(styles.lineHeight, styles.fontSize.number) / 2 + 2);
|
|
727
|
-
// this.ctx.textBaseline = 'bottom';
|
|
728
|
-
// this.ctx.textAlign = 'left';
|
|
729
542
|
this.context2dCtx.textBaseline = 'bottom';
|
|
730
543
|
this.context2dCtx.textAlign = 'left';
|
|
731
544
|
}
|
|
732
|
-
_c.label =
|
|
733
|
-
case
|
|
545
|
+
_c.label = 18;
|
|
546
|
+
case 18:
|
|
734
547
|
if (this.options.fontConfig && this.options.fontConfig.fontFamily) {
|
|
735
548
|
this.jspdfCtx.setFont(this.options.fontConfig.fontFamily);
|
|
736
549
|
}
|
|
@@ -739,7 +552,6 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
739
552
|
});
|
|
740
553
|
});
|
|
741
554
|
};
|
|
742
|
-
// 渲染堆叠上下文内容
|
|
743
555
|
CanvasRenderer.prototype.renderStackContent = function (stack) {
|
|
744
556
|
return __awaiter(this, void 0, void 0, function () {
|
|
745
557
|
var _i, _a, child, _b, _c, child, _d, _e, child, _f, _g, child, _h, _j, child, _k, _l, child, _m, _o, child;
|
|
@@ -749,12 +561,8 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
749
561
|
if ((0, bitwise_1.contains)(stack.element.container.flags, 16 /* FLAGS.DEBUG_RENDER */)) {
|
|
750
562
|
debugger;
|
|
751
563
|
}
|
|
752
|
-
// https://www.w3.org/TR/css-position-3/#painting-order
|
|
753
|
-
// 1. the background and borders of the element forming the stacking context.
|
|
754
564
|
return [4 /*yield*/, this.renderNodeBackgroundAndBorders(stack.element)];
|
|
755
565
|
case 1:
|
|
756
|
-
// https://www.w3.org/TR/css-position-3/#painting-order
|
|
757
|
-
// 1. the background and borders of the element forming the stacking context.
|
|
758
566
|
_p.sent();
|
|
759
567
|
_i = 0, _a = stack.negativeZIndex;
|
|
760
568
|
_p.label = 2;
|
|
@@ -768,11 +576,8 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
768
576
|
case 4:
|
|
769
577
|
_i++;
|
|
770
578
|
return [3 /*break*/, 2];
|
|
771
|
-
case 5:
|
|
772
|
-
// 3. For all its in-flow, non-positioned, block-level descendants in tree order:
|
|
773
|
-
return [4 /*yield*/, this.renderNodeContent(stack.element)];
|
|
579
|
+
case 5: return [4 /*yield*/, this.renderNodeContent(stack.element)];
|
|
774
580
|
case 6:
|
|
775
|
-
// 3. For all its in-flow, non-positioned, block-level descendants in tree order:
|
|
776
581
|
_p.sent();
|
|
777
582
|
_b = 0, _c = stack.nonInlineLevel;
|
|
778
583
|
_p.label = 7;
|
|
@@ -856,16 +661,7 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
856
661
|
});
|
|
857
662
|
});
|
|
858
663
|
};
|
|
859
|
-
// 创建遮罩
|
|
860
664
|
CanvasRenderer.prototype.mask = function (paths) {
|
|
861
|
-
// this.ctx.beginPath();
|
|
862
|
-
// this.ctx.moveTo(0, 0);
|
|
863
|
-
// this.ctx.lineTo(this.canvas.width, 0);
|
|
864
|
-
// this.ctx.lineTo(this.canvas.width, this.canvas.height);
|
|
865
|
-
// this.ctx.lineTo(0, this.canvas.height);
|
|
866
|
-
// this.ctx.lineTo(0, 0);
|
|
867
|
-
// this.formatPath(paths.slice(0).reverse());
|
|
868
|
-
// this.ctx.closePath();
|
|
869
665
|
this.context2dCtx.beginPath();
|
|
870
666
|
this.context2dCtx.moveTo(0, 0);
|
|
871
667
|
this.context2dCtx.lineTo(this.options.width, 0);
|
|
@@ -875,54 +671,33 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
875
671
|
this.formatPath(paths.slice(0).reverse());
|
|
876
672
|
this.context2dCtx.closePath();
|
|
877
673
|
};
|
|
878
|
-
// 创建路径
|
|
879
674
|
CanvasRenderer.prototype.path = function (paths) {
|
|
880
|
-
// this.ctx.beginPath();
|
|
881
|
-
// this.formatPath(paths);
|
|
882
|
-
// this.ctx.closePath();
|
|
883
675
|
this.context2dCtx.beginPath();
|
|
884
676
|
this.formatPath(paths);
|
|
885
677
|
this.context2dCtx.closePath();
|
|
886
678
|
};
|
|
887
|
-
// 格式化路径
|
|
888
679
|
CanvasRenderer.prototype.formatPath = function (paths) {
|
|
889
680
|
var _this = this;
|
|
890
681
|
paths.forEach(function (point, index) {
|
|
891
682
|
var start = (0, bezier_curve_1.isBezierCurve)(point) ? point.start : point;
|
|
892
683
|
if (index === 0) {
|
|
893
|
-
// this.ctx.moveTo(start.x, start.y);
|
|
894
684
|
_this.context2dCtx.moveTo(start.x, start.y);
|
|
895
685
|
}
|
|
896
686
|
else {
|
|
897
|
-
// this.ctx.lineTo(start.x, start.y);
|
|
898
687
|
_this.context2dCtx.lineTo(start.x, start.y);
|
|
899
688
|
}
|
|
900
689
|
if ((0, bezier_curve_1.isBezierCurve)(point)) {
|
|
901
|
-
// this.ctx.bezierCurveTo(
|
|
902
|
-
// point.startControl.x,
|
|
903
|
-
// point.startControl.y,
|
|
904
|
-
// point.endControl.x,
|
|
905
|
-
// point.endControl.y,
|
|
906
|
-
// point.end.x,
|
|
907
|
-
// point.end.y
|
|
908
|
-
// );
|
|
909
690
|
_this.context2dCtx.bezierCurveTo(point.startControl.x, point.startControl.y, point.endControl.x, point.endControl.y, point.end.x, point.end.y);
|
|
910
691
|
}
|
|
911
692
|
});
|
|
912
693
|
};
|
|
913
|
-
// 渲染重复图案
|
|
914
694
|
CanvasRenderer.prototype.renderRepeat = function (path, pattern, offsetX, offsetY) {
|
|
915
695
|
this.path(path);
|
|
916
696
|
this.ctx.fillStyle = pattern;
|
|
917
|
-
// this.ctx.translate(offsetX, offsetY);
|
|
918
|
-
// this.ctx.fill();
|
|
919
|
-
// this.ctx.translate(-offsetX, -offsetY);
|
|
920
|
-
// this.context2dCtx.fillStyle =this.convertColor(pattern) ;
|
|
921
697
|
this.context2dCtx.translate(offsetX, offsetY);
|
|
922
698
|
this.context2dCtx.fill();
|
|
923
699
|
this.context2dCtx.translate(-offsetX, -offsetY);
|
|
924
700
|
};
|
|
925
|
-
// 调整图片大小
|
|
926
701
|
CanvasRenderer.prototype.resizeImage = function (image, width, height) {
|
|
927
702
|
var _a;
|
|
928
703
|
if (image.width === width && image.height === height) {
|
|
@@ -936,7 +711,6 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
936
711
|
ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, width, height);
|
|
937
712
|
return canvas;
|
|
938
713
|
};
|
|
939
|
-
// 渲染背景图片
|
|
940
714
|
CanvasRenderer.prototype.renderBackgroundImage = function (container) {
|
|
941
715
|
return __awaiter(this, void 0, void 0, function () {
|
|
942
716
|
var index, _i, _a, backgroundImage, image, url, e_4, _b, path, x, y, width, height, pattern, xPt, yPt, widthPt, heightPt;
|
|
@@ -947,7 +721,7 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
947
721
|
_i = 0, _a = container.styles.backgroundImage.slice(0).reverse();
|
|
948
722
|
_c.label = 1;
|
|
949
723
|
case 1:
|
|
950
|
-
if (!(_i < _a.length)) return [3 /*break*/,
|
|
724
|
+
if (!(_i < _a.length)) return [3 /*break*/, 8];
|
|
951
725
|
backgroundImage = _a[_i];
|
|
952
726
|
if (!(backgroundImage.type === 0 /* CSSImageType.URL */)) return [3 /*break*/, 6];
|
|
953
727
|
image = void 0;
|
|
@@ -976,109 +750,31 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
976
750
|
yPt = this.pxToPt(y - this.options.y);
|
|
977
751
|
widthPt = this.pxToPt(width);
|
|
978
752
|
heightPt = this.pxToPt(height);
|
|
979
|
-
|
|
980
|
-
this.jspdfCtx.addImage(image, 'JPEG', xPt, yPt, widthPt, heightPt);
|
|
753
|
+
this.addImagePdf(image, 'JPEG', xPt, yPt, widthPt, heightPt);
|
|
981
754
|
}
|
|
982
|
-
|
|
755
|
+
_c.label = 6;
|
|
983
756
|
case 6:
|
|
984
|
-
|
|
985
|
-
// const [path, x, y, width, height] = calculateBackgroundRendering(container, index, [null, null, null]);
|
|
986
|
-
// const [lineLength, x0, x1, y0, y1] = calculateGradientDirection(backgroundImage.angle, width, height);
|
|
987
|
-
// const canvas = document.createElement('canvas');
|
|
988
|
-
// canvas.width = width;
|
|
989
|
-
// canvas.height = height;
|
|
990
|
-
// const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
|
991
|
-
// const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
992
|
-
// processColorStops(backgroundImage.stops, lineLength).forEach((colorStop) =>
|
|
993
|
-
// gradient.addColorStop(colorStop.stop, this.convertColor(colorStop.color))
|
|
994
|
-
// );
|
|
995
|
-
// ctx.fillStyle = gradient;
|
|
996
|
-
// ctx.fillRect(0, 0, width, height);
|
|
997
|
-
// if (width > 0 && height > 0) {
|
|
998
|
-
// const pattern = this.ctx.createPattern(canvas, 'repeat') as CanvasPattern;
|
|
999
|
-
// this.renderRepeat(path, pattern, x, y);
|
|
1000
|
-
// }
|
|
1001
|
-
}
|
|
1002
|
-
else if ((0, image_1.isRadialGradient)(backgroundImage)) {
|
|
1003
|
-
// const [path, left, top, width, height] = calculateBackgroundRendering(container, index, [
|
|
1004
|
-
// null,
|
|
1005
|
-
// null,
|
|
1006
|
-
// null
|
|
1007
|
-
// ]);
|
|
1008
|
-
// const position = backgroundImage.position.length === 0 ? [FIFTY_PERCENT] : backgroundImage.position;
|
|
1009
|
-
// const x = getAbsoluteValue(position[0], width);
|
|
1010
|
-
// const y = getAbsoluteValue(position[position.length - 1], height);
|
|
1011
|
-
// const [rx, ry] = calculateRadius(backgroundImage, x, y, width, height);
|
|
1012
|
-
// if (rx > 0 && ry > 0) {
|
|
1013
|
-
// const radialGradient = this.ctx.createRadialGradient(left + x, top + y, 0, left + x, top + y, rx);
|
|
1014
|
-
// processColorStops(backgroundImage.stops, rx * 2).forEach((colorStop) =>
|
|
1015
|
-
// radialGradient.addColorStop(colorStop.stop, this.convertColor(colorStop.color))
|
|
1016
|
-
// );
|
|
1017
|
-
// this.path(path);
|
|
1018
|
-
// this.ctx.fillStyle = radialGradient;
|
|
1019
|
-
// this.context2dCtx.fillStyle = this.convertColor(radialGradient);
|
|
1020
|
-
// if (rx !== ry) {
|
|
1021
|
-
// // transforms for elliptical radial gradient
|
|
1022
|
-
// const midX = container.bounds.left + 0.5 * container.bounds.width;
|
|
1023
|
-
// const midY = container.bounds.top + 0.5 * container.bounds.height;
|
|
1024
|
-
// const f = ry / rx;
|
|
1025
|
-
// const invF = 1 / f;
|
|
1026
|
-
// // this.ctx.save();
|
|
1027
|
-
// // this.ctx.translate(midX, midY);
|
|
1028
|
-
// // this.ctx.transform(1, 0, 0, f, 0, 0);
|
|
1029
|
-
// // this.ctx.translate(-midX, -midY);
|
|
1030
|
-
// // this.ctx.fillRect(left, invF * (top - midY) + midY, width, height * invF);
|
|
1031
|
-
// // this.ctx.restore();
|
|
1032
|
-
// this.context2dCtx.save();
|
|
1033
|
-
// this.context2dCtx.translate(midX, midY);
|
|
1034
|
-
// this.context2dCtx.transform(1, 0, 0, f, 0, 0);
|
|
1035
|
-
// this.context2dCtx.translate(-midX, -midY);
|
|
1036
|
-
// this.context2dCtx.fillRect(left, invF * (top - midY) + midY, width, height * invF);
|
|
1037
|
-
// this.context2dCtx.restore();
|
|
1038
|
-
// } else {
|
|
1039
|
-
// // this.ctx.fill();
|
|
1040
|
-
// this.context2dCtx.fill()
|
|
1041
|
-
// }
|
|
1042
|
-
// }
|
|
1043
|
-
}
|
|
757
|
+
index--;
|
|
1044
758
|
_c.label = 7;
|
|
1045
759
|
case 7:
|
|
1046
|
-
index--;
|
|
1047
|
-
_c.label = 8;
|
|
1048
|
-
case 8:
|
|
1049
760
|
_i++;
|
|
1050
761
|
return [3 /*break*/, 1];
|
|
1051
|
-
case
|
|
762
|
+
case 8: return [2 /*return*/];
|
|
1052
763
|
}
|
|
1053
764
|
});
|
|
1054
765
|
});
|
|
1055
766
|
};
|
|
1056
|
-
/**
|
|
1057
|
-
* 渲染实线边框
|
|
1058
|
-
* @param color - 边框颜色
|
|
1059
|
-
* @param side - 边的位置(0-3,分别代表上右下左)
|
|
1060
|
-
* @param curvePoints - 边框曲线点
|
|
1061
|
-
*/
|
|
1062
767
|
CanvasRenderer.prototype.renderSolidBorder = function (color, side, curvePoints) {
|
|
1063
768
|
return __awaiter(this, void 0, void 0, function () {
|
|
1064
769
|
return __generator(this, function (_a) {
|
|
1065
|
-
// console.log('绘制边框')
|
|
1066
|
-
// 解析边框路径
|
|
1067
|
-
// console.log('Border curve points:', JSON.stringify(curvePoints));
|
|
1068
|
-
// console.log('Page height:', this.jspdf.internal.pageSize.height);
|
|
1069
770
|
this.path((0, border_1.parsePathForBorder)(curvePoints, side));
|
|
1070
|
-
// 设置填充颜色
|
|
1071
|
-
// this.ctx.fillStyle = this.convertColor(color);
|
|
1072
771
|
this.context2dCtx.fillStyle = this.convertColor(color);
|
|
1073
|
-
// 填充路径
|
|
1074
|
-
// this.ctx.fill();
|
|
1075
772
|
this.jspdfCtx.fill();
|
|
1076
773
|
this.context2dCtx.fill();
|
|
1077
774
|
return [2 /*return*/];
|
|
1078
775
|
});
|
|
1079
776
|
});
|
|
1080
777
|
};
|
|
1081
|
-
// 渲染双线边框
|
|
1082
778
|
CanvasRenderer.prototype.renderDoubleBorder = function (color, width, side, curvePoints) {
|
|
1083
779
|
return __awaiter(this, void 0, void 0, function () {
|
|
1084
780
|
var outerPaths, innerPaths;
|
|
@@ -1093,27 +789,22 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
1093
789
|
case 2:
|
|
1094
790
|
outerPaths = (0, border_1.parsePathForBorderDoubleOuter)(curvePoints, side);
|
|
1095
791
|
this.path(outerPaths);
|
|
1096
|
-
// this.ctx.fillStyle = this.convertColor(color);
|
|
1097
|
-
// this.ctx.fill();
|
|
1098
792
|
this.context2dCtx.fillStyle = this.convertColor(color);
|
|
1099
793
|
this.context2dCtx.fill();
|
|
1100
794
|
innerPaths = (0, border_1.parsePathForBorderDoubleInner)(curvePoints, side);
|
|
1101
795
|
this.path(innerPaths);
|
|
1102
|
-
// this.ctx.fill();
|
|
1103
796
|
this.context2dCtx.fill();
|
|
1104
797
|
return [2 /*return*/];
|
|
1105
798
|
}
|
|
1106
799
|
});
|
|
1107
800
|
});
|
|
1108
801
|
};
|
|
1109
|
-
// 渲染节点的背景和边框
|
|
1110
802
|
CanvasRenderer.prototype.renderNodeBackgroundAndBorders = function (paint) {
|
|
1111
803
|
return __awaiter(this, void 0, void 0, function () {
|
|
1112
804
|
var styles, hasBackground, borders, backgroundPaintingArea, foreignobjectrendering, side, _i, borders_1, border;
|
|
1113
805
|
return __generator(this, function (_a) {
|
|
1114
806
|
switch (_a.label) {
|
|
1115
807
|
case 0:
|
|
1116
|
-
// 应用背景和边框的效果
|
|
1117
808
|
this.applyEffects(paint.getEffects(2 /* EffectTarget.BACKGROUND_BORDERS */));
|
|
1118
809
|
styles = paint.container.styles;
|
|
1119
810
|
hasBackground = !(0, color_1.isTransparent)(styles.backgroundColor) || styles.backgroundImage.length;
|
|
@@ -1126,8 +817,6 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
1126
817
|
backgroundPaintingArea = calculateBackgroundCurvedPaintingArea((0, background_1.getBackgroundValueForIndex)(styles.backgroundClip, 0), paint.curves);
|
|
1127
818
|
foreignobjectrendering = paint.container.foreignobjectrendering;
|
|
1128
819
|
if (!(hasBackground || styles.boxShadow.length)) return [3 /*break*/, 2];
|
|
1129
|
-
// console.log(paint,foreignobjectrendering, 'paint边框')
|
|
1130
|
-
// 在 save 之前确保字体设置正确
|
|
1131
820
|
if (this.options.fontConfig && this.options.fontConfig.fontFamily) {
|
|
1132
821
|
this.jspdfCtx.setFont(this.options.fontConfig.fontFamily);
|
|
1133
822
|
}
|
|
@@ -1135,12 +824,7 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
1135
824
|
this.context2dCtx.save();
|
|
1136
825
|
this.path(backgroundPaintingArea);
|
|
1137
826
|
this.context2dCtx.clip();
|
|
1138
|
-
// this.ctx.save();
|
|
1139
|
-
// this.path(backgroundPaintingArea);
|
|
1140
|
-
// this.ctx.clip();
|
|
1141
827
|
if (!(0, color_1.isTransparent)(styles.backgroundColor)) {
|
|
1142
|
-
// this.ctx.fillStyle = asString(styles.backgroundColor);
|
|
1143
|
-
// this.ctx.fill();
|
|
1144
828
|
this.context2dCtx.fillStyle = this.convertColor(styles.backgroundColor);
|
|
1145
829
|
this.context2dCtx.fill();
|
|
1146
830
|
}
|
|
@@ -1148,9 +832,7 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
1148
832
|
return [4 /*yield*/, this.renderBackgroundImage(paint.container)];
|
|
1149
833
|
case 1:
|
|
1150
834
|
_a.sent();
|
|
1151
|
-
// this.ctx.restore();
|
|
1152
835
|
this.context2dCtx.restore();
|
|
1153
|
-
// 在 restore 之后重新设置字体
|
|
1154
836
|
if (this.options.fontConfig && this.options.fontConfig.fontFamily) {
|
|
1155
837
|
this.jspdfCtx.setFont(this.options.fontConfig.fontFamily);
|
|
1156
838
|
}
|
|
@@ -1197,27 +879,15 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
1197
879
|
});
|
|
1198
880
|
});
|
|
1199
881
|
};
|
|
1200
|
-
|
|
1201
|
-
CanvasRenderer.prototype.renderDashedDottedBorder = function (color, // 边框颜色
|
|
1202
|
-
width, // 边框宽度
|
|
1203
|
-
side, // 边的位置(0-3,分别代表上右下左)
|
|
1204
|
-
curvePoints, // 边框曲线点
|
|
1205
|
-
style // 边框样式(DASHED或DOTTED)
|
|
1206
|
-
) {
|
|
882
|
+
CanvasRenderer.prototype.renderDashedDottedBorder = function (color, width, side, curvePoints, style) {
|
|
1207
883
|
return __awaiter(this, void 0, void 0, function () {
|
|
1208
884
|
var strokePaths, boxPaths, startX, startY, endX, endY, length, dashLength, spaceLength, useLineDash, multiplier, numberOfDashes, minSpace, maxSpace, path1, path2, x1, y1, x2, y2, path1, path2;
|
|
1209
885
|
return __generator(this, function (_a) {
|
|
1210
|
-
// this.ctx.save(); // 保存当前画布状态
|
|
1211
|
-
// this.jspdfCtx.saveGraphicsState(); // 保存PDF绘图状态
|
|
1212
886
|
this.context2dCtx.save();
|
|
1213
887
|
strokePaths = (0, border_1.parsePathForBorderStroke)(curvePoints, side);
|
|
1214
888
|
boxPaths = (0, border_1.parsePathForBorder)(curvePoints, side);
|
|
1215
|
-
// 如果是虚线边框,需要先裁剪路径
|
|
1216
889
|
if (style === 2 /* BORDER_STYLE.DASHED */) {
|
|
1217
890
|
this.path(boxPaths);
|
|
1218
|
-
// this.ctx.clip();
|
|
1219
|
-
// // PDF裁剪路径
|
|
1220
|
-
// this.jspdfCtx.clip();
|
|
1221
891
|
this.context2dCtx.clip();
|
|
1222
892
|
}
|
|
1223
893
|
if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) {
|
|
@@ -1242,10 +912,8 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
1242
912
|
else {
|
|
1243
913
|
length = Math.abs(startY - endY);
|
|
1244
914
|
}
|
|
1245
|
-
// 开始绘制路径
|
|
1246
|
-
// this.ctx.beginPath();
|
|
1247
915
|
this.context2dCtx.beginPath();
|
|
1248
|
-
this.jspdfCtx.setDrawColor(this.convertColor(color));
|
|
916
|
+
this.jspdfCtx.setDrawColor(this.convertColor(color));
|
|
1249
917
|
if (style === 3 /* BORDER_STYLE.DOTTED */) {
|
|
1250
918
|
this.formatPath(strokePaths);
|
|
1251
919
|
}
|
|
@@ -1276,34 +944,23 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
1276
944
|
? minSpace
|
|
1277
945
|
: maxSpace;
|
|
1278
946
|
}
|
|
1279
|
-
// 设置虚线样式
|
|
1280
947
|
if (useLineDash) {
|
|
1281
948
|
if (style === 3 /* BORDER_STYLE.DOTTED */) {
|
|
1282
|
-
|
|
1283
|
-
this.jspdfCtx.setLineDashPattern([0, dashLength + spaceLength], 0); // PDF虚线样式
|
|
949
|
+
this.jspdfCtx.setLineDashPattern([0, dashLength + spaceLength], 0);
|
|
1284
950
|
}
|
|
1285
951
|
else {
|
|
1286
|
-
|
|
1287
|
-
this.jspdfCtx.setLineDashPattern([dashLength, spaceLength], 0); // PDF虚线样式
|
|
952
|
+
this.jspdfCtx.setLineDashPattern([dashLength, spaceLength], 0);
|
|
1288
953
|
}
|
|
1289
954
|
}
|
|
1290
|
-
// 设置线条样式并绘制
|
|
1291
955
|
if (style === 3 /* BORDER_STYLE.DOTTED */) {
|
|
1292
|
-
|
|
1293
|
-
// this.ctx.lineWidth = width;
|
|
1294
|
-
this.jspdfCtx.setLineCap('round'); // PDF线帽样式
|
|
956
|
+
this.jspdfCtx.setLineCap('round');
|
|
1295
957
|
this.jspdfCtx.setLineWidth(width);
|
|
1296
958
|
}
|
|
1297
959
|
else {
|
|
1298
|
-
// this.ctx.lineWidth = width * 2 + 1.1;
|
|
1299
960
|
this.jspdfCtx.setLineWidth(width * 2 + 1.1);
|
|
1300
961
|
}
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
this.jspdfCtx.stroke(); // PDF绘制线条
|
|
1304
|
-
// this.ctx.setLineDash([]);
|
|
1305
|
-
this.jspdfCtx.setLineDashPattern([], 0); // 重置PDF虚线样式
|
|
1306
|
-
// 处理虚线边框的圆角连接处
|
|
962
|
+
this.jspdfCtx.stroke();
|
|
963
|
+
this.jspdfCtx.setLineDashPattern([], 0);
|
|
1307
964
|
if (style === 2 /* BORDER_STYLE.DASHED */) {
|
|
1308
965
|
if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) {
|
|
1309
966
|
path1 = boxPaths[3];
|
|
@@ -1323,42 +980,189 @@ var CanvasRenderer = /** @class */ (function (_super) {
|
|
|
1323
980
|
if ((0, bezier_curve_1.isBezierCurve)(boxPaths[1])) {
|
|
1324
981
|
path1 = boxPaths[1];
|
|
1325
982
|
path2 = boxPaths[2];
|
|
1326
|
-
|
|
1327
|
-
// this.formatPath([new Vector(path1.end.x, path1.end.y), new Vector(path2.start.x, path2.start.y)]);
|
|
1328
|
-
// this.ctx.stroke();
|
|
1329
|
-
this.jspdfCtx.lines([[path1.end.x, path1.end.y, path2.start.x, path2.start.y]], path1.end.x, path1.end.y); // PDF绘制连接线
|
|
983
|
+
this.jspdfCtx.lines([[path1.end.x, path1.end.y, path2.start.x, path2.start.y]], path1.end.x, path1.end.y);
|
|
1330
984
|
this.jspdfCtx.stroke();
|
|
1331
985
|
}
|
|
1332
986
|
}
|
|
1333
|
-
|
|
1334
|
-
this.jspdfCtx.restoreGraphicsState(); // 恢复PDF绘图状态
|
|
987
|
+
this.jspdfCtx.restoreGraphicsState();
|
|
1335
988
|
return [2 /*return*/];
|
|
1336
989
|
});
|
|
1337
990
|
});
|
|
1338
991
|
};
|
|
1339
|
-
CanvasRenderer.prototype.
|
|
992
|
+
CanvasRenderer.prototype.addPage = function (offsetY) {
|
|
1340
993
|
return __awaiter(this, void 0, void 0, function () {
|
|
1341
|
-
|
|
994
|
+
return __generator(this, function (_a) {
|
|
995
|
+
this.context2dCtx.translate(0, -offsetY);
|
|
996
|
+
this.jspdfCtx.addPage();
|
|
997
|
+
return [2 /*return*/];
|
|
998
|
+
});
|
|
999
|
+
});
|
|
1000
|
+
};
|
|
1001
|
+
CanvasRenderer.prototype.renderPage = function (element, pageNum) {
|
|
1002
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1003
|
+
var cfg, pageW, pageH, mt, mb, bx, by, bw, bh, stack, headerText, headerPos, footerText, footerPos;
|
|
1342
1004
|
return __generator(this, function (_a) {
|
|
1343
1005
|
switch (_a.label) {
|
|
1344
1006
|
case 0:
|
|
1007
|
+
cfg = this.options.pageConfig;
|
|
1008
|
+
pageW = this.jspdfCtx.internal.pageSize.getWidth();
|
|
1009
|
+
pageH = this.jspdfCtx.internal.pageSize.getHeight();
|
|
1010
|
+
mt = 0;
|
|
1011
|
+
mb = 0;
|
|
1345
1012
|
if (this.options.backgroundColor) {
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
this.
|
|
1349
|
-
|
|
1013
|
+
this.jspdfCtx.setFillColor(this.convertColor(this.options.backgroundColor));
|
|
1014
|
+
bx = this.safe(this.options.x);
|
|
1015
|
+
by = this.safe(this.options.y);
|
|
1016
|
+
bw = Math.max(1, this.safe(this.options.width, 1));
|
|
1017
|
+
bh = Math.max(1, this.safe(this.options.height, 1));
|
|
1018
|
+
this.jspdfCtx.rect(bx, by, bw, bh, 'F');
|
|
1350
1019
|
}
|
|
1351
1020
|
stack = (0, stacking_context_1.parseStackingContexts)(element);
|
|
1352
1021
|
return [4 /*yield*/, this.renderStack(stack)];
|
|
1353
1022
|
case 1:
|
|
1354
1023
|
_a.sent();
|
|
1355
1024
|
this.applyEffects([]);
|
|
1356
|
-
|
|
1357
|
-
|
|
1025
|
+
if (cfg === null || cfg === void 0 ? void 0 : cfg.header) {
|
|
1026
|
+
headerText = String(cfg.header.content)
|
|
1027
|
+
.replace('${currentPage}', String(pageNum))
|
|
1028
|
+
.replace('${totalPages}', String(this.totalPages));
|
|
1029
|
+
this.jspdfCtx.setFontSize(this.safe(this.pxToPt(cfg.header.contentFontSize), 1));
|
|
1030
|
+
this.setTextColorFromString(cfg.header.contentColor);
|
|
1031
|
+
headerPos = this.computeContentPosition(cfg.header.contentPosition, pageW, pageH, cfg.header.height, mt, mb, 'header', cfg.header.padding);
|
|
1032
|
+
this.textPdf(headerText, headerPos.x, headerPos.y, headerPos.align);
|
|
1033
|
+
}
|
|
1034
|
+
if (cfg === null || cfg === void 0 ? void 0 : cfg.footer) {
|
|
1035
|
+
footerText = String(cfg.footer.content)
|
|
1036
|
+
.replace('${currentPage}', String(pageNum))
|
|
1037
|
+
.replace('${totalPages}', String(this.totalPages));
|
|
1038
|
+
this.jspdfCtx.setFontSize(this.safe(this.pxToPt(cfg.footer.contentFontSize), 1));
|
|
1039
|
+
this.setTextColorFromString(cfg.footer.contentColor);
|
|
1040
|
+
footerPos = this.computeContentPosition(cfg.footer.contentPosition, pageW, pageH, cfg.footer.height, mt, mb, 'footer', cfg.footer.padding);
|
|
1041
|
+
this.textPdf(footerText, footerPos.x, footerPos.y, footerPos.align);
|
|
1042
|
+
}
|
|
1043
|
+
return [2 /*return*/];
|
|
1358
1044
|
}
|
|
1359
1045
|
});
|
|
1360
1046
|
});
|
|
1361
1047
|
};
|
|
1048
|
+
CanvasRenderer.prototype.setTotalPages = function (total) {
|
|
1049
|
+
this.totalPages = total;
|
|
1050
|
+
};
|
|
1051
|
+
CanvasRenderer.prototype.setTextColorFromString = function (color) {
|
|
1052
|
+
var _a;
|
|
1053
|
+
var named = {
|
|
1054
|
+
black: [0, 0, 0],
|
|
1055
|
+
white: [255, 255, 255],
|
|
1056
|
+
red: [255, 0, 0],
|
|
1057
|
+
green: [0, 128, 0],
|
|
1058
|
+
blue: [0, 0, 255],
|
|
1059
|
+
gray: [128, 128, 128]
|
|
1060
|
+
};
|
|
1061
|
+
var r = 0, g = 0, b = 0;
|
|
1062
|
+
var c = (color === null || color === void 0 ? void 0 : color.toLowerCase()) || 'black';
|
|
1063
|
+
if (c in named) {
|
|
1064
|
+
_a = named[c], r = _a[0], g = _a[1], b = _a[2];
|
|
1065
|
+
}
|
|
1066
|
+
else if (c.startsWith('#') && (c.length === 7 || c.length === 4)) {
|
|
1067
|
+
var hex = c.length === 4 ? "#".concat(c[1]).concat(c[1]).concat(c[2]).concat(c[2]).concat(c[3]).concat(c[3]) : c;
|
|
1068
|
+
r = parseInt(hex.slice(1, 3), 16);
|
|
1069
|
+
g = parseInt(hex.slice(3, 5), 16);
|
|
1070
|
+
b = parseInt(hex.slice(5, 7), 16);
|
|
1071
|
+
}
|
|
1072
|
+
this.jspdfCtx.setTextColor(r, g, b);
|
|
1073
|
+
};
|
|
1074
|
+
CanvasRenderer.prototype.safe = function (n, min) {
|
|
1075
|
+
if (min === void 0) { min = 0; }
|
|
1076
|
+
var v = Number(n);
|
|
1077
|
+
return Number.isFinite(v) ? v : min;
|
|
1078
|
+
};
|
|
1079
|
+
CanvasRenderer.prototype.textPdf = function (text, x, y, align) {
|
|
1080
|
+
var sx = this.safe(x);
|
|
1081
|
+
var sy = this.safe(y);
|
|
1082
|
+
this.jspdfCtx.text(String(text), sx, sy, { align: align });
|
|
1083
|
+
};
|
|
1084
|
+
CanvasRenderer.prototype.computeContentPosition = function (pos, pageW, pageH, areaH, mt, mb, area, paddingPx) {
|
|
1085
|
+
var _this = this;
|
|
1086
|
+
var _a = (paddingPx !== null && paddingPx !== void 0 ? paddingPx : [24, 24, 24, 24]).map(function (v) { return _this.pxToPt(v); }), pt = _a[0], pr = _a[1], pb = _a[2], pl = _a[3];
|
|
1087
|
+
var areaHPt = this.pxToPt(areaH);
|
|
1088
|
+
var mtPt = this.pxToPt(mt);
|
|
1089
|
+
var mbPt = this.pxToPt(mb);
|
|
1090
|
+
if (Array.isArray(pos) && pos.length >= 2) {
|
|
1091
|
+
return { x: this.pxToPt(pos[0]), y: this.pxToPt(pos[1]), align: 'left' };
|
|
1092
|
+
}
|
|
1093
|
+
if (area === 'header') {
|
|
1094
|
+
switch (pos) {
|
|
1095
|
+
case 'center':
|
|
1096
|
+
return {
|
|
1097
|
+
x: pageW / 2,
|
|
1098
|
+
y: mtPt + pt + (areaHPt - pt - pb) / 2,
|
|
1099
|
+
align: 'center'
|
|
1100
|
+
};
|
|
1101
|
+
case 'centerLeft':
|
|
1102
|
+
return { x: pl, y: mtPt + pt + (areaHPt - pt - pb) / 2, align: 'left' };
|
|
1103
|
+
case 'centerRight':
|
|
1104
|
+
return { x: pageW - pr, y: mtPt + pt + (areaHPt - pt - pb) / 2, align: 'right' };
|
|
1105
|
+
case 'centerTop':
|
|
1106
|
+
return { x: pageW / 2, y: mtPt + pt, align: 'center' };
|
|
1107
|
+
case 'centerBottom':
|
|
1108
|
+
return { x: pageW / 2, y: mtPt + areaHPt - pb, align: 'center' };
|
|
1109
|
+
case 'leftTop':
|
|
1110
|
+
return { x: pl, y: mtPt + pt, align: 'left' };
|
|
1111
|
+
case 'leftBottom':
|
|
1112
|
+
return { x: pl, y: mtPt + areaHPt - pb, align: 'left' };
|
|
1113
|
+
case 'rightTop':
|
|
1114
|
+
return { x: pageW - pr, y: mtPt + pt, align: 'right' };
|
|
1115
|
+
case 'rightBottom':
|
|
1116
|
+
return { x: pageW - pr, y: mtPt + areaHPt - pb, align: 'right' };
|
|
1117
|
+
default:
|
|
1118
|
+
return { x: pl, y: mtPt + pt, align: 'left' };
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
else {
|
|
1122
|
+
switch (pos) {
|
|
1123
|
+
case 'center':
|
|
1124
|
+
return {
|
|
1125
|
+
x: pageW / 2,
|
|
1126
|
+
y: pageH - mbPt - areaHPt + pt + (areaHPt - pt - pb) / 2,
|
|
1127
|
+
align: 'center'
|
|
1128
|
+
};
|
|
1129
|
+
case 'centerLeft':
|
|
1130
|
+
return { x: pl, y: pageH - mbPt - areaHPt + pt + (areaHPt - pt - pb) / 2, align: 'left' };
|
|
1131
|
+
case 'centerRight':
|
|
1132
|
+
return { x: pageW - pr, y: pageH - mbPt - areaHPt + pt + (areaHPt - pt - pb) / 2, align: 'right' };
|
|
1133
|
+
case 'centerTop':
|
|
1134
|
+
return { x: pageW / 2, y: pageH - mbPt - areaHPt + pt, align: 'center' };
|
|
1135
|
+
case 'centerBottom':
|
|
1136
|
+
return { x: pageW / 2, y: pageH - mbPt - pb, align: 'center' };
|
|
1137
|
+
case 'leftTop':
|
|
1138
|
+
return { x: pl, y: pageH - mbPt - areaHPt + pt, align: 'left' };
|
|
1139
|
+
case 'leftBottom':
|
|
1140
|
+
return { x: pl, y: pageH - mbPt - pb, align: 'left' };
|
|
1141
|
+
case 'rightTop':
|
|
1142
|
+
return { x: pageW - pr, y: pageH - mbPt - areaHPt + pt, align: 'right' };
|
|
1143
|
+
case 'rightBottom':
|
|
1144
|
+
return { x: pageW - pr, y: pageH - mbPt - pb, align: 'right' };
|
|
1145
|
+
default:
|
|
1146
|
+
return { x: pl, y: pageH - mbPt - pb, align: 'left' };
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
};
|
|
1150
|
+
CanvasRenderer.prototype.addImagePdf = function (img, format, x, y, w, h) {
|
|
1151
|
+
var sx = this.safe(x);
|
|
1152
|
+
var sy = this.safe(y);
|
|
1153
|
+
var sw = Math.max(1, this.safe(w, 1));
|
|
1154
|
+
var sh = Math.max(1, this.safe(h, 1));
|
|
1155
|
+
this.jspdfCtx.addImage(img, format, sx, sy, sw, sh);
|
|
1156
|
+
};
|
|
1157
|
+
CanvasRenderer.prototype.output = function () {
|
|
1158
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1159
|
+
var pdfBlob;
|
|
1160
|
+
return __generator(this, function (_a) {
|
|
1161
|
+
pdfBlob = this.jspdfCtx.output('blob');
|
|
1162
|
+
return [2 /*return*/, pdfBlob];
|
|
1163
|
+
});
|
|
1164
|
+
});
|
|
1165
|
+
};
|
|
1362
1166
|
return CanvasRenderer;
|
|
1363
1167
|
}(renderer_1.Renderer));
|
|
1364
1168
|
exports.CanvasRenderer = CanvasRenderer;
|