예제 #1
0
        // Token: 0x06007CED RID: 31981 RVA: 0x0023255C File Offset: 0x0023075C
        private static FlowDirection GetTextFlowDirection(ITextPointer pointer)
        {
            Invariant.Assert(pointer != null, "Null pointer passed.");
            Invariant.Assert(pointer.IsAtInsertionPosition, "Pointer is not an insertion position");
            int num = 0;
            LogicalDirection   logicalDirection = pointer.LogicalDirection;
            TextPointerContext pointerContext   = pointer.GetPointerContext(logicalDirection);
            FlowDirection      result;

            if ((pointerContext == TextPointerContext.ElementEnd || pointerContext == TextPointerContext.ElementStart) && !TextSchema.IsFormattingType(pointer.ParentType))
            {
                result = (FlowDirection)pointer.GetValue(FrameworkElement.FlowDirectionProperty);
            }
            else
            {
                Rect         anchorRectangle = TextSelectionHelper.GetAnchorRectangle(pointer);
                ITextPointer textPointer     = pointer.GetNextInsertionPosition(logicalDirection);
                if (textPointer != null)
                {
                    textPointer = textPointer.CreatePointer((logicalDirection == LogicalDirection.Backward) ? LogicalDirection.Forward : LogicalDirection.Backward);
                    if (logicalDirection == LogicalDirection.Forward)
                    {
                        if (pointerContext == TextPointerContext.ElementEnd && textPointer.GetPointerContext(textPointer.LogicalDirection) == TextPointerContext.ElementStart)
                        {
                            return((FlowDirection)pointer.GetValue(FrameworkElement.FlowDirectionProperty));
                        }
                    }
                    else if (pointerContext == TextPointerContext.ElementStart && textPointer.GetPointerContext(textPointer.LogicalDirection) == TextPointerContext.ElementEnd)
                    {
                        return((FlowDirection)pointer.GetValue(FrameworkElement.FlowDirectionProperty));
                    }
                    Rect anchorRectangle2 = TextSelectionHelper.GetAnchorRectangle(textPointer);
                    if (anchorRectangle2 != Rect.Empty && anchorRectangle != Rect.Empty)
                    {
                        num = Math.Sign(anchorRectangle2.Left - anchorRectangle.Left);
                        if (logicalDirection == LogicalDirection.Backward)
                        {
                            num = -num;
                        }
                    }
                }
                if (num == 0)
                {
                    result = (FlowDirection)pointer.GetValue(FrameworkElement.FlowDirectionProperty);
                }
                else
                {
                    result = ((num > 0) ? FlowDirection.LeftToRight : FlowDirection.RightToLeft);
                }
            }
            return(result);
        }
 // Token: 0x06003C71 RID: 15473 RVA: 0x00117698 File Offset: 0x00115898
 internal static Color GetColor(UnsafeNativeMethods.TF_DA_COLOR dacolor, ITextPointer position)
 {
     if (dacolor.type == UnsafeNativeMethods.TF_DA_COLORTYPE.TF_CT_SYSCOLOR)
     {
         return(TextServicesDisplayAttribute.GetSystemColor(dacolor.indexOrColorRef));
     }
     if (dacolor.type == UnsafeNativeMethods.TF_DA_COLORTYPE.TF_CT_COLORREF)
     {
         int  indexOrColorRef = dacolor.indexOrColorRef;
         uint num             = (uint)TextServicesDisplayAttribute.FromWin32Value(indexOrColorRef);
         return(Color.FromArgb((byte)((num & 4278190080U) >> 24), (byte)((num & 16711680U) >> 16), (byte)((num & 65280U) >> 8), (byte)(num & 255U)));
     }
     Invariant.Assert(position != null, "position can't be null");
     return(((SolidColorBrush)position.GetValue(TextElement.ForegroundProperty)).Color);
 }
