Пример #1
0
        /////////////////////////////////////////////////////////////////////

        internal override void FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, bool oldValue)
        { 
            // This is all very sketchy...
            // 
            // Tablet can support multiple stylus devices concurrently.  They can each 
            // be over a different element.  They all update the IsStylusOver property,
            // which calls into here, but ends up using the "current" stylus device, 
            // instead of each using their own device.  Worse, all of these will end up
            // writing to the same bits in the UIElement.  They are going to step all over
            // each other.
            if(Stylus.CurrentStylusDevice == null) 
            {
                return; 
            } 

            StylusEventArgs stylusEventArgs = new StylusEventArgs(Stylus.CurrentStylusDevice, Environment.TickCount); 
            stylusEventArgs.RoutedEvent = oldValue ? Stylus.StylusLeaveEvent : Stylus.StylusEnterEvent;

            if (uie != null)
            { 
                uie.RaiseEvent(stylusEventArgs);
            } 
            else if (ce != null) 
            {
                ce.RaiseEvent(stylusEventArgs); 
            }
            else if (uie3D != null)
            {
                uie3D.RaiseEvent(stylusEventArgs); 
            }
        } 
        //-------------------------------------------------------------------
        //
        //  Internal Methods
        //
        //-------------------------------------------------------------------

        #region Internal Methods

        /// <summary>
        /// Given a ContentElement searches for associated IContentHost, if one exists.
        /// </summary>
        /// <param name="contentElement">Content element</param>
        /// <returns>Associated IContentHost with ContentElement.</returns>
        internal static IContentHost FindContentHost(ContentElement contentElement)
        {
            IContentHost ich = null;
            DependencyObject parent;
            TextContainer textContainer;

            if (contentElement == null) { return null; }

            // If the ContentElement is a TextElement, retrieve IContentHost form the owner
            // of TextContainer.
            if (contentElement is TextElement)
            {
                textContainer = ((TextElement)contentElement).TextContainer;
                parent = textContainer.Parent;
                if (parent is IContentHost) // TextBlock
                {
                    ich = (IContentHost)parent;
                }
                else if (parent is FlowDocument) // Viewers
                {
                    ich = GetICHFromFlowDocument((TextElement)contentElement, (FlowDocument)parent);
                }
                else if (textContainer.TextView != null && textContainer.TextView.RenderScope is IContentHost)
                {
                    // TextBlock hosted in ControlTemplate
                    ich = (IContentHost)textContainer.TextView.RenderScope;
                }
            }
            // else; cannot retrive IContentHost

            return ich;
        }
Пример #3
0
        /////////////////////////////////////////////////////////////////////

        internal override void FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, bool oldValue)
        {
            DependencyPropertyChangedEventArgs args = 
                    new DependencyPropertyChangedEventArgs(
                        UIElement.IsKeyboardFocusWithinProperty, 
                        BooleanBoxes.Box(oldValue), 
                        BooleanBoxes.Box(!oldValue));
            
            if (uie != null)
            {
                uie.RaiseIsKeyboardFocusWithinChanged(args);
            }
            else if (ce != null)
            {
                ce.RaiseIsKeyboardFocusWithinChanged(args);
            }
            else if (uie3D != null)
            {
                uie3D.RaiseIsKeyboardFocusWithinChanged(args);
            }
        }
Пример #4
0
        /////////////////////////////////////////////////////////////////////

        internal override void FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, bool oldValue)
        {
            // Before we fire the mouse event we need to figure if the notification is still relevant. 
            // This is because it is possible that the mouse state has changed during the previous 
            // property engine callout. Example: Consider a MessageBox being displayed during the 
            // IsMouseOver OnPropertyChanged override.
            
            bool shouldFireNotification = false;
            if (uie != null)
            {
                shouldFireNotification = (!oldValue && uie.IsMouseOver) || (oldValue && !uie.IsMouseOver);
            }
            else if (ce != null)
            {
                shouldFireNotification = (!oldValue && ce.IsMouseOver) || (oldValue && !ce.IsMouseOver);
            }
            else if (uie3D != null)
            {
                shouldFireNotification = (!oldValue && uie3D.IsMouseOver) || (oldValue && !uie3D.IsMouseOver);
            }

            if (shouldFireNotification)
            {
                MouseEventArgs mouseEventArgs = new MouseEventArgs(Mouse.PrimaryDevice, Environment.TickCount, Mouse.PrimaryDevice.StylusDevice);
                mouseEventArgs.RoutedEvent = oldValue ? Mouse.MouseLeaveEvent : Mouse.MouseEnterEvent;

                if (uie != null)
                {
                    uie.RaiseEvent(mouseEventArgs);
                }
                else if (ce != null)
                {
                    ce.RaiseEvent(mouseEventArgs);
                }
                else if (uie3D != null)
                {
                    uie3D.RaiseEvent(mouseEventArgs);
                }
            }
        }
Пример #5
0
        [FriendAccessAllowed] // Built into Core, also used by Framework.
        internal static void OnAncestorChanged(ContentElement ce)
        {
            if (ce == null)
            {
                throw new ArgumentNullException("ce");
            }


            if (true == (bool)ce.GetValue(GetsSourceChangedEventProperty))
            {
                UpdateSourceOfElement(ce, null, null);
            }
        }
