html2canvas-pro 2.0.3 → 2.0.4
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 +83 -24
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +83 -24
- package/dist/html2canvas-pro.js.map +1 -1
- package/dist/html2canvas-pro.min.js +5 -5
- package/dist/lib/css/index.js +2 -0
- package/dist/lib/css/index.js.map +1 -1
- package/dist/lib/css/layout/text.js +4 -0
- package/dist/lib/css/layout/text.js.map +1 -1
- package/dist/lib/css/property-descriptors/writing-mode.js +29 -0
- package/dist/lib/css/property-descriptors/writing-mode.js.map +1 -0
- package/dist/lib/dom/text-container.js +5 -0
- package/dist/lib/dom/text-container.js.map +1 -1
- package/dist/lib/render/canvas/__tests__/text-renderer.test.js +92 -0
- package/dist/lib/render/canvas/__tests__/text-renderer.test.js.map +1 -1
- package/dist/lib/render/canvas/canvas-renderer.js +2 -2
- package/dist/lib/render/canvas/canvas-renderer.js.map +1 -1
- package/dist/lib/render/canvas/text-renderer.js +48 -21
- package/dist/lib/render/canvas/text-renderer.js.map +1 -1
- package/dist/types/css/index.d.ts +2 -0
- package/dist/types/css/property-descriptors/writing-mode.d.ts +11 -0
- package/dist/types/render/canvas/text-renderer.d.ts +3 -1
- package/package.json +1 -1
package/dist/html2canvas-pro.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* html2canvas-pro 2.0.
|
|
2
|
+
* html2canvas-pro 2.0.4 <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
|
*/
|
|
@@ -4245,6 +4245,30 @@
|
|
|
4245
4245
|
}
|
|
4246
4246
|
};
|
|
4247
4247
|
|
|
4248
|
+
const isVerticalWritingMode = (writingMode) => writingMode !== 0 /* WRITING_MODE.HORIZONTAL_TB */;
|
|
4249
|
+
const isSidewaysWritingMode = (writingMode) => writingMode === 3 /* WRITING_MODE.SIDEWAYS_RL */ || writingMode === 4 /* WRITING_MODE.SIDEWAYS_LR */;
|
|
4250
|
+
const writingMode = {
|
|
4251
|
+
name: 'writing-mode',
|
|
4252
|
+
initialValue: 'horizontal-tb',
|
|
4253
|
+
prefix: false,
|
|
4254
|
+
type: 2 /* PropertyDescriptorParsingType.IDENT_VALUE */,
|
|
4255
|
+
parse: (_context, writingMode) => {
|
|
4256
|
+
switch (writingMode) {
|
|
4257
|
+
case 'vertical-rl':
|
|
4258
|
+
return 1 /* WRITING_MODE.VERTICAL_RL */;
|
|
4259
|
+
case 'vertical-lr':
|
|
4260
|
+
return 2 /* WRITING_MODE.VERTICAL_LR */;
|
|
4261
|
+
case 'sideways-rl':
|
|
4262
|
+
return 3 /* WRITING_MODE.SIDEWAYS_RL */;
|
|
4263
|
+
case 'sideways-lr':
|
|
4264
|
+
return 4 /* WRITING_MODE.SIDEWAYS_LR */;
|
|
4265
|
+
case 'horizontal-tb':
|
|
4266
|
+
default:
|
|
4267
|
+
return 0 /* WRITING_MODE.HORIZONTAL_TB */;
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4270
|
+
};
|
|
4271
|
+
|
|
4248
4272
|
const zIndex = {
|
|
4249
4273
|
name: 'z-index',
|
|
4250
4274
|
initialValue: 'auto',
|
|
@@ -4861,6 +4885,7 @@
|
|
|
4861
4885
|
this.webkitTextStrokeWidth = parse(context, webkitTextStrokeWidth, declaration.webkitTextStrokeWidth);
|
|
4862
4886
|
this.webkitLineClamp = parse(context, webkitLineClamp, declaration.webkitLineClamp);
|
|
4863
4887
|
this.wordBreak = parse(context, wordBreak, declaration.wordBreak);
|
|
4888
|
+
this.writingMode = parse(context, writingMode, declaration.writingMode);
|
|
4864
4889
|
this.zIndex = parse(context, zIndex, declaration.zIndex);
|
|
4865
4890
|
this.objectFit = parse(context, objectFit, declaration.objectFit);
|
|
4866
4891
|
this.imageRendering = parse(context, imageRendering, declaration.imageRendering);
|
|
@@ -5796,6 +5821,9 @@
|
|
|
5796
5821
|
return breakWords(value, styles);
|
|
5797
5822
|
};
|
|
5798
5823
|
const breakText = (value, styles) => {
|
|
5824
|
+
if (isVerticalWritingMode(styles.writingMode)) {
|
|
5825
|
+
return segmentGraphemes(value);
|
|
5826
|
+
}
|
|
5799
5827
|
return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value, styles);
|
|
5800
5828
|
};
|
|
5801
5829
|
// https://drafts.csswg.org/css-text/#word-separator
|
|
@@ -5835,6 +5863,11 @@
|
|
|
5835
5863
|
class TextContainer {
|
|
5836
5864
|
constructor(context, node, styles) {
|
|
5837
5865
|
this.text = transform(node.data, styles.textTransform);
|
|
5866
|
+
// Range offsets below are based on transformed text; keep the node in sync
|
|
5867
|
+
// when casing changes string length, for example "ß".toUpperCase() === "SS".
|
|
5868
|
+
if (this.text.length !== node.data.length) {
|
|
5869
|
+
node.data = this.text;
|
|
5870
|
+
}
|
|
5838
5871
|
this.textBounds = parseTextBounds(context, this.text, styles, node);
|
|
5839
5872
|
}
|
|
5840
5873
|
}
|
|
@@ -8723,7 +8756,11 @@
|
|
|
8723
8756
|
* call (fillText or strokeText), allowing fill and stroke paths to share one
|
|
8724
8757
|
* implementation.
|
|
8725
8758
|
*/
|
|
8726
|
-
iterateLettersWithLetterSpacing(text, letterSpacing, baseline, renderFn) {
|
|
8759
|
+
iterateLettersWithLetterSpacing(text, letterSpacing, baseline, writingMode, renderFn) {
|
|
8760
|
+
if (isVerticalWritingMode(writingMode)) {
|
|
8761
|
+
this.iterateVerticalGlyphs(text, letterSpacing, baseline, writingMode, renderFn);
|
|
8762
|
+
return;
|
|
8763
|
+
}
|
|
8727
8764
|
const letters = segmentGraphemes(text.text);
|
|
8728
8765
|
const y = text.bounds.top + baseline;
|
|
8729
8766
|
let left = text.bounds.left;
|
|
@@ -8740,17 +8777,39 @@
|
|
|
8740
8777
|
left += this.ctx.measureText(letter).width + letterSpacing;
|
|
8741
8778
|
}
|
|
8742
8779
|
}
|
|
8780
|
+
iterateVerticalGlyphs(text, letterSpacing, baseline, writingMode, renderFn) {
|
|
8781
|
+
const letters = segmentGraphemes(text.text);
|
|
8782
|
+
let top = text.bounds.top;
|
|
8783
|
+
for (const letter of letters) {
|
|
8784
|
+
if (isSidewaysWritingMode(writingMode) || (!hasCJKCharacters(letter) && letter.trim().length > 0)) {
|
|
8785
|
+
this.ctx.save();
|
|
8786
|
+
this.ctx.translate(text.bounds.left + baseline, top);
|
|
8787
|
+
this.ctx.rotate(writingMode === 4 /* WRITING_MODE.SIDEWAYS_LR */ ? -Math.PI / 2 : Math.PI / 2);
|
|
8788
|
+
renderFn(letter, 0, 0);
|
|
8789
|
+
this.ctx.restore();
|
|
8790
|
+
}
|
|
8791
|
+
else {
|
|
8792
|
+
const savedBaseline = this.ctx.textBaseline;
|
|
8793
|
+
if (hasCJKCharacters(letter)) {
|
|
8794
|
+
this.ctx.textBaseline = 'ideographic';
|
|
8795
|
+
}
|
|
8796
|
+
renderFn(letter, text.bounds.left, top + baseline);
|
|
8797
|
+
this.ctx.textBaseline = savedBaseline;
|
|
8798
|
+
}
|
|
8799
|
+
top += this.ctx.measureText(letter).width + letterSpacing;
|
|
8800
|
+
}
|
|
8801
|
+
}
|
|
8743
8802
|
/**
|
|
8744
8803
|
* Render text with letter-spacing applied (fill pass).
|
|
8745
8804
|
* When letterSpacing is 0 the whole string is drawn in one call; otherwise each
|
|
8746
8805
|
* grapheme is drawn individually so spacing and CJK baseline are applied correctly.
|
|
8747
8806
|
*/
|
|
8748
|
-
renderTextWithLetterSpacing(text, letterSpacing, baseline) {
|
|
8749
|
-
if (letterSpacing === 0) {
|
|
8807
|
+
renderTextWithLetterSpacing(text, letterSpacing, baseline, writingMode = 0 /* WRITING_MODE.HORIZONTAL_TB */) {
|
|
8808
|
+
if (letterSpacing === 0 && !isVerticalWritingMode(writingMode)) {
|
|
8750
8809
|
this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline);
|
|
8751
8810
|
}
|
|
8752
8811
|
else {
|
|
8753
|
-
this.iterateLettersWithLetterSpacing(text, letterSpacing, baseline, (letter, x, y) => {
|
|
8812
|
+
this.iterateLettersWithLetterSpacing(text, letterSpacing, baseline, writingMode, (letter, x, y) => {
|
|
8754
8813
|
this.ctx.fillText(letter, x, y);
|
|
8755
8814
|
});
|
|
8756
8815
|
}
|
|
@@ -8764,7 +8823,7 @@
|
|
|
8764
8823
|
switch (paintOrderLayer) {
|
|
8765
8824
|
case 0 /* PAINT_ORDER_LAYER.FILL */:
|
|
8766
8825
|
this.ctx.fillStyle = asString(styles.color);
|
|
8767
|
-
this.renderTextWithLetterSpacing(textBound, styles.letterSpacing, styles.fontSize.number);
|
|
8826
|
+
this.renderTextWithLetterSpacing(textBound, styles.letterSpacing, styles.fontSize.number, styles.writingMode);
|
|
8768
8827
|
break;
|
|
8769
8828
|
case 1 /* PAINT_ORDER_LAYER.STROKE */:
|
|
8770
8829
|
if (styles.webkitTextStrokeWidth && textBound.text.trim().length) {
|
|
@@ -8772,11 +8831,11 @@
|
|
|
8772
8831
|
this.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
8773
8832
|
this.ctx.lineJoin =
|
|
8774
8833
|
typeof window !== 'undefined' && !!window.chrome ? 'miter' : 'round';
|
|
8775
|
-
if (styles.letterSpacing === 0) {
|
|
8834
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
8776
8835
|
this.ctx.strokeText(textBound.text, textBound.bounds.left, textBound.bounds.top + styles.fontSize.number);
|
|
8777
8836
|
}
|
|
8778
8837
|
else {
|
|
8779
|
-
this.iterateLettersWithLetterSpacing(textBound, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
8838
|
+
this.iterateLettersWithLetterSpacing(textBound, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
8780
8839
|
}
|
|
8781
8840
|
this.ctx.strokeStyle = '';
|
|
8782
8841
|
this.ctx.lineWidth = 0;
|
|
@@ -9012,11 +9071,11 @@
|
|
|
9012
9071
|
switch (paintOrderLayer) {
|
|
9013
9072
|
case 0 /* PAINT_ORDER_LAYER.FILL */:
|
|
9014
9073
|
this.ctx.fillStyle = asString(styles.color);
|
|
9015
|
-
if (styles.letterSpacing === 0) {
|
|
9074
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9016
9075
|
this.ctx.fillText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9017
9076
|
}
|
|
9018
9077
|
else {
|
|
9019
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9078
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9020
9079
|
}
|
|
9021
9080
|
break;
|
|
9022
9081
|
case 1 /* PAINT_ORDER_LAYER.STROKE */:
|
|
@@ -9025,11 +9084,11 @@
|
|
|
9025
9084
|
this.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
9026
9085
|
this.ctx.lineJoin =
|
|
9027
9086
|
typeof window !== 'undefined' && !!window.chrome ? 'miter' : 'round';
|
|
9028
|
-
if (styles.letterSpacing === 0) {
|
|
9087
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9029
9088
|
this.ctx.strokeText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9030
9089
|
}
|
|
9031
9090
|
else {
|
|
9032
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9091
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9033
9092
|
}
|
|
9034
9093
|
this.ctx.strokeStyle = '';
|
|
9035
9094
|
this.ctx.lineWidth = 0;
|
|
@@ -9084,11 +9143,11 @@
|
|
|
9084
9143
|
switch (paintOrderLayer) {
|
|
9085
9144
|
case 0 /* PAINT_ORDER_LAYER.FILL */: {
|
|
9086
9145
|
this.ctx.fillStyle = asString(styles.color);
|
|
9087
|
-
if (styles.letterSpacing === 0) {
|
|
9146
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9088
9147
|
this.ctx.fillText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9089
9148
|
}
|
|
9090
9149
|
else {
|
|
9091
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9150
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9092
9151
|
}
|
|
9093
9152
|
const textShadows = styles.textShadow;
|
|
9094
9153
|
if (textShadows.length && truncatedText.trim().length) {
|
|
@@ -9100,11 +9159,11 @@
|
|
|
9100
9159
|
this.ctx.shadowOffsetX = textShadow.offsetX.number * this.options.scale;
|
|
9101
9160
|
this.ctx.shadowOffsetY = textShadow.offsetY.number * this.options.scale;
|
|
9102
9161
|
this.ctx.shadowBlur = textShadow.blur.number;
|
|
9103
|
-
if (styles.letterSpacing === 0) {
|
|
9162
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9104
9163
|
this.ctx.fillText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9105
9164
|
}
|
|
9106
9165
|
else {
|
|
9107
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9166
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9108
9167
|
}
|
|
9109
9168
|
});
|
|
9110
9169
|
this.ctx.shadowColor = '';
|
|
@@ -9120,11 +9179,11 @@
|
|
|
9120
9179
|
this.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
9121
9180
|
this.ctx.lineJoin =
|
|
9122
9181
|
typeof window !== 'undefined' && !!window.chrome ? 'miter' : 'round';
|
|
9123
|
-
if (styles.letterSpacing === 0) {
|
|
9182
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9124
9183
|
this.ctx.strokeText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9125
9184
|
}
|
|
9126
9185
|
else {
|
|
9127
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9186
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9128
9187
|
}
|
|
9129
9188
|
this.ctx.strokeStyle = '';
|
|
9130
9189
|
this.ctx.lineWidth = 0;
|
|
@@ -9141,7 +9200,7 @@
|
|
|
9141
9200
|
switch (paintOrderLayer) {
|
|
9142
9201
|
case 0 /* PAINT_ORDER_LAYER.FILL */: {
|
|
9143
9202
|
this.ctx.fillStyle = asString(styles.color);
|
|
9144
|
-
this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number);
|
|
9203
|
+
this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number, styles.writingMode);
|
|
9145
9204
|
const textShadows = styles.textShadow;
|
|
9146
9205
|
if (textShadows.length && text.text.trim().length) {
|
|
9147
9206
|
textShadows
|
|
@@ -9152,7 +9211,7 @@
|
|
|
9152
9211
|
this.ctx.shadowOffsetX = textShadow.offsetX.number * this.options.scale;
|
|
9153
9212
|
this.ctx.shadowOffsetY = textShadow.offsetY.number * this.options.scale;
|
|
9154
9213
|
this.ctx.shadowBlur = textShadow.blur.number;
|
|
9155
|
-
this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number);
|
|
9214
|
+
this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number, styles.writingMode);
|
|
9156
9215
|
});
|
|
9157
9216
|
this.ctx.shadowColor = '';
|
|
9158
9217
|
this.ctx.shadowOffsetX = 0;
|
|
@@ -9171,11 +9230,11 @@
|
|
|
9171
9230
|
this.ctx.lineJoin =
|
|
9172
9231
|
typeof window !== 'undefined' && !!window.chrome ? 'miter' : 'round';
|
|
9173
9232
|
const baseline = styles.fontSize.number;
|
|
9174
|
-
if (styles.letterSpacing === 0) {
|
|
9233
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9175
9234
|
this.ctx.strokeText(text.text, text.bounds.left, text.bounds.top + baseline);
|
|
9176
9235
|
}
|
|
9177
9236
|
else {
|
|
9178
|
-
this.iterateLettersWithLetterSpacing(text, styles.letterSpacing, baseline, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9237
|
+
this.iterateLettersWithLetterSpacing(text, styles.letterSpacing, baseline, styles.writingMode, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9179
9238
|
}
|
|
9180
9239
|
this.ctx.strokeStyle = '';
|
|
9181
9240
|
this.ctx.lineWidth = 0;
|
|
@@ -9470,7 +9529,7 @@
|
|
|
9470
9529
|
new Vector(bounds.left, bounds.top + bounds.height)
|
|
9471
9530
|
]);
|
|
9472
9531
|
this.ctx.clip();
|
|
9473
|
-
this.textRenderer.renderTextWithLetterSpacing(new TextBounds(container.value, textBounds), styles.letterSpacing, baseline);
|
|
9532
|
+
this.textRenderer.renderTextWithLetterSpacing(new TextBounds(container.value, textBounds), styles.letterSpacing, baseline, styles.writingMode);
|
|
9474
9533
|
this.ctx.restore();
|
|
9475
9534
|
this.ctx.textBaseline = 'alphabetic';
|
|
9476
9535
|
this.ctx.textAlign = 'left';
|
|
@@ -9497,7 +9556,7 @@
|
|
|
9497
9556
|
this.ctx.textBaseline = 'middle';
|
|
9498
9557
|
this.ctx.textAlign = 'right';
|
|
9499
9558
|
const bounds = new Bounds(container.bounds.left, container.bounds.top + getAbsoluteValue(container.styles.paddingTop, container.bounds.width), container.bounds.width, computeLineHeight(styles.lineHeight, styles.fontSize.number) / 2 + 1);
|
|
9500
|
-
this.textRenderer.renderTextWithLetterSpacing(new TextBounds(paint.listValue, bounds), styles.letterSpacing, computeLineHeight(styles.lineHeight, styles.fontSize.number) / 2 + 2);
|
|
9559
|
+
this.textRenderer.renderTextWithLetterSpacing(new TextBounds(paint.listValue, bounds), styles.letterSpacing, computeLineHeight(styles.lineHeight, styles.fontSize.number) / 2 + 2, styles.writingMode);
|
|
9501
9560
|
this.ctx.textBaseline = 'bottom';
|
|
9502
9561
|
this.ctx.textAlign = 'left';
|
|
9503
9562
|
}
|