예제 #3
0
        /// <summary>
        ///   Convert TF_DA_COLOR to Color.
        /// </summary>
        internal static Color GetColor(UnsafeNativeMethods.TF_DA_COLOR dacolor, ITextPointer position)
        {
            if (dacolor.type == UnsafeNativeMethods.TF_DA_COLORTYPE.TF_CT_SYSCOLOR)
            {
                return(GetSystemColor(dacolor.indexOrColorRef));
            }
            else if (dacolor.type == UnsafeNativeMethods.TF_DA_COLORTYPE.TF_CT_COLORREF)
            {
                int  color = dacolor.indexOrColorRef;
                uint argb  = (uint)FromWin32Value(color);
                return(Color.FromArgb((byte)((argb & 0xff000000) >> 24), (byte)((argb & 0x00ff0000) >> 16), (byte)((argb & 0x0000ff00) >> 8), (byte)(argb & 0x000000ff)));
            }

            Invariant.Assert(position != null, "position can't be null");
            return(((SolidColorBrush)position.GetValue(TextElement.ForegroundProperty)).Color);
        }
        // Writes a collection of attributes representing non-inheritable properties
        // whose values are set inline on the given element instance.
        // When we read properties fromContext we want all values including defaults; from text elements we only want only affected
        private static void WriteNoninheritableProperties(Type elementTypeStandardized, ITextPointer context, XmlWriter xmlWriter, bool onlyAffected, DependencyObject complexProperties)
        {
            DependencyProperty[] elementProperties = TextSchema.GetNoninheritableProperties(elementTypeStandardized);

            // We'll need a pointer to walk the tree up when onlyAffected=false
            ITextPointer parentContext = onlyAffected ? null : context.CreatePointer();

            for (int i = 0; i < elementProperties.Length; i++)
            {
                DependencyProperty property = elementProperties[i];
                Type propertyOwnerType = context.ParentType;

                object propertyValue;
                if (onlyAffected)
                {
                    // 

                    propertyValue = context.GetValue(property);
                }
                else
                {
                    // This is request for contextual properties - use "manual" inheritance to collect values
                    Invariant.Assert(elementTypeStandardized == typeof(Span), "Request for contextual properties is expected for Span wrapper only");

                    // Get property value from this element or from one of its ancestors (the latter in case of !onlyAffeted)
                    propertyValue = context.GetValue(property);

                    // Get property value from its ancestors if the property is not set. 
                    // TextDecorationCollection is special-cased as its default is empty collection, 
                    // and its value source cannot be distinguished from ITextPointer. 
                    if (propertyValue == null || TextDecorationCollection.Empty.ValueEquals(propertyValue as TextDecorationCollection))
                    {
                        if (property == Inline.BaselineAlignmentProperty || property == TextElement.TextEffectsProperty)
                        {
                            // These properties do not make sense as contextual; do not include them into context.
                            continue;
                        }

                        parentContext.MoveToPosition(context);
                        while ((propertyValue == null || TextDecorationCollection.Empty.ValueEquals(propertyValue as TextDecorationCollection))
                            && typeof(Inline).IsAssignableFrom(parentContext.ParentType))
                        {
                            parentContext.MoveToElementEdge(ElementEdge.BeforeStart);
                            propertyValue = parentContext.GetValue(property);
                            propertyOwnerType = parentContext.ParentType;
                        }
                    }
                }

                // 








                if ((property == Block.MarginProperty && (typeof(Paragraph).IsAssignableFrom(propertyOwnerType) || typeof(List).IsAssignableFrom(propertyOwnerType)))
                    ||
                    (property == Block.PaddingProperty) && typeof(List).IsAssignableFrom(propertyOwnerType))
                {
                    Thickness thickness = (Thickness)propertyValue;
                    if (Paragraph.IsMarginAuto(thickness))
                    {
                        continue;
                    }
                }

                // Write the property as attribute string or add it to a list of complex properties.
                WriteNoninheritableProperty(xmlWriter, property, propertyValue, propertyOwnerType, onlyAffected, complexProperties, context.ReadLocalValue(property));
            }
        }
        // Writes a collection of attributes representing inheritable properties
        // whose values has been affected by this element.
        // Parameter onlyAffected=true means that we serialize only properties affected by
        // the current element; otherwise we output all known inheritable properties.
        private static void WriteInheritableProperties(Type elementTypeStandardized, ITextPointer context, XmlWriter xmlWriter, bool onlyAffected, DependencyObject complexProperties)
        {
            // Create a pointer positioned immediately outside the element
            ITextPointer outerContext = null;
            if (onlyAffected)
            {
                outerContext = context.CreatePointer();
                outerContext.MoveToElementEdge(ElementEdge.BeforeStart);
            }

            DependencyProperty[] inheritableProperties = TextSchema.GetInheritableProperties(elementTypeStandardized);

            for (int i = 0; i < inheritableProperties.Length; i++)
            {
                DependencyProperty property = inheritableProperties[i];

                object innerValue = context.GetValue(property);
                if (innerValue == null)
                {
                    // Some properties like Foreground may have null as default value.
                    // Skip them.
                    continue;
                }

                object outerValue = null;
                if (onlyAffected)
                {
                    outerValue = outerContext.GetValue(property);
                }
                
                // The property must appear in markup if the element
                if (!onlyAffected ||  // all properties requested for saving context on root
                    !TextSchema.ValuesAreEqual(innerValue, outerValue)) // or the element really affects the property
                {
                    string stringValue = DPTypeDescriptorContext.GetStringValue(property, innerValue);

                    if (stringValue != null)
                    {
                        stringValue = FilterNaNStringValueForDoublePropertyType(stringValue, property.PropertyType);

                        string propertyName;
                        if (property == FrameworkContentElement.LanguageProperty)
                        {
                            // Special case for CultureInfo property that must be represented in xaml as xml:lang attribute
                            propertyName = "xml:lang";
                        }
                        else
                        {
                            // Regular case: serialize a property with its own name
                            propertyName = GetPropertyNameForElement(property, elementTypeStandardized, /*forceComplexName:*/false);
                        }
                        xmlWriter.WriteAttributeString(propertyName, stringValue);
                    }
                    else
                    {
                        complexProperties.SetValue(property, innerValue);
                    }
                }
            }
        }
        // Verify that a pointer is an acceptable ancestor.  Some types can't be ancestors at all, while
        // non-typographic-only elements are unacceptable if the range being serialized does not include the
        // element's start and end (because we don't want to serialize properties on such an element).
        private static bool IsAcceptableAncestor(ITextPointer commonAncestor, ITextRange range)
        {
            if (typeof(TableRow).IsAssignableFrom(commonAncestor.ParentType) ||
                typeof(TableRowGroup).IsAssignableFrom(commonAncestor.ParentType) ||
                typeof(Table).IsAssignableFrom(commonAncestor.ParentType) ||
                typeof(BlockUIContainer).IsAssignableFrom(commonAncestor.ParentType) ||
                typeof(List).IsAssignableFrom(commonAncestor.ParentType) ||
                typeof(Inline).IsAssignableFrom(commonAncestor.ParentType) && TextSchema.HasTextDecorations(commonAncestor.GetValue(Inline.TextDecorationsProperty)))
            {
                return false;
            }

            // We don't want to use any formatting from within a non-typographic-only element unless the entire
            // element is selected (in which case, the ancestor candidate will already be outside that element.
            // If there is such an element ANYWHERE in the ancestry, the only acceptable
            // ancestor is outside the outermost such element.
            ITextPointer navigator = commonAncestor.CreatePointer();
            while (typeof(TextElement).IsAssignableFrom(navigator.ParentType))
            {
                TextElementEditingBehaviorAttribute behaviorAttribute = (TextElementEditingBehaviorAttribute)Attribute.GetCustomAttribute(navigator.ParentType, typeof(TextElementEditingBehaviorAttribute));
                if (behaviorAttribute != null && !behaviorAttribute.IsTypographicOnly)
                {
                    return false;
                }
                navigator.MoveToElementEdge(ElementEdge.BeforeStart);
            }

            return true;
        }
            /// A handler for an event reporting that the drag over during drag-and-drop operation.
            internal void TargetOnDragOver(DragEventArgs e)
            {
                if (!AllowDragDrop(e))
                {
                    return;
                }

                // Ok, there's data to move or copy here.
                if ((e.AllowedEffects & DragDropEffects.Move) != 0)
                {
                    e.Effects = DragDropEffects.Move;
                }

                bool ctrlKeyDown = ((int)(e.KeyStates & DragDropKeyStates.ControlKey) != 0);

                if (ctrlKeyDown)
                {
                    e.Effects |= DragDropEffects.Copy;
                }

                // Show the caret on the drag over target position.
                if (_caretDragDrop != null)
                {
                    // Update the layout to get the corrected text position. Otherwise, we can get the
                    // incorrected text position.
                    if (!_textEditor.TextView.Validate(e.GetPosition(_textEditor.TextView.RenderScope)))
                    {
                        return;
                    }

                    // Find the scroller from the render scope
                    FrameworkElement scroller = _textEditor._Scroller;

                    // Automatically scroll the dropable content(line or page up/down) if scroller is available
                    if (scroller != null)
                    {
                        // Get the ScrollInfo to scroll a line or page up/down
                        IScrollInfo scrollInfo = scroller as IScrollInfo;

                        if (scrollInfo == null && scroller is ScrollViewer)
                        {
                            scrollInfo = ((ScrollViewer)scroller).ScrollInfo;
                        }

                        Invariant.Assert(scrollInfo != null);

                        // Takes care of scrolling mechanism when vertical scrollbar is available, it creates a virtual
                        // block within the viewport where if you position your mouse during drag leads to scrolling,here
                        // it is of 16pixels and within first 8pixels it does scrolling by line and for next it scrolls by page.

                        Point  pointScroller  = e.GetPosition((IInputElement)scroller);
                        double pageHeight     = (double)_textEditor.UiScope.GetValue(TextEditor.PageHeightProperty);
                        double slowAreaHeight = ScrollViewer._scrollLineDelta;

                        if (pointScroller.Y < slowAreaHeight)
                        {
                            // Drag position is on the scroll area that we need to scroll up
                            if (pointScroller.Y > slowAreaHeight / 2)
                            {
                                // scroll a line up
                                scrollInfo.LineUp();
                            }
                            else
                            {
                                // scroll a page up
                                scrollInfo.PageUp();
                            }
                        }
                        else if (pointScroller.Y > (pageHeight - slowAreaHeight))
                        {
                            // Drag position is on the scroll area that we need to scroll down
                            if (pointScroller.Y < (pageHeight - slowAreaHeight / 2))
                            {
                                // scroll a line down
                                scrollInfo.LineDown();
                            }
                            else
                            {
                                // scroll a page down
                                scrollInfo.PageDown();
                            }
                        }
                    }

                    // Get the current text position from the dropable mouse point.
                    _textEditor.TextView.RenderScope.UpdateLayout(); // REVIEW:benwest:6/27/2006: This should use TextView.Validate, and check the return value instead of using IsValid below.

                    if (_textEditor.TextView.IsValid)
                    {
                        ITextPointer dragPosition = GetDropPosition(_textEditor.TextView.RenderScope as Visual, e.GetPosition(_textEditor.TextView.RenderScope));

                        if (dragPosition != null)
                        {
                            // Get the caret position to show the dropable point.
                            Rect caretRectangle = this.TextView.GetRectangleFromTextPosition(dragPosition);

                            // NOTE: We DO NOT use GetCurrentValue because springload formatting should NOT be involved for drop caret.
                            object fontStylePropertyValue = dragPosition.GetValue(TextElement.FontStyleProperty);
                            bool   italic     = (_textEditor.AcceptsRichContent && fontStylePropertyValue != DependencyProperty.UnsetValue && (FontStyle)fontStylePropertyValue == FontStyles.Italic);
                            Brush  caretBrush = TextSelection.GetCaretBrush(_textEditor);

                            // Show the caret on the dropable position.
                            _caretDragDrop.Update(/*visible:*/ true, caretRectangle, caretBrush, 0.5, italic, CaretScrollMethod.None, /*wordWrappingPosition*/ double.NaN);
                        }
                    }
                }
            }
