Exemple #1
0
        public override void Paint(IntPtr hdc, ITextSegmentStyled textSegment, ITextView textView, TextSegmentVisualInfo info, int x, int y, int lineHeight, StyleRenderInfo sri)
        {
            if (staticBrushRed == null)
            {
                staticBrushRed = new SafeHandleGDI(SafeNativeMethods.CreateSolidBrush(ColorTranslator.ToWin32(Color.Red)));
            }

            var spaceSize = (lineHeight / 4d);

            var rectTop = new RECT
            {
                left   = x,
                top    = y,
                right  = x + (lineHeight / 8),
                bottom = (int)(y + (lineHeight - (spaceSize)))
            };

            var rectBottom = new RECT
            {
                left  = rectTop.left,
                top   = (int)(rectTop.bottom + (spaceSize / 2)),
                right = rectTop.right
            };

            rectBottom.bottom = (int)(rectBottom.top + (spaceSize / 2));

            SafeNativeMethods.FillRect(hdc, ref rectTop, staticBrushRed.DangerousGetHandle());
            SafeNativeMethods.FillRect(hdc, ref rectBottom, staticBrushRed.DangerousGetHandle());
        }
Exemple #2
0
        public override void Paint(IntPtr hdc, ITextSegmentStyled styledSegment, ITextView textView, TextSegmentVisualInfo info, int x, int y, int lineHeight, StyleRenderInfo sri)
        {
            //if (this._paintUnderline == null)
            //{
            //    this._paintUnderline = this.Settings.SpellcheckUnderlineEnabled; // Bridge.Get().GetSafe("Text.Style.Spellcheck.Underline.Enabled", true);
            //}

            if (textView.Settings.SpellcheckUnderlineEnabled == false)
            {
                return;
            }

            if (staticPenUnderline == null)
            {
                staticUnderlineColor = textView.Settings.ColorSpellcheckUnderline; // Bridge.Get().GetSafe("Text.Style.Spellcheck.Underline.Color", Color.Red);

                //int underlineType = Bridge.Get().GetSafe("Text.Style.Spellcheck.Underline.Type", (int) PenType.Dot);
                staticPenUnderline = new SafeHandleGDI(SafeNativeMethods.CreatePen((int)textView.Settings.SpellcheckUnderlineType, -1, ColorTranslator.ToWin32(staticUnderlineColor)));
            }

            var wordSize = styledSegment.Parent.GetSize(hdc, x, styledSegment.Index, styledSegment.GetLength(info.TextColumnIndex), info);

            var previousPen    = SafeNativeMethods.SelectObject(hdc, staticPenUnderline.DangerousGetHandle());
            var previousBkMode = SafeNativeMethods.SetBkMode(hdc, NativeConstants.TRANSPARENT);

            SafeNativeMethods.MoveToEx(hdc, x - wordSize.Width, y + lineHeight - 2, IntPtr.Zero);
            SafeNativeMethods.LineTo(hdc, x, y + lineHeight - 2);

            SafeNativeMethods.SelectObject(hdc, previousPen);
            SafeNativeMethods.SetBkMode(hdc, previousBkMode);
        }
Exemple #3
0
 public void Remove(ITextSegmentStyled segment)
 {
     for (var i = 0; i < this._items.Count; i++)
     {
         if (this._items[i].Segment == segment)
         {
             this._items.RemoveAt(i);
             break;
         }
     }
 }
Exemple #4
0
        public bool Add(ITextEditor textEditor, ITextSegmentStyled segment)
        {
            var newRsi = new RenderStateItem {
                Segment = segment
            };

            segment.Style.FillRenderStateItem(textEditor, newRsi);

            this._items.Add(newRsi);

            return(true);
        }
            public void AddManualTextSegment(ITextSegmentStyled segmentStyled, int index, int textColumnIndex)
            {
                var textAnchor = segmentStyled as TextAnchor;

                if (textAnchor.TextLine != null)
                {
                    textAnchor.TextLine = null;
                }

                var lineIndex = this.TextHandler.GetLineFromCharIndex(index, textColumnIndex);

                textAnchor.TextLine = this._lines[lineIndex];
            }
            public ITextSegmentStyled GetClosest(int index, string ofType)
            {
                ITextSegmentStyled closestMatch = null;
                var foundLineStartIndex         = -1;

                foreach (var textSegmentStyled in this.GetStyledTextSegments())
                {
                    if ((textSegmentStyled is TextAnchor) == false)
                    {
                        // This styled text segment is not an anchor, so we of course do not use it.
                        continue;
                    }

                    var anchor = (TextAnchor)textSegmentStyled;
                    if (ofType != null && anchor.Style.NameKey != ofType)
                    {
                        continue;
                    }

                    if (anchor.IndexGlobal > index)
                    {
                        if (foundLineStartIndex != -1 && foundLineStartIndex != anchor.TextLine.Index)
                        {
                            break;
                        }

                        continue;
                    }

                    if (closestMatch == null || anchor.IndexGlobal > closestMatch.IndexGlobal)
                    {
                        foundLineStartIndex = anchor.TextLine.Index;
                        closestMatch        = anchor;
                    }
                }

                return(closestMatch);
            }
