Пример #1
0
        private void Update()
        {
            if (!_dirty)
            {
                return;
            }

            if (string.IsNullOrEmpty(_text))
            {
                _strings = new TextLine[0];
                _dirty   = false;
                return;
            }

            var lines = new List <TextLine>();

            var i    = 0;
            var line = new TextLine
            {
                TextStartIndex = i
            };

            var width = Width;

            while (i < _text.Length)
            {
                var c = LayoutRow(i, width, true);
                if (i == c.StartIndex && c.CharsCount == 0)
                {
                    break;
                }

                var chunk = new TextChunk(_font, _text.Substring(c.StartIndex, c.CharsCount), new Point(c.X, c.Y), CalculateGlyphs)
                {
                    TextStartIndex = i,
                    Color          = c.Color
                };

                width -= chunk.Size.X;

                i = c.StartIndex + c.CharsCount;

                line.Chunks.Add(chunk);
                line.Count += chunk.Count;

                line.Size.X += chunk.Size.X;
                if (chunk.Size.Y > line.Size.Y)
                {
                    line.Size.Y = chunk.Size.Y;
                }

                if (c.LineEnd)
                {
                    // New line
                    lines.Add(line);

                    line = new TextLine
                    {
                        TextStartIndex = i
                    };

                    width = Width;
                }
            }

            _strings = lines.ToArray();

            // Calculate size
            _size = Point.Zero;
            for (i = 0; i < _strings.Length; ++i)
            {
                line = _strings[i];

                line.LineIndex = i;
                line.Top       = _size.Y;

                for (var j = 0; j < line.Chunks.Count; ++j)
                {
                    var chunk = line.Chunks[j];
                    chunk.LineIndex  = line.LineIndex;
                    chunk.ChunkIndex = j;
                    chunk.Top        = line.Top;
                }

                if (line.Size.X > _size.X)
                {
                    _size.X = line.Size.X;
                }

                _size.Y += line.Size.Y;

                if (i < _strings.Length - 1)
                {
                    _size.Y += _verticalSpacing;
                }
            }

            _dirty = false;
        }
Пример #2
0
            public TextLine[] Format(SpriteFont font, string text, Options options)
            {
                if (string.IsNullOrEmpty(text))
                {
                    return(new TextLine[0]);
                }

                _font = font;

                var pt = ParseType.Text;

                // First run - gather lexemes
                _lexeme = new Lexeme();
                _lexemes.Clear();
                var str = new StringBuilder();

                for (var pos = 0; pos < text.Length; ++pos)
                {
                    var c = text[pos];
                    if (pt == ParseType.Text)
                    {
                        if (options.Color && c == '[' && pos < text.Length - 1 && text[pos + 1] != '[')
                        {
                            // Switch to color parsing
                            StoreLexeme();
                            pt = ParseType.Color;
                        }
                        else if (c == '\n')
                        {
                            StoreLexeme();

                            // Add linebreak lexeme
                            _lexeme.type = LexemeType.LineBreak;
                            _lexeme.AppendChar(c, pos);
                            StoreLexeme();
                        }
                        else if (c == ' ' && _lexeme.type == LexemeType.Word)
                        {
                            StoreLexeme();
                            _lexeme.type = LexemeType.Space;
                            _lexeme.AppendChar(c, pos);
                        }
                        else if (c == ' ')
                        {
                            _lexeme.AppendChar(c, pos);
                        }
                        else if (c > ' ')
                        {
                            if (_lexeme.type == LexemeType.Space)
                            {
                                StoreLexeme();
                                _lexeme.type = LexemeType.Word;
                            }

                            if (options.IsMenuText && c == '&')
                            {
                                _lexeme.UnderscoreIndex = _lexeme.chars.Count;
                            }
                            else
                            {
                                _lexeme.AppendChar(c, pos);
                            }

                            if (options.Color && c == '[')
                            {
                                // Means we have [[
                                // So one [ should be skipped
                                ++pos;
                            }
                        }
                    }
                    else if (pt == ParseType.Color)
                    {
                        if (c != ']')
                        {
                            str.Append(c);
                        }
                        else if (str.Length >= 1)
                        {
                            var color = str.ToString().FromName();
                            str.Clear();

                            var l = new Lexeme
                            {
                                type  = LexemeType.Color,
                                color = color ?? Color.White
                            };

                            _lexemes.Add(l);
                            pt = ParseType.Text;
                        }
                    }
                }

                StoreLexeme();

                // Second run - go through lexemes
                _result.Clear();
                _lastLine = new TextLine();
                _lastRun  = new TextRun(_font, _currentColor);
                _fullString.Clear();

                foreach (var li in _lexemes)
                {
                    switch (li.type)
                    {
                    case LexemeType.LineBreak:
                        StoreLine();
                        break;

                    case LexemeType.Space:
                    case LexemeType.Word:
                        _fullString.Append(li.text);

                        if (li.UnderscoreIndex != null)
                        {
                            _lastRun.UnderscoreIndex = _lastRun.Count + li.UnderscoreIndex;
                        }

                        if (options.Width.HasValue)
                        {
                            var sz = font.MeasureString(_fullString.ToString());
                            if (sz.X <= options.Width.Value)
                            {
                                _lastRun.Append(li.chars);
                            }
                            else
                            {
                                StoreLine();

                                if (li.type == LexemeType.Word)
                                {
                                    _fullString.Append(li.text);
                                    _lastRun.Append(li.chars);
                                }
                            }
                        }
                        else
                        {
                            _lastRun.Append(li.chars);
                        }

                        break;

                    case LexemeType.Color:
                        _currentColor = li.color;
                        StoreRun();
                        break;
                    }
                }

                StoreLine();

                return(_result.ToArray());
            }