Exemplo n.º 1
0
        private void UpdateScrolling()
        {
            if (SelectedItem == null)
            {
                return;
            }

            var p = SelectedItem.Widget.Bounds;

            var bounds = _box.ActualBounds;

            InternalChild.UpdateLayout();
            var sz      = new Point(InternalChild.Bounds.Width, InternalChild.Bounds.Height);
            var maximum = InternalChild.ScrollMaximum;

            p.X -= bounds.X;
            p.Y -= bounds.Y;

            var lineHeight = CrossEngineStuff.LineSpacing(ListBoxStyle.ListItemStyle.LabelStyle.Font);

            var sp = InternalChild.ScrollPosition;

            if (p.Y < sp.Y)
            {
                sp.Y = p.Y;
            }
            else if (p.Y + lineHeight > sp.Y + sz.Y)
            {
                sp.Y = (p.Y + lineHeight - sz.Y);
            }

            InternalChild.ScrollPosition = sp;
        }
Exemplo n.º 2
0
        protected override Point InternalMeasure(Point availableSize)
        {
            if (Font == null)
            {
                return(Point.Zero);
            }

            var width = availableSize.X;

            if (Width != null && Width.Value < width)
            {
                width = Width.Value;
            }

            var result = Point.Zero;

            if (Font != null)
            {
                var formattedText = _formattedText.Clone();
                formattedText.Width = _wrap ? width : default(int?);

                result = formattedText.Size;
            }

            if (result.Y < CrossEngineStuff.LineSpacing(Font))
            {
                result.Y = CrossEngineStuff.LineSpacing(Font);
            }

            return(result);
        }
Exemplo n.º 3
0
        protected override Point InternalMeasure(Point availableSize)
        {
            if (Font == null)
            {
                return(Point.Zero);
            }

            var width = availableSize.X;

            width -= CursorWidth;

            var result = Point.Zero;

            if (Font != null)
            {
                result = _formattedText.Measure(_wrap ? width : default(int?));
            }

            if (result.Y < CrossEngineStuff.LineSpacing(Font))
            {
                result.Y = CrossEngineStuff.LineSpacing(Font);
            }

            if (Cursor != null)
            {
                result.X += CursorWidth;
                result.Y  = Math.Max(result.Y, Cursor.Size.Y);
            }

            return(result);
        }
Exemplo n.º 4
0
        public override void InternalRender(RenderContext context)
        {
            if (_formattedText.Font == null)
            {
                return;
            }

            var bounds = ActualBounds;

            RenderSelection(context);

            var textColor = TextColor;

            if (!Enabled && DisabledTextColor != null)
            {
                textColor = DisabledTextColor.Value;
            }
            else if (IsKeyboardFocused && FocusedTextColor != null)
            {
                textColor = FocusedTextColor.Value;
            }

            var centeredBounds = LayoutUtils.Align(new Point(bounds.Width, bounds.Height), _formattedText.Size, HorizontalAlignment.Left, TextVerticalAlignment);

            centeredBounds.Offset(bounds.Location);

            var p = new Point(centeredBounds.Location.X - _internalScrolling.X,
                              centeredBounds.Location.Y - _internalScrolling.Y);

            _formattedText.Draw(context.Batch,
                                p,
                                context.View, textColor, context.Opacity);

            if (!IsKeyboardFocused)
            {
                // Skip cursor rendering if the widget doesnt have the focus
                return;
            }

            var now = DateTime.Now;

            if ((now - _lastBlinkStamp).TotalMilliseconds >= BlinkIntervalInMs)
            {
                _cursorOn       = !_cursorOn;
                _lastBlinkStamp = now;
            }

            if (Enabled && _cursorOn && Cursor != null)
            {
                p    = GetRenderPositionByIndex(CursorPosition);
                p.X -= _internalScrolling.X;
                p.Y -= _internalScrolling.Y;
                context.Draw(Cursor,
                             new Rectangle(p.X, p.Y,
                                           Cursor.Size.X,
                                           CrossEngineStuff.LineSpacing(_formattedText.Font)));
            }
        }
