浏览代码

Refactor Paragraph.layout.

/main
Yuncong Zhang 5 年前
当前提交
9bb347f8
共有 3 个文件被更改,包括 285 次插入180 次删除
  1. 33
      Runtime/ui/txt/emoji.cs
  2. 6
      Runtime/ui/txt/layout.cs
  3. 426
      Runtime/ui/txt/paragraph.cs

33
Runtime/ui/txt/emoji.cs


{0x2935, 1224}, {0x2b05, 1225}, {0x2b06, 1226}, {0x2b07, 1227}, {0x2b1b, 1228}, {0x2b1c, 1229},
{0x2b50, 1230}, {0x2b55, 1231}, {0x3030, 1232}, {0x303d, 1233}, {0x3297, 1234}, {0x3299, 1235},
};
public static readonly HashSet<int> SingleCharEmojiCodePoints = new HashSet<int> {
0x203c, 0x2049, 0x2122, 0x2139, 0x2194,
0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x21a9,
0x21aa, 0x231a, 0x231b, 0x2328, 0x23cf, 0x23e9,
0x23ea, 0x23eb, 0x23ec, 0x23ed, 0x23ee, 0x23ef,
0x23f0, 0x23f1, 0x23f2, 0x23f3, 0x23f8, 0x23f9,
0x23fa, 0x24c2, 0x25aa, 0x25ab, 0x25b6, 0x25c0,
0x25fb, 0x25fc, 0x25fd, 0x25fe, 0x2600, 0x2601,
0x2602, 0x2603, 0x2604, 0x260e, 0x2611, 0x2614,
0x2615, 0x2618, 0x261d, 0x2620, 0x2622, 0x2623,
0x2626, 0x262a, 0x262e, 0x262f, 0x2638, 0x2639,
0x263a, 0x2640, 0x2642, 0x2648, 0x2649, 0x264a,
0x264b, 0x264c, 0x264d, 0x264e, 0x264f, 0x2650,
0x2651, 0x2652, 0x2653, 0x265f, 0x2660, 0x2663,
0x2665, 0x2666, 0x2668, 0x267b, 0x267e, 0x267f,
0x2692, 0x2693, 0x2694, 0x2695, 0x2696, 0x2697,
0x2699, 0x269b, 0x269c, 0x26a0, 0x26a1, 0x26aa,
0x26ab, 0x26b0, 0x26b1, 0x26bd, 0x26be, 0x26c4,
0x26c5, 0x26c8, 0x26ce, 0x26cf, 0x26d1, 0x26d3,
0x26d4, 0x26e9, 0x26ea, 0x26f0, 0x26f1, 0x26f2,
0x26f3, 0x26f4, 0x26f5, 0x26f7, 0x26f8, 0x26f9,
0x26fa, 0x26fd, 0x2702, 0x2705, 0x2708, 0x2709,
0x270a, 0x270b, 0x270c, 0x270d, 0x270f, 0x2712,
0x2714, 0x2716, 0x271d, 0x2721, 0x2728, 0x2733,
0x2734, 0x2744, 0x2747, 0x274c, 0x274e, 0x2753,
0x2754, 0x2755, 0x2757, 0x2763, 0x2764, 0x2795,
0x2796, 0x2797, 0x27a1, 0x27b0, 0x27bf, 0x2934,
0x2935, 0x2b05, 0x2b06, 0x2b07, 0x2b1b, 0x2b1c,
0x2b50, 0x2b55, 0x3030, 0x303d, 0x3297, 0x3299,
};
public const int rowCount = 35;
public const int colCount = 36;

}
public static bool isSingleCharNonEmptyEmoji(int c) {
return emojiLookupTable.ContainsKey(c);
return SingleCharEmojiCodePoints.Contains(c);
}
public static bool isEmptyEmoji(int c) {

6
Runtime/ui/txt/layout.cs


}
else {
// According to the logic of Paragraph.layout, it is assured that all the characters are requested
// in the texture before (in computing line breaks), so skip it here for optimization
// The only exception is the ellipsis, which is dealt with somewhere else.
// in the texture before (in computing line breaks), so skip it here for optimization.
// The only exception is the ellipsis, which did not appear in line breaking. It is taken care with
// only when needed.
// font.RequestCharactersInTextureSafe(buff.text, style.UnityFontSize, style.UnityFontStyle);
int wordstart = start == buff.size

426
Runtime/ui/txt/paragraph.cs


public readonly float? strikeoutPosition;
public readonly float? fxHeight;
static FontMetrics _previousFontMetrics;
static int _previousFontSize = 0;
public FontMetrics(float ascent, float descent,
float? underlineThickness = null, float? underlinePosition = null, float? strikeoutPosition = null,
float? fxHeight = null) {

}
public static FontMetrics fromFont(Font font, int fontSize) {
if (fontSize == _previousFontSize && _previousFontMetrics != null) {
return _previousFontMetrics;
}
_previousFontMetrics = new FontMetrics(ascent, descent, fxHeight: fxHeight);
_previousFontSize = fontSize;
return new FontMetrics(ascent, descent, fxHeight: fxHeight);
return _previousFontMetrics;
}
}