Exemple #7
0
        private void SetFocusedStyleSegment(int globalIndex, bool fromMouse, int textColumIndex)
        {
            var previous = this._renderer.FocusedStyledSegment;

            ITextSegmentStyled focusedStyledSegment = null;

            foreach (var styledSegment in TextDocument.TextSegmentStyledManager.Get(globalIndex, textColumIndex))
            {
                if (styledSegment.CanExecute == false)
                {
                    continue;
                }

                if (focusedStyledSegment == null)
                {
                    focusedStyledSegment = styledSegment;
                }

                if (styledSegment.CanExecute)
                {
                    focusedStyledSegment = styledSegment;
                    break;
                }
            }

            this._renderer.FocusedStyledSegment = focusedStyledSegment;

            if (this._renderer.FocusedStyledSegment != previous)
            {
                if (fromMouse && this.ScrollHost.IsScrollingHorizontally == false && this.ScrollHost.IsScrollingVertically == false)
                {
                    Cursor = focusedStyledSegment == null ? Cursors.IBeam : Cursors.Hand;
                }

                Invalidate();
            }
        }
Exemple #8
0
 public virtual bool Execute(ITextSegmentStyled styledTextSegment)
 {
     return(false);
 }
Exemple #9
0
 public virtual void ShowInfo(ITextSegmentStyled textSegment)
 {
     //this.Settings.Notifier.Info("Not implemented yet. Will show some info.", "Text Anchor");
 }
