예제 #1
0
 private string FindBreak(TextPointer pointer)
 {
     Rect rectAtStart = pointer.GetCharacterRect(LogicalDirection.Forward);
     pointer = pointer.GetNextInsertionPosition(LogicalDirection.Forward);
     Rect currentRect = pointer.GetCharacterRect(LogicalDirection.Forward);
     while (currentRect.Bottom == rectAtStart.Bottom)
     {
         pointer = pointer.GetNextInsertionPosition(LogicalDirection.Forward);
         currentRect = pointer.GetCharacterRect(LogicalDirection.Forward);
     }
     string textBeforeBreak = pointer.GetTextInRun(LogicalDirection.Backward);
     string textAfterBreak = pointer.GetTextInRun(LogicalDirection.Forward);
     return textAfterBreak;
 }
예제 #2
0
        private List <string> get_elements_in_string(TextPointer tp_start, TextPointer tp_end, Color color)
        {
            //获取选择区域内部指定颜色的所有单词和短语

            List <string> dc_list        = new List <string>();
            TextPointer   tp1            = tp_start;
            TextPointer   tp2            = tp1.GetNextInsertionPosition(LogicalDirection.Forward);
            string        color_mode_str = color.ToString();
            string        color_select_str;

            while (tp1 != tp_end)
            {
                if (tp2 == null)
                {
                    break;
                }
                TextRange range_char = new TextRange(tp1, tp2);
                color_select_str = range_char.GetPropertyValue(TextElement.ForegroundProperty).ToString();
                if (color_select_str == color_mode_str)
                {
                    TextPointer tp_dc_start = tp1;
                    TextPointer tp_dc_end;
                    while (color_select_str == color_mode_str)
                    {
                        tp1 = tp2;
                        tp2 = tp1.GetNextInsertionPosition(LogicalDirection.Forward);
                        if (tp2 == null)
                        {
                            break;
                        }
                        range_char       = new TextRange(tp1, tp2);
                        color_select_str = range_char.GetPropertyValue(TextElement.ForegroundProperty).ToString();
                    }

                    tp_dc_end = tp1;
                    TextRange range_word = new TextRange(tp_dc_start, tp_dc_end);
                    string    word       = range_word.Text;
                    dc_list.Add(word);
                }
                else
                {
                    tp1 = tp2;
                    tp2 = tp1.GetNextInsertionPosition(LogicalDirection.Forward);
                }
            }

            return(dc_list);
        }
예제 #3
0
        /// <summary>
        /// Pad the line of the text pointer to the length specified.
        /// </summary>
        /// <param name="Doc"></param>
        /// <param name="Pointer"></param>
        /// <param name="Length"></param>
        public static void PadLineToLength(
            this TextPointer Pointer, FlowDocument Doc, int Length, char PadChar = ' ')
        {
            TextPointer tp1 = Pointer.GetLineStartPosition(0);
            TextPointer tp2 = Pointer.GetLineStartPosition(1);

            if (tp2 != null)
            {
                tp2 = tp2.GetNextInsertionPosition(LogicalDirection.Backward);
            }
            else
            {
                tp2 = Doc.ContentEnd.GetNextInsertionPosition(LogicalDirection.Backward);
            }

            // current line text.
            TextRange r1       = new TextRange(tp1, tp2);
            string    lineText = r1.Text;

            // pad length
            string padText = null;
            int    padLx   = Length - lineText.Length;

            if (padLx > 0)
            {
                padText = new StringBuilder().AppendRepeat(PadChar, padLx).ToString();
                tp2.InsertTextInRun(padText);
            }
        }