Exemplo n.º 5
0
        public override void InternalRender(RenderContext context)
        {
            if (_formattedText.Font == null)
            {
                return;
            }

            var bounds = ActualBounds;

            var textColor = TextColor;

            if (!Enabled && DisabledTextColor != null)
            {
                textColor = DisabledTextColor.Value;
            }
            else if (IsFocused && FocusedTextColor != null)
            {
                textColor = FocusedTextColor.Value;
            }

            var centeredBounds = LayoutUtils.Align(new Point(bounds.Width, bounds.Height), _formattedText.Size, HorizontalAlignment.Left, TextVerticalAlignment);

            centeredBounds.Offset(bounds.Location);
            _formattedText.Draw(context.Batch, centeredBounds, textColor, context.Opacity);

            if (!IsFocused)
            {
                // Skip cursor rendering if the widget doesnt have the focus
                return;
            }

            var now = DateTime.Now;

            if ((now - _lastBlinkStamp).TotalMilliseconds >= BlinkIntervalInMs)
            {
                _cursorOn       = !_cursorOn;
                _lastBlinkStamp = now;
            }

            if (_cursorOn && Cursor != null)
            {
                var x           = bounds.X;
                var y           = bounds.Y;
                var glyphRender = _formattedText.GetGlyphInfoByIndex(_cursorIndex - 1);
                if (glyphRender != null && glyphRender.TextRun.RenderedPosition != null)
                {
                    x = glyphRender.TextRun.RenderedPosition.Value.X + glyphRender.Bounds.Right;
                    y = glyphRender.TextRun.RenderedPosition.Value.Y;
                }

                context.Draw(Cursor, new Rectangle(x,
                                                   y,
                                                   Cursor.Size.X,
                                                   CrossEngineStuff.LineSpacing(_formattedText.Font)));
            }
        }
Exemplo n.º 6
0
        public Point Measure(int?width)
        {
            var result = Point.Zero;

            if (_text != null)
            {
                var i = 0;
                var y = 0;

                var remainingWidth = width;
                var lineWidth      = 0;
                while (i < _text.Length)
                {
                    var chunkInfo = LayoutRow(i, remainingWidth, false);
                    if (i == chunkInfo.StartIndex && chunkInfo.CharsCount == 0)
                    {
                        break;
                    }

                    lineWidth += chunkInfo.X;
                    i          = chunkInfo.StartIndex + chunkInfo.CharsCount;

                    if (remainingWidth.HasValue)
                    {
                        remainingWidth = remainingWidth.Value - chunkInfo.X;
                    }

                    if (chunkInfo.LineEnd)
                    {
                        if (lineWidth > result.X)
                        {
                            result.X = lineWidth;
                        }

                        lineWidth      = 0;
                        remainingWidth = width;

                        y += chunkInfo.Y;
                        y += _verticalSpacing;
                    }
                }

                result.Y = y;
            }

            if (result.Y == 0)
            {
                result.Y = CrossEngineStuff.LineSpacing(_font);
            }

            return(result);
        }
Exemplo n.º 7
0
        private void _textEdit_CursorIndexChanged(object sender, EventArgs e)
        {
            var asScrollPane = Parent as ScrollPane;

            if (asScrollPane == null)
            {
                return;
            }

            var p = GetRenderPositionByIndex(_textEdit.CursorIndex);

            if (p.Y == _lastCursorY)
            {
                return;
            }

            var scrollMaximumPixels = asScrollPane.ScrollMaximumPixels;

            if (scrollMaximumPixels.Y == 0)
            {
                return;
            }

            var lineHeight = CrossEngineStuff.LineSpacing(_formattedText.Font);

            if (p.Y < asScrollPane.ActualBounds.Top)
            {
                var scrollMaximum = asScrollPane.ScrollMaximum;
                var newY          = (-Top + p.Y - asScrollPane.ActualBounds.Top) * scrollMaximum.Y / scrollMaximumPixels.Y;

                var sp = asScrollPane.ScrollPosition;
                asScrollPane.ScrollPosition = new Point(sp.X, newY);
            }
            else if (p.Y + lineHeight > asScrollPane.ActualBounds.Bottom)
            {
                var scrollMaximum = asScrollPane.ScrollMaximum;
                var newY          = (-Top + p.Y + lineHeight - asScrollPane.ActualBounds.Bottom) * scrollMaximum.Y / scrollMaximumPixels.Y;

                var sp = asScrollPane.ScrollPosition;
                asScrollPane.ScrollPosition = new Point(sp.X, newY);
            }

            _lastCursorY = p.Y;

            asScrollPane.UpdateLayout();
        }