Пример #6
0
        internal static List<Rect> GetRectanglesInTrack(
            PtsContext ptsContext,
            ContentElement e,
            int start,
            int length,
            ref PTS.FSTRACKDESCRIPTION trackDesc)
        {
            List<Rect> rectangles = new List<Rect>();
            // There is possibility to get empty track. (example: large figures)
            if (trackDesc.pfstrack == IntPtr.Zero)
            {
                // TRack is empty. Return empty list.
                return rectangles;
            }

            // Get track details
            PTS.FSTRACKDETAILS trackDetails;
            PTS.Validate(PTS.FsQueryTrackDetails(ptsContext.Context, trackDesc.pfstrack, out trackDetails));

            // There might be possibility to get empty track, skip the track
            // in such case.
            if (trackDetails.cParas != 0)
            {
                // Get list of paragraphs
                PTS.FSPARADESCRIPTION[] arrayParaDesc;
                ParaListFromTrack(ptsContext, trackDesc.pfstrack, ref trackDetails, out arrayParaDesc);

                // Check list of paragraphs for element
                rectangles = GetRectanglesInParaList(ptsContext, e, start, length, arrayParaDesc);
            }
            return rectangles;
        }
Пример #7
0
        private List<Rect> GetRectanglesInCompositeLines(
            ContentElement e,
            int start, 
            int length,
            ref PTS.FSTEXTDETAILSFULL textDetails) 
        { 
            ErrorHandler.Assert(!PTS.ToBoolean(textDetails.fDropCapPresent), ErrorHandler.NotSupportedDropCap);
 
            List<Rect> rectangles = new List<Rect>();
            int localStart = start - Paragraph.ParagraphStartCharacterPosition;

            if (localStart < 0) 
            {
                // May happen in case of figures, floaters 
                return rectangles; 
            }
 
            // Get list of complex lines.
            PTS.FSLINEDESCRIPTIONCOMPOSITE[] arrayLineDesc;
            PtsHelper.LineListCompositeFromTextPara(PtsContext, _paraHandle.Value, ref textDetails, out arrayLineDesc);
 
            // Find affected composite line by looking at vertical offset
            for (int index = 0; index < arrayLineDesc.Length; index++) 
            { 
                PTS.FSLINEDESCRIPTIONCOMPOSITE lineDesc = arrayLineDesc[index];
                if (lineDesc.cElements == 0) continue; 

                List<Rect> lineRectangles = GetRectanglesInCompositeLine(lineDesc, e, localStart, length);
                Invariant.Assert(lineRectangles != null);
 
                if (lineRectangles.Count != 0)
                { 
                    rectangles.AddRange(lineRectangles); 
                }
            } 

            return rectangles;
        }
Пример #8
0
        internal override List<Rect> GetRectangles(ContentElement e, int start, int length) 
        { 
            List<Rect> rectangles = new List<Rect>();
            Debug.Assert(Paragraph.Element as ContentElement != e); 

            PTS.FSTEXTDETAILS textDetails;
            PTS.Validate(PTS.FsQueryTextDetails(PtsContext.Context, _paraHandle.Value, out textDetails));
 
            // There are 3 different types of text paragraphs:
            // (a) full with simple lines 
            // (b) full with composite lines - when figures/floaters are present 
            // (c) cached - when using ParaChache
            if (textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdFull) 
            {
                // Check figures and floaters
                if (textDetails.u.full.cAttachedObjects > 0)
                { 
                    PTS.FSATTACHEDOBJECTDESCRIPTION[] arrayAttachedObjectDesc;
                    PtsHelper.AttachedObjectListFromParagraph(PtsContext, _paraHandle.Value, textDetails.u.full.cAttachedObjects, out arrayAttachedObjectDesc); 
 
                    for (int index = 0; index < arrayAttachedObjectDesc.Length; index++)
                    { 
                        PTS.FSATTACHEDOBJECTDESCRIPTION attachedObjectDesc = arrayAttachedObjectDesc[index];

                        BaseParaClient paraClient = PtsContext.HandleToObject(attachedObjectDesc.pfsparaclient) as BaseParaClient;
                        PTS.ValidateHandle(paraClient); 

                        if (start < paraClient.Paragraph.ParagraphEndCharacterPosition) 
                        { 
                            rectangles = paraClient.GetRectangles(e, start, length);
                            Invariant.Assert(rectangles != null); 
                            if (rectangles.Count != 0)
                            {
                                break;
                            } 
                        }
                    } 
                } 

                // If no success with figures and floaters, check in line 
                if (rectangles.Count == 0 && textDetails.u.full.cLines > 0)
                {
                    if (!PTS.ToBoolean(textDetails.u.full.fLinesComposite))
                    { 
                        // (a) full with simple lines
                        rectangles = GetRectanglesInSimpleLines(e, start, length, ref textDetails.u.full); 
                    } 
                    else
                    { 
                        // (b) full with complex lines
                        rectangles = GetRectanglesInCompositeLines(e, start, length, ref textDetails.u.full);
                    }
 
                    // Ensure these are specified in page coordinates.
                    if(rectangles.Count > 0 && ThisFlowDirection != PageFlowDirection) 
                    { 
                        PTS.FSRECT pageRect = _pageContext.PageRect;
 
                        for(int index = 0; index < rectangles.Count; index++)
                        {
                            PTS.FSRECT rectTransform = new PTS.FSRECT(rectangles[index]);
                            PTS.Validate(PTS.FsTransformRectangle(PTS.FlowDirectionToFswdir(ThisFlowDirection), ref pageRect, ref rectTransform, PTS.FlowDirectionToFswdir(PageFlowDirection), out rectTransform)); 
                            rectangles[index] = rectTransform.FromTextDpi();
                        } 
                    } 
                }
 
            }
            else
            {
                // (c) cached - when using ParaChache 
                Debug.Assert(textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdCached);
                Debug.Assert(false, "Should not get here. ParaCache is not currently used."); 
            } 

            Invariant.Assert(rectangles != null); 
            return rectangles;
        }
 // ------------------------------------------------------------------
 // Returns ArrayList of rectangles for the ContentElement e. 
 // Returns empty list if the paraClient does not contain e.
 // start: int representing start offset of e
 // length: int representing number of characters occupied by e.
 // parentOffset: indicates offset of parent element. Used only by
 //               subpage para clients when calculating rectangles
 // ------------------------------------------------------------------
 internal virtual List<Rect> GetRectangles(ContentElement e, int start, int length)
 {
     // Return empty collection as default
     return new List<Rect>();
 }