예제 #4
0
        internal void MoveCaretToFirstLine(Rect rect)
        {
            TextPointer tp      = Document.ContentStart;
            TextPointer last_tp = tp;

            Rect r = tp.GetCharacterRect(LogicalDirection.Forward);

            while (tp != null && r.X < rect.X && tp.CompareTo(Document.ContentEnd) != 0)
            {
                tp = tp.GetNextInsertionPosition(LogicalDirection.Forward);
                if (tp == null)
                {
                    break;
                }
                r       = tp.GetCharacterRect(LogicalDirection.Forward);
                last_tp = tp;
            }

            if (last_tp != null)
            {
                CaretPosition = last_tp;
            }

            // Workaround for bug in .NET 3.0
            if (!CaretPosition.IsAtLineStartPosition)
            {
                EditingCommands.MoveLeftByCharacter.Execute(null, this);
                EditingCommands.MoveRightByCharacter.Execute(null, this);
            }
            else if (CaretPosition.CompareTo(Document.ContentEnd) != 0)
            {
                EditingCommands.MoveRightByCharacter.Execute(null, this);
                EditingCommands.MoveLeftByCharacter.Execute(null, this);
            }
        }
예제 #5
0
        protected void OnCopy(object o, DataObjectCopyingEventArgs e)
        {
            string clipboard = "";

            for (TextPointer p = Selection.Start, next = null;
                 p != null && p.CompareTo(Selection.End) < 0;
                 p = next)
            {
                next = p.GetNextInsertionPosition(LogicalDirection.Forward);
                if (next == null)
                {
                    break;
                }

                var emoji = (next.Parent as Run)?.PreviousInline as EmojiInline;
                if (emoji == null && next.Parent != p.Parent)
                {
                    emoji = (p.Parent as Run)?.NextInline as EmojiInline;
                }
                if (emoji != null && (p.Parent as Run).PreviousInline != emoji)
                {
                    clipboard += emoji?.Text;
                }
                else
                {
                    clipboard += new TextRange(p, next).Text;
                }
            }

            Clipboard.SetText(clipboard);
            e.Handled = true;
            e.CancelCommand();
        }
예제 #6
0
        public static void ProcessParagraphLink(RichTextBox textBox, string text, Inline i)
        {
            foreach (string str in GetLinks(text))
            {
                TextPointer tp         = i.ContentStart;
                bool        reposition = false;
                while (!tp.GetTextInRun(LogicalDirection.Forward).StartsWith(str))
                {
                    tp = tp.GetNextInsertionPosition(LogicalDirection.Forward);
                }
                TextPointer end = tp;
                for (int j = 0; j < str.Length; j++)
                {
                    end = end.GetNextInsertionPosition(LogicalDirection.Forward);
                }
                TextRange tr = new TextRange(tp, end);
                if (textBox != null)
                {
                    reposition = textBox.CaretPosition.CompareTo(tr.End) == 0;
                }
                tr.Text = string.Empty;


                TextBlock block = new TextBlock();
                block.Text                        = str;
                block.ForceCursor                 = true;
                block.Cursor                      = System.Windows.Input.Cursors.Hand;
                block.TextDecorations             = TextDecorations.Underline;
                block.Foreground                  = Brushes.Blue;
                block.PreviewMouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(block_PreviewMouseLeftButtonDown);

                InlineUIContainer iui = new InlineUIContainer(block, tp);
            }
        }
예제 #7
0
        /// <summary>
        /// This function select a part of the text based on it's color. it is used for multi-line comments and strings
        /// </summary>
        public TextPointer getColorPoint(TextPointer current, LogicalDirection direction, TextPointer enterdPosition, Brush brush)
        {
            TextPointer nextPosition     = current;
            TextPointer StartingPosition = current;
            bool        isGreen          = true;
            TextRange   text             = new TextRange(current, nextPosition);

            while (isGreen)
            {
                nextPosition = current.GetNextInsertionPosition(direction);
                if (nextPosition == null)
                {
                    break;
                }
                text = new TextRange(current, nextPosition);


                if (text.GetPropertyValue(TextElement.ForegroundProperty) != brush)
                {
                    isGreen = false;
                }
                else
                {
                    current = nextPosition;
                }
            }
            return(current);
        }
