예제 #1
0
        } // End GetTextBetweenPointers.
        // </Snippet_TextPointer_GetTextInRun>

        // <Snippet_TextPointer_IsInSameDocument>
        // This method first checks for compatible text container scope, and then checks whether
        // a specified position is between two other specified positions.
        bool IsPositionContainedBetween(TextPointer positionToTest, TextPointer start, TextPointer end)
        {
            // Note that without this check, an exception will be raised by CompareTo if positionToTest 
            // does not point to a position that is in the same text container used by start and end.
            //
            // This test also implicitly indicates whether start and end share a common text container.
            if (!positionToTest.IsInSameDocument(start) || !positionToTest.IsInSameDocument(end)) 
                return false;
            
            return start.CompareTo(positionToTest) <= 0 && positionToTest.CompareTo(end) <= 0;
        }
예제 #2
0
        public bool IsRichTextBoxEmpty(RichTextBox rtb)
        {
            if (rtb.Document.Blocks.Count == 0)
            {
                return(true);
            }
            TextPointer startPointer = rtb.Document.ContentStart.GetNextInsertionPosition(LogicalDirection.Forward);
            TextPointer endPointer   = rtb.Document.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);

            return(startPointer.CompareTo(endPointer) == 0);
        }
예제 #3
0
        void MoveRightByCharacter(object target, ExecutedRoutedEventArgs e)
        {
            TextPointer tp = CaretPosition;

            CommandBindings.Remove(cbright);
            EditingCommands.MoveRightByCharacter.Execute(null, this);
            CommandBindings.Add(cbright);
            if (tp.CompareTo(CaretPosition) == 0)
            {
                RaiseEvent(new RoutedEventArgs(MoveToNextColumn));
            }
        }
 /// <summary>
 /// Find all matches of the input string.
 /// </summary>
 /// <param name="input">The string to search for a match.</param>
 /// <param name="findOptions">the search options</param>
 /// <returns>The <see cref="TextRange"/> instance representing the input string.</returns>
 /// <remarks>
 /// This method will advance the <see cref="CurrentPosition"/> to next context position.
 /// </remarks>
 public IEnumerable <TextRange> FindAll(String input, FindOptions findOptions)
 {
     while (currentPosition.CompareTo(inputTextRange.End) < 0)
     {
         TextRange textRange = FindNext(input, findOptions);
         if (textRange != null && !String.IsNullOrEmpty(textRange.Text))
         {
             Console.WriteLine(textRange.Text);
             yield return(textRange);
         }
     }
 }
예제 #5
0
 // <Snippet_TextPointer_GetInsertionPosition>
 // Tests to see if the specified TextElement is empty (has no printatble content).
 bool IsElementEmpty(TextElement element)
 {
     // Find starting and ending insertion positions in the element.
     // Inward-facing directions are used to make sure that insertion position
     // will be found correctly in case when the element may contain inline 
     // formatting elements (such as a Span or Run that contains Bold or Italic elements).
     TextPointer start = element.ContentStart.GetInsertionPosition(LogicalDirection.Forward);
     TextPointer end = element.ContentEnd.GetInsertionPosition(LogicalDirection.Backward);
      
     // The element has no printable content if its first and last insertion positions are equal.
     return start.CompareTo(end) == 0;
 } // End IsEmptyElement method.
예제 #6
0
        private static TextPointer GetPositionAtTextOffset(TextPointer source, int count)
        {
            // this function might be slow if we have to travers across meny blocks,
            // might be an idea to save positions and counts so you can later check them first
            // so you don't have to recalculate large numbers

            var res = source;

            TextPointer lastPoint = null;

            // we simly travers the textpoint untill we count reaches 0
            while (res != null && count > 0)
            {
                if (lastPoint != null && lastPoint.CompareTo(res) == 0)
                {
                    break;
                }
                lastPoint = res;
                int length = res.GetTextRunLength(LogicalDirection.Forward);
                // If it's within the run we just jump to the position
                if (count <= length)
                {
                    res = res.GetPositionAtOffset(count);
                    break;
                }
                else
                {
                    // Otherwise we jump across the run and get to the next position
                    count -= length;
                    res    = res.GetPositionAtOffset(length);
                    res    = res.GetInsertionPosition(LogicalDirection.Forward);
                    // To check if we exit an paragraph
                    var lastPara = res.Paragraph;
                    if (res.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd)
                    {
                        res = res.GetPositionAtOffset(2, LogicalDirection.Forward);
                        // if we enter a new paragraph, count up by two
                        // res might be null if we reach the end of the document
                        if (res != null && lastPara != res.Paragraph)
                        {
                            count -= 2;
                        }
                    }
                }
            }
            // Make sure we return either null or a InsertionPosition
            if (res != null && !res.IsAtInsertionPosition)
            {
                res = res.GetNextInsertionPosition(LogicalDirection.Forward);
            }
            return(res);
        }
