Skip to content

Commit

Permalink
Fix text error for set text to "" and set enableWrapping to true (#1634)
Browse files Browse the repository at this point in the history
* fix(text): fix text error for set text to "" and set enableWrapping to true
---------

Co-authored-by: cptbtptpbcptdtptp <[email protected]>
  • Loading branch information
singlecoder and cptbtptpbcptdtptp authored Jul 10, 2023
1 parent 0f70543 commit ceb7b48
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 96 deletions.
159 changes: 82 additions & 77 deletions packages/core/src/2d/text/TextRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
35 changes: 16 additions & 19 deletions packages/core/src/2d/text/TextUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>();
const lineWidths = new Array<number>();
const lineMaxSizes = new Array<FontSizeInfo>();
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);
Expand All @@ -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,
Expand Down

0 comments on commit ceb7b48

Please sign in to comment.