예제 #8
0
        } // End GetXaml method.
        // </Snippet_TextPointer_GetNextContextPosition>

        // <Snippet_TextPointer_GetNextInsertionPosition>
        // This method returns the number of pagragraphs between two
        // specified TextPointers.
        int GetParagraphCount(TextPointer start, TextPointer end)
        {
            int paragraphCount = 0;
         
            while (start != null && start.CompareTo(end) < 0)
            {
                Paragraph paragraph = start.Paragraph;
         
                if (paragraph != null)
                {
                    paragraphCount++;
         
                    // Advance start to the end of the current paragraph.
                    start = paragraph.ContentEnd;
                 }
         
                 // Use the GetNextInsertionPosition method to skip over any interceding
                 // content element tags.
                 start = start.GetNextInsertionPosition(LogicalDirection.Forward);

             } // End while.
         
                 return paragraphCount;
         
        }  // End GetParagraphCount.
예제 #9
0
        public TextPointer getCurrentChar(TextPointer current, LogicalDirection direction)
        {
            // in tabe ye textPointer migire va az unja ta berese be ye delimeter dar jahati behesh migim harekat mikone
            //va dar akhar texpointer noghte payani ro bar migardune
            TextPointer nextPosition = current;
            string      test;

            while (1 == 1)
            {
                nextPosition = current.GetNextInsertionPosition(direction);
                if (nextPosition == null)
                {
                    break;
                }
                test = new TextRange(current, nextPosition).Text;
                for (int i = 0; i < delimeters.Length; i++)
                {
                    if (test == delimeters[i])
                    {
                        break;
                    }
                }
                current = nextPosition;
            }
            return(current);
        }
예제 #10
0
        protected void OnCopy(object o, DataObjectCopyingEventArgs e)
        {
            string clipboard = "";

            for (TextPointer p = Selection.Start, next = null;
                 p != null && p.CompareTo(Selection.End) < 0;
                 p = next)
            {
                next = p.GetNextInsertionPosition(LogicalDirection.Forward);
                if (next == null)
                {
                    break;
                }

                //var word = new TextRange(p, next);
                //Console.WriteLine($"Word '{word.Text}' Inline {word.Start.Parent.GetType()}");
                //Console.WriteLine($" ... p {p.Parent.GetType()}");

                var t = new TextRange(p, next);
                clipboard += t.Start.Parent is EmojiInline ? (t.Start.Parent as EmojiInline).Text
                                                           : t.Text;
            }

            Clipboard.SetText(clipboard);
            e.Handled = true;
            e.CancelCommand();
        }
예제 #11
0
        // По координате получает указатель в тексте. Если координаты берутся мышиные, мышь нужно брать относительно
        // корневого элемента управления в котором сидит FlowDocument (как пример)
        public static TextPointer GetPositionFromPoint(this Run run, Point searchForPoint)
        {
            // Работает тормозно. Возможно стоит пробежаться 1 раз при перерисовке flowdocument-а и в какое нибудь дерево или чето подобное запихнуть все эти рект-ы
            // чтобы быстро находить букву по позиции

            TextPointer currentTextPointer = run.ContentStart;
            TextPointer nextTextPointer    = currentTextPointer.GetNextInsertionPosition(LogicalDirection.Forward);

            while (nextTextPointer != null)
            {
                Rect currentRect = currentTextPointer.GetCharacterRect(LogicalDirection.Forward);
                Rect nextRect    = nextTextPointer.GetCharacterRect(LogicalDirection.Backward);

                if (searchForPoint.X >= currentRect.X && searchForPoint.X <= nextRect.X &&
                    searchForPoint.Y >= currentRect.Top && searchForPoint.Y <= nextRect.Bottom)
                {
                    return(currentTextPointer);
                }

                currentTextPointer = nextTextPointer;
                nextTextPointer    = nextTextPointer.GetNextInsertionPosition(LogicalDirection.Forward);
            }

            return(null);
        }
