Beispiel #1
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());
            }