From ceb7b48e805fb2aeb9f00b58a5b3df78ae52a003 Mon Sep 17 00:00:00 2001 From: singlecoder Date: Mon, 10 Jul 2023 15:44:43 +0800 Subject: [PATCH] Fix text error for set text to "" and set enableWrapping to true (#1634) * fix(text): fix text error for set text to "" and set enableWrapping to true --------- Co-authored-by: cptbtptpbcptdtptp --- packages/core/src/2d/text/TextRenderer.ts | 159 +++++++++++----------- packages/core/src/2d/text/TextUtils.ts | 35 +++-- 2 files changed, 98 insertions(+), 96 deletions(-) diff --git a/packages/core/src/2d/text/TextRenderer.ts b/packages/core/src/2d/text/TextRenderer.ts index 9b0aa08ff5..dc75e7366c 100644 --- a/packages/core/src/2d/text/TextRenderer.ts +++ b/packages/core/src/2d/text/TextRenderer.ts @@ -480,97 +480,102 @@ export class TextRenderer extends Renderer { } private _updateLocalData(): void { - const { color, horizontalAlignment, verticalAlignment, _charRenderDatas: charRenderDatas } = this; + const { color, _charRenderDatas: charRenderDatas, _subFont: charFont } = this; const { min, max } = this._localBounds; - const { _pixelsPerUnit } = Engine; - const pixelsPerUnitReciprocal = 1.0 / _pixelsPerUnit; - const charFont = this._subFont; - const rendererWidth = this.width * _pixelsPerUnit; - const halfRendererWidth = rendererWidth * 0.5; - const rendererHeight = this.height * _pixelsPerUnit; - const textMetrics = this.enableWrapping ? TextUtils.measureTextWithWrap(this) : TextUtils.measureTextWithoutWrap(this); const { height, lines, lineWidths, lineHeight, lineMaxSizes } = textMetrics; const charRenderDataPool = TextRenderer._charRenderDataPool; - const halfLineHeight = lineHeight * 0.5; const linesLen = lines.length; + let renderDataCount = 0; - let startY = 0; - const topDiff = lineHeight * 0.5 - lineMaxSizes[0].ascent; - const bottomDiff = lineHeight * 0.5 - lineMaxSizes[linesLen - 1].descent - 1; - switch (verticalAlignment) { - case TextVerticalAlignment.Top: - startY = rendererHeight * 0.5 - halfLineHeight + topDiff; - break; - case TextVerticalAlignment.Center: - startY = height * 0.5 - halfLineHeight - (bottomDiff - topDiff) * 0.5; - break; - case TextVerticalAlignment.Bottom: - startY = height - rendererHeight * 0.5 - halfLineHeight - bottomDiff; - break; - } + if (linesLen > 0) { + const { _pixelsPerUnit } = Engine; + const { horizontalAlignment } = this; + const pixelsPerUnitReciprocal = 1.0 / _pixelsPerUnit; + const rendererWidth = this.width * _pixelsPerUnit; + const halfRendererWidth = rendererWidth * 0.5; + const rendererHeight = this.height * _pixelsPerUnit; + const halfLineHeight = lineHeight * 0.5; + + let startY = 0; + const topDiff = lineHeight * 0.5 - lineMaxSizes[0].ascent; + const bottomDiff = lineHeight * 0.5 - lineMaxSizes[linesLen - 1].descent - 1; + switch (this.verticalAlignment) { + case TextVerticalAlignment.Top: + startY = rendererHeight * 0.5 - halfLineHeight + topDiff; + break; + case TextVerticalAlignment.Center: + startY = height * 0.5 - halfLineHeight - (bottomDiff - topDiff) * 0.5; + break; + case TextVerticalAlignment.Bottom: + startY = height - rendererHeight * 0.5 - halfLineHeight - bottomDiff; + break; + } - let renderDataCount = 0; - let firstLine = -1; - let minX = Number.MAX_SAFE_INTEGER; - let minY = Number.MAX_SAFE_INTEGER; - let maxX = Number.MIN_SAFE_INTEGER; - let maxY = Number.MIN_SAFE_INTEGER; - for (let i = 0; i < linesLen; ++i) { - const lineWidth = lineWidths[i]; - if (lineWidth > 0) { - const line = lines[i]; - let startX = 0; - let firstRow = -1; - if (firstLine < 0) { - firstLine = i; - } - switch (horizontalAlignment) { - case TextHorizontalAlignment.Left: - startX = -halfRendererWidth; - break; - case TextHorizontalAlignment.Center: - startX = -lineWidth * 0.5; - break; - case TextHorizontalAlignment.Right: - startX = halfRendererWidth - lineWidth; - break; - } - for (let j = 0, n = line.length; j < n; ++j) { - const char = line[j]; - const charInfo = charFont._getCharInfo(char); - if (charInfo.h > 0) { - firstRow < 0 && (firstRow = j); - const charRenderData = (charRenderDatas[renderDataCount++] ||= charRenderDataPool.get()); - const { renderData, localPositions } = charRenderData; - charRenderData.texture = charFont._getTextureByIndex(charInfo.index); - renderData.color = color; - renderData.uvs = charInfo.uvs; - - const { w, ascent, descent } = charInfo; - const left = startX * pixelsPerUnitReciprocal; - const right = (startX + w) * pixelsPerUnitReciprocal; - const top = (startY + ascent) * pixelsPerUnitReciprocal; - const bottom = (startY - descent + 1) * pixelsPerUnitReciprocal; - localPositions.set(left, top, right, bottom); - i === firstLine && (maxY = Math.max(maxY, top)); - minY = Math.min(minY, bottom); - j === firstRow && (minX = Math.min(minX, left)); - maxX = Math.max(maxX, right); + let firstLine = -1; + let minX = Number.MAX_SAFE_INTEGER; + let minY = Number.MAX_SAFE_INTEGER; + let maxX = Number.MIN_SAFE_INTEGER; + let maxY = Number.MIN_SAFE_INTEGER; + for (let i = 0; i < linesLen; ++i) { + const lineWidth = lineWidths[i]; + if (lineWidth > 0) { + const line = lines[i]; + let startX = 0; + let firstRow = -1; + if (firstLine < 0) { + firstLine = i; + } + switch (horizontalAlignment) { + case TextHorizontalAlignment.Left: + startX = -halfRendererWidth; + break; + case TextHorizontalAlignment.Center: + startX = -lineWidth * 0.5; + break; + case TextHorizontalAlignment.Right: + startX = halfRendererWidth - lineWidth; + break; + } + for (let j = 0, n = line.length; j < n; ++j) { + const char = line[j]; + const charInfo = charFont._getCharInfo(char); + if (charInfo.h > 0) { + firstRow < 0 && (firstRow = j); + const charRenderData = (charRenderDatas[renderDataCount++] ||= charRenderDataPool.get()); + const { renderData, localPositions } = charRenderData; + charRenderData.texture = charFont._getTextureByIndex(charInfo.index); + renderData.color = color; + renderData.uvs = charInfo.uvs; + + const { w, ascent, descent } = charInfo; + const left = startX * pixelsPerUnitReciprocal; + const right = (startX + w) * pixelsPerUnitReciprocal; + const top = (startY + ascent) * pixelsPerUnitReciprocal; + const bottom = (startY - descent + 1) * pixelsPerUnitReciprocal; + localPositions.set(left, top, right, bottom); + i === firstLine && (maxY = Math.max(maxY, top)); + minY = Math.min(minY, bottom); + j === firstRow && (minX = Math.min(minX, left)); + maxX = Math.max(maxX, right); + } + startX += charInfo.xAdvance; } - startX += charInfo.xAdvance; } + startY -= lineHeight; } - startY -= lineHeight; - } - if (firstLine < 0) { + if (firstLine < 0) { + min.set(0, 0, 0); + max.set(0, 0, 0); + } else { + min.set(minX, minY, 0); + max.set(maxX, maxY, 0); + } + } else { min.set(0, 0, 0); max.set(0, 0, 0); - } else { - min.set(minX, minY, 0); - max.set(maxX, maxY, 0); } // Revert excess render data to pool. diff --git a/packages/core/src/2d/text/TextUtils.ts b/packages/core/src/2d/text/TextUtils.ts index 3b5e21e55b..1210deea27 100644 --- a/packages/core/src/2d/text/TextUtils.ts +++ b/packages/core/src/2d/text/TextUtils.ts @@ -252,25 +252,21 @@ export class TextUtils { const { _subFont: subFont } = renderer; const fontString = subFont.nativeFontString; const fontSizeInfo = TextUtils.measureFont(fontString); - const lines = renderer.text.split(/(?:\r\n|\r|\n)/); - const lineCount = lines.length; + const subTexts = renderer.text.split(/(?:\r\n|\r|\n)/); + const textCount = subTexts.length; + const lines = new Array(); const lineWidths = new Array(); const lineMaxSizes = new Array(); const { _pixelsPerUnit } = Engine; const lineHeight = fontSizeInfo.size + renderer.lineSpacing * _pixelsPerUnit; let width = 0; - let height = renderer.height * _pixelsPerUnit; - if (renderer.overflowMode === OverflowMode.Overflow) { - height = lineHeight * lineCount; - } - subFont.nativeFontString = fontString; - for (let i = 0; i < lineCount; ++i) { - const line = lines[i]; + for (let i = 0; i < textCount; ++i) { + const line = subTexts[i]; let curWidth = 0; - let maxAscent = -1; - let maxDescent = -1; + let maxAscent = 0; + let maxDescent = 0; for (let j = 0, m = line.length; j < m; ++j) { const charInfo = TextUtils._getCharInfo(line[j], fontString, subFont); @@ -282,17 +278,18 @@ export class TextUtils { maxAscent < ascent && (maxAscent = ascent); maxDescent < descent && (maxDescent = descent); } - lineWidths[i] = curWidth; - lineMaxSizes[i] = { - ascent: maxAscent, - descent: maxDescent, - size: maxAscent + maxDescent - }; - if (curWidth > width) { - width = curWidth; + + if (curWidth > 0) { + this._pushLine(lines, lineWidths, lineMaxSizes, line, curWidth, maxAscent, maxDescent); + width = Math.max(width, curWidth); } } + let height = renderer.height * _pixelsPerUnit; + if (renderer.overflowMode === OverflowMode.Overflow) { + height = lineHeight * lines.length; + } + return { width, height,