您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

125 行
4.9 KiB

using System;
using System.Collections.Generic;
using UnityEngine;
namespace Unity.UIWidgets.ui {
public class LineBreaker {
public class LineInfo {
public int start;
public double width;
}
StyledRuns _runs;
public Vector2d[] _characterPositions;
public double[] _characterWidth;
string _text;
double _width;
int _lineStart;
int _wordStart;
int _spaceCount = 0;
int tabCount = 4;
double _lineLength;
List<LineInfo> _lines;
public void setup(string text, StyledRuns runs, double width, Vector2d[] characterPositions,
double[] characterWidth) {
this._text = text;
this._runs = runs;
this._characterPositions = characterPositions;
this._characterWidth = characterWidth;
this._width = width;
}
public List<LineInfo> getLines() {
return this._lines;
}
public void doBreak(int blockStart, int blockEnd) {
this._lines = new List<LineInfo>();
this._lineStart = blockStart;
this._wordStart = blockStart;
this._spaceCount = 0;
double offsetX = 0.0;
var runIterator = this._runs.iterator();
for (var charIndex = blockStart; charIndex < blockEnd; charIndex++) {
runIterator.nextTo(charIndex);
var run = runIterator.run;
var font = FontManager.instance.getOrCreate(run.style.fontFamily).font;
var style = run.style;
var charInfo = new CharacterInfo();
if (this._text[charIndex] == '\t') {
this._spaceCount++;
font.GetCharacterInfo(' ', out charInfo,
style.UnityFontSize, style.UnityFontStyle);
double tabSize = charInfo.advance * this.tabCount;
var newX = Math.Floor(((offsetX / tabSize) + 1) * tabSize);
if (newX > this._width && this._lineStart != charIndex) {
this._characterWidth[charIndex] = tabSize;
this.makeLine(charIndex, charIndex);
} else {
this._characterWidth[charIndex] = newX - offsetX;
this._characterPositions[charIndex].x = offsetX;
}
offsetX = this._characterPositions[charIndex].x + this._characterWidth[charIndex];
} else if (this._text[charIndex] == ' ') {
font.GetCharacterInfo(this._text[charIndex], out charInfo, style.UnityFontSize,
run.style.UnityFontStyle);
this._spaceCount++;
this._characterPositions[charIndex].x = offsetX;
this._characterWidth[charIndex] = charInfo.advance;
offsetX = this._characterPositions[charIndex].x + this._characterWidth[charIndex];
// todo no wrap in space ?
} else {
font.GetCharacterInfo(this._text[charIndex], out charInfo, style.UnityFontSize,
run.style.UnityFontStyle);
if (this._spaceCount > 0 || blockStart == charIndex) {
this._wordStart = charIndex;
}
this._characterPositions[charIndex].x = offsetX;
this._characterWidth[charIndex] = charInfo.advance;
if (offsetX + charInfo.advance > this._width && this._lineStart != charIndex) {
if (this._lineStart == this._wordStart) {
this.makeLine(charIndex, charIndex);
this._wordStart = charIndex;
} else {
this.makeLine(this._wordStart, charIndex);
}
}
offsetX = this._characterPositions[charIndex].x + this._characterWidth[charIndex];
this._spaceCount = 0;
}
}
this.makeLine(blockEnd, blockEnd);
}
void makeLine(int end, int last) {
Debug.Assert(this._lineStart < end);
Debug.Assert(end <= last);
this._lines.Add(new LineInfo() {
start = this._lineStart,
width = this._characterPositions[end - 1].x + this._characterWidth[end - 1],
});
this._lineStart = end;
if (end >= this._characterPositions.Length) {
return;
}
var offset = new Vector2d(-this._characterPositions[end].x, 0);
this._characterPositions[end].x = 0;
if (end < last) {
Paragraph.offsetCharacters(offset, this._characterPositions, end + 1, last + 1);
}
}
}
}