Пример #10
0
 //-------------------------------------------------------------------
 // Returns rectangles for a specified element.
 //
 //      e - ContentElement for which rectangles are to be returned
 //      start - int representing start offset of e
 //      length - int representing number of positions occupied by e
 //
 // Returns: ArrayList of rectangles. If element is not found or if 
 // there is nothing in this page, returns empty ArrayList
 //-------------------------------------------------------------------
 internal List<Rect> GetRectangles(ContentElement e, int start, int length)
 {
     List<Rect> rectangles = new List<Rect>();
     if (!IsEmpty)
     {
         rectangles = GetRectanglesInPage(e, start, length);
     }
     return rectangles;
 }
 public static void SetParent(ContentElement reference, DependencyObject parent)
 {
 }
 public static DependencyObject GetParent(ContentElement reference)
 {
     return(default(DependencyObject));
 }
Пример #13
0
 internal abstract void FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, bool oldValue);
Пример #14
0
        /////////////////////////////////////////////////////////////////////

        private static void CastElement(DependencyObject o, out UIElement uie, out ContentElement ce, out UIElement3D uie3D)
        {
            uie   = o as UIElement;
            ce    = (uie != null) ? null : o as ContentElement;
            uie3D = (uie != null || ce != null) ? null : o as UIElement3D;
        }
Пример #15
0
        private static bool ValidateContentElementForCapture(ContentElement element)
        {
            if (element.IsEnabled == false)
                return false;

            // NOTE: there is no IsVisible property for ContentElements.

            return true;
        }
Пример #16
0
        private List<Rect> GetRectanglesInPage(ContentElement e, int start, int length)
        {            
            // Rectangles to be returned
            List<Rect> rectangles = new List<Rect>();
            Invariant.Assert(!IsEmpty);

            // Get page details
            PTS.FSPAGEDETAILS pageDetails;
            PTS.Validate(PTS.FsQueryPageDetails(PtsContext.Context, _ptsPage.Value, out pageDetails));

            // Check for page content - if simple, contains only one track and we call the helper to
            // find the element within that track. If complex, we must traverse sections within the content.
            if (PTS.ToBoolean(pageDetails.fSimple))
            {
                // (1) simple page (contains only one track)
                rectangles = PtsHelper.GetRectanglesInTrack(PtsContext, e, start, length, ref pageDetails.u.simple.trackdescr);
            }
            else
            {
                // (2) complex page (contains header, page body (list of sections), footnotes and footer)
                //     NOTE: only page body (list of sections is currently supported).
                //ErrorHandler.Assert(!PTS.ToBoolean(pageDetails.u.complex.fTopBottomHeaderFooter), ErrorHandler.NotSupportedHeadersFooters);
                //ErrorHandler.Assert(!PTS.ToBoolean(pageDetails.u.complex.fJustified), ErrorHandler.NotSupportedVerticalJustify);
                ErrorHandler.Assert(pageDetails.u.complex.cFootnoteColumns == 0, ErrorHandler.NotSupportedFootnotes);

                // cSections == 0, means that page body content is empty.
                // In such case there is nothing to render.
                if (pageDetails.u.complex.cSections != 0)
                {
                    // Retrieve description for each section.
                    PTS.FSSECTIONDESCRIPTION[] arraySectionDesc;
                    PtsHelper.SectionListFromPage(PtsContext, _ptsPage.Value, ref pageDetails, out arraySectionDesc);

                    // Check each section for element
                    for (int index = 0; index < arraySectionDesc.Length; index++)
                    {
                        rectangles = GetRectanglesInSection(e, start, length, ref arraySectionDesc[index]);
                        
                        // For consistency, helpers cannot return null for rectangles
                        Invariant.Assert(rectangles != null);
                        if (rectangles.Count != 0)
                        {
                            // Found element and rectangles. We will sotp here because the element has been
                            // found and it cannot span more than one section. So we do not need to search
                            // the rest of the sections
                            break;
                        }
                    }
                }
                else
                {
                    // No complex content, return empty list
                    rectangles = new List<Rect>();
                }
            }
            return rectangles;
        }