Exemplo n.º 8
0
        public Point Measure(int?width)
        {
            var result = Point.Zero;

            if (_text != null)
            {
                var i = 0;

                float y = 0;
                while (i < _text.Length)
                {
                    var r = LayoutRow(i, width);

                    if (r.num_chars == 0)
                    {
                        break;
                    }

                    if (r.x1 > result.X)
                    {
                        result.X = (int)r.x1;
                    }

                    i += r.num_chars;

                    y += r.ymax;
                    y += _verticalSpacing;
                }

                result.Y = (int)y;
            }

            if (result.Y == 0)
            {
                result.Y = CrossEngineStuff.LineSpacing(_font);
            }

            return(result);
        }
Exemplo n.º 9
0
        public Point Measure(int?width)
        {
            var result = Point.Zero;

            if (_text != null)
            {
                var i = 0;
                var y = 0;
                while (i < _text.Length)
                {
                    var r = LayoutRow(i, width);

                    if (r.CharsCount == 0)
                    {
                        break;
                    }

                    if (r.X > result.X)
                    {
                        result.X = r.X;
                    }

                    i += r.CharsCount;

                    y += r.Y;
                    y += _verticalSpacing;
                }

                result.Y = y;
            }

            if (result.Y == 0)
            {
                result.Y = CrossEngineStuff.LineSpacing(_font);
            }

            return(result);
        }
Exemplo n.º 10
0
        private void RenderSelection(RenderContext context)
        {
            var bounds = ActualBounds;

            if (string.IsNullOrEmpty(Text) || Selection == null)
            {
                return;
            }

            var selectStart = Math.Min(SelectStart, SelectEnd);
            var selectEnd   = Math.Max(SelectStart, SelectEnd);

            if (selectStart >= selectEnd)
            {
                return;
            }

            var startGlyph = _formattedText.GetGlyphInfoByIndex(selectStart);

            if (startGlyph == null)
            {
                return;
            }

            var lineIndex = startGlyph.TextChunk.LineIndex;
            var i         = selectStart;

            var lineHeight = CrossEngineStuff.LineSpacing(_formattedText.Font);

            while (true)
            {
                startGlyph = _formattedText.GetGlyphInfoByIndex(i);
                var startPosition = GetRenderPositionByIndex(i);

                var line = _formattedText.Lines[startGlyph.TextChunk.LineIndex];

                if (selectEnd < line.TextStartIndex + line.Count)
                {
                    var endPosition = GetRenderPositionByIndex(selectEnd);

                    context.Draw(Selection,
                                 new Rectangle(startPosition.X - _internalScrolling.X,
                                               startPosition.Y - _internalScrolling.Y,
                                               endPosition.X - startPosition.X,
                                               lineHeight));

                    break;
                }

                context.Draw(Selection,
                             new Rectangle(startPosition.X - _internalScrolling.X,
                                           startPosition.Y - _internalScrolling.Y,
                                           bounds.Left + startGlyph.TextChunk.Size.X - startPosition.X,
                                           lineHeight));

                ++lineIndex;
                if (lineIndex >= _formattedText.Lines.Count)
                {
                    break;
                }

                i = _formattedText.Lines[lineIndex].TextStartIndex;
            }
        }
