浏览代码

Optimize.

/main
Yuncong Zhang 5 年前
当前提交
88cc2fcf
共有 4 个文件被更改,包括 76 次插入66 次删除
  1. 71
      Runtime/ui/txt/layout.cs
  2. 22
      Runtime/ui/txt/layout_utils.cs
  3. 39
      Runtime/ui/txt/paragraph.cs
  4. 10
      Runtime/ui/txt/wordbreaker.cs

71
Runtime/ui/txt/layout.cs


class Layout {
int _start;
int _count;
List<float> _advances = new List<float>();
List<float> _positions = new List<float>();
float[] _advances;
float[] _positions;
static UnityEngine.Rect _innerBounds; // Used to pass bounds from static to non-static doLayout
static float _x, _y, _maxX, _maxY; // Used to pass bounds from static to non-static doLayout
List<float> advances, int advanceOffset, TabStops tabStops) {
float[] advances, int advanceOffset, TabStops tabStops) {
return _doLayout(offset, buff, start, count, style, advances, null, advanceOffset, tabStops);
}

this._advances.reset(count);
this._positions.reset(count);
this._advances = new float[count];
this._positions = new float[count];
_innerBounds = default;
_x = _y = _maxX = _maxY = 0;
this._bounds = _innerBounds;
this._bounds.Set(_x, _y, _maxX - _x, _maxY - _y);
this._count = count;
}

}
static float _doLayout(float offset, TextBuff buff, int start, int count, TextStyle style,
List<float> advances, List<float> positions, int advanceOffset, TabStops tabStops) {
float[] advances, float[] positions, int advanceOffset, TabStops tabStops) {
float advance = 0;
Font font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font;

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 did not appear in line breaking. It is taken care with
// The only exception is the ellipsis, which did not appear in line breaking. It is taken care of
int wordstart = start == buff.size
? start
: LayoutUtils.getPrevWordBreakForCache(buff, start + 1);
// int wordstart = start == buff.size
// ? start
// : LayoutUtils.getPrevWordBreakForCache(buff, start + 1);
wordend = LayoutUtils.getNextWordBreakForCache(buff, iter);
int wordCount = Mathf.Min(start + count, wordend) - iter;
advance = _layoutWord(offset, iter - start, buff.subBuff(wordstart, wordend - wordstart),
iter - wordstart, wordCount, style, font, advances, positions,
advanceOffset, advance, tabStops);
wordstart = wordend;
wordend = LayoutUtils.getNextWordBreak(buff, iter, start + count);
advance = _layoutWord(offset, iter - start, buff, iter, wordend - iter,
style, font, advances, positions, advanceOffset, advance, tabStops);
}
}