예제 #12
0
        /// <summary>
        /// 获取第n个zhifu的结束位置
        /// </summary>
        /// <param name="rtb"></param>
        /// <param name="zhifu"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        private static TextPointer get_tp(RichTextBox rtb, string zhifu, int n)
        {
            TextPointer tpStart = rtb.Document.ContentStart;

            if (n == 0)
            {
                return(tpStart);
            }
            TextPointer tpEnd      = rtb.Document.ContentEnd;
            TextPointer tp1        = tpStart;
            TextPointer tp2        = tp1.GetNextInsertionPosition(LogicalDirection.Forward);
            TextRange   range_char = new TextRange(tp1, tp2);
            int         count      = 0;

            while (tp2 != tpEnd)
            {
                tp1        = tp2;
                tp2        = tp1.GetNextInsertionPosition(LogicalDirection.Forward);
                range_char = new TextRange(tp1, tp2);

                if (zhifu == "\n")
                {
                    if (range_char.Text == "\n" || range_char.Text == "\r\n")
                    {
                        count++;
                    }
                    if (count == n)
                    {
                        break;
                    }
                }
                else
                {
                    if (range_char.Text == zhifu)
                    {
                        count++;
                    }
                    if (count == n)
                    {
                        break;
                    }
                }
            }

            return(tp2);
        }
예제 #13
0
        private static void RemoveHyperlink(AutoCompleteRichTextBox myRichTextBox, TextPointer caretPosition)
        {
            var       backspacePosition = caretPosition.GetNextInsertionPosition(LogicalDirection.Backward);
            Hyperlink hyperlink;

            if (backspacePosition == null || !DocumentUtils.IsHyperlinkBoundaryCrossed(caretPosition, backspacePosition, out hyperlink))
            {
                return;
            }

            // Remember caretPosition with forward gravity. This is necessary since we are going to delete
            // the hyperlink element preceeding caretPosition and after deletion current caretPosition
            // (with backward gravity) will follow content preceeding the hyperlink.
            // We want to remember content following the hyperlink to set new caret position at.

            var newCaretPosition = caretPosition.GetPositionAtOffset(0, LogicalDirection.Forward);

            // Deleting the hyperlink is done using logic below.

            // 1. Copy its children Inline to a temporary array.
            var hyperlinkChildren = hyperlink.Inlines;
            var inlines           = new Inline[hyperlinkChildren.Count];

            hyperlinkChildren.CopyTo(inlines, 0);

            // 2. Remove each child from parent hyperlink element and insert it after the hyperlink.
            for (int i = inlines.Length - 1; i >= 0; i--)
            {
                hyperlinkChildren.Remove(inlines[i]);
                hyperlink.SiblingInlines.InsertAfter(hyperlink, inlines[i]);
            }

            // 3. Apply hyperlink's local formatting properties to inlines (which are now outside hyperlink scope).
            var localProperties = hyperlink.GetLocalValueEnumerator();
            var inlineRange     = new TextRange(inlines[0].ContentStart, inlines[inlines.Length - 1].ContentEnd);

            while (localProperties.MoveNext())
            {
                var    property = localProperties.Current;
                var    dp       = property.Property;
                object value    = property.Value;

                if (!dp.ReadOnly &&
                    dp != Inline.TextDecorationsProperty && // Ignore hyperlink defaults.
                    dp != TextElement.ForegroundProperty &&
                    dp != BaseUriHelper.BaseUriProperty &&
                    !DocumentUtils.IsHyperlinkProperty(dp))
                {
                    inlineRange.ApplyPropertyValue(dp, value);
                }
            }

            // 4. Delete the (empty) hyperlink element.
            hyperlink.SiblingInlines.Remove(hyperlink);

            // 5. Update selection, since we deleted Hyperlink element and caretPosition was at that Hyperlink's end boundary.
            myRichTextBox.Selection.Select(newCaretPosition, newCaretPosition);
        }
예제 #14
0
        /// <summary>
        /// 清除语段模式标记
        /// </summary>
        /// <param name="rtb"></param>
        /// <param name="tp_biaoji_start"></param>
        private static void clear_yd_biaoji(RichTextBox rtb, TextPointer tp_biaoji_start)
        {
            TextPointer tp1 = tp_biaoji_start;
            TextPointer tp2 = tp1.GetNextInsertionPosition(LogicalDirection.Forward);

            Inline run = (Inline)tp2.Parent;

            tp2.Paragraph.Inlines.Remove(run);
        }