Exemplo n.º 11
0
        private void UpdateScrolling()
        {
            var p = GetRenderPositionByIndex(CursorPosition);

            if (p == _lastCursorPosition)
            {
                return;
            }

            var asScrollViewer = Parent as ScrollViewer;

            Point sz, maximum;
            var   bounds = ActualBounds;

            if (asScrollViewer != null)
            {
                asScrollViewer.UpdateLayout();
                sz      = new Point(asScrollViewer.Bounds.Width, asScrollViewer.Bounds.Height);
                maximum = asScrollViewer.ScrollMaximum;
            }
            else
            {
                sz      = new Point(Bounds.Width, Bounds.Height);
                maximum = new Point(_formattedText.Size.X + CursorWidth - sz.X,
                                    _formattedText.Size.Y - sz.Y);

                if (maximum.X < 0)
                {
                    maximum.X = 0;
                }

                if (maximum.Y < 0)
                {
                    maximum.Y = 0;
                }
            }

            if (maximum == Point.Zero)
            {
                _internalScrolling  = Point.Zero;
                _lastCursorPosition = p;
                return;
            }

            p.X -= bounds.X;
            p.Y -= bounds.Y;

            var lineHeight = CrossEngineStuff.LineSpacing(_formattedText.Font);

            Point sp;

            if (asScrollViewer != null)
            {
                sp = asScrollViewer.ScrollPosition;
            }
            else
            {
                sp = _internalScrolling;
            }

            if (p.Y < sp.Y)
            {
                sp.Y = p.Y;
            }
            else if (p.Y + lineHeight > sp.Y + sz.Y)
            {
                sp.Y = p.Y + lineHeight - sz.Y;
            }

            if (p.X < sp.X)
            {
                sp.X = p.X;
            }
            else if (p.X + CursorWidth > sp.X + sz.X)
            {
                sp.X = p.X + CursorWidth - sz.X;
            }

            if (asScrollViewer != null)
            {
                asScrollViewer.ScrollPosition = sp;
            }
            else
            {
                if (sp.X < 0)
                {
                    sp.X = 0;
                }

                if (sp.X > maximum.X)
                {
                    sp.X = maximum.X;
                }

                if (sp.Y < 0)
                {
                    sp.Y = 0;
                }

                if (sp.Y > maximum.Y)
                {
                    sp.Y = maximum.Y;
                }

                _internalScrolling = sp;
            }

            _lastCursorPosition = p;
        }
Exemplo n.º 12
0
        public Point Measure(int?width)
        {
            var result = Point.Zero;

            var key = GetMeasureKey(width);

            if (_measures.TryGetValue(key, out result))
            {
                return(result);
            }

            if (!string.IsNullOrEmpty(_text))
            {
                var i = 0;
                var y = 0;

                var remainingWidth = width;
                var lineWidth      = 0;
                while (i < _text.Length)
                {
                    var chunkInfo = LayoutRow(i, remainingWidth, false);
                    if (i == chunkInfo.StartIndex && chunkInfo.CharsCount == 0)
                    {
                        break;
                    }

                    lineWidth += chunkInfo.X;
                    i          = chunkInfo.StartIndex + chunkInfo.CharsCount;

                    if (remainingWidth.HasValue)
                    {
                        remainingWidth = remainingWidth.Value - chunkInfo.X;
                    }

                    if (chunkInfo.LineEnd)
                    {
                        if (lineWidth > result.X)
                        {
                            result.X = lineWidth;
                        }

                        lineWidth      = 0;
                        remainingWidth = width;

                        y += chunkInfo.Y;
                        y += _verticalSpacing;
                    }
                }

                result.Y = y;
            }

            if (result.Y == 0)
            {
                result.Y = CrossEngineStuff.LineSpacing(_font);
            }

            _measures[key] = result;

            return(result);
        }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