static float _layoutWord(float offset, int layoutOffset,
TextBuff buff, int start, int wordCount, TextStyle style, Font font, List<float> advances,
List<float> positions, int advanceOffset, float initAdvance, TabStops tabStops) {
TextBuff buff, int start, int wordCount, TextStyle style, Font font, float[] advances,
float[] positions, int advanceOffset, float initAdvance, TabStops tabStops) {
float wordSpacing =
wordCount == 1 && LayoutUtils.isWordSpace(buff.charAt(start)) ? style.wordSpacing : 0;

return x;
}
static float _layoutEmoji(string text, TextStyle style, Font font, int count, List<float> advances,
List<float> positions, int advanceOffset, float initAdvance) {
static float _layoutEmoji(string text, TextStyle style, Font font, int count, float[] advances,
float[] positions, int advanceOffset, float initAdvance) {
var metrics = FontMetrics.fromFont(font, style.UnityFontSize);
float x = initAdvance;
for (int i = 0; i < count; i++) {

}
static void _updateInnerBounds(float minX, float maxX, float minY, float maxY) {
if (_innerBounds.width <= 0 || _innerBounds.height <= 0) {
_innerBounds.x = minX;
_innerBounds.y = minY;
_innerBounds.xMax = maxX;
_innerBounds.yMax = maxY;
if (_maxX - _x <= 0 || _maxY - _y <= 0) {
_x = minX;
_y = minY;
_maxX = maxX;
_maxY = maxY;
if (minX < _innerBounds.x) {
_innerBounds.x = minX;
if (minX < _x) {
_x = minX;
if (minY < _innerBounds.y) {
_innerBounds.y = minY;
if (minY < _y) {
_y = minY;
if (maxX > _innerBounds.xMax) {
_innerBounds.xMax = maxX;
if (maxX > _maxX) {
_maxX = maxX;
if (maxY > _innerBounds.yMax) {
_innerBounds.yMax = maxY;
if (maxY > _maxY) {
_maxY = maxY;
}
}
}

return this._count;
}
public List<float> getAdvances() {
public float[] getAdvances() {
return this._advances;
}

22
Runtime/ui/txt/layout_utils.cs


return offset - 1;
}
for (int i = offset - 1; i > 0; i--) {
if (isWordBreakBefore(buff.charAt(i)) || isWordBreakAfter(buff.charAt(i - 1))) {
// Since i steps down, isWordBreakAfter(i) has already been checked in the previous step
// isWordBreakBeforeNotAfter cuts that part out to save time.
if (isWordBreakBeforeNotAfter(buff.charAt(i)) || isWordBreakAfter(buff.charAt(i - 1))) {
return i;
}
}

public static int getNextWordBreakForCache(TextBuff buff, int offset) {
public static int getNextWordBreak(TextBuff buff, int offset, int maxOffset) {
if (len > maxOffset) {
len = maxOffset + 1;
}
if (offset >= len) {
return len;
}

}
}
return len;
return maxOffset;
if (isWordSpace(c) || (c >= 0x2000 && c <= 0x200a) || c == 0x3000) {
// spaces
return true;
}
return false;
return isWordSpace(c) || (c >= 0x2000 && c <= 0x200a) || c == 0x3000;
}
public static bool isWordBreakBeforeNotAfter(ushort c) {
return c >= 3400 && c <= 0x9fff;
}
}

39
Runtime/ui/txt/paragraph.cs


public void shift(float shift) {
this.xPos = RangeUtils.shift(this.xPos, shift);
for (int i = 0; i < this.positions.Count; ++i) {
this.positions[i] = this.positions[i].shift(shift);
this.positions[i].shiftSelf(shift);
}
}
}

}
struct GlyphPosition {
public readonly Range<float> xPos;
public Range<float> xPos;
public readonly Range<int> codeUnits;
public GlyphPosition(float start, float advance, Range<int> codeUnits) {

public GlyphPosition shift(float shift) {
return new GlyphPosition(this.xPos.start + shift, this.xPos.end - this.xPos.start, this.codeUnits);
}
public void shiftSelf(float shift) {
this.xPos = new Range<float>(this.xPos.start + shift, this.xPos.end + shift);
}
}

this._paragraphStyle.ellipsis.Length, style, null, 0, this._tabStops);
// 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 List<float>(new float[textCount]);
var textAdvances = new float[textCount];
float textWidth = Layout.measureText(runXOffset, new TextBuff(text), textStart, textCount, style,
textAdvances, 0, this._tabStops);

builder.positions[glyphIndex] = new Vector2d(glyphXOffset);
glyphPositions.Add(new GlyphPosition(runXOffset + glyphXOffset, glyphAdvance,
new Range<int>(textStart + glyphIndex, textStart + glyphIndex + 1)));
if (wordIndex < words.Count && words[wordIndex].start == runStart + glyphIndex) {
wordStartPosition = runXOffset + glyphXOffset;
}
if (wordIndex < words.Count) {
Range<int> word = words[wordIndex];
if (word.start == runStart + glyphIndex) {
wordStartPosition = runXOffset + glyphXOffset;
}
if (wordIndex < words.Count && words[wordIndex].end == runStart + glyphIndex + 1) {
if (justifyLine) {
justifyXOffset += wordGapWidth;
}
if (word.end == runStart + glyphIndex + 1) {
if (justifyLine) {
justifyXOffset += wordGapWidth;
}
wordIndex++;
if (!float.IsNaN(wordStartPosition)) {
float wordWidth = glyphPositions.last().xPos.end - wordStartPosition;
maxWordWidth = Mathf.Max(wordWidth, maxWordWidth);
wordStartPosition = float.NaN;
wordIndex++;
if (!float.IsNaN(wordStartPosition)) {
float wordWidth = glyphPositions.last().xPos.end - wordStartPosition;
maxWordWidth = Mathf.Max(wordWidth, maxWordWidth);
wordStartPosition = float.NaN;
}
}
}
}

}
for (int i = 0; i < lineGlyphPositions.Count; ++i) {
lineGlyphPositions[i] = lineGlyphPositions[i].shift(lineXOffset);
lineGlyphPositions[i].shiftSelf(lineXOffset);
}
}
}

10
Runtime/ui/txt/wordbreaker.cs


}
char c = this._text.charAt(this._current);
bool preType = char.IsWhiteSpace(c);
bool preWhiteSpace = char.IsWhiteSpace(c);
bool preBoundaryChar = isBoundaryChar(c);
this._current++;
if (preBoundaryChar) {

this._findBoundaryCharOrTypeChange(preType);
this._findBoundaryCharOrTypeChange(preWhiteSpace);
void _findBoundaryCharOrTypeChange(bool preType) {
void _findBoundaryCharOrTypeChange(bool preWhiteSpace) {
for (; this._current < this._text.size; ++this._current) {
// this.nextUntilCodePoint();
if (this._current >= this._text.size) {

}
bool currentType = char.IsWhiteSpace(c);
if (currentType != preType) {
if (currentType != preWhiteSpace) {
preType = currentType;
preWhiteSpace = currentType;
}
}

正在加载...
取消
保存