Пример #17
0
        /// <summary>
        ///     Removes a handler for the SourceChanged event to the element.
        /// </summary>
        /// <param name="e">The element to remove the handler from.</param>
        /// <param name="handler">The hander to remove.</param>
        /// <remarks>
        ///     Even though this is a routed event handler, there are special
        ///     restrictions placed on this event.
        ///     1) You cannot use the UIElement or ContentElement RemoveHandler() method.
        /// </remarks>
        public static void RemoveSourceChangedHandler(IInputElement e, SourceChangedEventHandler handler)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }

            if (!InputElement.IsValid(e))
            {
                throw new ArgumentException(SR.Get(SRID.Invalid_IInputElement), "e");
            }
            DependencyObject o = (DependencyObject)e;

            //             o.VerifyAccess();

            // I would rather throw an exception here, but the CLR doesn't
            // so we won't either.
            if (handler != null)
            {
                FrugalObjectList <RoutedEventHandlerInfo> info = null;
                EventHandlersStore store;

                // Either UIElement or ContentElement.
                if (InputElement.IsUIElement(o))
                {
                    UIElement uie = o as UIElement;
                    uie.RemoveHandler(SourceChangedEvent, handler);
                    store = uie.EventHandlersStore;
                    if (store != null)
                    {
                        info = store[SourceChangedEvent];
                    }
                    if (info == null || info.Count == 0)
                    {
                        uie.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie.OnVisualAncestorChanged);;
                        RemoveElementFromWatchList(uie);
                    }
                }
                else if (InputElement.IsUIElement3D(o))
                {
                    UIElement3D uie3D = o as UIElement3D;
                    uie3D.RemoveHandler(SourceChangedEvent, handler);
                    store = uie3D.EventHandlersStore;
                    if (store != null)
                    {
                        info = store[SourceChangedEvent];
                    }
                    if (info == null || info.Count == 0)
                    {
                        uie3D.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie3D.OnVisualAncestorChanged);;
                        RemoveElementFromWatchList(uie3D);
                    }
                }
                else
                {
                    ContentElement ce = o as ContentElement;
                    ce.RemoveHandler(SourceChangedEvent, handler);
                    store = ce.EventHandlersStore;
                    if (store != null)
                    {
                        info = store[SourceChangedEvent];
                    }
                    if (info == null || info.Count == 0)
                    {
                        RemoveElementFromWatchList(ce);
                    }
                }
            }
        }
Пример #18
0
 public static void SetParent(ContentElement reference, DependencyObject parent)
 {
     throw new NotImplementedException();
 }
Пример #19
0
 /// <summary>
 /// Returns rectangles for element. First finds element by navigating in FlowDocumentPage.
 /// If element is not found or if call to get rectangles from FlowDocumentPage returns null
 /// we return an empty collection. If the layout is not valid we return null.
 /// </summary>
 /// <param name="child">
 /// Content element for which rectangles are required
 /// </param>
 ReadOnlyCollection<Rect> IContentHost.GetRectangles(ContentElement child)
 {
     // Restrict search to only the text segments in the page's text view. This is not needed for
     // HitTest because it takes only a point
     return this.GetRectanglesCore(child, true);
 }
Пример #20
0
 /// <summary> 
 /// <see cref="IContentHost.GetRectangles"/>
 /// </summary> 
 ReadOnlyCollection<Rect> IContentHost.GetRectangles(ContentElement child)
 {
     return new ReadOnlyCollection<Rect>(new List<Rect>());
 } 
Пример #21
0
        /// <summary>
        /// Returns rectangles for element. First finds element by navigating in FlowDocumentPage.
        /// If element is not found or if call to get rectangles from FlowDocumentPage returns null
        /// we return an empty collection. If the layout is not valid we return null.
        /// </summary>
        /// <param name="child">
        /// Content element for which rectangles are required
        /// </param>
        /// <param name="isLimitedToTextView">
        /// Indicates whether search should be restricted only to those text segments within the page's text view
        /// </param>
        internal ReadOnlyCollection<Rect> GetRectanglesCore(ContentElement child, bool isLimitedToTextView)
        {
            Invariant.Assert(!IsDisposed);

            List<Rect> rectangles = new List<Rect>();
            Debug.Assert(child != null);
            if (IsLayoutDataValid)
            {
                TextPointer elementStart = FindElementPosition(child, isLimitedToTextView);
                if (elementStart != null)
                {
                    // Element exists within this Page, calculate its length
                    int elementStartOffset = _structuralCache.TextContainer.Start.GetOffsetToPosition(elementStart);
                    int elementLength = 1;
                    if (child is TextElement)
                    {
                        TextPointer elementEnd = new TextPointer(((TextElement)child).ElementEnd);
                        elementLength = elementStart.GetOffsetToPosition(elementEnd);
                    }

                    rectangles = _ptsPage.GetRectangles(child, elementStartOffset, elementLength);
                }
            }

            if(this.PageVisual != null && rectangles.Count > 0)
            {
                List<Rect> transformedRectangles = new List<Rect>(rectangles.Count);
                // NOTE: TransformToAncestor is safe (will never throw an exception).
                GeneralTransform transform = this.PageVisual.Child.TransformToAncestor(this.PageVisual);

                for(int index = 0; index < rectangles.Count; index++)
                {
                    transformedRectangles.Add(transform.TransformBounds(rectangles[index]));
                }

                rectangles = transformedRectangles;
            }

            // We should never return null for rectangles from public API, only empty ArrayList
            Invariant.Assert(rectangles != null);

            return new ReadOnlyCollection<Rect>(rectangles);
        }
