///////////////////////////////////////////////////////////////////// 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; }
///////////////////////////////////////////////////////////////////// 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); } }
///////////////////////////////////////////////////////////////////// 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); } } }
[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); } }
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; }
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; }
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>(); }
//------------------------------------------------------------------- // 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)); }
internal abstract void FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, bool oldValue);
///////////////////////////////////////////////////////////////////// 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; }
private static bool ValidateContentElementForCapture(ContentElement element) { if (element.IsEnabled == false) return false; // NOTE: there is no IsVisible property for ContentElements. return true; }
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; }
/// <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); } } } }
public static void SetParent(ContentElement reference, DependencyObject parent) { throw new NotImplementedException(); }
/// <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); }
/// <summary> /// <see cref="IContentHost.GetRectangles"/> /// </summary> ReadOnlyCollection<Rect> IContentHost.GetRectangles(ContentElement child) { return new ReadOnlyCollection<Rect>(new List<Rect>()); }
/// <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); }
// ------------------------------------------------------------------ // 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; }
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; }
// ------------------------------------------------------------------ // 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);
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; }
/// <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)); }
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; }
/// <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; }
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; }
public static DependencyObject GetParent(ContentElement reference) { throw new NotImplementedException(); }