예제 #7
0
        public static List <DependencyObject> GetUserControls(TextPointer start, TextPointer end)
        {
            List <DependencyObject> list = new List <DependencyObject>();

            for (TextPointer pointer = start; pointer.CompareTo(end) < 0; pointer = pointer.GetNextContextPosition(LogicalDirection.Forward))
            {
                if (((pointer.Parent is BlockUIContainer) || (pointer.Parent is InlineUIContainer)) && !list.Contains(pointer.Parent))
                {
                    list.Add(pointer.Parent);
                }
            }
            return(list);
        }
예제 #8
0
        public static int GetLineForTextPointer(this RichTextBox rtb, TextPointer tp)
        {
            TextPointer tpLine = tp.GetLineStartPosition(0);
            int         lineNr = 1;

            for (TextPointer linePointer = rtb.Document.ContentStart.GetLineStartPosition(0);
                 linePointer.CompareTo(tpLine) < 0; linePointer = linePointer.GetLineStartPosition(1))
            {
                lineNr++;
            }

            return(lineNr);
        }
        private static TextPointer GetCaretPosition(TextPointer lhs, TextPointer rhs)
        {
            if (lhs == null)
            {
                return(rhs);
            }
            if (rhs == null)
            {
                return(lhs);
            }

            return(lhs.CompareTo(rhs) > 0 ? lhs : rhs);
        }
예제 #10
0
        public static int GetColumnForTextPointer(this RichTextBox rtb, TextPointer tp)
        {
            TextPointer tpColumn = tp.GetInsertionPosition(LogicalDirection.Backward);
            int         columnNr = 1;

            for (TextPointer linePointer = tpColumn.GetLineStartPosition(0).GetNextInsertionPosition(LogicalDirection.Forward);
                 linePointer.CompareTo(tpColumn) < 0; linePointer = linePointer.GetNextInsertionPosition(LogicalDirection.Forward))
            {
                columnNr++;
            }

            return(columnNr);
        }
예제 #11
0
        private void DocumentEditor_SelectionChanged(object sender, RoutedEventArgs e)
        {
            TextPointer ls   = CaretPosition.GetLineStartPosition(0);
            TextPointer p    = Document.ContentStart.GetLineStartPosition(0);
            int         @int = 1;
            int         int2 = 1;

            while (true)
            {
                if (ls.CompareTo(p) < 1)
                {
                    break;                     // TODO: might not be correct. Was : Exit While
                }
                int r = 0;
                p = p.GetLineStartPosition(1, out r);
                if (r == 0)
                {
                    break;                     // TODO: might not be correct. Was : Exit While
                }
                @int += 1;
            }
            TextPointer ls2 = Document.ContentStart.DocumentEnd.GetLineStartPosition(0);
            TextPointer p2  = Document.ContentEnd.DocumentStart.GetLineStartPosition(0);

            while (true)
            {
                if (ls2.CompareTo(p2) < 1)
                {
                    break;                     // TODO: might not be correct. Was : Exit While
                }
                int r = 0;
                p2 = p2.GetLineStartPosition(1, out r);
                if (r == 0)
                {
                    break;                     // TODO: might not be correct. Was : Exit While
                }
                int2 += 1;
            }
            SelectedLineNumber = @int;
            LineCount          = int2;
            TextRange   t                   = new TextRange(Document.ContentStart, Document.ContentEnd);
            TextPointer caretPos            = CaretPosition;
            TextPointer poi                 = CaretPosition.GetLineStartPosition(0);
            int         currentColumnNumber = Math.Max(p.GetOffsetToPosition(caretPos) - 1, 0) + 1;
            int         currentColumnCount  = currentColumnNumber;

            currentColumnCount  += CaretPosition.GetTextRunLength(System.Windows.Documents.LogicalDirection.Forward);
            SelectedColumnNumber = currentColumnNumber;
            ColumnCount          = currentColumnCount;
        }
