html2canvas-pro 2.3.1 → 2.3.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.cjs +34 -64
- package/dist/html2canvas-pro.cjs.map +1 -1
- package/dist/html2canvas-pro.esm.js +34 -64
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +34 -64
- 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 -4
- package/dist/lib/render/canvas/content-renderer.js +5 -3
- package/dist/lib/render/canvas/font-utils.js +29 -0
- package/dist/lib/render/canvas/text-renderer.js +7 -6
- package/dist/types/render/canvas/canvas-renderer.d.ts +0 -1
- package/dist/types/render/canvas/content-renderer.d.ts +1 -2
- package/dist/types/render/canvas/font-utils.d.ts +19 -0
- package/dist/types/render/canvas/text-renderer.d.ts +0 -3
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* html2canvas-pro 2.3.
|
|
2
|
+
* html2canvas-pro 2.3.2 <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
|
*/
|
|
@@ -8943,60 +8943,6 @@ const calculateBackgroundRepeatPath = (repeat, [x, y], [width, height], backgrou
|
|
|
8943
8943
|
}
|
|
8944
8944
|
};
|
|
8945
8945
|
//#endregion
|
|
8946
|
-
//#region src/core/util.ts
|
|
8947
|
-
const SMALL_IMAGE = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
8948
|
-
//#endregion
|
|
8949
|
-
//#region src/render/font-metrics.ts
|
|
8950
|
-
const SAMPLE_TEXT = "Hidden Text";
|
|
8951
|
-
var FontMetrics = class {
|
|
8952
|
-
constructor(document) {
|
|
8953
|
-
this._data = {};
|
|
8954
|
-
this._document = document;
|
|
8955
|
-
}
|
|
8956
|
-
parseMetrics(fontFamily, fontSize) {
|
|
8957
|
-
const container = this._document.createElement("div");
|
|
8958
|
-
const img = this._document.createElement("img");
|
|
8959
|
-
const span = this._document.createElement("span");
|
|
8960
|
-
const body = this._document.body;
|
|
8961
|
-
container.style.visibility = "hidden";
|
|
8962
|
-
container.style.fontFamily = fontFamily;
|
|
8963
|
-
container.style.fontSize = fontSize;
|
|
8964
|
-
container.style.margin = "0";
|
|
8965
|
-
container.style.padding = "0";
|
|
8966
|
-
container.style.whiteSpace = "nowrap";
|
|
8967
|
-
body.appendChild(container);
|
|
8968
|
-
img.src = SMALL_IMAGE;
|
|
8969
|
-
img.width = 1;
|
|
8970
|
-
img.height = 1;
|
|
8971
|
-
img.style.margin = "0";
|
|
8972
|
-
img.style.padding = "0";
|
|
8973
|
-
img.style.verticalAlign = "baseline";
|
|
8974
|
-
span.style.fontFamily = fontFamily;
|
|
8975
|
-
span.style.fontSize = fontSize;
|
|
8976
|
-
span.style.margin = "0";
|
|
8977
|
-
span.style.padding = "0";
|
|
8978
|
-
span.appendChild(this._document.createTextNode(SAMPLE_TEXT));
|
|
8979
|
-
container.appendChild(span);
|
|
8980
|
-
container.appendChild(img);
|
|
8981
|
-
const baseline = img.offsetTop - span.offsetTop + 2;
|
|
8982
|
-
container.removeChild(span);
|
|
8983
|
-
container.appendChild(this._document.createTextNode(SAMPLE_TEXT));
|
|
8984
|
-
container.style.lineHeight = "normal";
|
|
8985
|
-
img.style.verticalAlign = "super";
|
|
8986
|
-
const middle = img.offsetTop - container.offsetTop + 2;
|
|
8987
|
-
body.removeChild(container);
|
|
8988
|
-
return {
|
|
8989
|
-
baseline,
|
|
8990
|
-
middle
|
|
8991
|
-
};
|
|
8992
|
-
}
|
|
8993
|
-
getMetrics(fontFamily, fontSize) {
|
|
8994
|
-
const key = `${fontFamily} ${fontSize}`;
|
|
8995
|
-
if (typeof this._data[key] === "undefined") this._data[key] = this.parseMetrics(fontFamily, fontSize);
|
|
8996
|
-
return this._data[key];
|
|
8997
|
-
}
|
|
8998
|
-
};
|
|
8999
|
-
//#endregion
|
|
9000
8946
|
//#region src/render/canvas/text/text-decoration-renderer.ts
|
|
9001
8947
|
var TextDecorationRenderer = class {
|
|
9002
8948
|
constructor(ctx) {
|
|
@@ -9085,6 +9031,33 @@ var TextDecorationRenderer = class {
|
|
|
9085
9031
|
}
|
|
9086
9032
|
};
|
|
9087
9033
|
//#endregion
|
|
9034
|
+
//#region src/render/canvas/font-utils.ts
|
|
9035
|
+
/**
|
|
9036
|
+
* Font measurement utility
|
|
9037
|
+
*
|
|
9038
|
+
* Provides Canvas API-based baseline measurement that works correctly with
|
|
9039
|
+
* webfonts (which may not be loaded in the original document) and system fonts.
|
|
9040
|
+
*
|
|
9041
|
+
* Fallback chain:
|
|
9042
|
+
* 1. fontBoundingBoxAscent — font-level metric (Chrome 99+, FF 116+, Safari 17.4+)
|
|
9043
|
+
* 2. actualBoundingBoxAscent — glyph-level metric (widely supported)
|
|
9044
|
+
* 3. fallback value — coarse CSS fallback
|
|
9045
|
+
*/
|
|
9046
|
+
const SAMPLE_TEXT = "Mg";
|
|
9047
|
+
/**
|
|
9048
|
+
* Measure the baseline ascent for the currently set font.
|
|
9049
|
+
*
|
|
9050
|
+
* @param ctx - Canvas 2D rendering context with ctx.font already set
|
|
9051
|
+
* @param fallback - Fallback value when no metrics are available (e.g. fontSize.number)
|
|
9052
|
+
* @returns The distance from the text baseline to the top of the bounding box
|
|
9053
|
+
*/
|
|
9054
|
+
const measureBaseline = (ctx, fallback) => {
|
|
9055
|
+
const tm = ctx.measureText(SAMPLE_TEXT);
|
|
9056
|
+
const fmAscent = tm.fontBoundingBoxAscent;
|
|
9057
|
+
const ascent = fmAscent !== void 0 && !Number.isNaN(fmAscent) ? fmAscent : tm.actualBoundingBoxAscent;
|
|
9058
|
+
return ascent !== void 0 && !Number.isNaN(ascent) ? ascent : fallback;
|
|
9059
|
+
};
|
|
9060
|
+
//#endregion
|
|
9088
9061
|
//#region src/render/canvas/text-renderer.ts
|
|
9089
9062
|
const iOSBrokenFonts = ["-apple-system", "system-ui"];
|
|
9090
9063
|
/**
|
|
@@ -9137,7 +9110,6 @@ var TextRenderer = class {
|
|
|
9137
9110
|
constructor(deps) {
|
|
9138
9111
|
this.glyphWidthCache = null;
|
|
9139
9112
|
this.ctx = deps.ctx;
|
|
9140
|
-
this.fontMetrics = deps.fontMetrics;
|
|
9141
9113
|
this.options = deps.options;
|
|
9142
9114
|
this.decorationRenderer = new TextDecorationRenderer(deps.ctx);
|
|
9143
9115
|
}
|
|
@@ -9398,13 +9370,13 @@ var TextRenderer = class {
|
|
|
9398
9370
|
}
|
|
9399
9371
|
async renderTextNode(text, styles, containerBounds) {
|
|
9400
9372
|
this.glyphWidthCache = null;
|
|
9401
|
-
const [fontString
|
|
9373
|
+
const [fontString] = this.createFontStyle(styles);
|
|
9402
9374
|
this.ctx.font = fontString;
|
|
9403
9375
|
this.ctx.direction = styles.direction === 1 ? "rtl" : "ltr";
|
|
9404
9376
|
this.ctx.textAlign = "left";
|
|
9405
9377
|
this.ctx.textBaseline = "alphabetic";
|
|
9406
9378
|
const paintOrder = styles.paintOrder;
|
|
9407
|
-
const
|
|
9379
|
+
const baseline = measureBaseline(this.ctx, styles.fontSize.number);
|
|
9408
9380
|
if (styles.webkitLineClamp > 0 && (styles.display & 2) !== 0 && styles.overflowY === 1 && text.textBounds.length > 0) {
|
|
9409
9381
|
if (this.renderLineClampedText(text, styles, paintOrder, baseline, containerBounds)) return;
|
|
9410
9382
|
}
|
|
@@ -10300,7 +10272,7 @@ async function renderReplacedElements(ctx, context, options, iframeRendererFacto
|
|
|
10300
10272
|
/**
|
|
10301
10273
|
* Render form element content: checkbox, radio, text input.
|
|
10302
10274
|
*/
|
|
10303
|
-
function renderFormElements(ctx,
|
|
10275
|
+
function renderFormElements(ctx, textRenderer, pathFn, container, styles) {
|
|
10304
10276
|
if (container instanceof InputElementContainer) {
|
|
10305
10277
|
const size = Math.min(container.bounds.width, container.bounds.height);
|
|
10306
10278
|
if (container.type === "checkbox" && container.checked) {
|
|
@@ -10327,9 +10299,9 @@ function renderFormElements(ctx, fontMetrics, textRenderer, pathFn, container, s
|
|
|
10327
10299
|
}
|
|
10328
10300
|
}
|
|
10329
10301
|
if (isTextInputElement(container) && container.value.length) {
|
|
10330
|
-
const [font
|
|
10331
|
-
const { baseline } = fontMetrics.getMetrics(fontFamily, fontSize);
|
|
10302
|
+
const [font] = textRenderer.createFontStyle(styles);
|
|
10332
10303
|
ctx.font = font;
|
|
10304
|
+
const baseline = measureBaseline(ctx, getAbsoluteValue(styles.fontSize, 0));
|
|
10333
10305
|
ctx.fillStyle = container instanceof InputElementContainer && container.isPlaceholder ? asString(PLACEHOLDER_COLOR) : asString(styles.color);
|
|
10334
10306
|
ctx.textBaseline = "alphabetic";
|
|
10335
10307
|
ctx.textAlign = canvasTextAlign(container.styles.textAlign);
|
|
@@ -10427,7 +10399,6 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
10427
10399
|
this.canvas.style.width = `${options.width}px`;
|
|
10428
10400
|
this.canvas.style.height = `${options.height}px`;
|
|
10429
10401
|
}
|
|
10430
|
-
this.fontMetrics = new FontMetrics(document);
|
|
10431
10402
|
this.ctx.scale(this.options.scale, this.options.scale);
|
|
10432
10403
|
this.ctx.translate(-options.x, -options.y);
|
|
10433
10404
|
this.ctx.textBaseline = "bottom";
|
|
@@ -10451,7 +10422,6 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
10451
10422
|
this.effectsRenderer = new EffectsRenderer({ ctx: this.ctx }, { path: (paths) => this.path(paths) });
|
|
10452
10423
|
this.textRenderer = new TextRenderer({
|
|
10453
10424
|
ctx: this.ctx,
|
|
10454
|
-
fontMetrics: this.fontMetrics,
|
|
10455
10425
|
options: { scale: options.scale }
|
|
10456
10426
|
});
|
|
10457
10427
|
this.context.logger.debug(`Canvas renderer initialized (${options.width}x${options.height}) with scale ${options.scale}`);
|
|
@@ -10499,7 +10469,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
10499
10469
|
width: this.options.width,
|
|
10500
10470
|
height: this.options.height
|
|
10501
10471
|
}, (ctx, opts) => new CanvasRenderer(ctx, opts), container, curves, styles, (c, cv, img) => this.renderReplacedElement(c, cv, img));
|
|
10502
|
-
renderFormElements(this.ctx, this.
|
|
10472
|
+
renderFormElements(this.ctx, this.textRenderer, this.path.bind(this), container, styles);
|
|
10503
10473
|
await renderListMarker(this.ctx, this.context, this.textRenderer, paint, container, styles);
|
|
10504
10474
|
}
|
|
10505
10475
|
async renderStackContent(stack) {
|