Пример #22
0
        // ------------------------------------------------------------------ 
        // Returns ArrayList of rectangles (at msot one) for the given ContentElement 
        // e if it spans all or part of the specified line
        // ----------------------------------------------------------------- 
        private List<Rect> GetRectanglesInSingleLine(
            PTS.FSLINEDESCRIPTIONSINGLE lineDesc,
            ContentElement e,
            int start, 
            int length)
        { 
            // Calculate end of element relative to TextParagraph by adding length to start position 
            int end = start + length;
            List<Rect> rectangles = new List<Rect>(); 

            // If the element does not lie in the line at all, return empty list
            if (start >= lineDesc.dcpLim)
            { 
                // Element starts after line ends
                return rectangles; 
            } 
            if (end <= lineDesc.dcpFirst)
            { 
                // Element ends before line starts
                return rectangles;
            }
 
            // Establish start and end points of element span within the line so that
            // we can get rectangle between them 
            int localStart = (start < lineDesc.dcpFirst) ? lineDesc.dcpFirst : start; 
            int localEnd = (end < lineDesc.dcpLim) ? end : lineDesc.dcpLim;
            Debug.Assert(localEnd > localStart); 

            // Create and format line
            Line line = new Line(Paragraph.StructuralCache.TextFormatterHost, this, Paragraph.ParagraphStartCharacterPosition);
            Line.FormattingContext ctx = new Line.FormattingContext(false, PTS.ToBoolean(lineDesc.fClearOnLeft), PTS.ToBoolean(lineDesc.fClearOnRight), TextParagraph.TextRunCache); 

            if(IsOptimalParagraph) 
            { 
                ctx.LineFormatLengthTarget = lineDesc.dcpLim - lineDesc.dcpFirst;
            } 

            TextParagraph.FormatLineCore(line, lineDesc.pfsbreakreclineclient, ctx, lineDesc.dcpFirst, lineDesc.dur, PTS.ToBoolean(lineDesc.fTreatedAsFirst), lineDesc.dcpFirst);

            // Assert that number of characters in Text line is the same as our expected length 
            Invariant.Assert(line.SafeLength == lineDesc.dcpLim - lineDesc.dcpFirst, "Line length is out of [....]");
 
            // Get rectangles from start and end positions of range 
            rectangles = line.GetRangeBounds(localStart, localEnd - localStart, TextDpi.FromTextDpi(lineDesc.urStart), TextDpi.FromTextDpi(lineDesc.vrStart));
 
            // Rectangles must have at least one element
            Invariant.Assert(rectangles.Count > 0);

            // Dispose the line 
            line.Dispose();
 
            return rectangles; 
        }
        internal static bool InvalidateAutomationPeer(
            DependencyObject o, 
            out UIElement e, 
            out ContentElement ce, 
            out UIElement3D e3d)
        {
            e = null;
            ce = null;
            e3d = null;
            
            AutomationPeer ap = null;
            
            e = o as UIElement;
            if (e != null)
            {
                if (e.HasAutomationPeer == true)
                    ap = e.GetAutomationPeer();
            }
            else
            {
                ce = o as ContentElement;
                if (ce != null)
                {
                    if (ce.HasAutomationPeer == true)
                        ap = ce.GetAutomationPeer();
                }
                else
                {
                    e3d = o as UIElement3D;
                    if (e3d != null)
                    {
                        if (e3d.HasAutomationPeer == true)
                            ap = e3d.GetAutomationPeer();
                    }
                }
            }

            if (ap != null)
            {
                ap.InvalidateAncestorsRecursive();
            
                // Check for parent being non-null while stopping as we don't want to stop in between due to peers not connected to AT
                // those peers sometimes gets created to serve for various patterns.
                // e.g: ScrollViewAutomationPeer for Scroll Pattern in case of ListBox.
                if (ap.GetParent() != null)
                    return false;
            }

            return true;
        }
