html2canvas-pro 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/html2canvas-pro.cjs +25 -22
- package/dist/html2canvas-pro.cjs.map +1 -1
- package/dist/html2canvas-pro.esm.js +25 -22
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +25 -22
- package/dist/html2canvas-pro.js.map +1 -1
- package/dist/html2canvas-pro.min.js +2 -2
- package/dist/lib/render/canvas/canvas-renderer.js +1 -1
- package/dist/lib/render/canvas/text-renderer.js +26 -20
- package/dist/types/render/canvas/text-renderer.d.ts +3 -2
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* html2canvas-pro 2.3.
|
|
2
|
+
* html2canvas-pro 2.3.1 <https://yorickshan.github.io/html2canvas-pro/>
|
|
3
3
|
* Copyright (c) 2024-present yorickshan and html2canvas-pro contributors
|
|
4
4
|
* Released under MIT License
|
|
5
5
|
*/
|
|
@@ -9137,6 +9137,7 @@ var TextRenderer = class {
|
|
|
9137
9137
|
constructor(deps) {
|
|
9138
9138
|
this.glyphWidthCache = null;
|
|
9139
9139
|
this.ctx = deps.ctx;
|
|
9140
|
+
this.fontMetrics = deps.fontMetrics;
|
|
9140
9141
|
this.options = deps.options;
|
|
9141
9142
|
this.decorationRenderer = new TextDecorationRenderer(deps.ctx);
|
|
9142
9143
|
}
|
|
@@ -9251,19 +9252,19 @@ var TextRenderer = class {
|
|
|
9251
9252
|
this.ctx.strokeText(letter, x, y);
|
|
9252
9253
|
});
|
|
9253
9254
|
}
|
|
9254
|
-
renderTextStrokeWithStyle(text, styles) {
|
|
9255
|
+
renderTextStrokeWithStyle(text, styles, baseline) {
|
|
9255
9256
|
if (!styles.webkitTextStrokeWidth || !text.text.trim().length) return;
|
|
9256
9257
|
this.ctx.strokeStyle = asString(styles.webkitTextStrokeColor);
|
|
9257
9258
|
this.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
9258
9259
|
this.ctx.lineJoin = getTextStrokeLineJoin();
|
|
9259
|
-
this.renderStrokeText(text, styles.letterSpacing,
|
|
9260
|
+
this.renderStrokeText(text, styles.letterSpacing, baseline, styles.writingMode);
|
|
9260
9261
|
this.ctx.strokeStyle = "";
|
|
9261
9262
|
this.ctx.lineWidth = 0;
|
|
9262
9263
|
this.ctx.lineJoin = "miter";
|
|
9263
9264
|
}
|
|
9264
|
-
renderTextFillWithShadows(text, styles) {
|
|
9265
|
+
renderTextFillWithShadows(text, styles, baseline) {
|
|
9265
9266
|
this.ctx.fillStyle = asString(styles.color);
|
|
9266
|
-
this.renderTextWithLetterSpacing(text, styles.letterSpacing,
|
|
9267
|
+
this.renderTextWithLetterSpacing(text, styles.letterSpacing, baseline, styles.writingMode);
|
|
9267
9268
|
const textShadows = styles.textShadow;
|
|
9268
9269
|
if (textShadows.length && text.text.trim().length) {
|
|
9269
9270
|
textShadows.slice(0).reverse().forEach((textShadow) => {
|
|
@@ -9271,7 +9272,7 @@ var TextRenderer = class {
|
|
|
9271
9272
|
this.ctx.shadowOffsetX = textShadow.offsetX.number * this.options.scale;
|
|
9272
9273
|
this.ctx.shadowOffsetY = textShadow.offsetY.number * this.options.scale;
|
|
9273
9274
|
this.ctx.shadowBlur = textShadow.blur.number;
|
|
9274
|
-
this.renderTextWithLetterSpacing(text, styles.letterSpacing,
|
|
9275
|
+
this.renderTextWithLetterSpacing(text, styles.letterSpacing, baseline, styles.writingMode);
|
|
9275
9276
|
});
|
|
9276
9277
|
this.ctx.shadowColor = "";
|
|
9277
9278
|
this.ctx.shadowOffsetX = 0;
|
|
@@ -9283,15 +9284,15 @@ var TextRenderer = class {
|
|
|
9283
9284
|
* Helper method to render text with paint order support
|
|
9284
9285
|
* Reduces code duplication in line-clamp and normal rendering
|
|
9285
9286
|
*/
|
|
9286
|
-
renderTextBoundWithPaintOrder(textBound, styles, paintOrderLayers) {
|
|
9287
|
+
renderTextBoundWithPaintOrder(textBound, styles, paintOrderLayers, baseline) {
|
|
9287
9288
|
paintOrderLayers.forEach((paintOrderLayer) => {
|
|
9288
9289
|
switch (paintOrderLayer) {
|
|
9289
9290
|
case 0:
|
|
9290
9291
|
this.ctx.fillStyle = asString(styles.color);
|
|
9291
|
-
this.renderTextWithLetterSpacing(textBound, styles.letterSpacing,
|
|
9292
|
+
this.renderTextWithLetterSpacing(textBound, styles.letterSpacing, baseline, styles.writingMode);
|
|
9292
9293
|
break;
|
|
9293
9294
|
case 1:
|
|
9294
|
-
this.renderTextStrokeWithStyle(textBound, styles);
|
|
9295
|
+
this.renderTextStrokeWithStyle(textBound, styles, baseline);
|
|
9295
9296
|
break;
|
|
9296
9297
|
}
|
|
9297
9298
|
});
|
|
@@ -9351,7 +9352,7 @@ var TextRenderer = class {
|
|
|
9351
9352
|
* Groups text bounds by their Y position into visual lines, then renders
|
|
9352
9353
|
* only the first N-1 complete lines followed by an ellipsis on the Nth line.
|
|
9353
9354
|
*/
|
|
9354
|
-
renderLineClampedText(text, styles, paintOrder, containerBounds) {
|
|
9355
|
+
renderLineClampedText(text, styles, paintOrder, baseline, containerBounds) {
|
|
9355
9356
|
const lineHeight = styles.fontSize.number * 1.5;
|
|
9356
9357
|
const lines = [];
|
|
9357
9358
|
let currentLine = [];
|
|
@@ -9366,7 +9367,7 @@ var TextRenderer = class {
|
|
|
9366
9367
|
if (currentLine.length > 0) lines.push(currentLine);
|
|
9367
9368
|
const maxLines = styles.webkitLineClamp;
|
|
9368
9369
|
if (lines.length <= maxLines) return false;
|
|
9369
|
-
for (let i = 0; i < maxLines - 1; i++) lines[i].forEach((tb) => this.renderTextBoundWithPaintOrder(tb, styles, paintOrder));
|
|
9370
|
+
for (let i = 0; i < maxLines - 1; i++) lines[i].forEach((tb) => this.renderTextBoundWithPaintOrder(tb, styles, paintOrder, baseline));
|
|
9370
9371
|
const lastLine = lines[maxLines - 1];
|
|
9371
9372
|
if (lastLine?.length && containerBounds) {
|
|
9372
9373
|
const textStr = lastLine.map((tb) => tb.text).join("");
|
|
@@ -9375,8 +9376,8 @@ var TextRenderer = class {
|
|
|
9375
9376
|
const bounds = new TextBounds(this.truncateTextWithEllipsis(textStr, avail, styles.letterSpacing), first.bounds);
|
|
9376
9377
|
for (const layer of paintOrder) if (layer === 0) {
|
|
9377
9378
|
this.ctx.fillStyle = asString(styles.color);
|
|
9378
|
-
this.renderTextWithLetterSpacing(bounds, styles.letterSpacing,
|
|
9379
|
-
} else if (layer === 1) this.renderTextStrokeWithStyle(bounds, styles);
|
|
9379
|
+
this.renderTextWithLetterSpacing(bounds, styles.letterSpacing, baseline, styles.writingMode);
|
|
9380
|
+
} else if (layer === 1) this.renderTextStrokeWithStyle(bounds, styles, baseline);
|
|
9380
9381
|
}
|
|
9381
9382
|
return true;
|
|
9382
9383
|
}
|
|
@@ -9384,34 +9385,36 @@ var TextRenderer = class {
|
|
|
9384
9385
|
* Render single-line text with text-overflow: ellipsis.
|
|
9385
9386
|
* Returns true if ellipsis was applied (caller should skip normal rendering).
|
|
9386
9387
|
*/
|
|
9387
|
-
renderEllipsisText(text, styles, paintOrder, containerBounds) {
|
|
9388
|
+
renderEllipsisText(text, styles, paintOrder, baseline, containerBounds) {
|
|
9388
9389
|
const lineHeight = styles.fontSize.number * 1.5;
|
|
9389
9390
|
const firstTop = text.textBounds[0].bounds.top;
|
|
9390
9391
|
if (!text.textBounds.every((tb) => Math.abs(tb.bounds.top - firstTop) < lineHeight * .5)) return false;
|
|
9391
9392
|
let fullText = text.textBounds.map((tb) => tb.text).join("").replace(/\s+/g, " ").trim();
|
|
9392
9393
|
if (this.ctx.measureText(fullText).width <= containerBounds.width) return false;
|
|
9393
9394
|
const bounds = new TextBounds(this.truncateTextWithEllipsis(fullText, containerBounds.width, styles.letterSpacing), text.textBounds[0].bounds);
|
|
9394
|
-
for (const layer of paintOrder) if (layer === 0) this.renderTextFillWithShadows(bounds, styles);
|
|
9395
|
-
else if (layer === 1) this.renderTextStrokeWithStyle(bounds, styles);
|
|
9395
|
+
for (const layer of paintOrder) if (layer === 0) this.renderTextFillWithShadows(bounds, styles, baseline);
|
|
9396
|
+
else if (layer === 1) this.renderTextStrokeWithStyle(bounds, styles, baseline);
|
|
9396
9397
|
return true;
|
|
9397
9398
|
}
|
|
9398
9399
|
async renderTextNode(text, styles, containerBounds) {
|
|
9399
9400
|
this.glyphWidthCache = null;
|
|
9400
|
-
|
|
9401
|
+
const [fontString, fontFamily, fontSize] = this.createFontStyle(styles);
|
|
9402
|
+
this.ctx.font = fontString;
|
|
9401
9403
|
this.ctx.direction = styles.direction === 1 ? "rtl" : "ltr";
|
|
9402
9404
|
this.ctx.textAlign = "left";
|
|
9403
9405
|
this.ctx.textBaseline = "alphabetic";
|
|
9404
9406
|
const paintOrder = styles.paintOrder;
|
|
9407
|
+
const { baseline } = this.fontMetrics.getMetrics(fontFamily, fontSize);
|
|
9405
9408
|
if (styles.webkitLineClamp > 0 && (styles.display & 2) !== 0 && styles.overflowY === 1 && text.textBounds.length > 0) {
|
|
9406
|
-
if (this.renderLineClampedText(text, styles, paintOrder, containerBounds)) return;
|
|
9409
|
+
if (this.renderLineClampedText(text, styles, paintOrder, baseline, containerBounds)) return;
|
|
9407
9410
|
}
|
|
9408
|
-
if (styles.textOverflow === 1 && containerBounds && styles.overflowX === 1 && text.textBounds.length > 0 && this.renderEllipsisText(text, styles, paintOrder, containerBounds)) return;
|
|
9411
|
+
if (styles.textOverflow === 1 && containerBounds && styles.overflowX === 1 && text.textBounds.length > 0 && this.renderEllipsisText(text, styles, paintOrder, baseline, containerBounds)) return;
|
|
9409
9412
|
text.textBounds.forEach((tb) => {
|
|
9410
9413
|
paintOrder.forEach((layer) => {
|
|
9411
9414
|
if (layer === 0) {
|
|
9412
|
-
this.renderTextFillWithShadows(tb, styles);
|
|
9415
|
+
this.renderTextFillWithShadows(tb, styles, baseline);
|
|
9413
9416
|
if (styles.textDecorationLine.length) this.renderTextDecoration(tb.bounds, styles);
|
|
9414
|
-
} else if (layer === 1) this.renderTextStrokeWithStyle(tb, styles);
|
|
9417
|
+
} else if (layer === 1) this.renderTextStrokeWithStyle(tb, styles, baseline);
|
|
9415
9418
|
});
|
|
9416
9419
|
});
|
|
9417
9420
|
}
|
|
@@ -10448,7 +10451,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
10448
10451
|
this.effectsRenderer = new EffectsRenderer({ ctx: this.ctx }, { path: (paths) => this.path(paths) });
|
|
10449
10452
|
this.textRenderer = new TextRenderer({
|
|
10450
10453
|
ctx: this.ctx,
|
|
10451
|
-
|
|
10454
|
+
fontMetrics: this.fontMetrics,
|
|
10452
10455
|
options: { scale: options.scale }
|
|
10453
10456
|
});
|
|
10454
10457
|
this.context.logger.debug(`Canvas renderer initialized (${options.width}x${options.height}) with scale ${options.scale}`);
|