this._needsLayout = false;
this._width = Mathf.Floor(constraints.width);
this.computeLineBreak();
this._paintRecords.Clear();
this._lineHeights.Clear();
this._lineBaseLines.Clear();

this._computeLineBreak();
this._layout();
}
void _layout() {
var lineLimit = Mathf.Min(styleMaxLines, this._lineRanges.Count);
float maxWordWidth = 0;
var lineLimit = Mathf.Min(styleMaxLines, this._lineRanges.Count);
Layout layout = new Layout();
layout.setTabStops(this._tabStops);

float preMaxDescent = 0;
float maxWordWidth = 0;
List<CodeUnitRun> lineCodeUnitRuns = new List<CodeUnitRun>();
List<GlyphPosition> glyphPositions = new List<GlyphPosition>();

List<Range<int>> words = new List<Range<int>>();
List<float> textAdvances = new List<float>();
string ellipsis = this._paragraphStyle.ellipsis;
TextBuff ellipsisTextBuff = new TextBuff(ellipsis);
float wordGapWidth = 0;
this._computePaintRecordsFromLine(lineNumber, ref lineLimit, lineRange, words, lineRuns, ref styleRunIndex,
lineCodeUnitRuns, lineGlyphPositions, paintRecords, builder, glyphPositions, textAdvances, layout,
ref maxWordWidth, ref yOffset, ref preMaxDescent);
}
// Break the line into words if justification should be applied.
int wordIndex = 0;
bool justifyLine = this._paragraphStyle.textAlign == TextAlign.justify &&
lineNumber != lineLimit - 1 &&
!lineRange.hardBreak;
words.Clear();
this.findWords(lineRange.start, lineRange.end, words);
if (justifyLine) {
if (words.Count > 1) {
wordGapWidth = (this._width - this._lineWidths[lineNumber]) / (words.Count - 1);
}
}
this._updateIntrinsicWidth(maxWordWidth);
}
// Exclude trailing whitespace from right-justified lines so the last
// visible character in the line will be flush with the right margin.
int lineEndIndex = (this._paragraphStyle.textAlign == TextAlign.right ||
this._paragraphStyle.textAlign == TextAlign.center)
? lineRange.endExcludingWhitespace
: lineRange.end;
void _computeLineRuns(List<LineStyleRun> lineRuns, LineRange lineRange, ref int styleRunIndex) {
// Exclude trailing whitespace from right-justified lines so the last
// visible character in the line will be flush with the right margin.
int lineEndIndex = this._paragraphStyle.textAlign == TextAlign.right ||
this._paragraphStyle.textAlign == TextAlign.center
? lineRange.endExcludingWhitespace
: lineRange.end;
lineRuns.Clear();
while (styleRunIndex < this._runs.size) {
var styleRun = this._runs.getRun(styleRunIndex);
if (styleRun.start < lineEndIndex && styleRun.end > lineRange.start) {
lineRuns.Add(new LineStyleRun(Mathf.Max(styleRun.start, lineRange.start),
Mathf.Min(styleRun.end, lineEndIndex), styleRun.style));
}
lineRuns.Clear();
while (styleRunIndex < this._runs.size) {
var styleRun = this._runs.getRun(styleRunIndex);
if (styleRun.start < lineEndIndex && styleRun.end > lineRange.start) {
lineRuns.Add(new LineStyleRun(Mathf.Max(styleRun.start, lineRange.start),
Mathf.Min(styleRun.end, lineEndIndex), styleRun.style));
}
if (styleRun.end >= lineEndIndex) {
break;
}
if (styleRun.end >= lineEndIndex) {
break;
}
styleRunIndex++;
}
}
void _computePaintRecordsFromLine(int lineNumber, ref int lineLimit, LineRange lineRange, List<Range<int>> words,
List<LineStyleRun> lineRuns, ref int styleRunIndex, List<CodeUnitRun> lineCodeUnitRuns, List<GlyphPosition> lineGlyphPositions,
List<PaintRecord> paintRecords, TextBlobBuilder builder, List<GlyphPosition> glyphPositions, List<float> textAdvances,
Layout layout, ref float maxWordWidth, ref float yOffset, ref float preMaxDescent) {
float wordGapWidth = 0;
styleRunIndex++;
// Break the line into words if justification should be applied.
int wordIndex = 0;
bool justifyLine = this._paragraphStyle.textAlign == TextAlign.justify &&
lineNumber != lineLimit - 1 && !lineRange.hardBreak;
words.Clear();
this.findWords(lineRange.start, lineRange.end, words);
if (justifyLine) {
if (words.Count > 1) {
wordGapWidth = (this._width - this._lineWidths[lineNumber]) / (words.Count - 1);
}
float runXOffset = 0;
float justifyXOffset = 0;
lineCodeUnitRuns.Clear();
lineGlyphPositions.Clear();
paintRecords.Clear();
for (int i = 0; i < lineRuns.Count; ++i) {
var run = lineRuns[i];
string text = this._text;
int textStart = run.start;
int textEnd = run.end;
int textCount = textEnd - textStart;
this._computeLineRuns(lineRuns, lineRange, ref styleRunIndex);
if (!string.IsNullOrEmpty(ellipsis) && !this._width.isInfinite() && !lineRange.hardBreak
&& i == lineRuns.Count - 1 &&
(lineNumber == lineLimit - 1 || this._paragraphStyle.maxLines == null)) {
// By now, all characters have been "RequestCharactersInTexture"d by computeLineBreaks
// except the ellipsis, so Layout.doLayout skips calling RequestCharactersInTexture for
// performance, and the ellipsis is handled here
Layout.requireEllipsisInTexture(ellipsis, run.style);
float ellipsisWidth = Layout.measureText(runXOffset, ellipsisTextBuff, 0,
ellipsis.Length, run.style, null, 0, this._tabStops);
textAdvances.reset(textCount);
float textWidth = Layout.measureText(runXOffset, new TextBuff(text), textStart, textCount,
run.style, textAdvances, 0, this._tabStops);
float runXOffset = 0;
float justifyXOffset = 0;
lineCodeUnitRuns.Clear();
lineGlyphPositions.Clear();
paintRecords.Clear();
for (int i = 0; i < lineRuns.Count; ++i) {
var run = lineRuns[i];
this._generatePaintRecordFromLineStyleRun(run, i,
lineRange, lineRuns.Count, lineNumber, ref lineLimit, ref runXOffset, textAdvances,
layout, builder, glyphPositions, ref justifyXOffset,
words, ref wordIndex, justifyLine, wordGapWidth, ref maxWordWidth,
paintRecords, lineGlyphPositions, lineCodeUnitRuns);
}
int truncateCount = 0;
while (truncateCount < textCount &&
runXOffset + textWidth + ellipsisWidth > this._width) {
textWidth -= textAdvances[textCount - truncateCount - 1];
truncateCount++;
}
float lineXOffset = this._getAndShiftByLineXOffset(runXOffset, lineCodeUnitRuns, lineGlyphPositions);
this._computeLineOffset(lineNumber, lineRange, lineGlyphPositions, lineCodeUnitRuns, paintRecords,
ref yOffset, ref preMaxDescent);
this._addPaintRecordsWithOffset(paintRecords, lineXOffset, yOffset);
}
var ellipsizedText = this._text.Substring(textStart, textCount - truncateCount) + ellipsis;
textStart = 0;
textCount = ellipsizedText.Length;
text = ellipsizedText;
void _generatePaintRecordFromLineStyleRun(LineStyleRun run, int lineRunIndex, LineRange lineRange,
int lineRunsCount, int lineNumber, ref int lineLimit, ref float runXOffset, List<float> textAdvances,
Layout layout, TextBlobBuilder builder, List<GlyphPosition> glyphPositions, ref float justifyXOffset,
List<Range<int>> words, ref int wordIndex, bool justifyLine, float wordGapWidth, ref float maxWordWidth,
List<PaintRecord> paintRecords, List<GlyphPosition> lineGlyphPositions, List<CodeUnitRun> lineCodeUnitRuns) {
string text = this._text;
int textStart = run.start;
int textEnd = run.end;
int textCount = textEnd - textStart;
if (this._paragraphStyle.maxLines == null) {
lineLimit = lineNumber + 1;
this._didExceedMaxLines = true;
}
}
if (this._shouldConsiderEllipsis(lineRange, lineRunIndex, lineRunsCount, lineNumber, lineLimit)) {
this._handleOverflowEllipsis(ref text, run, runXOffset, textAdvances,
ref textStart, ref textCount, ref lineLimit, lineNumber);
}
layout.doLayout(runXOffset, new TextBuff(text), textStart, textCount, run.style);
if (layout.nGlyphs() == 0) {
continue;
}
layout.doLayout(runXOffset, new TextBuff(text), textStart, textCount, run.style);
if (layout.nGlyphs() == 0) {
return;
}
float wordStartPosition = float.NaN;
builder.allocRunPos(run.style, text, textStart, textCount);
builder.setBounds(layout.getBounds()
.translate(-layout.getX(0), 0)); // bounds relative to first character
float wordStartPosition = float.NaN;
builder.allocRunPos(run.style, text, textStart, textCount);
builder.setBounds(layout.getBounds()
.translate(-layout.getX(0), 0)); // bounds relative to first character
glyphPositions.Clear();
glyphPositions.Clear();
this._populateGlyphPositions(textStart, textCount, builder, layout, ref justifyXOffset, glyphPositions,
runXOffset, words, ref wordIndex, run, ref wordStartPosition, justifyLine, wordGapWidth, ref maxWordWidth);
for (int glyphIndex = 0; glyphIndex < textCount; ++glyphIndex) {
float glyphXOffset = layout.getX(glyphIndex) + justifyXOffset;
builder.positions[glyphIndex] = new Vector2d(
glyphXOffset, layout.getY(glyphIndex)
);
if (glyphPositions.Count == 0) {
return;
}
float glyphAdvance = layout.getCharAdvance(glyphIndex);
glyphPositions.Add(new GlyphPosition(runXOffset + glyphXOffset, glyphAdvance,
new Range<int>(textStart + glyphIndex, textStart + glyphIndex + 1)));
if (wordIndex < words.Count && words[wordIndex].start == run.start + glyphIndex) {
wordStartPosition = runXOffset + glyphXOffset;
}
runXOffset = this._generatePaintRecord(run, paintRecords, builder, lineNumber, runXOffset, layout,
lineGlyphPositions, glyphPositions, lineCodeUnitRuns);
}
if (wordIndex < words.Count && words[wordIndex].end == run.start + glyphIndex + 1) {
if (justifyLine) {
justifyXOffset += wordGapWidth;
}
bool _shouldConsiderEllipsis(LineRange lineRange, int lineRunIndex, int lineRunsCount, int lineNumber, int lineLimit) {
return !string.IsNullOrEmpty(this._paragraphStyle.ellipsis) && !this._width.isInfinite() && !lineRange.hardBreak
&& lineRunIndex == lineRunsCount - 1 &&
(lineNumber == lineLimit - 1 || this._paragraphStyle.maxLines == null);
}
wordIndex++;
if (!float.IsNaN(wordStartPosition)) {
float wordWidth = glyphPositions.last().xPos.end - wordStartPosition;
maxWordWidth = Mathf.Max(wordWidth, maxWordWidth);
wordStartPosition = float.NaN;
}
}
}
void _handleOverflowEllipsis(ref string text, LineStyleRun run, float runXOffset,
List<float> textAdvances, ref int textStart, ref int textCount, ref int lineLimit, int lineNumber) {
// By now, all characters have been "RequestCharactersInTexture"d by computeLineBreaks
// except the ellipsis, so Layout.doLayout skips calling RequestCharactersInTexture for
// performance, and the ellipsis is handled here
Layout.requireEllipsisInTexture(this._paragraphStyle.ellipsis, run.style);
TextBuff ellipsisTextBuff = new TextBuff(this._paragraphStyle.ellipsis);
float ellipsisWidth = Layout.measureText(runXOffset, ellipsisTextBuff, 0,
this._paragraphStyle.ellipsis.Length, run.style, null, 0, this._tabStops);
textAdvances.reset(textCount);
float textWidth = Layout.measureText(runXOffset, new TextBuff(text), textStart, textCount,
run.style, textAdvances, 0, this._tabStops);
int truncateCount = 0;
while (truncateCount < textCount &&
runXOffset + textWidth + ellipsisWidth > this._width) {
textWidth -= textAdvances[textCount - truncateCount - 1];
truncateCount++;
}
if (glyphPositions.Count == 0) {
continue;
}
var ellipsizedText = this._text.Substring(textStart, textCount - truncateCount) + this._paragraphStyle.ellipsis;
textStart = 0;
textCount = ellipsizedText.Length;
text = ellipsizedText;
var font = FontManager.instance.getOrCreate(run.style.fontFamily,
run.style.fontWeight, run.style.fontStyle).font;
var metrics = FontMetrics.fromFont(font, run.style.UnityFontSize);
paintRecords.Add(new PaintRecord(run.style, new Offset(runXOffset, 0),
builder.make(), metrics, lineNumber, layout.getAdvance()
));
lineGlyphPositions.AddRange(glyphPositions);
var codeUnitPositions = new List<GlyphPosition>(glyphPositions);
lineCodeUnitRuns.Add(new CodeUnitRun(codeUnitPositions,
new Range<int>(run.start, run.end), lineNumber,
new Range<float>(glyphPositions[0].xPos.start, glyphPositions.last().xPos.end),
metrics, TextDirection.ltr));
runXOffset += layout.getAdvance();
if (this._paragraphStyle.maxLines == null) {
lineLimit = lineNumber + 1;
this._didExceedMaxLines = true;
}
}
void _populateGlyphPositions(int textStart, int textCount, TextBlobBuilder builder, Layout layout,
ref float justifyXOffset, List<GlyphPosition> glyphPositions, float runXOffset, List<Range<int>> words,
ref int wordIndex, LineStyleRun run, ref float wordStartPosition, bool justifyLine, float wordGapWidth,
ref float maxWordWidth) {
for (int glyphIndex = 0; glyphIndex < textCount; ++glyphIndex) {
float glyphXOffset = layout.getX(glyphIndex) + justifyXOffset;
builder.positions[glyphIndex] = new Vector2d(
glyphXOffset, layout.getY(glyphIndex)
);
float glyphAdvance = layout.getCharAdvance(glyphIndex);
glyphPositions.Add(new GlyphPosition(runXOffset + glyphXOffset, glyphAdvance,
new Range<int>(textStart + glyphIndex, textStart + glyphIndex + 1)));
if (wordIndex < words.Count && words[wordIndex].start == run.start + glyphIndex) {
wordStartPosition = runXOffset + glyphXOffset;
float lineXOffset = this.getLineXOffset(runXOffset);
if (lineXOffset != 0) {
foreach (var codeUnitRun in lineCodeUnitRuns) {
codeUnitRun.Shift(lineXOffset);
if (wordIndex < words.Count && words[wordIndex].end == run.start + glyphIndex + 1) {
if (justifyLine) {
justifyXOffset += wordGapWidth;
for (int i = 0; i < lineGlyphPositions.Count; ++i) {
lineGlyphPositions[i] = lineGlyphPositions[i].shift(lineXOffset);
wordIndex++;
if (!float.IsNaN(wordStartPosition)) {
float wordWidth = glyphPositions.last().xPos.end - wordStartPosition;
maxWordWidth = Mathf.Max(wordWidth, maxWordWidth);
wordStartPosition = float.NaN;
}
}
int nextLineStart = (lineNumber < this._lineRanges.Count - 1)
? this._lineRanges[lineNumber + 1].start
: this._text.Length;
this._glyphLines.Add(new GlyphLine(lineGlyphPositions, nextLineStart - lineRange.start));
this._codeUnitRuns.AddRange(lineCodeUnitRuns);
float _generatePaintRecord(LineStyleRun run, List<PaintRecord> paintRecords, TextBlobBuilder builder,
int lineNumber, float runXOffset, Layout layout, List<GlyphPosition> lineGlyphPositions,
List<GlyphPosition> glyphPositions, List<CodeUnitRun> lineCodeUnitRuns) {
var font = FontManager.instance.getOrCreate(run.style.fontFamily,
run.style.fontWeight, run.style.fontStyle).font;
var metrics = FontMetrics.fromFont(font, run.style.UnityFontSize);
paintRecords.Add(new PaintRecord(run.style, new Offset(runXOffset, 0),
builder.make(), metrics, lineNumber, layout.getAdvance()
));
lineGlyphPositions.AddRange(glyphPositions);
var codeUnitPositions = new List<GlyphPosition>(glyphPositions);
lineCodeUnitRuns.Add(new CodeUnitRun(codeUnitPositions,
new Range<int>(run.start, run.end), lineNumber,
new Range<float>(glyphPositions[0].xPos.start, glyphPositions.last().xPos.end),
metrics, TextDirection.ltr));
runXOffset += layout.getAdvance();
return runXOffset;
}
float _getAndShiftByLineXOffset(float runXOffset, List<CodeUnitRun> lineCodeUnitRuns, List<GlyphPosition> lineGlyphPositions) {
float lineXOffset = this.getLineXOffset(runXOffset);
if (lineXOffset != 0) {
foreach (var codeUnitRun in lineCodeUnitRuns) {
codeUnitRun.Shift(lineXOffset);
}
for (int i = 0; i < lineGlyphPositions.Count; ++i) {
lineGlyphPositions[i] = lineGlyphPositions[i].shift(lineXOffset);
}
}
return lineXOffset;
}
void _computeLineOffset(int lineNumber,LineRange lineRange, List<GlyphPosition> lineGlyphPositions,
List<CodeUnitRun> lineCodeUnitRuns, List<PaintRecord> paintRecords, ref float yOffset, ref float preMaxDescent) {
int nextLineStart = (lineNumber < this._lineRanges.Count - 1)
? this._lineRanges[lineNumber + 1].start
: this._text.Length;
this._glyphLines.Add(new GlyphLine(lineGlyphPositions, nextLineStart - lineRange.start));
this._codeUnitRuns.AddRange(lineCodeUnitRuns);
float maxLineSpacing = 0;
float maxDescent = 0;
int line = lineNumber; // Resolve "accessing modified closure" problem
float maxLineSpacing = 0;
float maxDescent = 0;
void updateLineMetrics(FontMetrics metrics, TextStyle style) {
float lineSpacing = ((line == 0)
? -metrics.ascent * style.height
: (-metrics.ascent + metrics.leading) * (style.height));
if (lineSpacing > maxLineSpacing) {
maxLineSpacing = lineSpacing;
if (line == 0) {
this._alphabeticBaseline = lineSpacing;
this._ideographicBaseline =
(metrics.underlinePosition ?? 0.0f - metrics.ascent) * style.height;
}
void updateLineMetrics(FontMetrics metrics, TextStyle style) {
float lineSpacing = lineNumber == 0
? -metrics.ascent * style.height
: (-metrics.ascent + metrics.leading) * style.height;
if (lineSpacing > maxLineSpacing) {
maxLineSpacing = lineSpacing;
if (lineNumber == 0) {
this._alphabeticBaseline = lineSpacing;
this._ideographicBaseline =
(metrics.underlinePosition ?? 0.0f - metrics.ascent) * style.height;
}
float descent = metrics.descent * style.height;
maxDescent = Mathf.Max(descent, maxDescent);
}
float descent = metrics.descent * style.height;
maxDescent = Mathf.Max(descent, maxDescent);
}
foreach (var paintRecord in paintRecords) {
updateLineMetrics(paintRecord.metrics, paintRecord.style);
}
foreach (var paintRecord in paintRecords) {
updateLineMetrics(paintRecord.metrics, paintRecord.style);
}
if (paintRecords.Count == 0) {
var defaultStyle = this._paragraphStyle.getTextStyle();
var defaultFont = FontManager.instance.getOrCreate(defaultStyle.fontFamily,
defaultStyle.fontWeight, defaultStyle.fontStyle).font;
var metrics = FontMetrics.fromFont(defaultFont, defaultStyle.UnityFontSize);
updateLineMetrics(metrics, defaultStyle);
}
if (paintRecords.Count == 0) {
var defaultStyle = this._paragraphStyle.getTextStyle();
var defaultFont = FontManager.instance.getOrCreate(defaultStyle.fontFamily,
defaultStyle.fontWeight, defaultStyle.fontStyle).font;
var metrics = FontMetrics.fromFont(defaultFont, defaultStyle.UnityFontSize);
updateLineMetrics(metrics, defaultStyle);
}
this._lineHeights.Add(
(this._lineHeights.Count == 0 ? 0 : this._lineHeights.last())
+ Mathf.Round(maxLineSpacing + maxDescent));
this._lineBaseLines.Add(this._lineHeights.last() - maxDescent);
yOffset += Mathf.Round(maxLineSpacing + preMaxDescent);
preMaxDescent = maxDescent;
this._lineHeights.Add(
(this._lineHeights.Count == 0 ? 0 : this._lineHeights.last())
+ Mathf.Round(maxLineSpacing + maxDescent));
this._lineBaseLines.Add(this._lineHeights.last() - maxDescent);
yOffset += Mathf.Round(maxLineSpacing + preMaxDescent);
preMaxDescent = maxDescent;
}
for (int i = 0; i < paintRecords.Count; i++) {
PaintRecord paintRecord = paintRecords[i];
paintRecord.offset = new Offset(paintRecord.offset.dx + lineXOffset, yOffset);
this._paintRecords.Add(paintRecord);
}
void _addPaintRecordsWithOffset(List<PaintRecord> paintRecords, float lineXOffset, float yOffset) {
for (int i = 0; i < paintRecords.Count; i++) {
PaintRecord paintRecord = paintRecords[i];
paintRecord.offset = new Offset(paintRecord.offset.dx + lineXOffset, yOffset);
this._paintRecords.Add(paintRecord);
}
void _updateIntrinsicWidth(float maxWordWidth) {
this._maxIntrinsicWidth = 0;
float lineBlockWidth = 0;
for (int i = 0; i < this._lineWidths.Count; ++i) {

this._minIntrinsicWidth = Mathf.Min(maxWordWidth, this.maxIntrinsicWidth);
}
}
internal void setText(string text, StyledRuns runs) {
this._text = text;

return this._lineHeights.Count;
}
void computeLineBreak() {
void _computeLineBreak() {
this._lineRanges.Clear();
this._lineWidths.Clear();
this._maxIntrinsicWidth = 0;

正在加载...
取消
保存