예제 #12
0
        void MoveUpByLineExecuted(object target, ExecutedRoutedEventArgs e)
        {
            TextPointer tp = CaretPosition;
            Rect        r  = CaretPosition.GetCharacterRect(LogicalDirection.Forward);

            CommandBindings.Remove(cbup);
            EditingCommands.MoveUpByLine.Execute(null, this);
            CommandBindings.Add(cbup);
            if (tp.CompareTo(CaretPosition) == 0)
            {
                MoveToLiveEventArgs l = new MoveToLiveEventArgs(MyEdit.MoveToPrevLine, r);
                RaiseEvent(l);
            }
        }
예제 #13
0
        /// <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);
        }
예제 #14
0
        /// <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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        public static TextPointer Highlight(FlowDocument flowDoc, TextPointer start, TextPointer end)
        {
            if (start.CompareTo(flowDoc.ContentStart) == 0)
            {
                brackets.Clear();
            }

            // this is SO SLOW
            //TextRange documentRange = new TextRange(start, end);
            //documentRange.ClearAllProperties();

            TextPointer tpointer = start;

            while (tpointer.CompareTo(end) != 0)
            {
                String      s    = tpointer.GetTextInRun(LogicalDirection.Forward);
                TextPointer next = tpointer.GetPositionAtOffset(1);
                if (s.Length != 0)
                {
                    if (s[0] == '(' || s[0] == '[' || s[0] == '{')
                    {
                        Tag t = new Tag();
                        t.StartPosition = tpointer;
                        t.EndPosition   = tpointer.GetPositionAtOffset(1);
                        t.Word          = s[0].ToString();
                        brackets.Push(t);
                    }
                    else if (s[0] == ')' || s[0] == ']' || s[0] == '}')
                    {
                        if (brackets.Count > 0)
                        {
                            Tag         left    = brackets.Pop();
                            Boolean     matched = rightVariant(left.Word) == s[0].ToString();
                            TextPointer tpS     = tpointer;
                            TextPointer tpE     = tpointer.GetPositionAtOffset(1);
                            colorizeBracket(left.StartPosition, left.EndPosition, matched);
                            colorizeBracket(tpS, tpE, matched);
                        }
                        else
                        {
                            colorizeBracket(tpointer, tpointer.GetPositionAtOffset(1), false);
                        }
                    }
                }
                tpointer = next;
            }

            return(tpointer);
        }
예제 #17
0
        public void TextPointersAreSnapshots()
        {
            TextSelection ts = rtb.Selection;

            ts.Text = "Moon";

            rtb.SelectAll();

            TextPointer start = ts.Start;
            TextPointer end   = ts.End;

            ts.Select(ts.Start.GetPositionAtOffset(1, LogicalDirection.Backward), ts.End.GetPositionAtOffset(-1, LogicalDirection.Forward));
            Assert.AreEqual(-1, start.CompareTo(ts.Start), "#1");
            Assert.AreEqual(1, end.CompareTo(ts.End), "#2");
        }
예제 #18
0
        public void TextPointerContentEndAfterInsert()
        {
            Paragraph p = new Paragraph();
            Run       r = new Run();

            p.Inlines.Add(r);

            rtb.Blocks.Add(p);

            TextPointer tp = r.ContentEnd;

            r.Text = "Moonlight";

            Assert.AreEqual(0, tp.CompareTo(r.ContentEnd), "#0");
        }
예제 #19
0
 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);
         }
     }
 }
        internal override Rect[] GetCharacterRects(TextPointer startPointer, TextPointer endPointer)
        {
            if (!invalidatedCache && cachedStartP != null && startPointer.CompareTo(cachedStartP) == 0)
            {
                return(cachedRects);
            }
            else
            {
                cachedRects      = base.GetCharacterRects(startPointer, endPointer);
                cachedStartP     = startPointer;
                invalidatedCache = false;
            }

            return(cachedRects);
        }
