Example #1
0
        internal ChunkInfo LayoutRow(int startIndex, int?width, bool parseCommands)
        {
            var r = new ChunkInfo
            {
                StartIndex = startIndex,
                LineEnd    = true
            };

            if (string.IsNullOrEmpty(_text))
            {
                return(r);
            }

            _stringBuilder.Clear();
            int?  lastBreakPosition = null;
            Point?lastBreakMeasure  = null;

            for (var i = r.StartIndex; i < _text.Length; ++i)
            {
                var c = _text[i];

                if (SupportsCommands && c == '\\')
                {
                    if (i < _text.Length - 2 && _text[i + 1] == 'c' && _text[i + 2] == '[')
                    {
                        // Find end
                        var startPos = i + 3;
                        var j        = _text.IndexOf(']', startPos);

                        if (j != -1)
                        {
                            // Found
                            if (i > r.StartIndex)
                            {
                                // Break right here, as next chunk has another color
                                r.LineEnd = false;
                                return(r);
                            }

                            if (parseCommands)
                            {
                                r.Color = ColorStorage.FromName(_text.Substring(startPos, j - startPos));
                            }

                            r.StartIndex = j + 1;
                            i            = j;
                            continue;
                        }
                    }
                }

                _stringBuilder.Append(c);

                var sz = Point.Zero;

                if (c != '\n')
                {
                    var v = Font.MeasureString(_stringBuilder);
                    sz = new Point((int)v.X, (int)v.Y);
                }
                else
                {
                    sz = new Point(r.X + NewLineWidth, Math.Max(r.Y, CrossEngineStuff.LineSpacing(_font)));

                    // Break right here
                    ++r.CharsCount;
                    r.X = sz.X;
                    r.Y = sz.Y;
                    break;
                }

                if (width != null && sz.X > width.Value)
                {
                    if (lastBreakPosition != null)
                    {
                        r.CharsCount = lastBreakPosition.Value - r.StartIndex;
                    }

                    if (lastBreakMeasure != null)
                    {
                        r.X = lastBreakMeasure.Value.X;
                        r.Y = lastBreakMeasure.Value.Y;
                    }

                    break;
                }

                if (char.IsWhiteSpace(c))
                {
                    lastBreakPosition = i + 1;
                    lastBreakMeasure  = sz;
                }

                ++r.CharsCount;
                r.X = sz.X;
                r.Y = sz.Y;
            }

            return(r);
        }
Example #2
0
        internal ChunkInfo LayoutRow(int startIndex, int?width, bool parseCommands)
        {
            var r = new ChunkInfo {
                StartIndex = startIndex, LineEnd = true
            };

            if (string.IsNullOrEmpty(_text))
            {
                return(r);
            }

            _stringBuilder.Clear();
            int?  lastBreakPosition = null;
            Point?lastBreakMeasure  = null;

            for (var i = r.StartIndex; i < _text.Length; ++i)
            {
                var c = _text[i];

                if (char.IsHighSurrogate(c))
                {
                    _stringBuilder.Append(c);
                    ++r.CharsCount;
                    continue;
                }

                if (SupportsCommands && c == '\\')
                {
                    if (i < _text.Length - 2)
                    {
                        char commandChar = _text[i + 1];

                        if (_text[i + 2] == '[')
                        {
                            // Find parameter end
                            var parameterStartIndex = i + 3;
                            var parameterEndIndex   = _text.IndexOf(']', parameterStartIndex);

                            if (parameterEndIndex != -1)
                            {
                                // Found
                                if (i > r.StartIndex)
                                {
                                    // Break right here, as next chunk is a command block
                                    if (commandChar == SpriteCommandChar)
                                    {
                                        // sprites have width, will this one fit on our line?
                                        if (width != null)
                                        {
                                            var spriteId = SpriteChunk.GetSpriteId(_text, parameterStartIndex, parameterEndIndex);
                                            var size     = TrollskogIntegration.MeasureSprite(spriteId, _font);
                                            r.LineEnd = (r.X + size.X) > width.Value;
                                        }
                                    }
                                    else
                                    {
                                        r.LineEnd = false;
                                    }

                                    return(r);
                                }

                                if (parseCommands && commandChar == ColorCommandChar)
                                {
                                    r.Color = ColorStorage.FromName(_text.Substring(parameterStartIndex, parameterEndIndex - parameterStartIndex));
                                }
                                else if (commandChar == SpriteCommandChar)
                                {
                                    // Break because this is a sprite chunk
                                    var spriteId = SpriteChunk.GetSpriteId(_text, parameterStartIndex, parameterEndIndex);
                                    var size     = TrollskogIntegration.MeasureSprite(spriteId, _font);

                                    r.LineEnd    = parameterEndIndex == _text.Length - 1;
                                    r.X          = size.X;
                                    r.Y          = size.Y;
                                    r.SpriteId   = spriteId;
                                    r.CharsCount = parameterEndIndex - r.StartIndex + 1;
                                    return(r);
                                }
                            }

                            r.StartIndex = parameterEndIndex + 1;
                            i            = parameterEndIndex;
                            continue;
                        }

                        if (commandChar == NewlineCommandChar)
                        {
                            Point sz2 = new(r.X + NewLineWidth, Math.Max(r.Y, _font.FontSize));

                            // Break right here, consuming 2 chars '\\' and 'n'
                            r.SkipChars   = 2;
                            r.CharsCount += 2;
                            r.LineEnd     = true;
                            r.X           = sz2.X;
                            r.Y           = sz2.Y;
                            break;
                        }
                    }
                }

                _stringBuilder.Append(c);

                Point sz;
                if (c != '\n')
                {
                    var v = Font.MeasureString(_stringBuilder);
                    sz = new Point((int)v.X, _font.FontSize);
                }
                else
                {
                    sz = new Point(r.X + NewLineWidth, Math.Max(r.Y, _font.FontSize));

                    // Break right here
                    ++r.CharsCount;
                    r.X = sz.X;
                    r.Y = sz.Y;
                    break;
                }

                if (width != null && sz.X > width.Value)
                {
                    if (lastBreakPosition != null)
                    {
                        r.CharsCount = lastBreakPosition.Value - r.StartIndex;
                    }

                    if (lastBreakMeasure != null)
                    {
                        r.X = lastBreakMeasure.Value.X;
                        r.Y = lastBreakMeasure.Value.Y;
                    }

                    break;
                }

                if (char.IsWhiteSpace(c))
                {
                    lastBreakPosition = i + 1;
                    lastBreakMeasure  = sz;
                }

                ++r.CharsCount;
                r.X = sz.X;
                r.Y = sz.Y;
            }

            return(r);
        }