From 038ba2b98dc85a4133205426df6a69e150305d4a Mon Sep 17 00:00:00 2001 From: caleb_liu Date: Tue, 2 Jul 2024 13:03:14 +0800 Subject: [PATCH 1/8] Fixes #2238 #1624 - Fix the issue of TextNode content being overlooked in rendering due to being perceived as blank by trim(). --- src/dom/node-parser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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) { From 806f466e1355089371926cf875df30b8c9bef0fb Mon Sep 17 00:00:00 2001 From: caleb_liu Date: Wed, 3 Jul 2024 16:19:34 +0800 Subject: [PATCH 2/8] Fixes #2107: Corrects line-height discrepancies in non-Firefox-based browsers by modifying the x-axis calculation method. This update addresses line-height issues caused by differences in x-axis calculation methods in browsers that do not use the Firefox engine. By refining the x-axis calculation method, it ensures uniform line-height behavior across all major browsers. --- src/render/canvas/canvas-renderer.ts | 39 +++++++++++----------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/render/canvas/canvas-renderer.ts b/src/render/canvas/canvas-renderer.ts index 6efb648bf..f9a007d97 100644 --- a/src/render/canvas/canvas-renderer.ts +++ b/src/render/canvas/canvas-renderer.ts @@ -146,7 +146,16 @@ 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); + // 修复 Chrome 中,数字字符上移的问题。 + // https://github.com/niklasvh/html2canvas/issues/2107#issuecomment-692462900 + if (navigator.userAgent.indexOf('Firefox') === -1){ + // non-Firefox browser add this + this.ctx.textBaseline = 'ideographic'; + this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); + // this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); + } else { + this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); + } } else { const letters = segmentGraphemes(text.text); letters.reduce((left, letter) => { @@ -214,35 +223,17 @@ export class CanvasRenderer extends Renderer { if (styles.textDecorationLine.length) { this.ctx.fillStyle = asString(styles.textDecorationColor || styles.color); styles.textDecorationLine.forEach((textDecorationLine) => { + var fillHeight = 1; + // High-resolution x-axis positioning errors due to scaling can be corrected by using the relative height values of elements. On high-resolution displays, scaling can introduce inaccuracies in x-axis positioning. By referencing the relative height values of elements, these errors can be rectified, achieving more precise display accuracy. 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 - fillHeight, text.bounds.width, fillHeight); 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, fillHeight); 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 - fillHeight / 2), text.bounds.width, fillHeight); break; } }); From 19f42e185fb9fe4837352c3d6e15e64f1ddff1c5 Mon Sep 17 00:00:00 2001 From: caleb_liu Date: Wed, 3 Jul 2024 16:19:43 +0800 Subject: [PATCH 3/8] Revert "Fixes #2107: Corrects line-height discrepancies in non-Firefox-based browsers by modifying the x-axis calculation method. This update addresses line-height issues caused by differences in x-axis calculation methods in browsers that do not use the Firefox engine. By refining the x-axis calculation method, it ensures uniform line-height behavior across all major browsers." This reverts commit 806f466e1355089371926cf875df30b8c9bef0fb. --- src/render/canvas/canvas-renderer.ts | 39 +++++++++++++++++----------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/render/canvas/canvas-renderer.ts b/src/render/canvas/canvas-renderer.ts index f9a007d97..6efb648bf 100644 --- a/src/render/canvas/canvas-renderer.ts +++ b/src/render/canvas/canvas-renderer.ts @@ -146,16 +146,7 @@ export class CanvasRenderer extends Renderer { renderTextWithLetterSpacing(text: TextBounds, letterSpacing: number, baseline: number): void { if (letterSpacing === 0) { - // 修复 Chrome 中,数字字符上移的问题。 - // https://github.com/niklasvh/html2canvas/issues/2107#issuecomment-692462900 - if (navigator.userAgent.indexOf('Firefox') === -1){ - // non-Firefox browser add this - this.ctx.textBaseline = 'ideographic'; - this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); - // this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); - } else { - this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); - } + this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); } else { const letters = segmentGraphemes(text.text); letters.reduce((left, letter) => { @@ -223,17 +214,35 @@ export class CanvasRenderer extends Renderer { if (styles.textDecorationLine.length) { this.ctx.fillStyle = asString(styles.textDecorationColor || styles.color); styles.textDecorationLine.forEach((textDecorationLine) => { - var fillHeight = 1; - // High-resolution x-axis positioning errors due to scaling can be corrected by using the relative height values of elements. On high-resolution displays, scaling can introduce inaccuracies in x-axis positioning. By referencing the relative height values of elements, these errors can be rectified, achieving more precise display accuracy. switch (textDecorationLine) { case TEXT_DECORATION_LINE.UNDERLINE: - this.ctx.fillRect(text.bounds.left, text.bounds.top + text.bounds.height - fillHeight, text.bounds.width, fillHeight); + // 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 + ); + break; case TEXT_DECORATION_LINE.OVERLINE: - this.ctx.fillRect(text.bounds.left, text.bounds.top , text.bounds.width, fillHeight); + this.ctx.fillRect( + text.bounds.left, + Math.round(text.bounds.top), + text.bounds.width, + 1 + ); break; case TEXT_DECORATION_LINE.LINE_THROUGH: - this.ctx.fillRect(text.bounds.left, text.bounds.top + (text.bounds.height / 2 - fillHeight / 2), text.bounds.width, fillHeight); + // 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 + ); break; } }); From 5fd81cb69c7a0b388c7aa98192baac675550a305 Mon Sep 17 00:00:00 2001 From: caleb_liu Date: Wed, 3 Jul 2024 16:20:18 +0800 Subject: [PATCH 4/8] Fixes #2107: Corrects line-height discrepancies in non-Firefox-based browsers by modifying the x-axis calculation method. This update addresses line-height issues caused by differences in x-axis calculation methods in browsers that do not use the Firefox engine. By refining the x-axis calculation method, it ensures uniform line-height behavior across all major browsers. --- src/render/canvas/canvas-renderer.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/render/canvas/canvas-renderer.ts b/src/render/canvas/canvas-renderer.ts index 6efb648bf..9fe0b9b29 100644 --- a/src/render/canvas/canvas-renderer.ts +++ b/src/render/canvas/canvas-renderer.ts @@ -146,7 +146,16 @@ 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); + // 修复 Chrome 中,数字字符上移的问题。 + // https://github.com/niklasvh/html2canvas/issues/2107#issuecomment-692462900 + if (navigator.userAgent.indexOf('Firefox') === -1){ + // non-Firefox browser add this + this.ctx.textBaseline = 'ideographic'; + this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); + // this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); + } else { + this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); + } } else { const letters = segmentGraphemes(text.text); letters.reduce((left, letter) => { From a78c62b43a3f46d3a46a394a943bb9d76cffdabf Mon Sep 17 00:00:00 2001 From: caleb_liu Date: Wed, 3 Jul 2024 16:25:15 +0800 Subject: [PATCH 5/8] 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. --- src/render/canvas/canvas-renderer.ts | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/render/canvas/canvas-renderer.ts b/src/render/canvas/canvas-renderer.ts index 9fe0b9b29..8e4dd869d 100644 --- a/src/render/canvas/canvas-renderer.ts +++ b/src/render/canvas/canvas-renderer.ts @@ -223,35 +223,17 @@ export class CanvasRenderer extends Renderer { if (styles.textDecorationLine.length) { this.ctx.fillStyle = asString(styles.textDecorationColor || styles.color); styles.textDecorationLine.forEach((textDecorationLine) => { + var fillHeight = 1; + // 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. 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 - fillHeight, text.bounds.width, fillHeight); 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, fillHeight); 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 - fillHeight / 2), text.bounds.width, fillHeight); break; } }); From de0b521b23f8e4e063ff6c86bc05ef0ea1537e27 Mon Sep 17 00:00:00 2001 From: caleb_liu Date: Wed, 17 Jul 2024 09:53:15 +0800 Subject: [PATCH 6/8] Update comments and fix variable names --- src/render/canvas/canvas-renderer.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/render/canvas/canvas-renderer.ts b/src/render/canvas/canvas-renderer.ts index 8e4dd869d..bc2c08f3e 100644 --- a/src/render/canvas/canvas-renderer.ts +++ b/src/render/canvas/canvas-renderer.ts @@ -146,7 +146,7 @@ export class CanvasRenderer extends Renderer { renderTextWithLetterSpacing(text: TextBounds, letterSpacing: number, baseline: number): void { if (letterSpacing === 0) { - // 修复 Chrome 中,数字字符上移的问题。 + // 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){ // non-Firefox browser add this @@ -223,17 +223,17 @@ export class CanvasRenderer extends Renderer { if (styles.textDecorationLine.length) { this.ctx.fillStyle = asString(styles.textDecorationColor || styles.color); styles.textDecorationLine.forEach((textDecorationLine) => { - var fillHeight = 1; // 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: - this.ctx.fillRect(text.bounds.left, text.bounds.top + text.bounds.height - fillHeight, text.bounds.width, fillHeight); + 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, text.bounds.top , text.bounds.width, fillHeight); + this.ctx.fillRect(text.bounds.left, text.bounds.top , text.bounds.width, decorationLineHeight); break; case TEXT_DECORATION_LINE.LINE_THROUGH: - this.ctx.fillRect(text.bounds.left, text.bounds.top + (text.bounds.height / 2 - fillHeight / 2), text.bounds.width, fillHeight); + this.ctx.fillRect(text.bounds.left, text.bounds.top + (text.bounds.height / 2 - decorationLineHeight / 2), text.bounds.width, decorationLineHeight); break; } }); From a953c47a1033e9b6adec8f6166eba6cee505a17b Mon Sep 17 00:00:00 2001 From: caleb_liu Date: Thu, 18 Jul 2024 10:19:37 +0800 Subject: [PATCH 7/8] Clean up meaningless comments --- src/render/canvas/canvas-renderer.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/render/canvas/canvas-renderer.ts b/src/render/canvas/canvas-renderer.ts index bc2c08f3e..ee6357b54 100644 --- a/src/render/canvas/canvas-renderer.ts +++ b/src/render/canvas/canvas-renderer.ts @@ -149,10 +149,8 @@ export class CanvasRenderer extends Renderer { // 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){ - // non-Firefox browser add this this.ctx.textBaseline = 'ideographic'; this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height); - // this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); } else { this.ctx.fillText(text.text, text.bounds.left, text.bounds.top + baseline); } From 7071e329839713ec6f8607d2d562ec48e79a53c7 Mon Sep 17 00:00:00 2001 From: caleb_liu Date: Thu, 18 Jul 2024 15:26:43 +0800 Subject: [PATCH 8/8] fix build failure --- src/render/canvas/canvas-renderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/canvas/canvas-renderer.ts b/src/render/canvas/canvas-renderer.ts index ee6357b54..28a009d25 100644 --- a/src/render/canvas/canvas-renderer.ts +++ b/src/render/canvas/canvas-renderer.ts @@ -188,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) => {