예제 #21
0
        // </Snippet_TextPointer_GetPositionAtOffset>

        // <Snippet_TextPointer_GetTextInRun>
        // Returns a string containing the text content between two specified TextPointers.
        string GetTextBetweenTextPointers(TextPointer start, TextPointer end)
        {
            StringBuilder buffer = new StringBuilder();
         
            while (start != null && start.CompareTo(end) < 0)
            {
                if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
                    buffer.Append(start.GetTextInRun(LogicalDirection.Forward));
         
                // Note that when the TextPointer points into a text run, this skips over the entire
                // run, not just the current character in the run.
                start = start.GetNextContextPosition(LogicalDirection.Forward);
            }
            return buffer.ToString();
        } // End GetTextBetweenPointers.
예제 #22
0
        private static IEnumerable <TextElement> GetRunsAndParagraphs(FlowDocument doc)
        {
            for (TextPointer position = doc.ContentStart;
                 position != null && position.CompareTo(doc.ContentEnd) <= 0;
                 position = position.GetNextContextPosition(LogicalDirection.Forward))
            {
                if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd &&
                    (position.Parent is Run || position.Parent is Paragraph))
                {
                    yield return((TextElement)position.Parent);
                }
            }

            yield break;
        }
예제 #23
0
        public TextPointer GetTextPointer(int charOffset, bool reset = false)
        {
            if (reset)
            {
                ResetToStart();
            }

            while (CurrentPosition.CompareTo(EndOfDocument) < 0)
            {
                switch (CurrentPosition.GetPointerContext(LogicalDirection.Forward))
                {
                case TextPointerContext.ElementEnd: {
                    DependencyObject d = this.CurrentPosition.GetAdjacentElement(LogicalDirection.Forward);
                    if (d is Paragraph || d is LineBreak)
                    {
                        CurrentCharacterOffset += 2;
                    }
                    if (d is InlineUIContainer)
                    {
                        CurrentCharacterOffset += 1;
                    }
                    break;
                }

                case TextPointerContext.Text: {
                    int characterInCurrentRun = CurrentCharacterOffset + CurrentPosition.GetTextRunLength(LogicalDirection.Forward);

                    if (charOffset <= characterInCurrentRun)
                    {
                        int offset = charOffset - CurrentCharacterOffset;

                        return(CurrentPosition.GetPositionAtOffset(offset, LogicalDirection.Forward));
                    }

                    CurrentCharacterOffset = characterInCurrentRun;
                    break;
                }
                }
                CurrentPosition = CurrentPosition.GetNextContextPosition(LogicalDirection.Forward);
            }

            if (CurrentCharacterOffset != 0 && charOffset <= CurrentCharacterOffset)
            {
                return(EndOfDocument.GetNextInsertionPosition(LogicalDirection.Backward));
            }

            return(EndOfDocument);
        }
        /// <summary>
        /// 根据搜索选项在文档中查找并替换全部匹配字串
        /// </summary>
        /// <param name="input">要查找的字串</param>
        /// <param name="replacement">用于替换的字串</param>
        /// <param name="findOptions">搜索选项 </param>
        /// <returns>进行了替换的次数</returns>
        /// <remarks>
        /// 此方法将移动文字指针到最后位置
        /// </remarks>
        public int ReplaceAll(String input, String replacement, FindOptions findOptions)
        {
            int count = 0;

            currentPosition = inputDocument.ContentStart;
            while (currentPosition.CompareTo(inputDocument.ContentEnd) < 0)
            {
                TextRange textRange = Replace(input, replacement, findOptions);
                if (textRange != null)
                {
                    count++;
                }
            }

            return(count);
        }
예제 #25
0
        private static int GetCharOffsetToPosition(BlockCollection blockCollection, TextPointer position, out TextPointer result)
        {
            int offset = 0;

            foreach (var block in blockCollection)
            {
                offset += GetCharOffsetToPosition(block, position, out result);
                if (result == null || result.CompareTo(position) >= 0)
                {
                    return(offset);
                }
            }

            result = null;
            return(offset);
        }