예제 #15
0
        private void FixEmojis()
        {
            if (m_pending_change)
            {
                return;
            }

            /* This will prevent our operation from polluting the undo buffer, but it
             * will create an infinite undo stack... need to fix this. */
            BeginChange();

            m_pending_change = true;

            TextPointer cur = Document.ContentStart;

            while (cur.CompareTo(Document.ContentEnd) < 0)
            {
                TextPointer next = cur.GetNextInsertionPosition(LogicalDirection.Forward);
                if (next == null)
                {
                    break;
                }

                TextRange word = new TextRange(cur, next);
                if (word.Text.Length > 0)
                {
                    // Test this so as to preserve caret position
                    bool caret_was_next = (0 == next.CompareTo(CaretPosition));

                    Inline inline;
                    // FIXME: this is a hack, normally we should split into Runs and EmojiInlines
                    if (word.Text == "\n")
                    {
                        inline = new LineBreak();
                    }
                    else
                    {
                        inline = new EmojiInline()
                        {
                            Text = word.Text, FontSize = FontSize, FallbackBrush = Foreground
                        }
                    };

                    next = Replace(word, inline);
                    if (caret_was_next)
                    {
                        CaretPosition = next;
                    }
                }

                cur = next;
            }

            EndChange();

            m_pending_change = false;
        }
예제 #16
0
        protected override void OnTextChanged(TextChangedEventArgs e)
        {
            if (m_pending_change)
            {
                return;
            }

            m_pending_change = true;

            base.OnTextChanged(e);

            /* This will prevent our operation from polluting the undo buffer, but it
             * will create an infinite undo stack... need to fix this. */
            BeginChange();

            m_pending_change = true;

            TextPointer cur = Document.ContentStart;

            while (cur.CompareTo(Document.ContentEnd) < 0)
            {
                TextPointer next = cur.GetNextInsertionPosition(LogicalDirection.Forward);
                if (next == null)
                {
                    break;
                }

                TextRange word = new TextRange(cur, next);
                if (EmojiData.MatchOne.IsMatch(word.Text))
                {
                    Inline inline = new EmojiInline()
                    {
                        Text          = word.Text,
                        FontSize      = FontSize,
                        FallbackBrush = Foreground,
                    };

                    // Preserve caret position
                    bool caret_was_next = (0 == next.CompareTo(CaretPosition));
                    next = Replace(word, inline);
                    if (caret_was_next)
                    {
                        CaretPosition = next;
                    }
                }

                cur = next;
            }

            EndChange();

            m_pending_change = false;

            // FIXME: debug
            //Console.WriteLine(XamlWriter.Save(Document));
        }
예제 #17
0
        private static void GetPointer(TextPointer start, int startOffset, int endOffset, out TextPointer startPointer, out TextPointer endPointer)
        {
            int i = 0;

            startPointer = null;
            endPointer   = null;
            //while (start.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
            //    start = start.GetNextContextPosition(LogicalDirection.Forward);
            while (i < startOffset && start != null)
            {
                if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
                {
                    //string textrun = start.GetTextInRun(LogicalDirection.Forward);
                    //start = start.GetNextContextPosition(LogicalDirection.Forward);
                    //i += start.GetTextInRun(LogicalDirection.Forward).Length;
                    start = start.GetNextInsertionPosition(LogicalDirection.Forward);
                    i++;
                }
                else if (start.GetPositionAtOffset(1, LogicalDirection.Forward) == null)
                {
                    break;
                }
                else
                {
                    start = start.GetNextInsertionPosition(LogicalDirection.Forward);
                    i    += 2;
                }
            }
            startPointer = start;
            while (i < endOffset)
            {
                if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
                {
                    i++;
                }
                else if (start.GetPositionAtOffset(1, LogicalDirection.Forward) == null)
                {
                    break;
                }
                start = start.GetNextInsertionPosition(LogicalDirection.Forward);
            }
            endPointer = start;
        }
예제 #18
0
        private static Hyperlink FindHyperlink(TextPointer textPointer, LogicalDirection logicalDirection)
        {
            TextPointer tp = textPointer.GetNextInsertionPosition(logicalDirection);

            if (tp != null)
            {
                return(DialogHyperlink.SelectedHyperlink(tp));
            }
            return(null);
        }