예제 #8
0
            // Token: 0x060085BC RID: 34236 RVA: 0x0024A7EC File Offset: 0x002489EC
            internal void TargetOnDragOver(DragEventArgs e)
            {
                if (!this.AllowDragDrop(e))
                {
                    return;
                }
                if ((e.AllowedEffects & DragDropEffects.Move) != DragDropEffects.None)
                {
                    e.Effects = DragDropEffects.Move;
                }
                bool flag = (e.KeyStates & DragDropKeyStates.ControlKey) > DragDropKeyStates.None;

                if (flag)
                {
                    e.Effects |= DragDropEffects.Copy;
                }
                if (this._caretDragDrop != null)
                {
                    if (!this._textEditor.TextView.Validate(e.GetPosition(this._textEditor.TextView.RenderScope)))
                    {
                        return;
                    }
                    FrameworkElement scroller = this._textEditor._Scroller;
                    if (scroller != null)
                    {
                        IScrollInfo scrollInfo = scroller as IScrollInfo;
                        if (scrollInfo == null && scroller is ScrollViewer)
                        {
                            scrollInfo = ((ScrollViewer)scroller).ScrollInfo;
                        }
                        Invariant.Assert(scrollInfo != null);
                        Point  position = e.GetPosition(scroller);
                        double num      = (double)this._textEditor.UiScope.GetValue(TextEditor.PageHeightProperty);
                        double num2     = 16.0;
                        if (position.Y < num2)
                        {
                            if (position.Y > num2 / 2.0)
                            {
                                scrollInfo.LineUp();
                            }
                            else
                            {
                                scrollInfo.PageUp();
                            }
                        }
                        else if (position.Y > num - num2)
                        {
                            if (position.Y < num - num2 / 2.0)
                            {
                                scrollInfo.LineDown();
                            }
                            else
                            {
                                scrollInfo.PageDown();
                            }
                        }
                    }
                    this._textEditor.TextView.RenderScope.UpdateLayout();
                    if (this._textEditor.TextView.IsValid)
                    {
                        ITextPointer dropPosition = this.GetDropPosition(this._textEditor.TextView.RenderScope, e.GetPosition(this._textEditor.TextView.RenderScope));
                        if (dropPosition != null)
                        {
                            Rect   rectangleFromTextPosition = this.TextView.GetRectangleFromTextPosition(dropPosition);
                            object value      = dropPosition.GetValue(TextElement.FontStyleProperty);
                            bool   italic     = this._textEditor.AcceptsRichContent && value != DependencyProperty.UnsetValue && (FontStyle)value == FontStyles.Italic;
                            Brush  caretBrush = TextSelection.GetCaretBrush(this._textEditor);
                            this._caretDragDrop.Update(true, rectangleFromTextPosition, caretBrush, 0.5, italic, CaretScrollMethod.None, double.NaN);
                        }
                    }
                }
            }