예제 #26
0
        private static int GetCharOffsetToPosition(ListItemCollection listItemCollection, TextPointer position, out TextPointer result)
        {
            int offset = 0;

            foreach (var listItem in listItemCollection)
            {
                offset += GetCharOffsetToPosition(listItem, position, out result);
                if (result == null || result.CompareTo(position) >= 0)
                {
                    return(offset);
                }
            }

            result = null;
            return(offset);
        }
예제 #27
0
        // </Snippet_TextPointer_GetOffsetToPosition>

        // <Snippet_TextPointer_GetOffsetToPosition2>
        // Calculate and return the relative balance of opening and closing element tags
        // between two specified TextPointers.
        int GetElementTagBalance(TextPointer start, TextPointer end)
        {
            int balance = 0;
         
            while (start != null && start.CompareTo(end) < 0)
            {
                TextPointerContext forwardContext = start.GetPointerContext(LogicalDirection.Forward);
         
                if (forwardContext == TextPointerContext.ElementStart)     balance++;
                else if (forwardContext == TextPointerContext.ElementEnd)  balance--;
                     
                start = start.GetNextContextPosition(LogicalDirection.Forward);
            } // End while.
         
            return balance;
        } // End GetElementTagBalance
예제 #28
0
        public void Highlight(string regexStr)
        {
            Text = Text; //clean

            var         regex     = CreateRegex(regexStr);
            TextPointer navigator = tbxRich.Document.ContentStart;

            while (navigator.CompareTo(tbxRich.Document.ContentEnd) < 0)
            {
                TextPointerContext context = navigator.GetPointerContext(LogicalDirection.Backward);
                if (context == TextPointerContext.ElementStart && navigator.Parent is Run)
                {
                    HighlightRun((Run)navigator.Parent, regex);
                }
                navigator = navigator.GetNextContextPosition(LogicalDirection.Forward);
            }
        }
예제 #29
0
        private static bool IsRichTextBoxEmpty(RichTextBox richTextBox)
        {
            // Taken from:
            // https://stackoverflow.com/a/5825644/10018492
            // May need to be adapted a little bit, but for now, this seems to do what it's
            // supposed to do.
            if (richTextBox.Document.Blocks.Count == 0)
            {
                return(true);
            }
            TextPointer contentStart = richTextBox.Document.ContentStart;
            TextPointer contentEnd   = richTextBox.Document.ContentEnd;
            TextPointer startPointer = contentStart.GetNextInsertionPosition(LogicalDirection.Forward);
            TextPointer endPointer   = contentEnd.GetNextInsertionPosition(LogicalDirection.Backward);

            return(startPointer.CompareTo(endPointer) == 0);
        }
예제 #30
0
 private TextPointer GetPointer(TextPointer docEnd, TextPointer startPointer, int offset)
 {
     try
     {
         int findEnd = offset, textLength = 0;
         while (startPointer != null && docEnd.CompareTo(startPointer) > -1)
         {
             while (startPointer != null && startPointer.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
             {
                 TextPointerContext context = startPointer.GetPointerContext(LogicalDirection.Forward);
                 if (context == TextPointerContext.ElementEnd)
                 {
                     var next = startPointer.GetNextContextPosition(LogicalDirection.Forward);
                     if (next != null && next.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd)
                     {
                         textLength  += 2;
                         offset      -= 2;
                         startPointer = next;
                     }
                 }
                 startPointer = startPointer.GetNextContextPosition(LogicalDirection.Forward);
             }
             if (startPointer == null)
             {
                 return(docEnd);
             }
             var len = startPointer.GetTextRunLength(LogicalDirection.Forward);
             if (textLength + len < findEnd)
             {
                 textLength  += len;
                 offset      -= len;
                 startPointer = startPointer.GetNextContextPosition(LogicalDirection.Forward);
             }
             else
             {
                 break;
             }
         }
         var tp = startPointer.GetPositionAtOffset(offset, LogicalDirection.Forward);
         return(tp);
     }
     catch (Exception ex)
     {
         throw ex;
     }
 }