html2canvas-pro 2.0.2 → 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 +88 -28
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +88 -28
- 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/document-cloner.js +5 -4
- package/dist/lib/dom/document-cloner.js.map +1 -1
- 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/karma.conf.cjs +6 -1
- package/package.json +5 -4
|
@@ -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
|
*/
|
|
@@ -4239,6 +4239,30 @@ const wordBreak = {
|
|
|
4239
4239
|
}
|
|
4240
4240
|
};
|
|
4241
4241
|
|
|
4242
|
+
const isVerticalWritingMode = (writingMode) => writingMode !== 0 /* WRITING_MODE.HORIZONTAL_TB */;
|
|
4243
|
+
const isSidewaysWritingMode = (writingMode) => writingMode === 3 /* WRITING_MODE.SIDEWAYS_RL */ || writingMode === 4 /* WRITING_MODE.SIDEWAYS_LR */;
|
|
4244
|
+
const writingMode = {
|
|
4245
|
+
name: 'writing-mode',
|
|
4246
|
+
initialValue: 'horizontal-tb',
|
|
4247
|
+
prefix: false,
|
|
4248
|
+
type: 2 /* PropertyDescriptorParsingType.IDENT_VALUE */,
|
|
4249
|
+
parse: (_context, writingMode) => {
|
|
4250
|
+
switch (writingMode) {
|
|
4251
|
+
case 'vertical-rl':
|
|
4252
|
+
return 1 /* WRITING_MODE.VERTICAL_RL */;
|
|
4253
|
+
case 'vertical-lr':
|
|
4254
|
+
return 2 /* WRITING_MODE.VERTICAL_LR */;
|
|
4255
|
+
case 'sideways-rl':
|
|
4256
|
+
return 3 /* WRITING_MODE.SIDEWAYS_RL */;
|
|
4257
|
+
case 'sideways-lr':
|
|
4258
|
+
return 4 /* WRITING_MODE.SIDEWAYS_LR */;
|
|
4259
|
+
case 'horizontal-tb':
|
|
4260
|
+
default:
|
|
4261
|
+
return 0 /* WRITING_MODE.HORIZONTAL_TB */;
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
};
|
|
4265
|
+
|
|
4242
4266
|
const zIndex = {
|
|
4243
4267
|
name: 'z-index',
|
|
4244
4268
|
initialValue: 'auto',
|
|
@@ -4855,6 +4879,7 @@ class CSSParsedDeclaration {
|
|
|
4855
4879
|
this.webkitTextStrokeWidth = parse(context, webkitTextStrokeWidth, declaration.webkitTextStrokeWidth);
|
|
4856
4880
|
this.webkitLineClamp = parse(context, webkitLineClamp, declaration.webkitLineClamp);
|
|
4857
4881
|
this.wordBreak = parse(context, wordBreak, declaration.wordBreak);
|
|
4882
|
+
this.writingMode = parse(context, writingMode, declaration.writingMode);
|
|
4858
4883
|
this.zIndex = parse(context, zIndex, declaration.zIndex);
|
|
4859
4884
|
this.objectFit = parse(context, objectFit, declaration.objectFit);
|
|
4860
4885
|
this.imageRendering = parse(context, imageRendering, declaration.imageRendering);
|
|
@@ -5790,6 +5815,9 @@ const segmentWords = (value, styles) => {
|
|
|
5790
5815
|
return breakWords(value, styles);
|
|
5791
5816
|
};
|
|
5792
5817
|
const breakText = (value, styles) => {
|
|
5818
|
+
if (isVerticalWritingMode(styles.writingMode)) {
|
|
5819
|
+
return segmentGraphemes(value);
|
|
5820
|
+
}
|
|
5793
5821
|
return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value, styles);
|
|
5794
5822
|
};
|
|
5795
5823
|
// https://drafts.csswg.org/css-text/#word-separator
|
|
@@ -5829,6 +5857,11 @@ const breakWords = (str, styles) => {
|
|
|
5829
5857
|
class TextContainer {
|
|
5830
5858
|
constructor(context, node, styles) {
|
|
5831
5859
|
this.text = transform(node.data, styles.textTransform);
|
|
5860
|
+
// Range offsets below are based on transformed text; keep the node in sync
|
|
5861
|
+
// when casing changes string length, for example "ß".toUpperCase() === "SS".
|
|
5862
|
+
if (this.text.length !== node.data.length) {
|
|
5863
|
+
node.data = this.text;
|
|
5864
|
+
}
|
|
5832
5865
|
this.textBounds = parseTextBounds(context, this.text, styles, node);
|
|
5833
5866
|
}
|
|
5834
5867
|
}
|
|
@@ -6586,10 +6619,11 @@ class DocumentCloner {
|
|
|
6586
6619
|
return iframe;
|
|
6587
6620
|
});
|
|
6588
6621
|
/**
|
|
6589
|
-
* The
|
|
6590
|
-
*
|
|
6591
|
-
*
|
|
6592
|
-
|
|
6622
|
+
* The base URI used for resolving relative URLs (e.g. background-image) in the clone.
|
|
6623
|
+
* Must come from the source document: the iframe document is about:blank, so
|
|
6624
|
+
* documentClone.baseURI would break getComputedStyle() for relative background URLs.
|
|
6625
|
+
*/
|
|
6626
|
+
const baseUri = ownerDocument.baseURI;
|
|
6593
6627
|
documentClone.open();
|
|
6594
6628
|
const rawHTML = serializeDoctype(document.doctype) + '<html></html>';
|
|
6595
6629
|
try {
|
|
@@ -8716,7 +8750,11 @@ class TextRenderer {
|
|
|
8716
8750
|
* call (fillText or strokeText), allowing fill and stroke paths to share one
|
|
8717
8751
|
* implementation.
|
|
8718
8752
|
*/
|
|
8719
|
-
iterateLettersWithLetterSpacing(text, letterSpacing, baseline, renderFn) {
|
|
8753
|
+
iterateLettersWithLetterSpacing(text, letterSpacing, baseline, writingMode, renderFn) {
|
|
8754
|
+
if (isVerticalWritingMode(writingMode)) {
|
|
8755
|
+
this.iterateVerticalGlyphs(text, letterSpacing, baseline, writingMode, renderFn);
|
|
8756
|
+
return;
|
|
8757
|
+
}
|
|
8720
8758
|
const letters = segmentGraphemes(text.text);
|
|
8721
8759
|
const y = text.bounds.top + baseline;
|
|
8722
8760
|
let left = text.bounds.left;
|
|
@@ -8733,17 +8771,39 @@ class TextRenderer {
|
|
|
8733
8771
|
left += this.ctx.measureText(letter).width + letterSpacing;
|
|
8734
8772
|
}
|
|
8735
8773
|
}
|
|
8774
|
+
iterateVerticalGlyphs(text, letterSpacing, baseline, writingMode, renderFn) {
|
|
8775
|
+
const letters = segmentGraphemes(text.text);
|
|
8776
|
+
let top = text.bounds.top;
|
|
8777
|
+
for (const letter of letters) {
|
|
8778
|
+
if (isSidewaysWritingMode(writingMode) || (!hasCJKCharacters(letter) && letter.trim().length > 0)) {
|
|
8779
|
+
this.ctx.save();
|
|
8780
|
+
this.ctx.translate(text.bounds.left + baseline, top);
|
|
8781
|
+
this.ctx.rotate(writingMode === 4 /* WRITING_MODE.SIDEWAYS_LR */ ? -Math.PI / 2 : Math.PI / 2);
|
|
8782
|
+
renderFn(letter, 0, 0);
|
|
8783
|
+
this.ctx.restore();
|
|
8784
|
+
}
|
|
8785
|
+
else {
|
|
8786
|
+
const savedBaseline = this.ctx.textBaseline;
|
|
8787
|
+
if (hasCJKCharacters(letter)) {
|
|
8788
|
+
this.ctx.textBaseline = 'ideographic';
|
|
8789
|
+
}
|
|
8790
|
+
renderFn(letter, text.bounds.left, top + baseline);
|
|
8791
|
+
this.ctx.textBaseline = savedBaseline;
|
|
8792
|
+
}
|
|
8793
|
+
top += this.ctx.measureText(letter).width + letterSpacing;
|
|
8794
|
+
}
|
|
8795
|
+
}
|
|
8736
8796
|
/**
|
|
8737
8797
|
* Render text with letter-spacing applied (fill pass).
|
|
8738
8798
|
* When letterSpacing is 0 the whole string is drawn in one call; otherwise each
|
|
8739
8799
|
* grapheme is drawn individually so spacing and CJK baseline are applied correctly.
|
|
8740
8800
|
*/
|
|
8741
|
-
renderTextWithLetterSpacing(text, letterSpacing, baseline) {
|
|
8742
|
-
if (letterSpacing === 0) {
|
|
8801
|
+
renderTextWithLetterSpacing(text, letterSpacing, baseline, writingMode = 0 /* WRITING_MODE.HORIZONTAL_TB */) {
|
|
8802
|
+
if (letterSpacing === 0 && !isVerticalWritingMode(writingMode)) {
|
|
8743
8803
|
this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline);
|
|
8744
8804
|
}
|
|
8745
8805
|
else {
|
|
8746
|
-
this.iterateLettersWithLetterSpacing(text, letterSpacing, baseline, (letter, x, y) => {
|
|
8806
|
+
this.iterateLettersWithLetterSpacing(text, letterSpacing, baseline, writingMode, (letter, x, y) => {
|
|
8747
8807
|
this.ctx.fillText(letter, x, y);
|
|
8748
8808
|
});
|
|
8749
8809
|
}
|
|
@@ -8757,7 +8817,7 @@ class TextRenderer {
|
|
|
8757
8817
|
switch (paintOrderLayer) {
|
|
8758
8818
|
case 0 /* PAINT_ORDER_LAYER.FILL */:
|
|
8759
8819
|
this.ctx.fillStyle = asString(styles.color);
|
|
8760
|
-
this.renderTextWithLetterSpacing(textBound, styles.letterSpacing, styles.fontSize.number);
|
|
8820
|
+
this.renderTextWithLetterSpacing(textBound, styles.letterSpacing, styles.fontSize.number, styles.writingMode);
|
|
8761
8821
|
break;
|
|
8762
8822
|
case 1 /* PAINT_ORDER_LAYER.STROKE */:
|
|
8763
8823
|
if (styles.webkitTextStrokeWidth && textBound.text.trim().length) {
|
|
@@ -8765,11 +8825,11 @@ class TextRenderer {
|
|
|
8765
8825
|
this.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
8766
8826
|
this.ctx.lineJoin =
|
|
8767
8827
|
typeof window !== 'undefined' && !!window.chrome ? 'miter' : 'round';
|
|
8768
|
-
if (styles.letterSpacing === 0) {
|
|
8828
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
8769
8829
|
this.ctx.strokeText(textBound.text, textBound.bounds.left, textBound.bounds.top + styles.fontSize.number);
|
|
8770
8830
|
}
|
|
8771
8831
|
else {
|
|
8772
|
-
this.iterateLettersWithLetterSpacing(textBound, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
8832
|
+
this.iterateLettersWithLetterSpacing(textBound, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
8773
8833
|
}
|
|
8774
8834
|
this.ctx.strokeStyle = '';
|
|
8775
8835
|
this.ctx.lineWidth = 0;
|
|
@@ -9005,11 +9065,11 @@ class TextRenderer {
|
|
|
9005
9065
|
switch (paintOrderLayer) {
|
|
9006
9066
|
case 0 /* PAINT_ORDER_LAYER.FILL */:
|
|
9007
9067
|
this.ctx.fillStyle = asString(styles.color);
|
|
9008
|
-
if (styles.letterSpacing === 0) {
|
|
9068
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9009
9069
|
this.ctx.fillText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9010
9070
|
}
|
|
9011
9071
|
else {
|
|
9012
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9072
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9013
9073
|
}
|
|
9014
9074
|
break;
|
|
9015
9075
|
case 1 /* PAINT_ORDER_LAYER.STROKE */:
|
|
@@ -9018,11 +9078,11 @@ class TextRenderer {
|
|
|
9018
9078
|
this.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
9019
9079
|
this.ctx.lineJoin =
|
|
9020
9080
|
typeof window !== 'undefined' && !!window.chrome ? 'miter' : 'round';
|
|
9021
|
-
if (styles.letterSpacing === 0) {
|
|
9081
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9022
9082
|
this.ctx.strokeText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9023
9083
|
}
|
|
9024
9084
|
else {
|
|
9025
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9085
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9026
9086
|
}
|
|
9027
9087
|
this.ctx.strokeStyle = '';
|
|
9028
9088
|
this.ctx.lineWidth = 0;
|
|
@@ -9077,11 +9137,11 @@ class TextRenderer {
|
|
|
9077
9137
|
switch (paintOrderLayer) {
|
|
9078
9138
|
case 0 /* PAINT_ORDER_LAYER.FILL */: {
|
|
9079
9139
|
this.ctx.fillStyle = asString(styles.color);
|
|
9080
|
-
if (styles.letterSpacing === 0) {
|
|
9140
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9081
9141
|
this.ctx.fillText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9082
9142
|
}
|
|
9083
9143
|
else {
|
|
9084
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9144
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9085
9145
|
}
|
|
9086
9146
|
const textShadows = styles.textShadow;
|
|
9087
9147
|
if (textShadows.length && truncatedText.trim().length) {
|
|
@@ -9093,11 +9153,11 @@ class TextRenderer {
|
|
|
9093
9153
|
this.ctx.shadowOffsetX = textShadow.offsetX.number * this.options.scale;
|
|
9094
9154
|
this.ctx.shadowOffsetY = textShadow.offsetY.number * this.options.scale;
|
|
9095
9155
|
this.ctx.shadowBlur = textShadow.blur.number;
|
|
9096
|
-
if (styles.letterSpacing === 0) {
|
|
9156
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9097
9157
|
this.ctx.fillText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9098
9158
|
}
|
|
9099
9159
|
else {
|
|
9100
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9160
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.fillText(letter, x, y));
|
|
9101
9161
|
}
|
|
9102
9162
|
});
|
|
9103
9163
|
this.ctx.shadowColor = '';
|
|
@@ -9113,11 +9173,11 @@ class TextRenderer {
|
|
|
9113
9173
|
this.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
9114
9174
|
this.ctx.lineJoin =
|
|
9115
9175
|
typeof window !== 'undefined' && !!window.chrome ? 'miter' : 'round';
|
|
9116
|
-
if (styles.letterSpacing === 0) {
|
|
9176
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9117
9177
|
this.ctx.strokeText(truncatedText, firstBound.bounds.left, firstBound.bounds.top + styles.fontSize.number);
|
|
9118
9178
|
}
|
|
9119
9179
|
else {
|
|
9120
|
-
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9180
|
+
this.iterateLettersWithLetterSpacing(truncatedBounds, styles.letterSpacing, styles.fontSize.number, styles.writingMode, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9121
9181
|
}
|
|
9122
9182
|
this.ctx.strokeStyle = '';
|
|
9123
9183
|
this.ctx.lineWidth = 0;
|
|
@@ -9134,7 +9194,7 @@ class TextRenderer {
|
|
|
9134
9194
|
switch (paintOrderLayer) {
|
|
9135
9195
|
case 0 /* PAINT_ORDER_LAYER.FILL */: {
|
|
9136
9196
|
this.ctx.fillStyle = asString(styles.color);
|
|
9137
|
-
this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number);
|
|
9197
|
+
this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number, styles.writingMode);
|
|
9138
9198
|
const textShadows = styles.textShadow;
|
|
9139
9199
|
if (textShadows.length && text.text.trim().length) {
|
|
9140
9200
|
textShadows
|
|
@@ -9145,7 +9205,7 @@ class TextRenderer {
|
|
|
9145
9205
|
this.ctx.shadowOffsetX = textShadow.offsetX.number * this.options.scale;
|
|
9146
9206
|
this.ctx.shadowOffsetY = textShadow.offsetY.number * this.options.scale;
|
|
9147
9207
|
this.ctx.shadowBlur = textShadow.blur.number;
|
|
9148
|
-
this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number);
|
|
9208
|
+
this.renderTextWithLetterSpacing(text, styles.letterSpacing, styles.fontSize.number, styles.writingMode);
|
|
9149
9209
|
});
|
|
9150
9210
|
this.ctx.shadowColor = '';
|
|
9151
9211
|
this.ctx.shadowOffsetX = 0;
|
|
@@ -9164,11 +9224,11 @@ class TextRenderer {
|
|
|
9164
9224
|
this.ctx.lineJoin =
|
|
9165
9225
|
typeof window !== 'undefined' && !!window.chrome ? 'miter' : 'round';
|
|
9166
9226
|
const baseline = styles.fontSize.number;
|
|
9167
|
-
if (styles.letterSpacing === 0) {
|
|
9227
|
+
if (styles.letterSpacing === 0 && !isVerticalWritingMode(styles.writingMode)) {
|
|
9168
9228
|
this.ctx.strokeText(text.text, text.bounds.left, text.bounds.top + baseline);
|
|
9169
9229
|
}
|
|
9170
9230
|
else {
|
|
9171
|
-
this.iterateLettersWithLetterSpacing(text, styles.letterSpacing, baseline, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9231
|
+
this.iterateLettersWithLetterSpacing(text, styles.letterSpacing, baseline, styles.writingMode, (letter, x, y) => this.ctx.strokeText(letter, x, y));
|
|
9172
9232
|
}
|
|
9173
9233
|
this.ctx.strokeStyle = '';
|
|
9174
9234
|
this.ctx.lineWidth = 0;
|
|
@@ -9463,7 +9523,7 @@ class CanvasRenderer extends Renderer {
|
|
|
9463
9523
|
new Vector(bounds.left, bounds.top + bounds.height)
|
|
9464
9524
|
]);
|
|
9465
9525
|
this.ctx.clip();
|
|
9466
|
-
this.textRenderer.renderTextWithLetterSpacing(new TextBounds(container.value, textBounds), styles.letterSpacing, baseline);
|
|
9526
|
+
this.textRenderer.renderTextWithLetterSpacing(new TextBounds(container.value, textBounds), styles.letterSpacing, baseline, styles.writingMode);
|
|
9467
9527
|
this.ctx.restore();
|
|
9468
9528
|
this.ctx.textBaseline = 'alphabetic';
|
|
9469
9529
|
this.ctx.textAlign = 'left';
|
|
@@ -9490,7 +9550,7 @@ class CanvasRenderer extends Renderer {
|
|
|
9490
9550
|
this.ctx.textBaseline = 'middle';
|
|
9491
9551
|
this.ctx.textAlign = 'right';
|
|
9492
9552
|
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);
|
|
9493
|
-
this.textRenderer.renderTextWithLetterSpacing(new TextBounds(paint.listValue, bounds), styles.letterSpacing, computeLineHeight(styles.lineHeight, styles.fontSize.number) / 2 + 2);
|
|
9553
|
+
this.textRenderer.renderTextWithLetterSpacing(new TextBounds(paint.listValue, bounds), styles.letterSpacing, computeLineHeight(styles.lineHeight, styles.fontSize.number) / 2 + 2, styles.writingMode);
|
|
9494
9554
|
this.ctx.textBaseline = 'bottom';
|
|
9495
9555
|
this.ctx.textAlign = 'left';
|
|
9496
9556
|
}
|