Пример #24
0
        private List<Rect> GetRectanglesInCompositeLine(
            PTS.FSLINEDESCRIPTIONCOMPOSITE lineDesc, 
            ContentElement e, 
            int start,
            int length) 
        {
            List<Rect> rectangles = new List<Rect>();
            int end = start + length;
 
            // If the element does not lie in the line at all, return empty list
            //if (start > lineDesc.dcpLim) 
            //{ 
            //    // Element starts after line ends
            //    return rectangles; 
            //}
            //if (end < lineDesc.dcpFirst)
            //{
                // Element ends before line starts 
            //    return rectangles;
            //} 
 
            // Get list of line elements.
            PTS.FSLINEELEMENT[] arrayLineElement; 
            PtsHelper.LineElementListFromCompositeLine(PtsContext, ref lineDesc, out arrayLineElement);

            for (int elIndex = 0; elIndex < arrayLineElement.Length; elIndex++)
            { 
                PTS.FSLINEELEMENT element = arrayLineElement[elIndex];
 
                // Check if element we are looking for does not span the current element at all 
                if (start >= element.dcpLim)
                { 
                    // Element starts after other element ends
                    continue;
                }
                if (end <= element.dcpFirst) 
                {
                    // Element ends before line starts 
                    continue; 
                }
                // Establish start and end points of element span within the line so that 
                // we can get rectangle between them
                int localStart = (start < element.dcpFirst) ? element.dcpFirst : start;
                int localEnd = (end < element.dcpLim) ? end : element.dcpLim;
                Debug.Assert(localEnd > localStart); 

                Line line = new Line(Paragraph.StructuralCache.TextFormatterHost, this, Paragraph.ParagraphStartCharacterPosition); 
                Line.FormattingContext ctx = new Line.FormattingContext(false, PTS.ToBoolean(element.fClearOnLeft), PTS.ToBoolean(element.fClearOnRight), TextParagraph.TextRunCache); 

                if(IsOptimalParagraph) 
                {
                    ctx.LineFormatLengthTarget = element.dcpLim - element.dcpFirst;
                }
 
                TextParagraph.FormatLineCore(line, element.pfsbreakreclineclient, ctx, element.dcpFirst, element.dur, PTS.ToBoolean(lineDesc.fTreatedAsFirst), element.dcpFirst);
 
                // Assert that number of characters in Text line is the same as our expected length 
                Invariant.Assert(line.SafeLength == element.dcpLim - element.dcpFirst, "Line length is out of [....]");
 
                // Get rectangles from start and end positions of range for this element
                List<Rect> elementRectangles = line.GetRangeBounds(localStart, localEnd - localStart, TextDpi.FromTextDpi(element.urStart), TextDpi.FromTextDpi(lineDesc.vrStart));

                // Rectangles must have at least one element 
                Invariant.Assert(elementRectangles.Count > 0);
 
                // Add rectangles from this element to rectangles from whole line 
                rectangles.AddRange(elementRectangles);
 
                // Dispose the line
                line.Dispose();
            }
            return rectangles; 
        }
        /////////////////////////////////////////////////////////////////////

        private static bool BlockReverseInheritance(UIElement uie, ContentElement ce, UIElement3D uie3D)
        {
            if (uie != null)
            {
                return uie.BlockReverseInheritance();
            }
            else if (ce != null)
            {
                return ce.BlockReverseInheritance();
            }
            else if (uie3D != null)
            {
                return uie3D.BlockReverseInheritance();
            }

            return false;
        }
