diff --git a/src/dom/node-parser.ts b/src/dom/node-parser.ts index 5f38a2411..85890edb0 100644 --- a/src/dom/node-parser.ts +++ b/src/dom/node-parser.ts @@ -17,8 +17,8 @@ const LIST_OWNERS = ['OL', 'UL', 'MENU']; const parseNodeTree = (context: Context, node: Node, parent: ElementContainer, root: ElementContainer) => { for (let childNode = node.firstChild, nextNode; childNode; childNode = nextNode) { nextNode = childNode.nextSibling; - - if (isTextNode(childNode) && childNode.data.trim().length > 0) { + // Fixes #2238 #1624 - Fix the issue of TextNode content being overlooked in rendering due to being perceived as blank by trim(). + if (isTextNode(childNode) && childNode.data.length > 0) { parent.textNodes.push(new TextContainer(context, childNode, parent.styles)); } else if (isElementNode(childNode)) { if (isSlotElement(childNode) && childNode.assignedNodes) { diff --git a/src/render/canvas/canvas-renderer.ts b/src/render/canvas/canvas-renderer.ts index 6efb648bf..28a009d25 100644 --- a/src/render/canvas/canvas-renderer.ts +++ b/src/render/canvas/canvas-renderer.ts @@ -146,7 +146,14 @@ export class CanvasRenderer extends Renderer { renderTextWithLetterSpacing(text: TextBounds, letterSpacing: number, baseline: number): void { if (letterSpacing === 0) { - this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); + // Fixed an issue with characters moving up in non-Firefox. + // https://github.com/niklasvh/html2canvas/issues/2107#issuecomment-692462900 + if (navigator.userAgent.indexOf('Firefox') === -1){ + this.ctx.textBaseline = 'ideographic'; + this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); + } else { + this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); + } } else { const letters = segmentGraphemes(text.text); letters.reduce((left, letter) => { @@ -181,7 +188,7 @@ export class CanvasRenderer extends Renderer { this.ctx.direction = styles.direction === DIRECTION.RTL ? 'rtl' : 'ltr'; this.ctx.textAlign = 'left'; this.ctx.textBaseline = 'alphabetic'; - const {baseline, middle} = this.fontMetrics.getMetrics(fontFamily, fontSize); + const {baseline} = this.fontMetrics.getMetrics(fontFamily, fontSize); const paintOrder = styles.paintOrder; text.textBounds.forEach((text) => { @@ -214,35 +221,17 @@ export class CanvasRenderer extends Renderer { if (styles.textDecorationLine.length) { this.ctx.fillStyle = asString(styles.textDecorationColor || styles.color); styles.textDecorationLine.forEach((textDecorationLine) => { + // Fix the issue where textDecorationLine exhibits x-axis positioning errors on high-resolution devices due to varying devicePixelRatio, corrected by using relative values of element heights. + var decorationLineHeight = 1; switch (textDecorationLine) { case TEXT_DECORATION_LINE.UNDERLINE: - // Draws a line at the baseline of the font - // TODO As some browsers display the line as more than 1px if the font-size is big, - // need to take that into account both in position and size - this.ctx.fillRect( - text.bounds.left, - Math.round(text.bounds.top + baseline), - text.bounds.width, - 1 - ); - + this.ctx.fillRect(text.bounds.left, text.bounds.top + text.bounds.height - decorationLineHeight, text.bounds.width, decorationLineHeight); break; case TEXT_DECORATION_LINE.OVERLINE: - this.ctx.fillRect( - text.bounds.left, - Math.round(text.bounds.top), - text.bounds.width, - 1 - ); + this.ctx.fillRect(text.bounds.left, text.bounds.top , text.bounds.width, decorationLineHeight); break; case TEXT_DECORATION_LINE.LINE_THROUGH: - // TODO try and find exact position for line-through - this.ctx.fillRect( - text.bounds.left, - Math.ceil(text.bounds.top + middle), - text.bounds.width, - 1 - ); + this.ctx.fillRect(text.bounds.left, text.bounds.top + (text.bounds.height / 2 - decorationLineHeight / 2), text.bounds.width, decorationLineHeight); break; } });