Exemple #10
0
 public abstract void Paint(IntPtr hdc, ITextSegmentStyled textSegment, ITextView textView, TextSegmentVisualInfo info, int x, int y, int lineHeight, StyleRenderInfo sri);
        public override void Paint(IntPtr hdc, ITextSegmentStyled textSegment, ITextView textView,
                                   TextSegmentVisualInfo info, int x, int y, int lineHeight, StyleRenderInfo sri)
        {
            var index = (int)textSegment.Object;

            var allSegments = sri.Get <ITextSegmentStyled[]>("speaker.segments");

            if (allSegments == null)
            {
                allSegments = textView.TextDocument.TextSegmentStyledManager.GetStyledTextSegments(NameKey).ToArray();
                sri.Set("speaker.segments", allSegments);
            }

            Color color;

            if (index == -1)
            {
                // TODO: Figure out the current speaker's index

                foreach (var styledSegment in allSegments)
                {
                    var otherIndex = (int)styledSegment.Object;
                    if (otherIndex == -1)
                    {
                        index = index == 1 ? 2 : 1;
                    }
                    else
                    {
                        index = otherIndex;
                    }

                    if (styledSegment == textSegment)
                    {
                        // We've arrived at our own row, so let's abort now.
                        break;
                    }
                }
            }

            var fill = false;

            switch (index)
            {
            case 1:
                color = Color.WhiteSmoke;
                break;

            case 2:
                color = Color.FromArgb(242, 255, 22);
                break;

            case 3:
                color = Color.FromArgb(189, 189, 255);
                break;

            case 4:
                color = Color.FromArgb(178, 255, 159);
                break;

            case 5:
                color = Color.FromArgb(255, 189, 189);
                break;

            case -2:
                fill  = true;
                color = Color.FromArgb(255, 0, 0);
                break;

            default:
                color = Color.FromArgb(200, 200, 200);
                break;
            }

            if (fill)
            {
                var brush = new SafeHandleGDI(SafeNativeMethods.CreateSolidBrush(ColorTranslator.ToWin32(color)));

                var previousBrush  = SafeNativeMethods.SelectObject(hdc, brush.DangerousGetHandle());
                var previousBkMode = SafeNativeMethods.SetBkMode(hdc, NativeConstants.TRANSPARENT);

                var r = new RECT
                {
                    top    = y,
                    right  = textView.ClientSize.Width,
                    bottom = y + lineHeight,
                    left   = info.Size.Width + 10
                };

                SafeNativeMethods.FillRect(hdc, ref r, brush.DangerousGetHandle());

                SafeNativeMethods.SelectObject(hdc, previousBrush);
                SafeNativeMethods.SetBkMode(hdc, previousBkMode);
            }
            else
            {
                var pen = new SafeHandleGDI(SafeNativeMethods.CreatePen(NativeConstants.PS_SOLID, -1,
                                                                        ColorTranslator.ToWin32(color)));

                var previousPen    = SafeNativeMethods.SelectObject(hdc, pen.DangerousGetHandle());
                var previousBkMode = SafeNativeMethods.SetBkMode(hdc, NativeConstants.TRANSPARENT);

                SafeNativeMethods.MoveToEx(hdc, 1, y, IntPtr.Zero);
                SafeNativeMethods.LineTo(hdc, 1, y + lineHeight);

                SafeNativeMethods.MoveToEx(hdc, fill ? info.Size.Width : 2, y, IntPtr.Zero);
                SafeNativeMethods.LineTo(hdc, fill ? info.Size.Width : 2, y + lineHeight);

                SafeNativeMethods.SelectObject(hdc, previousPen);
                SafeNativeMethods.SetBkMode(hdc, previousBkMode);
            }
        }
            public void RemoveTextSegment(ITextSegmentStyled textSegment)
            {
                var textAnchor = (textSegment as TextAnchor);

                textAnchor.TextLine = null;
            }
            /// <summary>
            /// TODO: Make this threaded and make the text control not editable meanwhile
            /// </summary>
            public bool SearchAndApplyTo(ITextView textView, ITextSegment textSegment, int index, int length, bool changeWasFinalizer, int textColumnIndex)
            {
                var foundOne = false;
                var canSkip  = false;
                var previousWasWhitespace = false;

                var textLine = textSegment as TextLine;

                var    textStyles         = new List <TextStyleBase>(textView.GetTextStyles());
                string previousStyleType  = null;
                var    previousStyleIndex = -1;

                if (textLine == null)
                {
                    return(false);
                }

                for (var i = index; i <= index + length && i < textSegment.GetLength(textColumnIndex); i++)
                {
                    #region If whitespace found, enable word-jump-search and only search on first char per word

                    var isWhitespace = i < index + length && Char.IsWhiteSpace(textSegment.GetText(textColumnIndex)[i]);

                    if (canSkip)
                    {
                        if (isWhitespace == false)
                        {
                            if (previousWasWhitespace == false)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            previousWasWhitespace = true;
                            continue; // Don't need to search on a whitespace.
                        }
                    }
                    else if (isWhitespace)
                    {
                        canSkip = true;
                        previousWasWhitespace = true;
                        continue; // Don't need to search on a whitespace.
                    }

                    previousWasWhitespace = false;

                    #endregion

                    ITextSegmentStyled newStyledTextSegment = null;

                    for (var s = 0; s < textStyles.Count; s++)
                    {
                        if (textStyles[s].UpdateOnlyOnFinalizingChange && changeWasFinalizer == false)
                        {
                            continue;
                        }

                        newStyledTextSegment = textStyles[s].FindStyledTextSegment(textView, textSegment, this.TextHandler, i, -1, textColumnIndex);

                        if (newStyledTextSegment != null)
                        {
                            //textStyles.RemoveAt(s);
                            break;
                        }
                    }

                    if (newStyledTextSegment == null)
                    {
                        continue;
                    }

                    var found = false;

                    foreach (var existingStyle in GetAll(textLine, i, newStyledTextSegment.Style.NameKey))
                    {
                        if (existingStyle.Style.NameKey == newStyledTextSegment.Style.NameKey)
                        {
                            if (newStyledTextSegment.Index == existingStyle.Index && newStyledTextSegment.GetLength(textColumnIndex) == existingStyle.GetLength(textColumnIndex))
                            {
                                found = true;
                                break;
                            }
                            this.RemoveTextSegment(existingStyle);
                            break;
                        }
                    }

                    if (found == false)
                    {
                        foundOne = true;

                        // TODO: Make this line actually work. (NOTE: what did I mean here? ;D)
                        this.AddManualTextSegment(newStyledTextSegment, textLine.Index + newStyledTextSegment.Index, textColumnIndex);
                    }

                    if (previousStyleType != newStyledTextSegment.Style.NameKey && previousStyleIndex != newStyledTextSegment.Index)
                    {
                        // Decrease it so that we stay on the same location, in case there are several styles overlapping on the same spot.
                        i--;
                    }

                    previousStyleType  = newStyledTextSegment.Style.NameKey;
                    previousStyleIndex = newStyledTextSegment.Index;
                }

                return(foundOne);
            }
            public unsafe void Render(IntPtr hdc, int vpx, int vpy, Size size)
            {
                #region Initialize GDI resources

                if (this._brushCurrentLine == null)
                {
                    var colorWithoutTransparency = Color.FromArgb(this.TextView.LineHighlightColor.R, this.TextView.LineHighlightColor.G, this.TextView.LineHighlightColor.B);
                    this._brushCurrentLine = new SafeHandleGDI(SafeNativeMethods.CreateSolidBrush(ColorTranslator.ToWin32(colorWithoutTransparency)));
                }

                #endregion

                var styleSelection = this.TextView.GetTextStyle("Selection");
                var styleDefault   = this.TextView.GetTextStyle("Default");

                var rs = new RendererState(this.TextView.GetTextRectangle(false), this.TextView.LineHeight);
                rs.TextView    = this.TextView;
                rs.RenderState = new RenderState(this.TextView, styleDefault);
                rs.ViewportX   = vpx - rs.TextRectangle.Left;
                rs.ViewportY   = vpy;

                ITextSegmentStyled selectionSegment = null;
                ITextSegment       firstVisibleLine = null;

                //var foundActiveLine = this.TextView.LineHighlightColor.A == Color.Transparent.A || this.TextView.LineHighlightColor == Color.Empty;

                var textColumnIndex = this.TextView.CurrentTextColumnIndex;

                var sri = new StyleRenderInfo(this.FocusedStyledSegment);

                // TODO: Paint some nice graphics for the current text column index, when it is stable enough.
                var clientSize        = this.TextView.ClientSize;
                var lineCount         = this.Strategy.Lines.Count;
                var firstCharIndex    = this.TextView.GetFirstCharIndexFromLine(this.TextView.GetCurrentLine());
                var lineIndexPhysical = 0;
                for (rs.LineIndexPhysical = 0; rs.LineIndexPhysical < lineCount; lineIndexPhysical++, rs.LineIndexPhysical++)
                {
                    if (rs.Y > rs.ViewportY + size.Height)
                    {
                        // This line is after the viewport and does not need painting.
                        break;
                    }

                    rs.Line = this.Strategy.Lines[lineIndexPhysical];
                    var visualInfo      = this.TextView.GetVisualInformation(lineIndexPhysical);
                    var lineCountVisual = visualInfo.GetLineCountVisual(textColumnIndex);
                    var linesHeight     = lineCountVisual * rs.LineHeight;

                    if (rs.Y + linesHeight <= rs.ViewportY)
                    {
                        // This line is before the viewport.
                        rs.Y += linesHeight;
                        rs.LineIndexVirtual += lineCountVisual;
                        continue;
                    }

                    if (rs.Line.Index >= firstCharIndex && rs.Line.Index <= (this.TextView.SelectionStart + this.TextView.SelectionLength))
                    {
                        rs.LineIndexVirtualFocused = rs.LineIndexVirtual;

                        if (this.TextView.SelectionLength == 0)
                        {
                            this.RenderSelectedLineBackground(hdc, rs);
                        }
                    }

                    var textPoints = new Dictionary <int, List <ITextSegmentStyled> >();

                    if (firstVisibleLine == null)
                    {
                        firstVisibleLine = rs.Line;

                        #region Special handling for selection

                        if (this.TextView.SelectionLength > 0)
                        {
                            if (this.TextView.SelectionStart < rs.Line.Index && this.TextView.SelectionStart + this.TextView.SelectionLength >= rs.Line.Index)
                            {
                                // The selection begins on the line before this.
                                selectionSegment       = new TextAnchor(styleSelection);
                                selectionSegment.Index = firstVisibleLine.Index;

                                var textPointIndex = rs.Line.Index;
                                if (textPoints.ContainsKey(textPointIndex) == false)
                                {
                                    textPoints.Add(textPointIndex, new List <ITextSegmentStyled>());
                                }

                                textPoints[textPointIndex].Add(selectionSegment);
                            }
                        }

                        #endregion
                    }

                    var lineLength = rs.Line.GetLength(textColumnIndex);
                    if (this.TextView.SelectionLength > 0)
                    {
                        #region Special handling for selection

                        if (this.TextView.SelectionStart >= rs.Line.Index && this.TextView.SelectionStart <= rs.Line.Index + lineLength)
                        {
                            // The selection begins on this line.
                            selectionSegment       = new TextAnchor(styleSelection);
                            selectionSegment.Index = rs.Line.Index;
                            selectionSegment.SetLength(textColumnIndex, this.TextView.SelectionLength);

                            var textPointIndex = this.TextView.SelectionStart;
                            if (textPoints.ContainsKey(textPointIndex) == false)
                            {
                                textPoints.Add(textPointIndex, new List <ITextSegmentStyled>());
                            }

                            textPoints[textPointIndex].Add(selectionSegment);
                        }

                        if (this.TextView.SelectionStart + this.TextView.SelectionLength >= rs.Line.Index &&
                            this.TextView.SelectionStart + this.TextView.SelectionLength <= rs.Line.Index + lineLength)
                        {
                            // The selection ends on this line.
                            var textPointIndex = -(this.TextView.SelectionStart + this.TextView.SelectionLength);
                            if (textPoints.ContainsKey(textPointIndex) == false)
                            {
                                textPoints.Add(textPointIndex, new List <ITextSegmentStyled>());
                            }

                            textPoints[textPointIndex].Add(selectionSegment);
                        }

                        #endregion
                    }

                    var textLine = (TextLine)rs.Line;
                    if (textLine.StyledTextSegments != null && textLine.StyledTextSegments.Count > 0)
                    {
                        foreach (var textSegment in textLine.StyledTextSegments)
                        {
                            var textPointStartIndex = textLine.Index + textSegment.Index;
                            if (textPoints.ContainsKey(textPointStartIndex) == false)
                            {
                                textPoints.Add(textPointStartIndex, new List <ITextSegmentStyled>());
                            }

                            textPoints[textPointStartIndex].Add(textSegment);

                            var textPointEndIndex = -(textLine.Index + textSegment.Index + textSegment.GetLength(textColumnIndex));
                            if (textPoints.ContainsKey(textPointEndIndex) == false)
                            {
                                textPoints.Add(textPointEndIndex, new List <ITextSegmentStyled>());
                            }

                            textPoints[textPointEndIndex].Add(textSegment);
                        }
                    }

                    var wordWrapIndex = 0;
                    var tabIndex      = 0;
                    rs.X = 0;
                    var previousTextIndex = 0;
                    //var textLength = rs.Line.GetLength(textColumnIndex);
                    var lineSplitIndexes = visualInfo.GetLineSplitIndexes(textColumnIndex);
                    for (var textIndex = 0; textIndex <= lineLength; textIndex++)
                    {
                        var isLastIndex = textIndex == lineLength;

                        var isNewline = lineSplitIndexes != null;
                        if (isNewline)
                        {
                            isNewline = wordWrapIndex < lineSplitIndexes.Length && lineSplitIndexes[wordWrapIndex] == textIndex;

                            if (isNewline)
                            {
                                wordWrapIndex++;
                            }
                        }

                        var isTab = visualInfo.GetTabSplitIndexes(textColumnIndex) != null;
                        if (isTab)
                        {
                            isTab = tabIndex < visualInfo.GetTabSplitIndexes(textColumnIndex).Length&& visualInfo.GetTabSplitIndexes(textColumnIndex)[tabIndex] == textIndex;

                            if (isTab)
                            {
                                tabIndex++;
                            }
                        }

                        var globalIndex = rs.Line.Index + textIndex;
                        var styleStart  = textPoints.ContainsKey(globalIndex) ? textPoints[globalIndex] : null;
                        var styleEnd    = globalIndex != 0 && textPoints.ContainsKey(-globalIndex) ? textPoints[-globalIndex] : null;

                        if ((isLastIndex || isNewline || isTab || styleStart != null || styleEnd != null) == false)
                        {
                            // This is a regular character, and no change is done for it.
                            continue;
                        }

                        var start  = previousTextIndex;
                        var length = textIndex - start;

                        var outputText = rs.Line.GetText(textColumnIndex);

                        #region Add empty space at end of text if selection goes beyond current line

                        if (start + length == lineLength)
                        {
                            foreach (var rsi in rs.RenderState.GetRenderStateItems())
                            {
                                if (rsi.Segment.Style.NameKey != styleSelection.NameKey)
                                {
                                    continue;
                                }

                                if (styleEnd != null)
                                {
                                    var isStyleSelection = false;
                                    foreach (var se in styleEnd)
                                    {
                                        if (se.Style.NameKey == styleSelection.NameKey)
                                        {
                                            isStyleSelection = true;
                                            break;
                                        }
                                    }

                                    if (isStyleSelection)
                                    {
                                        break;
                                    }
                                }

                                outputText += " ";
                                length++;

                                break;
                            }
                        }

                        #endregion

                        fixed(char *c = outputText)
                        {
                            SafeNativeMethods.TextOut(hdc, rs.TextRectangle.Left + (rs.X - rs.ViewportX), rs.TextRectangle.Top + rs.Y - rs.ViewportY, c + start, length);

                            if ((isNewline == false && isLastIndex == false) || styleEnd != null)
                            {
                                rs.X += rs.Line.GetSize(hdc, rs.X, start, length, visualInfo.GetVisualInfo(textColumnIndex)).Width;
                            }

                            if (styleEnd != null)
                            {
                                foreach (var t in styleEnd)
                                {
                                    switch (t.Style.PaintMode)
                                    {
                                    case TextStylePaintMode.Custom:
                                    {
                                        t.Style.Paint(hdc, t, this.TextView, visualInfo.GetVisualInfo(textColumnIndex),
                                                      rs.TextRectangle.Left + (rs.X - rs.ViewportX),
                                                      rs.TextRectangle.Top + rs.Y - rs.ViewportY,
                                                      rs.LineHeight,
                                                      sri);
                                    }
                                    break;
                                    }
                                }
                            }
                        }

                        if (isNewline)
                        {
                            this.RenderLineColumns(hdc, clientSize, rs);
                            rs.X = 0;
                            rs.LineIndexVirtual++;
                            rs.Y += rs.LineHeight;
                        }

                        if (styleStart != null)
                        {
                            foreach (var t in styleStart)
                            {
                                rs.RenderState.Add(this.TextView, t);
                            }

                            rs.RenderState.Apply(hdc);
                        }

                        if (styleEnd != null)
                        {
                            foreach (var t in styleEnd)
                            {
                                rs.RenderState.Remove(t);
                            }

                            rs.RenderState.Apply(hdc);
                        }

                        previousTextIndex = textIndex;
                    }

                    if (this.TextView.WordWrapGlyphs && lineCountVisual > 1)
                    {
                        RenderWordWrapGlyph(hdc, rs.ViewportY, rs.Y, rs.TextRectangle, rs.LineHeight);
                    }

                    this.RenderLineColumns(hdc, clientSize, rs);
                    rs.X = 0;
                    rs.LineIndexVirtual++;
                    rs.Y += rs.LineHeight;
                }

                this.PaintTooltipOverlay(hdc);
            }
        /// <summary>
        ///
        /// </summary>
        /// <param name="textView"></param>
        /// <param name="textLine"></param>
        /// <param name="relativeIndex">Relative index is the index before the new character, so text[relativeIndex] is the <see cref="c"/>.</param>
        /// <param name="c"></param>
        /// <param name="alterTextStyleIndexes"></param>
        /// <param name="length"></param>
        /// <param name="textColumnIndex"></param>
        private void ModifyStyledTextSegments(ITextView textView, TextLine textLine, int relativeIndex, char c, bool alterTextStyleIndexes, int length, int textColumnIndex)
        {
            var isErase = c == '\0' && length <= 0;

            if (isErase)
            {
                length *= -1;
            }

            IEnumerable <ITextSegmentStyled> befores = null;
            IEnumerable <ITextSegmentStyled> afters  = null;

            var startSearch = Math.Max(0, relativeIndex - 1);

            const bool foundMatch = false;

            if (alterTextStyleIndexes)
            {
                var offsetCount = 0;
                for (var n = 0; n < textLine.StyledTextSegments.Count - offsetCount; n++)
                {
                    if (textLine.StyledTextSegments[n].Index > textLine.GetLength(textColumnIndex))
                    {
                        // The style starts after the end of the line, which is silly and should be filtered out.
                        textLine.StyledTextSegments[n].TextLine = null;
                        n--;
                    }
                    else if (isErase && textLine.StyledTextSegments[n].Style.Type == TextStyleType.Automatic && textLine.StyledTextSegments[n].Index >= relativeIndex && textLine.StyledTextSegments[n].Index + textLine.StyledTextSegments[n].GetLength(textColumnIndex) <= relativeIndex + length)
                    {
                        // The whole styled text segment was inside the removed range of text.
                        // It does not exist anymore and is automatically eligible for removing.
                        textLine.StyledTextSegments[n].TextLine = null;
                        n--;
                    }
                    else if (textLine.StyledTextSegments[n].Style.Type == TextStyleType.Automatic && textLine.StyledTextSegments[n].Contains(relativeIndex, length, isErase, true))
                    {
                        if (befores == null)
                        {
                            // This will search from the character before the change, the character before a new addition,
                            // or the character before the character that was removed.
                            befores = this.FindStyles(textView, textLine, startSearch, textColumnIndex);

                            // If a new addition, we search from the character after the change (so "pol<new space>ice" will search on "i" and not <new space>).
                            // When removing we only need to search from where the removal took place.
                            var afterSearchIdx = isErase == false?Math.Min(textLine.GetLength(textColumnIndex), startSearch + 2) : startSearch + 1;

                            afters = this.FindStyles(textView, textLine, afterSearchIdx, textColumnIndex);
                        }

                        var current = textLine.StyledTextSegments[n];

                        if (befores != null || afters != null)
                        {
                            ITextSegmentStyled before = null;
                            ITextSegmentStyled after  = null;

                            if (befores != null)
                            {
                                foreach (var b in befores)
                                {
                                    if (b.Style.NameKey == current.Style.NameKey)
                                    {
                                        before = b;
                                        break;
                                    }
                                }
                            }

                            if (afters != null)
                            {
                                foreach (var a in afters)
                                {
                                    if (a.Style.NameKey == current.Style.NameKey)
                                    {
                                        after = a;
                                        break;
                                    }
                                }
                            }

                            if (before == null)
                            {
                                if (after == null)
                                {
                                    // The styled text segment is no more since it is no longer found.
                                    current.TextLine = null;
                                    n--;
                                    continue;
                                }

                                before = after;
                                after  = null;
                            }
                            else if (after != null && before.Object != null && before.Object.Equals(after.Object))
                            {
                                after = null;
                            }

                            if (before.Index == current.Index && before.GetLength(textColumnIndex) == current.GetLength(textColumnIndex) &&
                                ((before.Object != null && before.Object.Equals(current.Object)) || before.Object == null && current.Object == null))
                            {
                                continue; // No change was done. Just don't do any changes.
                            }

                            //foundMatch = true;

                            if (before.Contains(current.Index, current.GetLength(textColumnIndex), true, true))
                            {
                                current.TextLine = null;
                                n--;
                            }

                            ((TextAnchor)before).TextLine = textLine;
                            offsetCount++;

                            if (after != null)
                            {
                                ((TextAnchor)after).TextLine = textLine;
                                offsetCount++;
                            }
                        }
                        else
                        {
                            // The styled text segment is no more since it is no longer found.
                            current.TextLine = null;
                            n--;
                        }
                    }
                    else if (textLine.StyledTextSegments[n].Index > relativeIndex)
                    {
                        if (isErase)
                        {
                            textLine.StyledTextSegments[n].Index -= length;
                        }
                        else
                        {
                            textLine.StyledTextSegments[n].Index += length;
                        }
                    }
                }
            }

            if (foundMatch == false)
            {
#if DEBUG
                var foundOne =
#endif
                this.TextSegmentStyledManager.SearchAndApplyTo(textView, textLine, startSearch, 1, CharacterIsFinalizer(c), textColumnIndex);
            }
        }
Exemple #16
0
 public StyleRenderInfo(ITextSegmentStyled selectedSegmentStyled)
 {
     this.SelectedTextSegment = selectedSegmentStyled;
 }