浏览代码

Improve getBounds().translate()

/main
Yuncong Zhang 6 年前
当前提交
4d650f28
共有 2 个文件被更改,包括 58 次插入48 次删除
  1. 5
      Runtime/ui/txt/layout.cs
  2. 101
      Runtime/ui/txt/paragraph.cs

5
Runtime/ui/txt/layout.cs


public Rect getBounds() {
return Rect.fromLTWH(this._bounds.x, this._bounds.y, this._bounds.width, this._bounds.height);
}
public Rect translatedBounds() {
return Rect.fromLTWH(this._bounds.x - this._positions[0],
this._bounds.y, this._bounds.width, this._bounds.height);
}
}
}

101
Runtime/ui/txt/paragraph.cs


if (fontSize == _previousFontSize && _previousFontMetrics != null) {
return _previousFontMetrics;
}
var ascent = -font.ascent * fontSize / font.fontSize;
var descent = (font.lineHeight - font.ascent) * fontSize / font.fontSize;
font.RequestCharactersInTextureSafe("x", fontSize, UnityEngine.FontStyle.Normal);

struct GlyphLine {
public readonly List<GlyphPosition> positions;
public readonly GlyphPosition[] positions;
public GlyphLine(List<GlyphPosition> positions, int totalCountUnits) {
public GlyphLine(GlyphPosition[] positions, int totalCountUnits) {
this.positions = positions;
this.totalCountUnits = totalCountUnits;
}

void _layout() {
int styleMaxLines = this._paragraphStyle.maxLines ?? int.MaxValue;
this._didExceedMaxLines = this._lineRanges.Count > styleMaxLines;
var lineLimit = Mathf.Min(styleMaxLines, this._lineRanges.Count);
int styleRunIndex = 0;
float yOffset = 0;

List<Range<int>> words = new List<Range<int>>();
List<LineStyleRun> lineStyleRuns = new List<LineStyleRun>();
List<CodeUnitRun> lineCodeUnitRuns = new List<CodeUnitRun>();
List<GlyphPosition> lineGlyphPositions = new List<GlyphPosition>();
Layout layout = new Layout();
layout.setTabStops(this._tabStops);

lineCodeUnitRuns.Clear();
lineGlyphPositions.Clear();
words, lineStyleRuns, lineCodeUnitRuns, lineGlyphPositions,
builder, layout
words, lineStyleRuns, builder, layout
);
}

void _computePaintRecordsFromLine(int lineNumber,
ref int lineLimit, ref int styleRunIndex, ref float maxWordWidth, ref float yOffset, ref float preMaxDescent,
List<Range<int>> words, List<LineStyleRun> lineStyleRuns, List<CodeUnitRun> lineCodeUnitRuns,
List<GlyphPosition> lineGlyphPositions,
TextBlobBuilder builder, Layout layout) {
void _computePaintRecordsFromLine(int lineNumber, ref int lineLimit, ref int styleRunIndex,
ref float maxWordWidth, ref float yOffset, ref float preMaxDescent, List<Range<int>> words,
List<LineStyleRun> lineStyleRuns, TextBlobBuilder builder, Layout layout) {
float wordGapWidth = !(justifyLine && words.Count > 1) ? 0
float wordGapWidth = !(justifyLine && words.Count > 1)
? 0
this._computeLineStyleRuns(lineStyleRuns, lineRange, ref styleRunIndex);
int totalTextCount = this._computeLineStyleRuns(lineStyleRuns, lineRange, ref styleRunIndex);
// Add ellipsis length to make sure this array is big enough
GlyphPosition[] lineGlyphPositions = lineNumber == lineLimit - 1 || this._paragraphStyle.maxLines == null
? new GlyphPosition[totalTextCount + this._paragraphStyle.ellipsis.Length]
: new GlyphPosition[totalTextCount];
int pLineGlyphPositions = 0;
for (int i = 0; i < lineStyleRuns.Count; ++i) {
var run = lineStyleRuns[i];
var isLastLineStyleRun = i == lineStyleRuns.Count - 1;

ref maxWordWidth,
words,
lineGlyphPositions,
lineCodeUnitRuns);
ref pLineGlyphPositions);
this._shiftByLineXOffset(runXOffset, lineCodeUnitRuns, lineGlyphPositions);
this._computeLineOffset(lineNumber, lineGlyphPositions, lineCodeUnitRuns, paintRecords,
ref yOffset, ref preMaxDescent);
this._shiftByLineXOffset(runXOffset, lineStyleRuns.Count, lineGlyphPositions);
this._computeLineOffset(lineNumber, lineGlyphPositions, paintRecords, ref yOffset, ref preMaxDescent);
void _computeLineStyleRuns(List<LineStyleRun> lineStyleRuns, LineRange lineRange, ref int styleRunIndex) {
int _computeLineStyleRuns(List<LineStyleRun> lineStyleRuns, 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 ||

int totalTextCount = 0;
while (styleRunIndex < this._runs.size) {
var styleRun = this._runs.getRun(styleRunIndex);
if (styleRun.start < lineEndIndex && styleRun.end > lineRange.start) {

if (start < end) {
lineStyleRuns.Add(new LineStyleRun(start, end, styleRun.style));
totalTextCount += end - start;
}
}

styleRunIndex++;
}
return totalTextCount;
}
PaintRecord _generatePaintRecordFromLineStyleRun(

ref float justifyXOffset,
ref float maxWordWidth,
List<Range<int>> words,
List<GlyphPosition> lineGlyphPositions,
List<CodeUnitRun> lineCodeUnitRuns) {
GlyphPosition[] lineGlyphPositions,
ref int pLineGlyphPositions) {
string text = this._text;
int textStart = run.start;
int textEnd = run.end;

builder.allocRunPos(run.style, text, textStart, textCount);
// bounds relative to first character
builder.setBounds(layout.getBounds().translate(-layout.getX(0), 0));
builder.setBounds(layout.translatedBounds());
GlyphPosition[] glyphPositions = this._populateGlyphPositions(
textStart, textCount,

float advance = layout.getAdvance();
PaintRecord paintRecord = this._generatePaintRecord(run.style, textBlob, runXOffset, advance);
runXOffset += advance;
this._generateCodeUnitRun(lineCodeUnitRuns, run, lineNumber, glyphPositions);
lineGlyphPositions.AddRange(glyphPositions);
this._codeUnitRuns.Add(this._generateCodeUnitRun(run, lineNumber, glyphPositions));
for (int i = 0; i < glyphPositions.Length; i++) {
lineGlyphPositions[pLineGlyphPositions++] = glyphPositions[i];
}
return paintRecord;
}

}
void _handleOverflowEllipsis(ref string text, ref int textStart, ref int textCount, TextStyle style, float runXOffset) {
void _handleOverflowEllipsis(ref string text, ref int textStart, ref int textCount, TextStyle style,
float runXOffset) {
// This "new" is executed at most once in each layout, no need to bother create in the beginning
// and pass all the way here
var textAdvances = new float[textCount];
float textWidth = Layout.measureText(runXOffset, new TextBuff(text), textStart, textCount, style,
textAdvances, 0, this._tabStops);

ref int wordIndex,
ref float justifyXOffset,
ref float maxWordWidth) {
if (textCount == 0) return null;
if (textCount == 0) {
return null;
}
float wordStartPosition = float.NaN;
GlyphPosition[] glyphPositions = new GlyphPosition[textCount];
for (int glyphIndex = 0; glyphIndex < textCount; ++glyphIndex) {

return new PaintRecord(style, new Offset(runXOffset, 0), textBlob, metrics, advance);
}
void _generateCodeUnitRun(List<CodeUnitRun> lineCodeUnitRuns, LineStyleRun run, int lineNumber,
GlyphPosition[] glyphPositions) {
lineCodeUnitRuns.Add(new CodeUnitRun(glyphPositions,
CodeUnitRun _generateCodeUnitRun(LineStyleRun run, int lineNumber, GlyphPosition[] glyphPositions) {
return new CodeUnitRun(glyphPositions,
lineNumber, TextDirection.ltr));
lineNumber, TextDirection.ltr);
void _shiftByLineXOffset(float lineXOffset, List<CodeUnitRun> lineCodeUnitRuns, List<GlyphPosition> lineGlyphPositions) {
void _shiftByLineXOffset(float lineXOffset, int lineStyleRunCount, GlyphPosition[] lineGlyphPositions) {
foreach (var codeUnitRun in lineCodeUnitRuns) {
codeUnitRun.shift(lineXOffset);
for (int i = 0; i < lineStyleRunCount; i++) {
this._codeUnitRuns[this._codeUnitRuns.Count - 1 - i].shift(lineXOffset);
for (int i = 0; i < lineGlyphPositions.Count; ++i) {
for (int i = 0; i < lineGlyphPositions.Length; ++i) {
lineGlyphPositions[i].shiftSelf(lineXOffset);
}
}

List<GlyphPosition> lineGlyphPositions,
List<CodeUnitRun> lineCodeUnitRuns,
GlyphPosition[] lineGlyphPositions,
PaintRecord[] paintRecords,
ref float yOffset, ref float preMaxDescent) {
int lineStart = this._lineRanges[lineNumber].start;

this._glyphLines.Add(new GlyphLine(lineGlyphPositions, nextLineStart - lineStart));
this._codeUnitRuns.AddRange(lineCodeUnitRuns);
float maxLineSpacing = 0;
float maxDescent = 0;

}
var lineGlyphPosition = this._glyphLines[yIndex].positions;
if (lineGlyphPosition.Count == 0) {
if (lineGlyphPosition.Length == 0) {
int lineStartIndex = this._glyphLines.Where((g, i) => i < yIndex).Sum((gl) => gl.totalCountUnits);
return new PositionWithAffinity(lineStartIndex, TextAffinity.downstream);
}

bool gpSet = false;
for (int xIndex = 0; xIndex < lineGlyphPosition.Count; ++xIndex) {
float glyphEnd = xIndex < lineGlyphPosition.Count - 1
for (int xIndex = 0; xIndex < lineGlyphPosition.Length; ++xIndex) {
float glyphEnd = xIndex < lineGlyphPosition.Length - 1
? lineGlyphPosition[xIndex + 1].xPos.start
: lineGlyphPosition[xIndex].xPos.end;
if (dx < glyphEnd) {

正在加载...
取消
保存