// <Snippet_TextPointer_GetNextContextPosition> // This method will extract and return a string that contains a representation of // the XAML structure of content elements in a given TextElement. string GetXaml(TextElement element) { StringBuilder buffer = new StringBuilder(); // Position a "navigator" pointer before the opening tag of the element. TextPointer navigator = element.ElementStart; while (navigator.CompareTo(element.ElementEnd) < 0) { switch (navigator.GetPointerContext(LogicalDirection.Forward)) { case TextPointerContext.ElementStart : // Output opening tag of a TextElement buffer.AppendFormat("<{0}>", navigator.GetAdjacentElement(LogicalDirection.Forward).GetType().Name); break; case TextPointerContext.ElementEnd : // Output closing tag of a TextElement buffer.AppendFormat("</{0}>", navigator.GetAdjacentElement(LogicalDirection.Forward).GetType().Name); break; case TextPointerContext.EmbeddedElement : // Output simple tag for embedded element buffer.AppendFormat("<{0}/>", navigator.GetAdjacentElement(LogicalDirection.Forward).GetType().Name); break; case TextPointerContext.Text : // Output the text content of this text run buffer.Append(navigator.GetTextInRun(LogicalDirection.Forward)); break; } // Advance the naviagtor to the next context position. navigator = navigator.GetNextContextPosition(LogicalDirection.Forward); } // End while. return buffer.ToString(); } // End GetXaml method.
/// <summary> /// Test if the text pointer is in a hyperlink /// </summary> /// <param name="pos"></param> /// <returns></returns> private bool searchHyperlink(TextPointer pos) { if (null == pos) { return(false); } TextPointerContext context = pos.GetPointerContext(LogicalDirection.Backward); if (TextPointerContext.ElementStart == context) { object elem = pos.GetAdjacentElement(LogicalDirection.Backward); if (elem is Hyperlink) { return(true); } } else if (TextPointerContext.ElementEnd == context) { object elem = pos.GetAdjacentElement(LogicalDirection.Backward); if (elem is Hyperlink) { return(false); } } // go backwards... TextPointer back = pos.GetNextContextPosition(LogicalDirection.Backward); return(searchHyperlink(back)); }
/// <summary> /// Gets a set of rectangles suitable for highlighting a TextRange /// </summary> /// <param name="range">Range to obtain highlight rects for</param> /// <param name="contentHost">Optional IContent host used to performance</param> /// <returns>A set of rectangles suitable for highlighting a TextRange</returns> public static IEnumerable <Rect> GetHighlightRectanglesWithContentHost( TextRange range, Func <TextRange, IEnumerable <Rect> > getRectanglesCore, IContentHost contentHost ) { if (getRectanglesCore == null) { throw new ArgumentNullException("getRectanglesCore"); } IEnumerable <Rect> result; if (contentHost == null) { result = getRectanglesCore(range); } else { result = new Rect[] { }; const LogicalDirection fwd = LogicalDirection.Forward; TextPointer current = range.Start; TextElement te = current.GetAdjacentElement(fwd) as TextElement; while (te != null && te.ContentEnd.CompareTo(range.End) >= 0) { if (current.CompareTo(te.ElementStart) < 0) { TextRange leadingRange = new TextRange(current, te.ElementStart); IEnumerable <Rect> leadingRects = getRectanglesCore(leadingRange); result = result.Concat(leadingRects); current = te.ElementStart; } if (contentHost != null) { result = result.Concat(contentHost.GetRectangles(te)); } current = te.ElementEnd; te = current.GetAdjacentElement(fwd) as TextElement; } TextRange trailingRange = new TextRange(current, range.End); IEnumerable <Rect> trailingRects = getRectanglesCore(trailingRange); result = result.Concat(trailingRects); } return(result); }
internal void IncreaseFontSizeCommandExecuted(object target, ExecutedRoutedEventArgs e) { RichTextBox rtb = target as RichTextBox; TextPointer selStart = rtb.Selection.Start; TextPointer selEnd = rtb.Selection.End; if (selStart.IsAtInsertionPosition) { // look for the largest styles between TextPointer startTagPointer = SeekEnclosingStartTag(selStart); if (null == startTagPointer) { return; // NOOP } object element = startTagPointer.GetAdjacentElement(LogicalDirection.Backward); if (element is UIElement) { UIElement uiElement = element as UIElement; } else if (element is TextElement) { TextElement textElement = element as TextElement; double size = textElement.FontSize; ChangeFontSize(selStart, size, selEnd, true); } else { return; // NOOP } } }
public static InlineUIContainer GetAdjacentUIContainer(this TextPointer caret, LogicalDirection direction) { var nextElement = caret.GetAdjacentElement(direction) as InlineUIContainer; var nextNextElement = caret.GetNextContextPosition(direction)?.GetAdjacentElement(direction) as InlineUIContainer; return(nextElement ?? nextNextElement); }
private static void PlainConvertListStart(TextPointer navigator, ref Stack <int> listItemCounter) { List adjacentElement = (List)navigator.GetAdjacentElement(LogicalDirection.Forward); if (listItemCounter == null) { listItemCounter = new Stack <int>(1); } listItemCounter.Push(0); }
private void ChangeFontSize(TextPointer currentPoint, double size, TextPointer endingPoint, bool increase) { // currentPoint can split text, but size is the text's size based on the enclosing tag // find the next position TextPointer next = currentPoint.GetNextContextPosition(LogicalDirection.Forward); //TextPointerContext nextCtx = currentPoint.GetPointerContext(LogicalDirection.Forward); int currentOffset = next.GetOffsetToPosition(endingPoint); TextPointer endOfApply = (currentOffset <= 0) ? endingPoint : next; // apply the style for this portion TextRange range = new TextRange(currentPoint, endOfApply); try { string text = currentPoint.GetTextInRun(LogicalDirection.Forward); double newSize = increase ? GetNextFontSize(size) : GetPreviousFontSize(size); range.ApplyPropertyValue(TextElement.FontSizeProperty, newSize); } catch (Exception) { // ignore return; } if (currentOffset <= 0) { return; // done } // what's next? object element = endOfApply.GetAdjacentElement(LogicalDirection.Forward); TextPointerContext ctx = endOfApply.GetPointerContext(LogicalDirection.Forward); if (element is UIElement) { UIElement uiElement = element as UIElement; } else if (element is TextElement) { TextElement textElement = element as TextElement; size = textElement.FontSize; ChangeFontSize(endOfApply, size, endingPoint, increase); } else { ChangeFontSize(endOfApply, size, endingPoint, increase); } return; // don't know what to do = done }
public static TextPointer GetTextPointerAtOffset(this RichTextBox richTextBox, int offset) { TextPointer navigator = richTextBox.Document.ContentStart; int count = 0; while (navigator.CompareTo(richTextBox.Document.ContentEnd) < 0) { switch (navigator.GetPointerContext(LogicalDirection.Forward)) { case TextPointerContext.ElementStart: break; case TextPointerContext.ElementEnd: if (navigator.GetAdjacentElement(LogicalDirection.Forward) is Paragraph) { count += 2; } break; case TextPointerContext.EmbeddedElement: count++; break; case TextPointerContext.Text: int runLength = navigator.GetTextRunLength(LogicalDirection.Forward); if (runLength > 0 && runLength + count < offset) { count += runLength; navigator = navigator.GetPositionAtOffset(runLength); if (count > offset) { break; } continue; } count++; break; } if (count > offset) { break; } navigator = navigator.GetPositionAtOffset(1, LogicalDirection.Forward); } return(navigator); }
/// <summary> /// Gets the text pointer at the given character offset. /// Each line break will count as 2 chars. /// </summary> public TextPointer GetTextPointerAtOffset(int offset, TextPointer navigator) { int cnt = 0; while (navigator.CompareTo(Document.ContentEnd) < 0) { switch (navigator.GetPointerContext(LogicalDirection.Forward)) { case TextPointerContext.ElementStart: break; case TextPointerContext.ElementEnd: if (navigator.GetAdjacentElement(LogicalDirection.Forward) is Paragraph) { cnt += 2; } break; case TextPointerContext.EmbeddedElement: // TODO: Find out what to do here? cnt++; break; case TextPointerContext.Text: int runLength = navigator.GetTextRunLength(LogicalDirection.Forward); if (runLength > 0 && runLength + cnt < offset) { cnt += runLength; navigator = navigator.GetPositionAtOffset(runLength); if (cnt > offset) { break; } continue; } cnt++; break; } if (cnt > offset) { break; } navigator = navigator.GetPositionAtOffset(1, LogicalDirection.Forward); } // End while. return(navigator); }
static IEnumerable <T> GetItemsInSelection <T>(this RichTextBox box) where T : class { for ( TextPointer i = box.Selection.Start; i != null && i.CompareTo(box.Selection.End) == -1; i = i.GetNextContextPosition(LogicalDirection.Forward) ) { DependencyObject element = i.GetAdjacentElement(LogicalDirection.Forward); if (element is T item) { yield return(item); } } }
// Token: 0x06006855 RID: 26709 RVA: 0x001D677C File Offset: 0x001D497C private TextPointer FindElementPosition(IInputElement e, bool isLimitedToTextView) { TextPointer textPointer = null; if (e is TextElement) { if ((e as TextElement).TextContainer == this._structuralCache.TextContainer) { textPointer = new TextPointer((e as TextElement).ElementStart); } } else { if (this._structuralCache.TextContainer.Start == null || this._structuralCache.TextContainer.End == null) { return(null); } TextPointer textPointer2 = new TextPointer(this._structuralCache.TextContainer.Start); while (textPointer == null && ((ITextPointer)textPointer2).CompareTo(this._structuralCache.TextContainer.End) < 0) { TextPointerContext pointerContext = textPointer2.GetPointerContext(LogicalDirection.Forward); if (pointerContext == TextPointerContext.EmbeddedElement) { DependencyObject adjacentElement = textPointer2.GetAdjacentElement(LogicalDirection.Forward); if ((adjacentElement is ContentElement || adjacentElement is UIElement) && (adjacentElement == e as ContentElement || adjacentElement == e as UIElement)) { textPointer = new TextPointer(textPointer2); } } textPointer2.MoveToNextContextPosition(LogicalDirection.Forward); } } if (textPointer != null && isLimitedToTextView) { this._textView = this.GetTextView(); Invariant.Assert(this._textView != null); for (int i = 0; i < ((ITextView)this._textView).TextSegments.Count; i++) { if (((ITextPointer)textPointer).CompareTo(((ITextView)this._textView).TextSegments[i].Start) >= 0 && ((ITextPointer)textPointer).CompareTo(((ITextView)this._textView).TextSegments[i].End) < 0) { return(textPointer); } } textPointer = null; } return(textPointer); }
private TextPointer _GetTextPositionAtOffset(TextPointer position, int characterCount) { // Console.WriteLine($"Character count {characterCount}"); while (position != null) { var type = position.GetPointerContext(LogicalDirection.Forward); string TypeName; //Console.WriteLine($"type:{type}"); var AdjacentElementF = position.GetAdjacentElement(LogicalDirection.Forward); if (AdjacentElementF != null) { TypeName = AdjacentElementF.GetType().Name; // Console.WriteLine($"element {TypeName}"); } else { TypeName = ""; } if (type == TextPointerContext.Text) { //Console.WriteLine("Text in run:" + position.GetTextInRun(LogicalDirection.Forward)); int count = position.GetTextRunLength(LogicalDirection.Forward); if (characterCount <= count) { return(position.GetPositionAtOffset(characterCount)); } characterCount -= count; } if (type == TextPointerContext.ElementEnd && (TypeName == "Paragraph" || TypeName == "LineBreak")) { //Console.WriteLine("Enter Count -- "); characterCount -= 2; } TextPointer nextContextPosition = position.GetNextContextPosition(LogicalDirection.Forward); if (nextContextPosition == null) { return(position); } position = nextContextPosition; } return(position); }
public static TextPointer GetEdgeTextPointer(this TextPointer position, LogicalDirection direction) { string pattern = @" ,;.!""?"; // Delimiters int step = direction == LogicalDirection.Forward ? 1 : -1; for (; position != null;) { var text = position.GetTextInRun(direction); int offset = 0; int i = direction == LogicalDirection.Forward ? 0 : text.Length - 1; for (; i >= 0 && i < text.Length; offset++, i += step) { if (pattern.Contains(text[i])) { return(position.GetPositionAtOffset(offset * step, LogicalDirection.Forward)); } } position = position.GetPositionAtOffset(offset * step, LogicalDirection.Forward); for (TextPointer latest = position; ;) { if ((position = position.GetNextContextPosition(direction)) == null) { return(latest); } var context = position.GetPointerContext(direction); var adjacent = position.GetAdjacentElement(direction); if (context == TextPointerContext.Text) { if (position.GetTextInRun(direction).Length > 0) { break; } } else if (context == TextPointerContext.ElementStart && adjacent is Paragraph) { return(latest); } } } return(position); }
public static TextPointer GetCharPositionOnLine(this TextPointer Start, int CharOx) { int rem = CharOx; TextPointer tp = Start; TextPointer charPos = null; while (true) { var pc = tp.GetPointerContext(LogicalDirection.Forward); // LineBreak element means the end of the text line. the element the pointer points to is a LineBreak element. This is an end of // the line. if (pc == TextPointerContext.ElementStart) { var elem = tp.GetAdjacentElement(LogicalDirection.Forward) as TextElement; if ((elem != null) && (elem is LineBreak)) { charPos = null; break; } } if (pc == TextPointerContext.Text) { var lx = tp.GetTextInRun(LogicalDirection.Forward).Length; if (rem > lx) { rem -= lx; } else { charPos = tp.GetPositionAtOffset(rem); break; } } // Advance to the next context position. tp = tp.GetNextContextPosition(LogicalDirection.Forward); } return(charPos); }
private static List <T> FindDependencyObjects <T>(TextPointer topPos, TextPointer bottomPos) where T : DependencyObject { var results = new List <T>(); while (topPos != null && topPos.CompareTo(bottomPos) <= 0) { DependencyObject depObj = topPos.GetAdjacentElement(LogicalDirection.Forward); if (depObj is T) { if (!results.Contains((T)depObj)) { results.Add((T)depObj); } } topPos = topPos.GetNextContextPosition(LogicalDirection.Forward); } return(results); }
private static void PlainConvertListItemStart(StringBuilder textBuffer, TextPointer navigator, ref Stack <int> listItemCounter) { if (navigator is TextPointer) { List parent = (List)((TextPointer)navigator).Parent; ListItem adjacentElement = (ListItem)navigator.GetAdjacentElement(LogicalDirection.Forward); if (listItemCounter == null) { listItemCounter = new Stack <int>(1); } if (listItemCounter.Count == 0) { listItemCounter.Push(Array.IndexOf(adjacentElement.SiblingListItems.ToArray <ListItem>(), adjacentElement)); } int item = listItemCounter.Pop(); int num2 = (parent != null) ? parent.StartIndex : 0; TextMarkerStyle listMarkerStyle = (parent != null) ? parent.MarkerStyle : TextMarkerStyle.Disc; WriteListMarker(textBuffer, listMarkerStyle, item + num2); item++; listItemCounter.Push(item); } }
private void _CollectRangeProperties(TextRange TargetRange) { if (TargetRange != null) { _rangeProperty.Clear(); var start = TargetRange.Start; var end = TargetRange.End; int targetlength = TargetRange.Text.Length; int totallength = 0; TextPointer current = start; int length = 0; while (current.CompareTo(end) < 0) { if (current.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text) { length = current.GetTextRunLength(LogicalDirection.Forward); totallength += length; if (totallength > targetlength) { length = targetlength - totallength + length; } var ad = current.GetAdjacentElement(LogicalDirection.Forward); var tempRange = new TextRange(current, current.GetPositionAtOffset(length, LogicalDirection.Forward)); var backgroundProperty = tempRange.GetPropertyValue(Run.BackgroundProperty); _rangeProperty.Add(tempRange, backgroundProperty); } var nextPos = current.GetNextContextPosition(LogicalDirection.Forward); if (nextPos.CompareTo(end) > 0) { break; } current = nextPos; } } }
void WriteOpenXML(TextPointer contentstart, TextPointer contentend, XmlWriter xmlwriter, XmlWriter numberingwriter) { TextElement textElement; _openxmlwriter = xmlwriter; _numberingwriter = numberingwriter; WriteOpenXmlHeader(); WriteNumberingHeader(); WriteNumberingBody(); _textpointer = contentstart; while (_textpointer.CompareTo(contentend) < 0) { TextPointerContext tpc = _textpointer.GetPointerContext(LogicalDirection.Forward); if (tpc == TextPointerContext.ElementStart) { TextPointer position; position = _textpointer; position = position.GetNextContextPosition(LogicalDirection.Forward); textElement = position.Parent as TextElement; if (textElement is Paragraph) { CloseTextRunTag(); CreateParagraphTag(); } else if (textElement is Inline) { CloseTextRunTag(); EnsureWithinParagraphTag(); CreateTextRunTag(); } else if (textElement is List) { //keep track of list levels (add) List lx = (List)textElement; TextMarkerStyle mst = (TextMarkerStyle)lx.GetValue(List.MarkerStyleProperty); listMarkerStyle[listLevel] = mst; listLevel++; if (listLevel > 29) { listLevel = 29; } } else if (textElement is ListItem) { listContext = 1; } } else if (tpc == TextPointerContext.ElementEnd) { textElement = _textpointer.Parent as TextElement; if (textElement is Inline) { CloseTextRunTag(); } else if (textElement is Paragraph) { CloseParagraphTag(); } else if (textElement is List) { //keep track of list levels (subtract) listLevel--; if (listLevel < 0) { listLevel = 0; } } else if (textElement is ListItem) { } } else if (tpc == TextPointerContext.Text) { CreateTextRunTag(); _openxmlwriter.WriteStartElement("w:t"); _openxmlwriter.WriteString(_textpointer.GetTextInRun(LogicalDirection.Forward)); _openxmlwriter.WriteEndElement(); } else if (tpc == TextPointerContext.EmbeddedElement) { DependencyObject obj = _textpointer.GetAdjacentElement(LogicalDirection.Forward); if (obj is LineBreak) { CreateTextRunTag(); _openxmlwriter.WriteStartElement("w:br"); _openxmlwriter.WriteEndElement(); } // other embedded objects here } _textpointer = _textpointer.GetNextContextPosition(LogicalDirection.Forward); }//end while CloseTextRunTag(); WriteNumberingFooter(); WriteOpenXmlFooter(); }
internal string GetTextInternal(TextPointer startPosition, TextPointer endPosition, ref char[] charArray) { StringBuilder textBuffer = new StringBuilder(); Stack <int> listItemCounter = null; TextPointer navigator = startPosition; Debug.Assert(startPosition.CompareTo(endPosition) <= 0, "expecting: startPosition <= endPosition"); while (navigator.CompareTo(endPosition) < 0) { Type elementType; int start = textBuffer.Length; TextPointer begin = navigator; switch (navigator.GetPointerContext(LogicalDirection.Forward)) { case TextPointerContext.Text: { PlainConvertTextRun(textBuffer, ref navigator, endPosition, ref charArray); Add(begin, navigator, start, textBuffer.Length); continue; } case TextPointerContext.EmbeddedElement: { textBuffer.Append(' '); navigator = navigator.GetNextContextPosition(LogicalDirection.Forward); Add(begin, navigator, start, textBuffer.Length); continue; } case TextPointerContext.ElementStart: { elementType = navigator.GetAdjacentElement(LogicalDirection.Forward).GetType(); if (!typeof(AnchoredBlock).IsAssignableFrom(elementType)) { if (typeof(List).IsAssignableFrom(elementType) && (navigator is TextPointer)) { PlainConvertListStart(navigator, ref listItemCounter); } else if (typeof(ListItem).IsAssignableFrom(elementType)) { PlainConvertListItemStart(textBuffer, navigator, ref listItemCounter); } else { PlainConvertAccessKey(textBuffer, navigator); } } //textBuffer.Append(Environment.NewLine); navigator = navigator.GetNextContextPosition(LogicalDirection.Forward); Add(begin, navigator, start, textBuffer.Length); continue; } case TextPointerContext.ElementEnd: { elementType = navigator.Parent.GetType(); if (!typeof(Paragraph).IsAssignableFrom(elementType) && !typeof(BlockUIContainer).IsAssignableFrom(elementType)) { break; } PlainConvertParagraphEnd(textBuffer, ref navigator); Add(begin, navigator, start, textBuffer.Length); continue; } default: Debug.Assert(false, "Unexpected value for TextPointerContext"); continue; } if (typeof(LineBreak).IsAssignableFrom(elementType)) { navigator = navigator.GetNextContextPosition(LogicalDirection.Forward); textBuffer.Append(Environment.NewLine); Add(begin, navigator, start, textBuffer.Length); } else if (typeof(List).IsAssignableFrom(elementType)) { PlainConvertListEnd(ref navigator, ref listItemCounter); Add(begin, navigator, start, textBuffer.Length); } else { navigator = navigator.GetNextContextPosition(LogicalDirection.Forward); } continue; } return(textBuffer.ToString()); }
/// <summary> /// Writes the container into the specified XmlWriter. /// </summary> private void WriteContainer(TextPointer start, TextPointer end, XmlWriter writer) { TextElement textElement; System.Diagnostics.Debug.Assert(start != null); System.Diagnostics.Debug.Assert(end != null); System.Diagnostics.Debug.Assert(writer != null); _writer = writer; WriteWordXmlHead(); _cursor = start; while (_cursor.CompareTo(end) < 0) { switch (_cursor.GetPointerContext(_dir)) { case TextPointerContext.None: System.Diagnostics.Debug.Assert(false, "Next symbol should never be None if cursor < End."); break; case TextPointerContext.Text: RequireOpenRange(); _writer.WriteStartElement(WordXmlSerializer.WordTextTag); _writer.WriteString(_cursor.GetTextInRun(_dir)); _writer.WriteEndElement(); break; case TextPointerContext.EmbeddedElement: DependencyObject obj = _cursor.GetAdjacentElement(LogicalDirection.Forward); if (obj is LineBreak) { RequireOpenRange(); _writer.WriteStartElement(WordXmlSerializer.WordBreakTag); _writer.WriteEndElement(); } // TODO: try to convert some known embedded objects. break; case TextPointerContext.ElementStart: TextPointer position; position = _cursor; position = position.GetNextContextPosition(LogicalDirection.Forward); textElement = position.Parent as TextElement; if (textElement is Paragraph) { RequireClosedRange(); RequireOpenParagraph(); } else if (textElement is Inline) { RequireClosedRange(); RequireOpenParagraph(); RequireOpenRange(); } break; case TextPointerContext.ElementEnd: textElement = _cursor.Parent as TextElement; if (textElement is Inline) { RequireClosedRange(); } else if (textElement is Paragraph) { RequireClosedParagraph(); } break; } _cursor = _cursor.GetNextContextPosition(_dir); } RequireClosedRange(); WriteWordXmlTail(); }
protected override void OnClick() { base.OnClick(); MainWindow mainWindow = (MainWindow)Application.Current.MainWindow; if (this.Parent != StackPanelRecentColor) { ColorButton colorButton = new ColorButton(CustomRichTextBox, GridProp, Brush, StackPanelRecentColor, DropButton, RectangleColor); if (mainWindow.RecentColorCollection.Count < 7) { StackPanelRecentColor.Children.Add(colorButton); mainWindow.RecentColorCollection.Add(colorButton); } else { mainWindow.RecentColorCollection.RemoveAt(0); mainWindow.RecentColorCollection.Add(colorButton); StackPanelRecentColor.Children.RemoveAt(0); StackPanelRecentColor.Children.Add(colorButton); } } RectangleColor.Fill = Brush; DropButton.IsOpen = false; if (GridProp == null) { TextPointer textPoint = CustomRichTextBox.CaretPosition; CustomRichTextBox.startTextPointer = null; CustomRichTextBox.endTextPointer = null; if (CustomRichTextBox.Selection.IsEmpty) { TextElement textElement = null; if (CustomRichTextBox.CaretPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.None) { CustomRichTextBox.IsCreateRunNull = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; return; } else if (CustomRichTextBox.CaretPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart) { textElement = (TextElement)CustomRichTextBox.CaretPosition.GetAdjacentElement(LogicalDirection.Backward); if (textElement is Paragraph) { CustomRichTextBox.IsCreateRunNull = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; return; } else if (textElement is ListItem) { CustomRichTextBox.IsCreateRunNull = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; return; } } else if (CustomRichTextBox.CaretPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementEnd) { textElement = (TextElement)CustomRichTextBox.CaretPosition.GetAdjacentElement(LogicalDirection.Backward); if (textElement is LineBreak) { CustomRichTextBox.IsCreateRunNull = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; return; } } if (textPoint.GetTextRunLength(LogicalDirection.Backward) > 0) // Если позади каретки в текстовом элементе есть текст { TextPointer textPointer = textPoint.GetNextContextPosition(LogicalDirection.Backward); Run run = (Run)textPointer.GetAdjacentElement(LogicalDirection.Backward); TextElement nextBackTextElement = (TextElement)run.ElementStart.GetAdjacentElement(LogicalDirection.Backward); int i = CustomRichTextBox.CaretPosition.GetTextRunLength(LogicalDirection.Backward); TextRange textRange = new TextRange(textPointer, CustomRichTextBox.CaretPosition); int index = textRange.Text.LastIndexOfAny(new char[] { ' ', ',', '.', '?', '!', ':', ';' }); if (index != -1) { if (textRange.Text[i - 1] != ' ' && textRange.Text[i - 1] != ',' && textRange.Text[i - 1] != '.' && textRange.Text[i - 1] != '?' && textRange.Text[i - 1] != '!' && textRange.Text[i - 1] != ':' && textRange.Text[i - 1] != ';') { CustomRichTextBox.startTextPointer = CustomRichTextBox.CaretPosition.GetPositionAtOffset(index + 1 - i); } else { CustomRichTextBox.startTextPointer = null; } } else { CustomRichTextBox.IsText = true; CustomRichTextBox.StartTextPointer(nextBackTextElement); } } else { CustomRichTextBox.IsTextNull = true; TextElement nextBackTextElement = (TextElement)CustomRichTextBox.CaretPosition.GetAdjacentElement(LogicalDirection.Backward); if (nextBackTextElement is Run) { nextBackTextElement = (TextElement)nextBackTextElement.ElementStart.GetAdjacentElement(LogicalDirection.Backward); } CustomRichTextBox.StartTextPointer(nextBackTextElement); } CustomRichTextBox.IsTextNull = false; CustomRichTextBox.IsText = false; if (textPoint.GetTextRunLength(LogicalDirection.Forward) > 0) // Если в текстовом элементе впереди каретки есть текст { TextPointer textPointer = textPoint.GetNextContextPosition(LogicalDirection.Forward); Run run = (Run)textPointer.GetAdjacentElement(LogicalDirection.Forward); TextElement nextForwardTextElement = (TextElement)run.ElementEnd.GetAdjacentElement(LogicalDirection.Forward); int i = CustomRichTextBox.CaretPosition.GetTextRunLength(LogicalDirection.Forward); TextRange textRange = new TextRange(CustomRichTextBox.CaretPosition, textPointer); int index = textRange.Text.IndexOfAny(new char[] { ' ', ',', '.', '?', '!', ':', ';' }); if (index != -1) { if (textRange.Text[0] != ' ' && textRange.Text[0] != ',' && textRange.Text[0] != '.' && textRange.Text[0] != '?' && textRange.Text[0] != '!' && textRange.Text[0] != ':' && textRange.Text[0] != ';') { CustomRichTextBox.endTextPointer = CustomRichTextBox.CaretPosition.GetPositionAtOffset(index); } else { CustomRichTextBox.endTextPointer = null; } } else { CustomRichTextBox.IsText = true; CustomRichTextBox.EndTextPointer(nextForwardTextElement); } } else { CustomRichTextBox.IsTextNull = true; TextElement nextForwardTextElement = (TextElement)CustomRichTextBox.CaretPosition.GetAdjacentElement(LogicalDirection.Forward); if (nextForwardTextElement is Run) { nextForwardTextElement = (TextElement)nextForwardTextElement.ElementEnd.GetAdjacentElement(LogicalDirection.Forward); } CustomRichTextBox.EndTextPointer(nextForwardTextElement); } CustomRichTextBox.IsText = false; CustomRichTextBox.IsTextNull = false; if (CustomRichTextBox.startTextPointer != null && CustomRichTextBox.endTextPointer != null) { TextRange textRange = new TextRange(CustomRichTextBox.startTextPointer, CustomRichTextBox.endTextPointer); textRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brush); } else { if (CustomRichTextBox.Run.Foreground is SolidColorBrush && Brush is SolidColorBrush) { SolidColorBrush runBrush = CustomRichTextBox.Run.Foreground as SolidColorBrush; SolidColorBrush newBrush = Brush as SolidColorBrush; if (runBrush.Color.A != newBrush.Color.A || runBrush.Color.B != newBrush.Color.B || runBrush.Color.G != newBrush.Color.G || runBrush.Color.R != newBrush.Color.R || runBrush.Color.ScA != newBrush.Color.ScA || runBrush.Color.ScB != newBrush.Color.ScB || runBrush.Color.ScG != newBrush.Color.ScG || runBrush.Color.ScR != newBrush.Color.ScR || runBrush.Opacity != newBrush.Opacity) { CustomRichTextBox.IsCreateRunColor = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; } else { CustomRichTextBox.IsCreateRunColor = false; } } else if (CustomRichTextBox.Run.Foreground is LinearGradientBrush && Brush is LinearGradientBrush) { LinearGradientBrush runBrush = CustomRichTextBox.Run.Foreground as LinearGradientBrush; LinearGradientBrush newBrush = Brush as LinearGradientBrush; int count = 0; if (runBrush.ColorInterpolationMode != newBrush.ColorInterpolationMode || runBrush.EndPoint != newBrush.EndPoint || runBrush.Opacity != newBrush.Opacity || runBrush.MappingMode != newBrush.MappingMode || runBrush.SpreadMethod != newBrush.SpreadMethod || runBrush.StartPoint != newBrush.StartPoint || runBrush.GradientStops.Count != newBrush.GradientStops.Count) { CustomRichTextBox.IsCreateRunColor = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; } else { GradientStop newGradientStop; foreach (GradientStop runGradientStop in runBrush.GradientStops) { newGradientStop = newBrush.GradientStops[count]; if (runGradientStop.Color.A != newGradientStop.Color.A || runGradientStop.Color.B != newGradientStop.Color.B || runGradientStop.Color.G != newGradientStop.Color.G || runGradientStop.Color.R != newGradientStop.Color.R || runGradientStop.Color.ScA != newGradientStop.Color.ScA || runGradientStop.Color.ScB != newGradientStop.Color.ScB || runGradientStop.Color.ScG != newGradientStop.Color.ScG || runGradientStop.Color.ScR != newGradientStop.Color.ScR) { CustomRichTextBox.IsCreateRunColor = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; return; } else { CustomRichTextBox.IsCreateRunColor = false; } count++; } } } else if (CustomRichTextBox.Run.Foreground is RadialGradientBrush && Brush is RadialGradientBrush) { RadialGradientBrush runBrush = CustomRichTextBox.Run.Foreground as RadialGradientBrush; RadialGradientBrush newBrush = Brush as RadialGradientBrush; int count = 0; if (runBrush.Center != newBrush.Center || runBrush.ColorInterpolationMode != newBrush.ColorInterpolationMode || runBrush.GradientOrigin != newBrush.GradientOrigin || runBrush.MappingMode != newBrush.MappingMode || runBrush.Opacity != newBrush.Opacity || runBrush.RadiusX != newBrush.RadiusX || runBrush.RadiusY != newBrush.RadiusY || runBrush.SpreadMethod != newBrush.SpreadMethod || runBrush.GradientStops.Count != newBrush.GradientStops.Count) { CustomRichTextBox.IsCreateRunColor = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; } else { GradientStop newGradientStop; foreach (GradientStop runGradientStop in runBrush.GradientStops) { newGradientStop = newBrush.GradientStops[count]; if (runGradientStop.Color.A != newGradientStop.Color.A || runGradientStop.Color.B != newGradientStop.Color.B || runGradientStop.Color.G != newGradientStop.Color.G || runGradientStop.Color.R != newGradientStop.Color.R || runGradientStop.Color.ScA != newGradientStop.Color.ScA || runGradientStop.Color.ScB != newGradientStop.Color.ScB || runGradientStop.Color.ScG != newGradientStop.Color.ScG || runGradientStop.Color.ScR != newGradientStop.Color.ScR) { CustomRichTextBox.IsCreateRunColor = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; return; } else { CustomRichTextBox.IsCreateRunColor = false; } count++; } } } else { CustomRichTextBox.IsCreateRunColor = true; CustomRichTextBox.CreateRunTextPointer = CustomRichTextBox.CaretPosition; } } } else { CustomRichTextBox.Selection.ApplyPropertyValue(TextElement.ForegroundProperty, Brush); } } else { GridProp.NewBrush = Brush; } }