예제 #19
0
        public static TextPointer GetTextPointerForPosition(this RichTextBox rtb, int line, int column)
        {
            TextPointer docStartLine = rtb.Document.ContentStart.GetLineStartPosition(0);
            TextPointer tp           = docStartLine.GetLineStartPosition(line);

            for (int i = 0; i <= column; i++)
            {
                tp = tp.GetNextInsertionPosition(LogicalDirection.Forward);
            }

            return(tp);
        }
예제 #20
0
        /// <summary>
        /// Create a PhysicalCharInfo for the character between position and the next forward insertion position
        /// </summary>
        /// <param name="position"></param>
        public PhysicalCharInfo(TextPointer position)
        {
            if (position == null)
            {
                throw new ArgumentNullException("position");
            }

            this.NearPosition = null;
            this.FarPosition  = null;

            Initialize(position, position.GetNextInsertionPosition(LogicalDirection.Forward) ?? position);
        }
예제 #21
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);
        }
예제 #22
0
        private static TextPointer LetterShift_Guess(TextPointer start, int numLetters, out int numOff)
        {
            if (numLetters == 0)
            {
                numOff = 0;
                return(start);
            }

            TextPointer result = start.GetPositionAtOffset(numLetters);

            if (result == null)
            {
                numOff = 0;
                return(null);
            }
            if (!result.IsAtInsertionPosition)
            {
                TextPointer save;
                if ((save = result.GetNextInsertionPosition(LogicalDirection.Backward)) == null)
                {
                    if ((save = result.GetNextInsertionPosition(LogicalDirection.Forward)) == null)
                    {
                        numOff = 0;
                        return(null);
                    }
                }
                result = save;
            }

            bool wasNegative = numLetters < 0;

            numOff = Math.Abs(numLetters) - start.GetLetterOffset(result);
            if (wasNegative)
            {
                numOff *= -1;
            }
            return(result);
        }
예제 #23
0
        /// <summary>
        /// return TextPointer position before the last char of the line of the input
        /// TextPointer.
        /// </summary>
        /// <param name="TextPointer"></param>
        /// <param name="Doc"></param>
        /// <returns></returns>
        public static TextPointer GetLineEndPosition(
            this TextPointer TextPointer, FlowDocument Doc,
            RelativePosition Relative = RelativePosition.After)
        {
            TextPointer tp1 = TextPointer.GetLineStartPosition(1);

            if (tp1 == null)
            {
                tp1 = Doc.ContentEnd;
                tp1 = tp1.GetNextInsertionPosition(LogicalDirection.Backward);
            }
            else
            {
                tp1 = tp1.GetNextInsertionPosition(LogicalDirection.Backward);

                // position before the last char of the line.
                if ((tp1 != null) && (Relative == RelativePosition.Before))
                {
                    tp1 = tp1.GetNextInsertionPosition(LogicalDirection.Backward);
                }
            }
            return(tp1);
        }
예제 #24
0
        /// <summary>
        /// 1.  When wordBreakDirection = Forward, returns a position at the end of the word,
        ///     i.e. a position with a wordBreak character (space) following it.
        /// 2.  When wordBreakDirection = Backward, returns a position at the start of the word,
        ///     i.e. a position with a wordBreak character (space) preceeding it.
        /// 3.  Returns null when there is no workbreak in the requested direction.
        /// </summary>
        private static TextPointer GetPositionAtWordBoundary(TextPointer position, LogicalDirection wordBreakDirection)
        {
            if (!position.IsAtInsertionPosition)
            {
                position = position.GetInsertionPosition(wordBreakDirection);
            }
            TextPointer navigator = position;

            while (navigator != null && !IsPositionNextToWordBreak(navigator, wordBreakDirection))
            {
                navigator = navigator.GetNextInsertionPosition(wordBreakDirection);
            }
            return(navigator);
        }