0
        internal TextEditRow LayoutRow(int startIndex, int?width)
        {
            var r = new TextEditRow();

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

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

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

                _stringBuilder.Append(c);

                Vector2 sz = Vector2.Zero;

                if (c != '\n')
                {
                    sz = Font.MeasureString(_stringBuilder);
                }
                else
                {
                    sz = new Vector2(r.x1 + NewLineWidth, Math.Max(r.ymax, CrossEngineStuff.LineSpacing(_font)));
                }

                if (width != null && c == '\n')
                {
                    // Break right here
                    ++r.num_chars;
                    r.x1               = sz.X;
                    r.ymax             = sz.Y;
                    r.baseline_y_delta = sz.Y;
                    break;
                }

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

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

                    break;
                }

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

                ++r.num_chars;
                r.x1               = sz.X;
                r.ymax             = sz.Y;
                r.baseline_y_delta = sz.Y;
            }

            return(r);
        }
Exemplo n.º 15
0
        public override void InternalRender(RenderContext context)
        {
            if (_formattedText.Font == null)
            {
                return;
            }

            var bounds = ActualBounds;

            if (Selection != null && !string.IsNullOrEmpty(Text))
            {
                var selectStart = Math.Min(SelectStart, SelectEnd);
                var selectEnd   = Math.Max(SelectStart, SelectEnd);

                if (selectStart < selectEnd)
                {
                    //					Debug.WriteLine("{0} - {1}", selectStart, selectEnd);

                    var startGlyph = _formattedText.GetGlyphInfoByIndex(selectStart);
                    var lineIndex  = startGlyph.TextLine.LineIndex;
                    var i          = selectStart;

                    while (true)
                    {
                        startGlyph = _formattedText.GetGlyphInfoByIndex(i);
                        var startPosition = GetRenderPositionByIndex(i);

                        if (selectEnd < i + startGlyph.TextLine.Count)
                        {
                            var endPosition = GetRenderPositionByIndex(selectEnd);

                            context.Draw(Selection,
                                         new Rectangle(startPosition.X - _internalScrolling.X,
                                                       startPosition.Y - _internalScrolling.Y,
                                                       endPosition.X - startPosition.X,
                                                       CrossEngineStuff.LineSpacing(_formattedText.Font)));

                            break;
                        }

                        context.Draw(Selection,
                                     new Rectangle(startPosition.X - _internalScrolling.X,
                                                   startPosition.Y - _internalScrolling.Y,
                                                   bounds.Left + startGlyph.TextLine.Size.X - startPosition.X,
                                                   CrossEngineStuff.LineSpacing(_formattedText.Font)));

                        ++lineIndex;
                        if (lineIndex >= _formattedText.Strings.Length)
                        {
                            break;
                        }

                        i = 0;
                        for (var k = 0; k < lineIndex; ++k)
                        {
                            i += _formattedText.Strings[k].Count;
                        }
                    }
                }
            }

            var textColor = TextColor;

            if (!Enabled && DisabledTextColor != null)
            {
                textColor = DisabledTextColor.Value;
            }
            else if (IsKeyboardFocused && FocusedTextColor != null)
            {
                textColor = FocusedTextColor.Value;
            }

            var centeredBounds = LayoutUtils.Align(new Point(bounds.Width, bounds.Height), _formattedText.Size, HorizontalAlignment.Left, TextVerticalAlignment);

            centeredBounds.Offset(bounds.Location);

            var p = new Point(centeredBounds.Location.X - _internalScrolling.X,
                              centeredBounds.Location.Y - _internalScrolling.Y);

            _formattedText.Draw(context.Batch,
                                p,
                                context.View, textColor, context.Opacity);

            if (!IsKeyboardFocused)
            {
                // Skip cursor rendering if the widget doesnt have the focus
                return;
            }

            var now = DateTime.Now;

            if ((now - _lastBlinkStamp).TotalMilliseconds >= BlinkIntervalInMs)
            {
                _cursorOn       = !_cursorOn;
                _lastBlinkStamp = now;
            }

            if (Enabled && _cursorOn && Cursor != null)
            {
                p    = GetRenderPositionByIndex(CursorPosition);
                p.X -= _internalScrolling.X;
                p.Y -= _internalScrolling.Y;
                context.Draw(Cursor,
                             new Rectangle(p.X, p.Y,
                                           Cursor.Size.X,
                                           CrossEngineStuff.LineSpacing(_formattedText.Font)));
            }
        }