Пример #26
0
        // ------------------------------------------------------------------
        // Returns ArrayList of rectangles for the ContentElement e within the
        // list of paragraphs. If the element is not found, returns empty list.
        //      start: int representing start offset of e
        //      length: int representing number of positions occupied by e
        // ------------------------------------------------------------------
        internal static List<Rect> GetRectanglesInParaList(
            PtsContext ptsContext,
            ContentElement e,
            int start,
            int length,
            PTS.FSPARADESCRIPTION[] arrayParaDesc)
        {
            List<Rect> rectangles = new List<Rect>();

            for (int index = 0; index < arrayParaDesc.Length; index++)
            {
                BaseParaClient paraClient = ptsContext.HandleToObject(arrayParaDesc[index].pfsparaclient) as BaseParaClient;
                PTS.ValidateHandle(paraClient);
                if (start < paraClient.Paragraph.ParagraphEndCharacterPosition)
                {
                    // Element lies within the paraClient boundaries.
                    rectangles = paraClient.GetRectangles(e, start, length);

                    // Rectangles collection should not be null for consistency
                    Invariant.Assert(rectangles != null);
                    if (rectangles.Count != 0)
                    {
                        // Element cannot span more than one para client in the same track, so we stop
                        // if the element is found and the rectangles are calculated
                        break;
                    }
                }
            }
            return rectangles;
        }
        /////////////////////////////////////////////////////////////////////

        private static void SetFlag(UIElement uie, ContentElement ce, UIElement3D uie3D, CoreFlags flag, bool value)
        {
            if (uie != null)
            {
                uie.WriteFlag(flag, value);
            }
            else if (ce != null)
            {
                ce.WriteFlag(flag, value);
            }
            else if (uie3D != null)
            {
                uie3D.WriteFlag(flag, value);
            }
        }
        internal override List<Rect> GetRectangles(ContentElement e, int start, int length)
        {
            List<Rect> rectangles = new List<Rect>();

            if (this.Paragraph.Element as ContentElement == e)
            {
                // We have found the element. Return rectangles for this paragraph.
                GetRectanglesForParagraphElement(out rectangles);
            }
            else
            {
                // Element not found as Paragraph.Element. Look inside

                // Query paragraph details
                PTS.FSSUBTRACKDETAILS subtrackDetails;
                PTS.Validate(PTS.FsQuerySubtrackDetails(PtsContext.Context, _paraHandle.Value, out subtrackDetails));

                // There might be possibility to get empty sub-track, skip the sub-track
                // in such case.
                if (subtrackDetails.cParas != 0)
                {
                    // Get list of paragraphs
                    // No changes to offset, since there are no subpages generated, only lists of paragraphs
                    PTS.FSPARADESCRIPTION[] arrayParaDesc;
                    PtsHelper.ParaListFromSubtrack(PtsContext, _paraHandle.Value, ref subtrackDetails, out arrayParaDesc);

                    // Render list of paragraphs
                    rectangles = PtsHelper.GetRectanglesInParaList(PtsContext, e, start, length, arrayParaDesc);
                }
                else
                {
                    rectangles = new List<Rect>();
                }
            }

            // Rectangles must be non-null
            Invariant.Assert(rectangles != null);    
            return rectangles;
        }
        /////////////////////////////////////////////////////////////////////

        private static bool IsFlagSet(UIElement uie, ContentElement ce, UIElement3D uie3D, CoreFlags flag)
        {
            if (uie != null)
            {
                return uie.ReadFlag(flag);
            }
            else if (ce != null)
            {
                return ce.ReadFlag(flag);
            }
            else if (uie3D != null)
            {
                return uie3D.ReadFlag(flag);
            }

            return false;
        }
        /////////////////////////////////////////////////////////////////////

        private static void CastElement(DependencyObject o, out UIElement uie, out ContentElement ce, out UIElement3D uie3D)
        {
            uie = o as UIElement;
            ce = (uie != null) ? null : o as ContentElement;
            uie3D = (uie != null || ce != null) ? null : o as UIElement3D;
        }
 internal abstract void FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, bool oldValue);
Пример #32
0
        internal override List<Rect> GetRectangles(ContentElement e, int start, int length)
        { 
            List<Rect> rectangles = new List<Rect>();

            if (Paragraph.Element as ContentElement == e)
            { 
                // We have found the element. Return rectangles for this paragraph.
                GetRectanglesForParagraphElement(out rectangles); 
            } 
            else
            { 
                // Query subpage details
                PTS.FSSUBPAGEDETAILS subpageDetails;
                PTS.Validate(PTS.FsQuerySubpageDetails(PtsContext.Context, _paraHandle.Value, out subpageDetails));
 
                // Check subpage content for element. Subpage content may be simple or complex -
                // depending of set of features used in the content of the page. 
                // (1) simple subpage (contains only one track) 
                // (2) complex subpage (contains columns)
                if (PTS.ToBoolean(subpageDetails.fSimple)) 
                {
                    // (1) simple subpage (contains only one track)
                    rectangles = PtsHelper.GetRectanglesInTrack(PtsContext, e, start, length, ref subpageDetails.u.simple.trackdescr);
                } 
                else
                { 
                    // (2) complex page (contains columns) 
                    // cBasicColumns == 0, means that subpage content is empty
                    if (subpageDetails.u.complex.cBasicColumns != 0) 
                    {
                        // Retrieve description for each column.
                        PTS.FSTRACKDESCRIPTION[] arrayColumnDesc;
                        PtsHelper.TrackListFromSubpage(PtsContext, _paraHandle.Value, ref subpageDetails, out arrayColumnDesc); 

                        // Arrange each track 
                        for (int index = 0; index < arrayColumnDesc.Length; index++) 
                        {
                            List<Rect> trackRectangles = PtsHelper.GetRectanglesInTrack(PtsContext, e, start, length, ref arrayColumnDesc[index]); 
                            Invariant.Assert(trackRectangles != null);
                            if (trackRectangles.Count != 0)
                            {
                                // Add rectangles found in this track to all rectangles 
                                rectangles.AddRange(trackRectangles);
                            } 
                        } 
                    }
                } 

                rectangles = PtsHelper.OffsetRectangleList(rectangles, TextDpi.FromTextDpi(ContentRect.u), TextDpi.FromTextDpi(ContentRect.v));
            }
 
            Invariant.Assert(rectangles != null);
            return rectangles; 
        } 
Пример #33
0
 /// <summary>
 /// <see cref="IContentHost.GetRectangles"/>
 /// </summary>
 ReadOnlyCollection<Rect> IContentHost.GetRectangles(ContentElement child)
 {
     IContentHost host = _owner.Target as IContentHost;
     if (host != null)
     {
         return host.GetRectangles(child);
     }
     return new ReadOnlyCollection<Rect>(new List<Rect>(0));
 }
