public void Build() { if (!_isDirty || _text == null || _font == null) { return; } if (_vbuffer == null) { _vbuffer = new VertexBuffer(VertexFormat.PositionColorUV); } if (_ibuffer == null) { _ibuffer = new IndexBuffer(); } var i = 0; TextRun run = null; var lines = new List <List <TextRun> >(); var line = new List <TextRun>(); //var nestedRuns = new Stack<TextRun>(); //var nestedTags = new Stack<string>(); lines.Add(line); run = new TextRun(_font, i, _kerning, _color); line.Add(run); var trim = false; while (i < _text.Length) { if (char.IsLowSurrogate(_text, i)) { i++; continue; } if (trim) { if (char.IsWhiteSpace(_text, i)) { i++; continue; } else { trim = false; } } var c = char.ConvertToUtf32(_text, i++); if (c == '\n') { run.End = i; line = new List <TextRun>(); lines.Add(line); run = new TextRun(run, i); line.Add(run); continue; } else if (c < 32) { continue; } var ch = run.Font[c]; if (ch == null) { ch = run.Font['?']; if (ch == null) { ch = run.Font[' ']; if (ch == null) { continue; } } } run.Push(ch); if (_width > 0f && line.Sum(tr => tr.Width) > _width) { int count; var back = run.FindBreak(out count); if (i - back <= run.Start) { if (line.Count > 1) { line.RemoveAt(line.Count - 1); line = new List <TextRun>(); lines.Add(line); line.Add(run); trim = true; continue; } else { back = 1; } } i -= back - count; run.Pop(back); line = new List <TextRun>(); lines.Add(line); run = new TextRun(run, i); line.Add(run); trim = true; } } run.End = i; _actualSize.X = lines.Max(l => l.Sum(tr => tr.Width)); _actualSize.Y = lines.Sum(l => l.Max(tr => tr.Height) + _leading); var vertices = new List <float>(); var indices = new List <int>(); var y = 0f; for (i = lines.Count - 1; i >= 0; --i) { var tl = lines[i]; var x = 0f; if (_halign == HorizontalAlignment.Right) { x = _width - tl.Sum(tr => tr.Width); } else if (_halign == HorizontalAlignment.Center) { x = Mathf.Floor((_width - tl.Sum(tr => tr.Width)) / 2f); } foreach (var tr in tl) { tr.Build(vertices, indices, new Vector3(x, y + (tr.Font.LineHeight - tr.Font.Base), 0f)); x += tr.Width; } y += tl.Max(tr => tr.Height) + _leading; } _vbuffer.Data = vertices.ToArray(); _vbuffer.Commit(); _ibuffer.Data = indices.ToArray(); _ibuffer.Commit(); _isDirty = false; }