Exemplo n.º 16
0
        internal void Update()
        {
            if (!_dirty)
            {
                return;
            }

            if (!string.IsNullOrEmpty(_text))
            {
                var sz = _spriteFont.MeasureString(_text);
                _size = new Point((int)sz.X, (int)sz.Y);
#if MONOGAME
                var fontGlyphs = _spriteFont.GetGlyphs();

                var offset           = Vector2.Zero;
                var firstGlyphOfLine = true;

                for (var i = 0; i < _text.Length; ++i)
                {
                    SpriteFont.Glyph g;
                    fontGlyphs.TryGetValue(_text[i], out g);

                    // The first character on a line might have a negative left side bearing.
                    // In this scenario, SpriteBatch/SpriteFont normally offset the text to the right,
                    //  so that text does not hang off the left side of its rectangle.
                    if (firstGlyphOfLine)
                    {
                        offset.X         = Math.Max(g.LeftSideBearing, 0);
                        firstGlyphOfLine = false;
                    }
                    else
                    {
                        offset.X += _spriteFont.Spacing + g.LeftSideBearing;
                    }

                    var p = offset;

                    p += g.Cropping.Location.ToVector2();

                    var result = new Rectangle((int)p.X, (int)p.Y, (int)(g.Width + g.RightSideBearing), g.BoundsInTexture.Height);

                    _glyphs[i].Bounds = result;

                    offset.X += g.Width + g.RightSideBearing;
                }
#else
                var offset = Vector2.Zero;
                for (var i = 0; i < _text.Length; ++i)
                {
                    Vector2 v      = _spriteFont.MeasureString(_text[i].ToString());
                    var     result = new Rectangle((int)offset.X, (int)offset.Y, (int)v.X, (int)v.Y);

                    _glyphs[i].Bounds = result;

                    offset.X += v.X;
                }
#endif
            }
            else
            {
                _size = new Point(0, CrossEngineStuff.LineSpacing(_spriteFont));
            }

            _dirty = false;
        }
Exemplo n.º 17
0
        internal TextEditRow LayoutRow(int startIndex, int?width)
        {
            var r = new TextEditRow();

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

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

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

                _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 - 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);
        }
Exemplo n.º 18
0
        private void RenderSelection(RenderContext context)
        {
            var bounds = ActualBounds;

            if (string.IsNullOrEmpty(Text) || Selection == null)
            {
                return;
            }

            var selectStart = Math.Min(SelectStart, SelectEnd);
            var selectEnd   = Math.Max(SelectStart, SelectEnd);

            if (selectStart >= selectEnd)
            {
                return;
            }

            var startGlyph = _formattedText.GetGlyphInfoByIndex(selectStart);

            if (startGlyph == null)
            {
                return;
            }

            var lineIndex = startGlyph.TextLine.LineIndex;
            var i         = selectStart;

            while (true)
            {
                startGlyph = _formattedText.GetGlyphInfoByIndex(i);
                var startPosition = GetRenderPositionByIndex(i);

                if (selectEnd < i + startGlyph.TextLine.Count)
                {
                    var endPosition = GetRenderPositionByIndex(selectEnd);

                    context.Draw(Selection,
                                 new Rectangle(startPosition.X - _internalScrolling.X,
                                               startPosition.Y - _internalScrolling.Y,
                                               endPosition.X - startPosition.X,
                                               CrossEngineStuff.LineSpacing(_formattedText.Font)));

                    break;
                }

                context.Draw(Selection,
                             new Rectangle(startPosition.X - _internalScrolling.X,
                                           startPosition.Y - _internalScrolling.Y,
                                           bounds.Left + startGlyph.TextLine.Size.X - startPosition.X,
                                           CrossEngineStuff.LineSpacing(_formattedText.Font)));

                ++lineIndex;
                if (lineIndex >= _formattedText.Strings.Length)
                {
                    break;
                }

                i = 0;
                for (var k = 0; k < lineIndex; ++k)
                {
                    i += _formattedText.Strings[k].Count;
                }
            }
        }