Пример #34
0
        private List<Rect> GetRectanglesInSection(
            ContentElement e,
            int start,
            int length,
            ref PTS.FSSECTIONDESCRIPTION sectionDesc)
        {
            // Get section details
            PTS.FSSECTIONDETAILS sectionDetails;
            PTS.Validate(PTS.FsQuerySectionDetails(PtsContext.Context, sectionDesc.pfssection, out sectionDetails));

            // Declare ArrayList to be returned
            List<Rect> rectangles = new List<Rect>();

            // There are 2 types of sections:
            // (1) with page notes - footnotes in section treated as endnotes
            // (2) with column notes - footnotes in section treated as column notes
            if (PTS.ToBoolean(sectionDetails.fFootnotesAsPagenotes))
            {
                // (1) with page notes - footnotes in section treated as endnotes
                ErrorHandler.Assert(sectionDetails.u.withpagenotes.cEndnoteColumns == 0, ErrorHandler.NotSupportedFootnotes);

                // 

                Debug.Assert(sectionDetails.u.withpagenotes.cSegmentDefinedColumnSpanAreas == 0);
                Debug.Assert(sectionDetails.u.withpagenotes.cHeightDefinedColumnSpanAreas == 0);

                // cBasicColumns == 0, means that section content is empty.
                // In such case there is nothing to hit-test.
                if (sectionDetails.u.withpagenotes.cBasicColumns != 0)
                {
                    // Retrieve description for each column.
                    PTS.FSTRACKDESCRIPTION[] arrayColumnDesc;
                    PtsHelper.TrackListFromSection(PtsContext, sectionDesc.pfssection, ref sectionDetails, out arrayColumnDesc);

                    // Check each column for element or part of element - element may span multiple
                    // columns/tracks
                    for (int index = 0; index < arrayColumnDesc.Length; index++)
                    {
                        // See if any rectangles for the element are found in this track
                        List<Rect> trackRectangles = PtsHelper.GetRectanglesInTrack(PtsContext, e, start, length, ref arrayColumnDesc[index]);
                        
                        // For consistency, rectangles collection is never null, only empty
                        Invariant.Assert(trackRectangles != null);
                        if (trackRectangles.Count != 0)
                        {
                            // Add rectangles found in this track to rectangles for element
                            rectangles.AddRange(trackRectangles);
                        }
                    }
                }
            }
            else
            {
                // (2) with column notes - footnotes in section treated as column notes
                ErrorHandler.Assert(false, ErrorHandler.NotSupportedCompositeColumns);
            }

            return rectangles;
        }
Пример #35
0
 /// <summary>
 /// Returns collection of rectangles for the BlockUIContainer element. 
 /// If the element is not the paragraph's owner, empty collection is returned.
 /// </summary>
 internal override List<Rect> GetRectangles(ContentElement e, int start, int length)
 {
     List<Rect> rectangles = new List<Rect>();
     if (Paragraph.Element == e)
     {
         // We have found the element. Return rectangles for this paragraph.
         GetRectanglesForParagraphElement(out rectangles);
     }
     return rectangles;
 }
Пример #36
0
        internal override List<Rect> GetRectangles(ContentElement e, int start, int length)
        {
            Debug.Assert(TableParagraph.Table != null
                        && CalculatedColumns != null);
            List<Rect> rectangles = new List<Rect>();

            if (TableParagraph.Table == e)
            {
                // We have found the element. Return rectangles for this paragraph.
                GetRectanglesForParagraphElement(out rectangles);
            }
            else
            {
                // Search subpage for table cells
                PTS.FSTABLEROWDESCRIPTION[] arrayTableRowDesc;
                PTS.FSKUPDATE fskupdTable;
                PTS.FSRECT rectTable;

                rectangles = new List<Rect>();
                if (QueryTableDetails(out arrayTableRowDesc, out fskupdTable, out rectTable))
                {
                    for (int iR = 0; iR < arrayTableRowDesc.Length; ++iR)
                    {
                        PTS.FSKUPDATE[] arrayUpdate;
                        IntPtr[] arrayFsCell;
                        PTS.FSTABLEKCELLMERGE[] arrayTableCellMerge;
                        QueryRowDetails(
                                arrayTableRowDesc[iR].pfstablerow,
                                out arrayFsCell,
                                out arrayUpdate,
                                out arrayTableCellMerge);
                        for (int iC = 0; iC < arrayFsCell.Length; ++iC)
                        {
                            if (arrayFsCell[iC] == IntPtr.Zero)
                            {
                                //  paginated case - cell may be null
                                continue;
                            }

                            CellParaClient cellParaClient = (CellParaClient)(PtsContext.HandleToObject(arrayFsCell[iC]));
                            if (start < cellParaClient.Paragraph.ParagraphEndCharacterPosition)
                            {
                                // Element start is within cell boundary
                                rectangles = cellParaClient.GetRectangles(e, start, length);
                                Invariant.Assert(rectangles != null);
                                if (rectangles.Count != 0)
                                {
                                    break;
                                }
                            }
                        }
                        if (rectangles.Count != 0)
                        {
                            break;
                        }
                    }
                }
            }

            Invariant.Assert(rectangles != null);
            return rectangles;
        }
Пример #37
0
 public static DependencyObject GetParent(ContentElement reference)
 {
     throw new NotImplementedException();
 }