Ejemplo n.º 1
0
 public TextRun(TextRun other, int start, BitmapFont font)
     : this(font, start, other._kerning, other._color)
 {
 }
Ejemplo n.º 2
0
        protected override void Build(bool isClipped, Rect clipRect)
        {
            if (_itext == null)
            {
                return;
            }

            var text = _itext.Text ?? "";
            var size = this.Size;

            int     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>();
            var     font       = Gui.Instance.GetFont(_itext.Font);

            lines.Add(line);
            run = new TextRun(font, i, _itext.Kerning, this.Color);
            line.Add(run);

            while (i < text.Length)
            {
                if (char.IsLowSurrogate(text, i))
                {
                    i++;
                    continue;
                }

                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;
                }
                else if (c == '[')
                {
                    var tagEnd = text.IndexOf(']', i);
                    if (tagEnd > 0 && tagEnd > i)
                    {
                        var tag = text.Substring(i, tagEnd - i).ToUpper();
                        switch (tag)
                        {
                        case "B":
                            nestedTags.Push(tag);
                            nestedRuns.Push(run);
                            run = new TextRun(run, tagEnd + 1, Gui.Instance.GetFont(_itext.BoldFont ?? _itext.Font));
                            line.Add(run);
                            i = tagEnd + 1;
                            continue;

                        case "/B":
                            if (nestedTags.Count > 0 && nestedTags.Peek() == "B")
                            {
                                run = new TextRun(nestedRuns.Pop(), tagEnd + 1);
                                line.Add(run);
                                nestedTags.Pop();
                                i = tagEnd + 1;
                                continue;
                            }
                            break;
                        }
                    }
                }

                var ch = run.Font.GetCharacter(c);
                run.Push(ch);
                if (_itext.Overflow == Overflow.Wrap && line.Sum(tr => tr.Width) + (lines.Count > 1 ? _itext.Indent : 0f) > size.x)
                {
                    var back = run.Break();
                    if (i - back <= run.Start)
                    {
                        if (line.Count > 1)
                        {
                            line.RemoveAt(line.Count - 1);
                            line = new List <TextRun>();
                            lines.Add(line);
                            line.Add(run);
                            continue;
                        }
                        else
                        {
                            back = 1;
                        }
                    }
                    else
                    {
                        back--;
                    }
                    i -= back;
                    run.Pop(back);
                    line = new List <TextRun>();
                    lines.Add(line);
                    run = new TextRun(run, i);
                    line.Add(run);
                }
                else if (_itext.Overflow == Overflow.Hidden && line.Sum(tr => tr.Width) > size.x)
                {
                    run.Pop(1);
                    break;
                }
            }
            run.End = i;

            var actualWidth  = lines.Max(l => l.Sum(tr => tr.Width));
            var actualHeight = lines.Sum(l => l.Max(tr => tr.Height) + _itext.Leading);
            var y            = 0f;

            switch (_itext.VerticalAlignment)
            {
            case VerticalAlignment.Top:
                y = size.y;
                break;

            case VerticalAlignment.Center:
                y = Mathf.Round(size.y - (size.y - actualHeight) / 2f);
                break;

            case VerticalAlignment.Bottom:
                y = actualHeight;
                break;
            }
            _bounds = new Rect(float.MaxValue, y - actualHeight, actualWidth, actualHeight);

            var hitTest = _itext.IsHitTestable;

            if (hitTest)
            {
                _charBoxes = new Rect[text.Length];
            }
            else
            {
                _charBoxes = new Rect[0];
            }

            var vertexOffset = Vector3.zero;

            if (this.RenderOptions.AnchorTo == AnchorTo.Center)
            {
                vertexOffset = new Vector3(-size.x / 2f, -size.y / 2f, 0);
                clipRect.x  -= size.x / 2f;
                clipRect.y  -= size.y / 2f;
            }

            for (i = 0; i < lines.Count; i++)
            {
                var tl = lines[i];
                var x  = 0f + (i > 0 ? _itext.Indent : 0f);
                switch (_itext.HorizontalAlignment)
                {
                case HorizontalAlignment.Center:
                    x = Mathf.Round((size.x - tl.Sum(tr => tr.Width)) / 2f);
                    break;

                case HorizontalAlignment.Right:
                    x = size.x - tl.Sum(tr => tr.Width);
                    break;
                }
                if (x < _bounds.x)
                {
                    _bounds.x = x;
                }
                y -= tl.Max(tr => tr.Height) + _itext.Leading;
                foreach (var tr in tl)
                {
                    tr.Build(gameObject, new Vector2(x, y - (font.Base - tr.Font.Base)), isClipped, clipRect, hitTest ? _charBoxes : null, vertexOffset);
                    x += tr.Width;
                }
            }
        }
Ejemplo n.º 3
0
 public TextRun(TextRun other, int start)
     : this(other.Font, start, other._kerning, other._color)
 {
 }