예제 #9
0
        /// <summary>
        /// </summary>
        void ITextSelection.SetCaretToPosition(ITextPointer caretPosition, LogicalDirection direction, bool allowStopAtLineEnd, bool allowStopNearSpace)
        {
            // We need a pointer with appropriate direction,
            // becasue it will be used in textRangeBase.Select method for
            // pointer normalization.
            caretPosition = caretPosition.CreatePointer(direction);

            // Normalize the position in its logical direction - to get to text content over there.
            caretPosition.MoveToInsertionPosition(direction);

            // We need a pointer with the reverse direction to confirm
            // the line wrapping position. So we can ensure Bidi caret navigation.
            // Bidi can have the different caret position by setting the
            // logical direction, so we have to only set the logical direction
            // as the forward for the real line wrapping position.
            ITextPointer reversePosition = caretPosition.CreatePointer(direction == LogicalDirection.Forward ? LogicalDirection.Backward : LogicalDirection.Forward);

            // Check line wrapping condition
            if (!allowStopAtLineEnd &&
                ((TextPointerBase.IsAtLineWrappingPosition(caretPosition, this.TextView) &&
                  TextPointerBase.IsAtLineWrappingPosition(reversePosition, this.TextView)) ||
                 TextPointerBase.IsNextToPlainLineBreak(caretPosition, LogicalDirection.Backward) ||
                 TextSchema.IsBreak(caretPosition.GetElementType(LogicalDirection.Backward))))
            {
                // Caret is at wrapping position, and we are not allowed to stay at end of line,
                // so we choose forward direction to appear in the begiinning of a second line
                caretPosition.SetLogicalDirection(LogicalDirection.Forward);
            }
            else
            {
                if (caretPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text &&
                    caretPosition.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
                {
                    // This is statistically most typical case. No "smartness" needed
                    // to choose standard Forward orientation for the caret.
                    // NOTE: By using caretPosition's direction we solve BiDi caret orientation case:
                    // The orietnation reflects a direction from where caret has been moved
                    // or orientation where mouse clicked. So we will stick with appropriate
                    // character.

                    // Nothing to do. The caretPosition is good to go.
                }
                else if (!allowStopNearSpace)
                {
                    // There are some tags around, and we are not allowed to choose a side near to space.
                    // So we need to perform some content analysis.

                    char[] charBuffer = new char[1];

                    if (caretPosition.GetPointerContext(direction) == TextPointerContext.Text &&
                        caretPosition.GetTextInRun(direction, charBuffer, 0, 1) == 1 &&
                        Char.IsWhiteSpace(charBuffer[0]))
                    {
                        LogicalDirection oppositeDirection = direction == LogicalDirection.Forward ? LogicalDirection.Backward : LogicalDirection.Forward;

                        // Check formatting switch condition at this position
                        FlowDirection initialFlowDirection = (FlowDirection)caretPosition.GetValue(FrameworkElement.FlowDirectionProperty);

                        bool moved = caretPosition.MoveToInsertionPosition(oppositeDirection);

                        if (moved &&
                            initialFlowDirection == (FlowDirection)caretPosition.GetValue(FrameworkElement.FlowDirectionProperty) &&
                            (caretPosition.GetPointerContext(oppositeDirection) != TextPointerContext.Text ||
                             caretPosition.GetTextInRun(oppositeDirection, charBuffer, 0, 1) != 1 ||
                             !Char.IsWhiteSpace(charBuffer[0])))
                        {
                            // In the opposite direction we have a non-space
                            // character. So we choose that direction
                            direction = oppositeDirection;
                            caretPosition.SetLogicalDirection(direction);
                        }
                    }
                }
            }

            // Now that orientation of a caretPosition is identified,
            // build an empty selection at this position
            TextRangeBase.BeginChange(this);
            try
            {
                TextRangeBase.Select(this, caretPosition, caretPosition);

                // Note how Select method works for the case of empty range:
                // It creates a single instance TextPointer normalized and oriented
                // in a direction taken from caretPosition:
                ITextSelection thisSelection = this;
                Invariant.Assert(thisSelection.Start.LogicalDirection == caretPosition.LogicalDirection); // orientation must be as passed
                Invariant.Assert(this.IsEmpty);
                //Invariant.Assert((object)thisSelection.Start == (object)thisSelection.End); // it must be the same instance of TextPointer
                //Invariant.Assert(TextPointerBase.IsAtInsertionPosition(thisSelection.Start, caretPosition.LogicalDirection)); // normalization must be done in the same diredction as orientation

                // Clear active positions when selection is empty
                SetActivePositions(null, null);
            }
            finally
            {
                TextRangeBase.EndChange(this);
            }
        }
예제 #10
0
        // Helper for MoveSelectionByMouse
        private bool ShouldSelectEmbeddedObject(ITextPointer cursorPosition, Point cursorMousePoint, Rect objectEdgeRect)
        {
            // Although we now know that cursorPosition is facing an embedded object,
            // we still need an additional test to determine if the original mouse point
            // fell within the object or outside it's bouding box (which can happen when
            // a mouse click is snapped to the nearest content).
            // If the mouse point is outside the object, we don't want to select it.
            if (!objectEdgeRect.IsEmpty &&
                cursorMousePoint.Y >= objectEdgeRect.Y && cursorMousePoint.Y < objectEdgeRect.Y + objectEdgeRect.Height)
            {
                // Compare X coordinates of mouse down point and object edge rect,
                // depending on the FlowDirection of the render scope and paragraph content.

                FlowDirection renderScopeFlowDirection = (FlowDirection)this.TextView.RenderScope.GetValue(Block.FlowDirectionProperty);
                FlowDirection paragraphFlowDirection = (FlowDirection)cursorPosition.GetValue(Block.FlowDirectionProperty);

                if (renderScopeFlowDirection == FlowDirection.LeftToRight)
                {
                    if (paragraphFlowDirection == FlowDirection.LeftToRight &&
                        (cursorPosition.LogicalDirection == LogicalDirection.Forward && objectEdgeRect.X < cursorMousePoint.X ||
                        cursorPosition.LogicalDirection == LogicalDirection.Backward && cursorMousePoint.X < objectEdgeRect.X))
                    {
                        return true;
                    }
                    else if (paragraphFlowDirection == FlowDirection.RightToLeft &&
                        (cursorPosition.LogicalDirection == LogicalDirection.Forward && objectEdgeRect.X > cursorMousePoint.X ||
                        cursorPosition.LogicalDirection == LogicalDirection.Backward && cursorMousePoint.X > objectEdgeRect.X))
                    {
                        return true;
                    }
                }
                else
                {
                    if (paragraphFlowDirection == FlowDirection.LeftToRight &&
                        (cursorPosition.LogicalDirection == LogicalDirection.Forward && objectEdgeRect.X > cursorMousePoint.X ||
                        cursorPosition.LogicalDirection == LogicalDirection.Backward && cursorMousePoint.X > objectEdgeRect.X))
                    {
                        return true;
                    }
                    else if (paragraphFlowDirection == FlowDirection.RightToLeft &&
                        (cursorPosition.LogicalDirection == LogicalDirection.Forward && objectEdgeRect.X < cursorMousePoint.X ||
                        cursorPosition.LogicalDirection == LogicalDirection.Backward && cursorMousePoint.X < objectEdgeRect.X))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
예제 #11
0
        // Returns the CultureInfo of the content at a position.
        // Returns null if there is no CultureInfo matching the current XmlLanguage. 
        private CultureInfo GetCurrentCultureAndLanguage(ITextPointer position, out XmlLanguage language) 
        {
            CultureInfo cultureInfo; 
            bool hasModifiers;

            // TextBox takes the input language iff no local LanguageProperty is set.
            if (!_textEditor.AcceptsRichContent && 
                _textEditor.UiScope.GetValueSource(FrameworkElement.LanguageProperty, null, out hasModifiers) == BaseValueSourceInternal.Default)
            { 
                cultureInfo = _defaultCulture; 
                language = XmlLanguage.GetLanguage(cultureInfo.IetfLanguageTag);
            } 
            else
            {
                language = (XmlLanguage)position.GetValue(FrameworkElement.LanguageProperty);
 
                if (language == null)
                { 
                    cultureInfo = null; 
                }
                else 
                {
                    try
                    {
                        cultureInfo = language.GetSpecificCulture(); 
                    }
                    catch (InvalidOperationException) 
                    { 
                        // Someone set a bogus language on the run.
                        cultureInfo = null; 
                    }
                }
            }
 
            return cultureInfo;
        } 
예제 #12
0
        // Gets a non-inherited property from a given position
        private static object GetCharacterValueFromPosition(ITextPointer pointer, DependencyProperty formattingProperty)
        { 
            object value = null;
 
            if (formattingProperty != Inline.TextDecorationsProperty) 
            {
                value = pointer.GetValue(formattingProperty); 
            }
            else
            {
                if (pointer is TextPointer) // Implement only for concrete TextCotainer returning null otherwise - for optimization 
                {
                    DependencyObject element = ((TextPointer)pointer).Parent as TextElement; 
                    while (value == null && (element is Inline || element is Paragraph || element is TextBlock)) 
                    {
                        value = element.GetValue(formattingProperty); 

                        element = element is TextElement ? ((TextElement)element).Parent : null;
                    }
                } 
            }
 
            return value; 
        }
예제 #13
0
        /// <summary>
        /// Retrieves FontFamily name.
        /// </summary>
        private static string GetFontFamilyName(FontFamily fontFamily, ITextPointer context)
        {
            if (fontFamily != null)
            {
                // Typical case: return the family name/URI used to construct the FontFamily.
                if (fontFamily.Source != null)
                    return fontFamily.Source;

                // Use the target font specified by the first family map with a compatible language.
                if (fontFamily.FamilyMaps != null)
                {
                    XmlLanguage textLanguage = (context != null) ?
                        (XmlLanguage)context.GetValue(FrameworkElement.LanguageProperty) :
                        null;

                    foreach (FontFamilyMap familyMap in fontFamily.FamilyMaps)
                    {
                        // A language-neutral family map matches any text language.
                        if (familyMap.Language == null)
                            return familyMap.Target;

                        // Does the language match the text culture or a parent culture?
                        if (textLanguage != null && familyMap.Language.RangeIncludes(textLanguage))
                            return familyMap.Target;
                    }
                }
            }

            // Worst case: we have to return something so just return a default family name.
            return _defaultFamilyName;
        }
예제 #14
0
        //----------------------------------------------------- 
        // 
        //  Static Methods
        // 
        //------------------------------------------------------
        #region Static Methods

        /// <summary> 
        /// Determine the flow direction of the character referred to by the TextPointer.
        /// If the context of the pointer is not text, we use the FlowDirection of the 
        /// containing element. 
        /// </summary>
        /// <param name="pointer">pointer to get flow direction for</param> 
        /// <returns>positive value means LeftToRight, negative value means RightToLeft</returns>
        private static FlowDirection GetTextFlowDirection(ITextPointer pointer)
        {
            Invariant.Assert(pointer != null, "Null pointer passed."); 
            Invariant.Assert(pointer.IsAtInsertionPosition, "Pointer is not an insertion position");
 
            int sign = 0; 
            FlowDirection flowDirection;
 
            LogicalDirection direction = pointer.LogicalDirection;

            TextPointerContext currentContext = pointer.GetPointerContext(direction);
            if ((currentContext == TextPointerContext.ElementEnd || currentContext == TextPointerContext.ElementStart) && 
                !TextSchema.IsFormattingType(pointer.ParentType))
            { 
                // If the current pointer (with its current direction) is at the start or end of a paragraph, 
                // the next insertion position will be in a separate paragraph.  We can't determine direction
                // based on the pointer rects in that case so we use the direction of the Paragraph. 
                flowDirection = (FlowDirection)pointer.GetValue(FlowDirectionProperty);
            }
            else
            { 
                // We get the rects before and after the character following the current
                // pointer and determine that character's flow direction based on the x-values 
                // of the rects.  Because we use direction when requesting a rect, we should 
                // always get rects that are on the same line (except for the case above)
 
                // Forward gravity for leading edge
                Rect current = TextSelectionHelper.GetAnchorRectangle(pointer);

                // Get insertion position after the current pointer 
                ITextPointer nextPointer = pointer.GetNextInsertionPosition(direction);
 
                // There may be no more insertion positions in this document 
                if (nextPointer != null)
                { 
                    // Backward gravity for trailing edge
                    nextPointer = nextPointer.CreatePointer(direction == LogicalDirection.Backward ? LogicalDirection.Forward : LogicalDirection.Backward);

                    // Special case - for pointers at the end of a paragraph 
                    // Actually the pointer is the last insertion position in the paragraph and the next insertion position is the first
                    // in the next paragraph.  We handle this by detecting that the two pointers only have markup between them.  If the 
                    // markup was only formatting, there would also be content (because insertion position would move past a character). 
                    if (direction == LogicalDirection.Forward)
                    { 
                        if (currentContext == TextPointerContext.ElementEnd && nextPointer.GetPointerContext(nextPointer.LogicalDirection) == TextPointerContext.ElementStart)
                        {
                            return (FlowDirection)pointer.GetValue(FlowDirectionProperty);
                        } 
                    }
                    else 
                    { 
                        if (currentContext == TextPointerContext.ElementStart && nextPointer.GetPointerContext(nextPointer.LogicalDirection) == TextPointerContext.ElementEnd)
                        { 
                            return (FlowDirection)pointer.GetValue(FlowDirectionProperty);
                        }
                    }
 

                    Rect next = TextSelectionHelper.GetAnchorRectangle(nextPointer); 
 
                    // Calculate the difference in x-coordinate between the two rects
                    if (next != Rect.Empty && current != Rect.Empty) 
                    {
                        sign = Math.Sign(next.Left - current.Left);

                        // If we are looking at the character before the current pointer, 
                        // we swap the difference since "next" was actually before "current"
                        if (direction == LogicalDirection.Backward) 
                        { 
                            sign = -(sign);
                        } 
                    }
                }

                // If the rects were at the same x-coordinate or we couldn't get rects 
                // at all, we simply use the FlowDirection at that pointer.
                if (sign == 0) 
                { 
                    flowDirection = (FlowDirection)pointer.GetValue(FlowDirectionProperty);
                } 
                else
                {
                    // Positive is left to right, negative is right to left
                    flowDirection = (sign > 0 ? FlowDirection.LeftToRight : FlowDirection.RightToLeft); 
                }
            } 
 
            return flowDirection;
        } 
        /// <summary>
        /// Returns a moving position and the suggestedX value for it.
        /// </summary>
        /// <param name="This">TextEditor</param>
        /// <param name="innerMovingPosition">Inner moving position if it has valid layout, otherwise null.</param>
        /// <returns>Returns suggestedX when moving position has valid layout, Double.NaN otherwise.</returns>
        private static Double GetSuggestedX(TextEditor This, out ITextPointer innerMovingPosition)
        {
            // When getting moving position, we need to take care of end-of-line case
            // and adjust moving position according to its orientation.
            innerMovingPosition = TextEditorSelection.GetMovingPositionInner(This);

            // We need a non-dirty layout to walk pages.
            if (!innerMovingPosition.ValidateLayout())
            {
                innerMovingPosition = null;
                return Double.NaN; // This value is not supposed to be used by a caller.
            }

            if (Double.IsNaN(This._suggestedX))
            {
                This._suggestedX = GetAbsoluteXOffset(This.TextView, innerMovingPosition);

                // If the original moving position is on the other side of a line break,
                // add in the pixel width of the line break visualization.
                // Note this logic implicitly only modifies suggested x when the
                // selection is non-empty.
                if (This.Selection.MovingPosition.CompareTo(innerMovingPosition) > 0)
                {
                    double breakWidth = (double)innerMovingPosition.GetValue(TextElement.FontSizeProperty) * CaretElement.c_endOfParaMagicMultiplier;

                    FlowDirection paragraphFlowDirection = GetScopingParagraphFlowDirection(innerMovingPosition);
                    FlowDirection controlFlowDirection = This.UiScope.FlowDirection;

                    if (paragraphFlowDirection != controlFlowDirection)
                    {
                        // Adjust for X-axis flip on Paragraphs with non-default flow direction.
                        breakWidth = -breakWidth;
                    }

                    This._suggestedX += breakWidth; 
                }
            }

            return This._suggestedX;
        }
        /// <summary>
        ///   Convert TF_DA_COLOR to Color.
        /// </summary>
        internal static Color GetColor(UnsafeNativeMethods.TF_DA_COLOR dacolor, ITextPointer position)
        {
            if (dacolor.type == UnsafeNativeMethods.TF_DA_COLORTYPE.TF_CT_SYSCOLOR)
            {
                return GetSystemColor(dacolor.indexOrColorRef);
            }
            else if (dacolor.type == UnsafeNativeMethods.TF_DA_COLORTYPE.TF_CT_COLORREF)
            {
                int color = dacolor.indexOrColorRef;
                uint argb = (uint)FromWin32Value(color);
                return Color.FromArgb((byte)((argb & 0xff000000) >> 24), (byte)((argb & 0x00ff0000) >> 16), (byte)((argb & 0x0000ff00) >> 8), (byte)(argb & 0x000000ff));
            }

            Invariant.Assert(position != null, "position can't be null");
            return ((SolidColorBrush)position.GetValue(TextElement.ForegroundProperty)).Color;
        }