예제 #25
0
        public static TextPointer GetPositionFromPoint(Run thiz, Point searchForPoint)
        {
            TextPointer ptrCurCharcter  = thiz.ContentStart.GetNextInsertionPosition(LogicalDirection.Forward);
            TextPointer ptrNextCharcter = ptrCurCharcter.GetNextInsertionPosition(LogicalDirection.Forward);

            while (ptrNextCharcter != null)
            {
                Rect charcterInsertionPointRectangle     = ptrCurCharcter.GetCharacterRect(LogicalDirection.Forward);
                Rect nextCharcterInsertionPointRectangle = ptrNextCharcter.GetCharacterRect(LogicalDirection.Backward);

                if (searchForPoint.X >= charcterInsertionPointRectangle.X &&
                    searchForPoint.X <= nextCharcterInsertionPointRectangle.X &&
                    searchForPoint.Y >= charcterInsertionPointRectangle.Top &&
                    searchForPoint.Y <= charcterInsertionPointRectangle.Bottom)
                {
                    return(ptrCurCharcter);
                }

                ptrCurCharcter  = ptrCurCharcter.GetNextInsertionPosition(LogicalDirection.Forward);
                ptrNextCharcter = ptrNextCharcter.GetNextInsertionPosition(LogicalDirection.Forward);
            }
            return(null);
        }
예제 #26
0
        /// <summary>
        /// return a TextPointer positioned before a specified position on the line.
        /// If the position exceeds the end of the line, either pad the line with
        /// blanks or set the position to the last char on the line.
        /// </summary>
        /// <param name="Doc"></param>
        /// <param name="Pointer"></param>
        /// <param name="Position"></param>
        /// <param name="Pad"></param>
        /// <returns></returns>
        public static TextPointer SetPositionOnLine(
            this TextPointer Pointer,
            FlowDocument Doc, int Position,
            bool Pad = false)
        {
            TextPointer tp  = Pointer.GetLineStartPosition(0);
            int         pos = Position;

            // make sure length of the line can accomodate the position.
            string lineText = Pointer.GetLineText(Doc, 0, "");

            if (pos > (lineText.Length - 1))
            {
                if (Pad == false)
                {
                    pos = lineText.Length - 1;
                }
                else
                {
                    Pointer.PadLineToLength(Doc, pos + 1);
                    lineText = Pointer.GetLineText(Doc);
                }
            }

            // position to the last char on the line.
            if (lineText.Length == (pos + 1))
            {
                tp = Pointer.GetLineEndPosition(Doc);
            }

            // advance a char at a time from the start of the line.
            else
            {
                for (int ix = 0; ix < pos; ++ix)
                {
                    var nextTp = tp.GetNextInsertionPosition(LogicalDirection.Forward);
                    if (nextTp != null)
                    {
                        tp = nextTp;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(tp);
        }
예제 #27
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);
        }
예제 #28
0
        private void SaveCheckTextPointer()
        {
            CheckTextPointer = new TextPointer[lenofCheck + 1];
            FlowDocument document = CheckTextBox.Document;
            TextPointer  txNext   = document.ContentStart;

            for (int i = 0; i <= lenofCheck; i++)
            {
                txNext = txNext.GetNextInsertionPosition(LogicalDirection.Forward);
                CheckTextPointer[i] = txNext;
            }
            for (int i = 0; i < lenofCheck; i++)
            {
                TextRange tr = new TextRange(CheckTextPointer[i], CheckTextPointer[i + 1]);
                //Console.WriteLine(tr.Text);
            }
        }
예제 #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
        //returns [0]=Rect of char at end of first line, [1]=Rect of char at start of second line
        internal static Rect[] FindStartEndOfVisualLineRects(TextPointer start, Rect startRect)
        {
            TextPointer next = start;
            Rect        nextRect;

            while ((next = next.GetNextInsertionPosition(LogicalDirection.Forward)) != null)
            {
                nextRect = next.GetCharacterRect(LogicalDirection.Forward);
                if (nextRect.Top != startRect.Top)
                {
                    return new Rect[2] {
                               next.GetCharacterRect(LogicalDirection.Backward), nextRect
                    }
                }
                ;                                                                                     //for some reason next.GetCharacterRect(LogicalDirection.Backward) is not the same as 'prior' (prev value of 'next')
            }
            return(null);
        }