// Token: 0x06002EE2 RID: 12002 RVA: 0x000D3AB0 File Offset: 0x000D1CB0 internal override bool IsAtCaretUnitBoundary(ITextPointer position) { FixedTextPointer ftp = this.Container.VerifyPosition(position); FixedPosition fixedPosition; if (this._GetFixedPosition(ftp, out fixedPosition)) { DependencyObject element = this.FixedPage.GetElement(fixedPosition.Node); if (element is Glyphs) { Glyphs glyphs = (Glyphs)element; int num = (glyphs.UnicodeString == null) ? 0 : glyphs.UnicodeString.Length; if (fixedPosition.Offset == num) { return(true); } GlyphRun measurementGlyphRun = glyphs.MeasurementGlyphRun; return(measurementGlyphRun.CaretStops == null || measurementGlyphRun.CaretStops[fixedPosition.Offset]); } else if (element is Image || element is Path) { return(true); } } return(false); }
// Token: 0x06002D1C RID: 11548 RVA: 0x000CB9FB File Offset: 0x000C9BFB internal FixedElement(FixedElement.ElementType type, FixedTextPointer start, FixedTextPointer end, int pageIndex) { this._type = type; this._start = start; this._end = end; this._pageIndex = pageIndex; }
// Token: 0x06002EE3 RID: 12003 RVA: 0x000D3B5C File Offset: 0x000D1D5C internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction) { FixedTextPointer ftp = this.Container.VerifyPosition(position); FixedPosition fixedPosition; if (this._GetFixedPosition(ftp, out fixedPosition)) { DependencyObject element = this.FixedPage.GetElement(fixedPosition.Node); if (element is Glyphs) { Glyphs glyphs = (Glyphs)element; GlyphRun glyphRun = glyphs.ToGlyphRun(); int num = (glyphRun.Characters == null) ? 0 : glyphRun.Characters.Count; CharacterHit characterHit = (fixedPosition.Offset == num) ? new CharacterHit(fixedPosition.Offset - 1, 1) : new CharacterHit(fixedPosition.Offset, 0); CharacterHit obj = (direction == LogicalDirection.Forward) ? glyphRun.GetNextCaretCharacterHit(characterHit) : glyphRun.GetPreviousCaretCharacterHit(characterHit); if (!characterHit.Equals(obj)) { LogicalDirection edge = LogicalDirection.Forward; if (obj.TrailingLength > 0) { edge = LogicalDirection.Backward; } int offset = obj.FirstCharacterIndex + obj.TrailingLength; return(this._CreateTextPointer(new FixedPosition(fixedPosition.Node, offset), edge)); } } } ITextPointer textPointer = position.CreatePointer(); textPointer.MoveToNextInsertionPosition(direction); return(textPointer); }
//Find the first valid insertion position after or before the boundary node private bool _GetFirstFixedPosition(FixedTextPointer ftp, out FixedPosition fixedP) { LogicalDirection dir = LogicalDirection.Forward; if (ftp.FlowPosition.FlowNode.Fp != 0) { //End boundary dir = LogicalDirection.Backward; } FlowPosition flowP = (FlowPosition)ftp.FlowPosition.Clone(); //Get the first node that comes before or after the boundary node(probably a start or end node) flowP.Move(dir); FixedTextPointer nav = new FixedTextPointer(true, dir, flowP); if (flowP.IsStart || flowP.IsEnd) { ((ITextPointer)nav).MoveToNextInsertionPosition(dir); } if (this.Container.GetPageNumber(nav) == this.PageIndex) { return(Container.FixedTextBuilder.GetFixedPosition(nav.FlowPosition, dir, out fixedP)); } else { //This position is on another page. fixedP = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0); return(false); } }
internal int GetPageNumber(ITextPointer textPointer) { FixedTextPointer fixedTextPointer = textPointer as FixedTextPointer; int pageNumber = int.MaxValue; if (fixedTextPointer != null) { if (fixedTextPointer.CompareTo(((ITextContainer)this).Start) == 0) { pageNumber = 0; } else if (fixedTextPointer.CompareTo(((ITextContainer)this).End) == 0) { pageNumber = this.FixedDocument.PageCount - 1; } else { FlowNode flowNode; int flowOffset; fixedTextPointer.FlowPosition.GetFlowNode(fixedTextPointer.LogicalDirection, out flowNode, out flowOffset); FixedElement fixedElement = flowNode.Cookie as FixedElement; if (flowNode.Type == FlowNodeType.Boundary) { if (flowNode.Fp > 0) { //Document end boundary node pageNumber = this.FixedDocument.PageCount - 1; } else { //Document start boundary node pageNumber = 0; } } else if (flowNode.Type == FlowNodeType.Virtual || flowNode.Type == FlowNodeType.Noop) { pageNumber = (int)flowNode.Cookie; } else if (fixedElement != null) { pageNumber = (int)fixedElement.PageIndex; } else { FixedPosition fixPos; bool res = FixedTextBuilder.GetFixedPosition(fixedTextPointer.FlowPosition, fixedTextPointer.LogicalDirection, out fixPos); Debug.Assert(res); if (res) { pageNumber = fixPos.Page; } } } } return(pageNumber); }
/// <summary> /// Determines if a position is located between two caret units. /// </summary> /// <param name="position"> /// Position to test. /// </param> /// <returns> /// Returns true if the specified position precedes or follows /// the first or last code point of a caret unit, respectively. /// </returns> /// <exception cref="System.InvalidOperationException"> /// Throws InvalidOperationException if IsValid is false. /// If IsValid returns false, Validate method must be called before /// calling this method. /// </exception> /// <remarks> /// In the context of this method, "caret unit" refers to a group /// of one or more Unicode code points that map to a single rendered /// glyph. /// </remarks> internal override bool IsAtCaretUnitBoundary(ITextPointer position) { FixedTextPointer ftp = Container.VerifyPosition(position); FixedPosition fixedp; if (_GetFixedPosition(ftp, out fixedp)) { DependencyObject element = this.FixedPage.GetElement(fixedp.Node); if (element is Glyphs) { Glyphs g = (Glyphs)element; int characterCount = (g.UnicodeString == null ? 0 : g.UnicodeString.Length); if (fixedp.Offset == characterCount) { //end of line -- allow caret return(true); } else { GlyphRun run = g.MeasurementGlyphRun; return(run.CaretStops == null || run.CaretStops[fixedp.Offset]); } } else if (element is Image || element is Path) { //support caret before and after image return(true); } else { // No text position should be on any other type of element Debug.Assert(false); } } return(false); }
// Token: 0x06002E74 RID: 11892 RVA: 0x000D2774 File Offset: 0x000D0974 private static void _GetFirstPageSearchPointers(ITextPointer start, ITextPointer end, int pageNumber, bool matchLast, out ITextPointer firstSearchPageStart, out ITextPointer firstSearchPageEnd) { if (matchLast) { DocumentSequenceTextPointer documentSequenceTextPointer = end as DocumentSequenceTextPointer; if (documentSequenceTextPointer != null) { FlowPosition pageStartFlowPosition = ((FixedTextContainer)documentSequenceTextPointer.ChildBlock.ChildContainer).FixedTextBuilder.GetPageStartFlowPosition(pageNumber); firstSearchPageStart = new DocumentSequenceTextPointer(documentSequenceTextPointer.ChildBlock, new FixedTextPointer(false, LogicalDirection.Forward, pageStartFlowPosition)); } else { FixedTextPointer fixedTextPointer = end as FixedTextPointer; firstSearchPageStart = new FixedTextPointer(false, LogicalDirection.Forward, fixedTextPointer.FixedTextContainer.FixedTextBuilder.GetPageStartFlowPosition(pageNumber)); } firstSearchPageEnd = end; return; } DocumentSequenceTextPointer documentSequenceTextPointer2 = start as DocumentSequenceTextPointer; if (documentSequenceTextPointer2 != null) { FlowPosition pageEndFlowPosition = ((FixedTextContainer)documentSequenceTextPointer2.ChildBlock.ChildContainer).FixedTextBuilder.GetPageEndFlowPosition(pageNumber); firstSearchPageEnd = new DocumentSequenceTextPointer(documentSequenceTextPointer2.ChildBlock, new FixedTextPointer(false, LogicalDirection.Backward, pageEndFlowPosition)); } else { FixedTextPointer fixedTextPointer2 = start as FixedTextPointer; firstSearchPageEnd = new FixedTextPointer(false, LogicalDirection.Backward, fixedTextPointer2.FixedTextContainer.FixedTextBuilder.GetPageEndFlowPosition(pageNumber)); } firstSearchPageStart = start; }
/// <summary> /// <see cref="TextViewBase.GetTightBoundingGeometryFromTextPositions"/> /// </summary> internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition) { PathGeometry boundingGeometry = new PathGeometry(); Debug.Assert(startPosition != null && this.Contains(startPosition)); Debug.Assert(endPosition != null && this.Contains(endPosition)); Dictionary <FixedPage, ArrayList> highlights = new Dictionary <FixedPage, ArrayList>(); FixedTextPointer startftp = this.Container.VerifyPosition(startPosition); FixedTextPointer endftp = this.Container.VerifyPosition(endPosition); this.Container.GetMultiHighlights(startftp, endftp, highlights, FixedHighlightType.TextSelection, null, null); ArrayList highlightList; highlights.TryGetValue(this.FixedPage, out highlightList); if (highlightList != null) { foreach (FixedHighlight fh in highlightList) { if (fh.HighlightType == FixedHighlightType.None) { continue; } Rect backgroundRect = fh.ComputeDesignRect(); if (backgroundRect == Rect.Empty) { continue; } GeneralTransform transform = fh.Element.TransformToAncestor(this.FixedPage); Transform t = transform.AffineTransform; if (t == null) { t = Transform.Identity; } Glyphs g = fh.Glyphs; if (fh.Element.Clip != null) { Rect clipRect = fh.Element.Clip.Bounds; backgroundRect.Intersect(clipRect); } Geometry thisGeometry = new RectangleGeometry(backgroundRect); thisGeometry.Transform = t; backgroundRect = transform.TransformBounds(backgroundRect); boundingGeometry.AddGeometry(thisGeometry); } } return(boundingGeometry); }
/// <summary> /// <see cref="ITextPointer.MoveToPosition"/> /// </summary> void ITextPointer.MoveToPosition(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!"); _flowPosition.MoveTo(ftp.FlowPosition); }
// Token: 0x06002EB5 RID: 11957 RVA: 0x000D3098 File Offset: 0x000D1298 bool ITextPointer.HasEqualScope(ITextPointer position) { FixedTextPointer fixedTextPointer = this.FixedTextContainer.VerifyPosition(position); FixedElement scopingElement = this._flowPosition.GetScopingElement(); FixedElement scopingElement2 = fixedTextPointer.FlowPosition.GetScopingElement(); return(scopingElement == scopingElement2); }
/// <summary> /// Determines whenever TextView contains specified position. /// </summary> /// <param name="position"> /// A position to test. /// </param> /// <returns> /// True if TextView contains specified text position. /// Otherwise returns false. /// </returns> /// <exception cref="System.InvalidOperationException"> /// Throws InvalidOperationException if IsValid is false. /// If IsValid returns false, Validate method must be called before /// calling this method. /// </exception> internal override bool Contains(ITextPointer position) { FixedTextPointer tp = Container.VerifyPosition(position); return((tp.CompareTo(this.Start) > 0 && tp.CompareTo(this.End) < 0) || (tp.CompareTo(this.Start) == 0 && (tp.LogicalDirection == LogicalDirection.Forward || this.IsContainerStart)) || (tp.CompareTo(this.End) == 0 && (tp.LogicalDirection == LogicalDirection.Backward || this.IsContainerEnd)) ); }
/// <summary> /// <see cref="ITextPointer.HasEqualScope"/> /// </summary> bool ITextPointer.HasEqualScope(ITextPointer position) { FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position); FixedElement thisFE = _flowPosition.GetScopingElement(); FixedElement thatFE = ftp.FlowPosition.GetScopingElement(); // We retun true even if both scoping elements are the // container element. return(thisFE == thatFE); }
// Token: 0x06002EA0 RID: 11936 RVA: 0x000D2AD4 File Offset: 0x000D0CD4 internal int GetPageNumber(ITextPointer textPointer) { FixedTextPointer fixedTextPointer = textPointer as FixedTextPointer; int result = int.MaxValue; if (fixedTextPointer != null) { if (fixedTextPointer.CompareTo(((ITextContainer)this).Start) == 0) { result = 0; } else if (fixedTextPointer.CompareTo(((ITextContainer)this).End) == 0) { result = this.FixedDocument.PageCount - 1; } else { FlowNode flowNode; int num; fixedTextPointer.FlowPosition.GetFlowNode(fixedTextPointer.LogicalDirection, out flowNode, out num); FixedElement fixedElement = flowNode.Cookie as FixedElement; if (flowNode.Type == FlowNodeType.Boundary) { if (flowNode.Fp > 0) { result = this.FixedDocument.PageCount - 1; } else { result = 0; } } else if (flowNode.Type == FlowNodeType.Virtual || flowNode.Type == FlowNodeType.Noop) { result = (int)flowNode.Cookie; } else if (fixedElement != null) { result = fixedElement.PageIndex; } else { FixedPosition fixedPosition2; bool fixedPosition = this.FixedTextBuilder.GetFixedPosition(fixedTextPointer.FlowPosition, fixedTextPointer.LogicalDirection, out fixedPosition2); if (fixedPosition) { result = fixedPosition2.Page; } } } } return(result); }
//-------------------------------------------------------------------- // FlowPosition --> FixedPosition //--------------------------------------------------------------------- // Helper function to overcome the limitation in FixedTextBuilder.GetFixedPosition // Making sure we are asking a position that is either a Run or an EmbeddedElement. private bool _GetFixedPosition(FixedTextPointer ftp, out FixedPosition fixedp) { LogicalDirection textdir = ftp.LogicalDirection; TextPointerContext symbolType = ((ITextPointer)ftp).GetPointerContext(textdir); if (ftp.FlowPosition.IsBoundary || symbolType == TextPointerContext.None) { return(_GetFirstFixedPosition(ftp, out fixedp)); } if (symbolType == TextPointerContext.ElementStart || symbolType == TextPointerContext.ElementEnd) { //Try to find the first valid insertion position if exists switch (symbolType) { case TextPointerContext.ElementStart: textdir = LogicalDirection.Forward; break; case TextPointerContext.ElementEnd: textdir = LogicalDirection.Backward; break; } FixedTextPointer nav = new FixedTextPointer(true, textdir, (FlowPosition)ftp.FlowPosition.Clone()); _SkipFormattingTags(nav); symbolType = ((ITextPointer)nav).GetPointerContext(textdir); if (symbolType != TextPointerContext.Text && symbolType != TextPointerContext.EmbeddedElement) { //Try moving to the next insertion position if (((ITextPointer)nav).MoveToNextInsertionPosition(textdir) && this.Container.GetPageNumber(nav) == this.PageIndex) { return(Container.FixedTextBuilder.GetFixedPosition(nav.FlowPosition, textdir, out fixedp)); } else { fixedp = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0); return(false); } } else { ftp = nav; } } Debug.Assert(symbolType == TextPointerContext.Text || symbolType == TextPointerContext.EmbeddedElement); return(Container.FixedTextBuilder.GetFixedPosition(ftp.FlowPosition, textdir, out fixedp)); }
//-------------------------------------------------------------------- // // Private Methods // //--------------------------------------------------------------------- #region Private Methods //-------------------------------------------------------------------- // Initilization //--------------------------------------------------------------------- private void _CreateEmptyContainer() { // new text builder with map _fixedTextBuilder = new FixedTextBuilder(this); // create initial TextPointer and container element _start = new FixedTextPointer(false, LogicalDirection.Backward, new FlowPosition(this, this.FixedTextBuilder.FixedFlowMap.FlowStartEdge, 1)); _end = new FixedTextPointer(false, LogicalDirection.Forward, new FlowPosition(this, this.FixedTextBuilder.FixedFlowMap.FlowEndEdge, 0)); _containerElement = new FixedElement(FixedElement.ElementType.Container, _start, _end, int.MaxValue); _start.FlowPosition.AttachElement(_containerElement); _end.FlowPosition.AttachElement(_containerElement); }
// Token: 0x06002EA9 RID: 11945 RVA: 0x000D2E8C File Offset: 0x000D108C private bool _GetFixedNodesForFlowRange(ITextPointer start, ITextPointer end, out FixedSOMElement[] elements, out int startIndex, out int endIndex) { elements = null; startIndex = 0; endIndex = 0; if (start.CompareTo(end) == 0) { return(false); } FixedTextPointer fixedTextPointer = (FixedTextPointer)start; FixedTextPointer fixedTextPointer2 = (FixedTextPointer)end; return(this.FixedTextBuilder.GetFixedNodesForFlowRange(fixedTextPointer.FlowPosition, fixedTextPointer2.FlowPosition, out elements, out startIndex, out endIndex)); }
// Token: 0x06002CBF RID: 11455 RVA: 0x000C9CB4 File Offset: 0x000C7EB4 internal int GetPageNumber(ContentPosition contentPosition) { if (contentPosition == null) { throw new ArgumentNullException("contentPosition"); } FixedTextPointer fixedTextPointer = contentPosition as FixedTextPointer; if (fixedTextPointer == null) { throw new ArgumentException(SR.Get("IDPInvalidContentPosition")); } return(fixedTextPointer.FixedTextContainer.GetPageNumber(fixedTextPointer)); }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ #region Constructors // Ctor always set mutable flag to false internal FixedElement(ElementType type, FixedTextPointer start, FixedTextPointer end, int pageIndex) { _type = type; #if DEBUG if (_type == ElementType.Object) // is EmbeddedObject { Debug.Assert((object)_start == (object)_end); } _children = new List <FixedElement>(); #endif _start = start; _end = end; _pageIndex = pageIndex; }
// Token: 0x06002EA8 RID: 11944 RVA: 0x000D2E3C File Offset: 0x000D103C internal void OnNewFlowElement(FixedElement parentElement, FixedElement.ElementType elementType, FlowPosition pStart, FlowPosition pEnd, object source, int pageIndex) { FixedTextPointer start = new FixedTextPointer(false, LogicalDirection.Backward, pStart); FixedTextPointer end = new FixedTextPointer(false, LogicalDirection.Forward, pEnd); FixedElement fixedElement = new FixedElement(elementType, start, end, pageIndex); if (source != null) { fixedElement.Object = source; } parentElement.Append(fixedElement); pStart.AttachElement(fixedElement); pEnd.AttachElement(fixedElement); }
private static void _GetFirstPageSearchPointers(ITextPointer start, ITextPointer end, int pageNumber, bool matchLast, out ITextPointer firstSearchPageStart, out ITextPointer firstSearchPageEnd) { if (matchLast) { //The page in question is the last page //Need to search between the start of the last page and the end pointer DocumentSequenceTextPointer endAsDSTP = end as DocumentSequenceTextPointer; if (endAsDSTP != null) { FlowPosition pageStartFlowPosition = ((FixedTextContainer)(endAsDSTP.ChildBlock.ChildContainer)).FixedTextBuilder.GetPageStartFlowPosition(pageNumber); firstSearchPageStart = new DocumentSequenceTextPointer(endAsDSTP.ChildBlock, new FixedTextPointer(false, LogicalDirection.Forward, pageStartFlowPosition)); } else { FixedTextPointer endAsFTP = end as FixedTextPointer; Debug.Assert(endAsFTP != null); firstSearchPageStart = new FixedTextPointer(false, LogicalDirection.Forward, endAsFTP.FixedTextContainer.FixedTextBuilder.GetPageStartFlowPosition(pageNumber)); } firstSearchPageEnd = end; } else { //The page in question is the first page //Need to search between the start pointer and the end of the first page DocumentSequenceTextPointer startAsDSTP = start as DocumentSequenceTextPointer; if (startAsDSTP != null) { FlowPosition pageEndFlowPosition = ((FixedTextContainer)startAsDSTP.ChildBlock.ChildContainer).FixedTextBuilder.GetPageEndFlowPosition(pageNumber); firstSearchPageEnd = new DocumentSequenceTextPointer(startAsDSTP.ChildBlock, new FixedTextPointer(false, LogicalDirection.Backward, pageEndFlowPosition)); } else { FixedTextPointer startAsFTP = start as FixedTextPointer; Debug.Assert(startAsFTP != null); firstSearchPageEnd = new FixedTextPointer(false, LogicalDirection.Backward, startAsFTP.FixedTextContainer.FixedTextBuilder.GetPageEndFlowPosition(pageNumber)); } firstSearchPageStart = start; } }
internal void OnNewFlowElement(FixedElement parentElement, FixedElement.ElementType elementType, FlowPosition pStart, FlowPosition pEnd, Object source, int pageIndex) { FixedTextPointer eStart = new FixedTextPointer(false, LogicalDirection.Backward, pStart); FixedTextPointer eEnd = new FixedTextPointer(false, LogicalDirection.Forward, pEnd); FixedElement e = new FixedElement(elementType, eStart, eEnd, pageIndex); if (source != null) { e.Object = source; } // hook up logical tree parentElement.Append(e); // attach element to flownode for faster lookup later. pStart.AttachElement(e); pEnd.AttachElement(e); }
//-------------------------------------------------------------------- // TextContainer Element //--------------------------------------------------------------------- // given a TextPointer range, find out all fixed position included in this range and // offset into the begin and end fixed element private bool _GetFixedNodesForFlowRange(ITextPointer start, ITextPointer end, out FixedSOMElement[] elements, out int startIndex, out int endIndex) { Debug.Assert(start.CompareTo(end) <= 0); elements = null; startIndex = 0; endIndex = 0; if (start.CompareTo(end) == 0) { return(false); } FixedTextPointer pStart = (FixedTextPointer)start; FixedTextPointer pEnd = (FixedTextPointer)end; return(this.FixedTextBuilder.GetFixedNodesForFlowRange(pStart.FlowPosition, pEnd.FlowPosition, out elements, out startIndex, out endIndex)); } //endofGetFixedNodes
// Token: 0x06002EE0 RID: 12000 RVA: 0x000D382C File Offset: 0x000D1A2C internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition) { PathGeometry pathGeometry = new PathGeometry(); Dictionary <FixedPage, ArrayList> dictionary = new Dictionary <FixedPage, ArrayList>(); FixedTextPointer start = this.Container.VerifyPosition(startPosition); FixedTextPointer end = this.Container.VerifyPosition(endPosition); this.Container.GetMultiHighlights(start, end, dictionary, FixedHighlightType.TextSelection, null, null); ArrayList arrayList; dictionary.TryGetValue(this.FixedPage, out arrayList); if (arrayList != null) { foreach (object obj in arrayList) { FixedHighlight fixedHighlight = (FixedHighlight)obj; if (fixedHighlight.HighlightType != FixedHighlightType.None) { Rect rect = fixedHighlight.ComputeDesignRect(); if (!(rect == Rect.Empty)) { GeneralTransform generalTransform = fixedHighlight.Element.TransformToAncestor(this.FixedPage); Transform transform = generalTransform.AffineTransform; if (transform == null) { transform = Transform.Identity; } Glyphs glyphs = fixedHighlight.Glyphs; if (fixedHighlight.Element.Clip != null) { Rect bounds = fixedHighlight.Element.Clip.Bounds; rect.Intersect(bounds); } Geometry geometry = new RectangleGeometry(rect); geometry.Transform = transform; rect = generalTransform.TransformBounds(rect); pathGeometry.AddGeometry(geometry); } } } } return(pathGeometry); }
/// <summary> /// Returns a TextSegment that spans the line on which position is located. /// </summary> /// <param name="position"> /// Any oriented text position on the line. /// </param> /// <returns> /// TextSegment that spans the line on which position is located. /// </returns> /// <exception cref="System.InvalidOperationException"> /// Throws InvalidOperationException if IsValid is false. /// If IsValid returns false, Validate method must be called before /// calling this method. /// </exception> internal override TextSegment GetLineRange(ITextPointer position) { #if DEBUG DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("GetLineRange {0}, {1}", (FixedTextPointer)position, position.LogicalDirection)); #endif FixedTextPointer ftp = Container.VerifyPosition(position); FixedPosition fixedp; if (!_GetFixedPosition(ftp, out fixedp)) { return(new TextSegment(position, position, true)); } int count = 0; FixedNode[] fixedNodes = Container.FixedTextBuilder.GetNextLine(fixedp.Node, true, ref count); if (fixedNodes == null) { // This will happen in the case of images fixedNodes = new FixedNode[] { fixedp.Node }; } FixedNode lastNode = fixedNodes[fixedNodes.Length - 1]; DependencyObject element = FixedPage.GetElement(lastNode); int lastIndex = 1; if (element is Glyphs) { lastIndex = ((Glyphs)element).UnicodeString.Length; } ITextPointer begin = _CreateTextPointer(new FixedPosition(fixedNodes[0], 0), LogicalDirection.Forward); ITextPointer end = _CreateTextPointer(new FixedPosition(lastNode, lastIndex), LogicalDirection.Backward); if (begin.CompareTo(end) > 0) { ITextPointer temp = begin; begin = end; end = temp; } return(new TextSegment(begin, end, true)); }
// Token: 0x06002EF6 RID: 12022 RVA: 0x000D45B4 File Offset: 0x000D27B4 private bool _GetFixedPosition(FixedTextPointer ftp, out FixedPosition fixedp) { LogicalDirection logicalDirection = ftp.LogicalDirection; TextPointerContext pointerContext = ((ITextPointer)ftp).GetPointerContext(logicalDirection); if (ftp.FlowPosition.IsBoundary || pointerContext == TextPointerContext.None) { return(this._GetFirstFixedPosition(ftp, out fixedp)); } if (pointerContext == TextPointerContext.ElementStart || pointerContext == TextPointerContext.ElementEnd) { if (pointerContext != TextPointerContext.ElementStart) { if (pointerContext == TextPointerContext.ElementEnd) { logicalDirection = LogicalDirection.Backward; } } else { logicalDirection = LogicalDirection.Forward; } FixedTextPointer fixedTextPointer = new FixedTextPointer(true, logicalDirection, (FlowPosition)ftp.FlowPosition.Clone()); this._SkipFormattingTags(fixedTextPointer); pointerContext = ((ITextPointer)fixedTextPointer).GetPointerContext(logicalDirection); if (pointerContext != TextPointerContext.Text && pointerContext != TextPointerContext.EmbeddedElement) { if (((ITextPointer)fixedTextPointer).MoveToNextInsertionPosition(logicalDirection) && this.Container.GetPageNumber(fixedTextPointer) == this.PageIndex) { return(this.Container.FixedTextBuilder.GetFixedPosition(fixedTextPointer.FlowPosition, logicalDirection, out fixedp)); } fixedp = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0); return(false); } else { ftp = fixedTextPointer; } } return(this.Container.FixedTextBuilder.GetFixedPosition(ftp.FlowPosition, logicalDirection, out fixedp)); }
/// <summary> /// Finds the next position at the edge of a caret unit in /// specified direction. /// </summary> /// <param name="position"> /// Initial text position of an object/character. /// </param> /// <param name="direction"> /// If Forward, this method returns the "caret unit" position following /// the initial position. /// If Backward, this method returns the caret unit" position preceding /// the initial position. /// </param> /// <returns> /// The next caret unit break position in specified direction. /// </returns> /// <exception cref="System.InvalidOperationException"> /// Throws InvalidOperationException if IsValid is false. /// If IsValid returns false, Validate method must be called before /// calling this method. /// </exception> /// <remarks> /// In the context of this method, "caret unit" refers to a group of one /// or more Unicode code points that map to a single rendered glyph. /// /// If position is located between two caret units, this method returns /// a new position located at the opposite edge of the caret unit in /// the indicated direction. /// If position is located within a group of Unicode code points that map /// to a single caret unit, this method returns a new position at /// the indicated edge of the containing caret unit. /// If position is located at the beginning of end of content -- there is /// no content in the indicated direction -- then this method returns /// a position located at the same location as initial position. /// </remarks> internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction) { FixedTextPointer ftp = Container.VerifyPosition(position); FixedPosition fixedp; if (_GetFixedPosition(ftp, out fixedp)) { DependencyObject element = this.FixedPage.GetElement(fixedp.Node); if (element is Glyphs) { Glyphs g = (Glyphs)element; GlyphRun run = g.ToGlyphRun(); int characterCount = (run.Characters == null) ? 0 : run.Characters.Count; CharacterHit start = (fixedp.Offset == characterCount) ? new CharacterHit(fixedp.Offset - 1, 1) : new CharacterHit(fixedp.Offset, 0); CharacterHit next = (direction == LogicalDirection.Forward) ? run.GetNextCaretCharacterHit(start) : run.GetPreviousCaretCharacterHit(start); if (!start.Equals(next)) { LogicalDirection edge = LogicalDirection.Forward; if (next.TrailingLength > 0) { edge = LogicalDirection.Backward; } int index = next.FirstCharacterIndex + next.TrailingLength; return(_CreateTextPointer(new FixedPosition(fixedp.Node, index), edge)); } } } //default behavior is to simply move textpointer ITextPointer pointer = position.CreatePointer(); pointer.MoveToNextInsertionPosition(direction); return(pointer); }
//-------------------------------------------------------------------- // // Internal Methods // //--------------------------------------------------------------------- #region Internal Methods //-------------------------------------------------------------------- // Utility Method //--------------------------------------------------------------------- internal FixedTextPointer VerifyPosition(ITextPointer position) { if (position == null) { throw new ArgumentNullException("position"); } if (position.TextContainer != this) { throw new ArgumentException(SR.Get(SRID.NotInAssociatedContainer, "position")); } FixedTextPointer ftp = position as FixedTextPointer; if (ftp == null) { throw new ArgumentException(SR.Get(SRID.BadFixedTextPosition, "position")); } return(ftp); }
// Token: 0x06002EE5 RID: 12005 RVA: 0x000D3C68 File Offset: 0x000D1E68 internal override TextSegment GetLineRange(ITextPointer position) { FixedTextPointer ftp = this.Container.VerifyPosition(position); FixedPosition fixedPosition; if (!this._GetFixedPosition(ftp, out fixedPosition)) { return(new TextSegment(position, position, true)); } int num = 0; FixedNode[] array = this.Container.FixedTextBuilder.GetNextLine(fixedPosition.Node, true, ref num); if (array == null) { array = new FixedNode[] { fixedPosition.Node }; } FixedNode fixedNode = array[array.Length - 1]; DependencyObject element = this.FixedPage.GetElement(fixedNode); int offset = 1; if (element is Glyphs) { offset = ((Glyphs)element).UnicodeString.Length; } ITextPointer textPointer = this._CreateTextPointer(new FixedPosition(array[0], 0), LogicalDirection.Forward); ITextPointer textPointer2 = this._CreateTextPointer(new FixedPosition(fixedNode, offset), LogicalDirection.Backward); if (textPointer.CompareTo(textPointer2) > 0) { ITextPointer textPointer3 = textPointer; textPointer = textPointer2; textPointer2 = textPointer3; } return(new TextSegment(textPointer, textPointer2, true)); }
// Token: 0x06002EF7 RID: 12023 RVA: 0x000D46A8 File Offset: 0x000D28A8 private bool _GetFirstFixedPosition(FixedTextPointer ftp, out FixedPosition fixedP) { LogicalDirection logicalDirection = LogicalDirection.Forward; if (ftp.FlowPosition.FlowNode.Fp != 0) { logicalDirection = LogicalDirection.Backward; } FlowPosition flowPosition = (FlowPosition)ftp.FlowPosition.Clone(); flowPosition.Move(logicalDirection); FixedTextPointer fixedTextPointer = new FixedTextPointer(true, logicalDirection, flowPosition); if (flowPosition.IsStart || flowPosition.IsEnd) { ((ITextPointer)fixedTextPointer).MoveToNextInsertionPosition(logicalDirection); } if (this.Container.GetPageNumber(fixedTextPointer) == this.PageIndex) { return(this.Container.FixedTextBuilder.GetFixedPosition(fixedTextPointer.FlowPosition, logicalDirection, out fixedP)); } fixedP = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0); return(false); }
// Token: 0x06002E9F RID: 11935 RVA: 0x000D2A68 File Offset: 0x000D0C68 internal FixedTextPointer VerifyPosition(ITextPointer position) { if (position == null) { throw new ArgumentNullException("position"); } if (position.TextContainer != this) { throw new ArgumentException(SR.Get("NotInAssociatedContainer", new object[] { "position" })); } FixedTextPointer fixedTextPointer = position as FixedTextPointer; if (fixedTextPointer == null) { throw new ArgumentException(SR.Get("BadFixedTextPosition", new object[] { "position" })); } return(fixedTextPointer); }
//-------------------------------------------------------------------- // FlowPosition --> FixedPosition //--------------------------------------------------------------------- // Helper function to overcome the limitation in FixedTextBuilder.GetFixedPosition // Making sure we are asking a position that is either a Run or an EmbeddedElement. private bool _GetFixedPosition(FixedTextPointer ftp, out FixedPosition fixedp) { LogicalDirection textdir = ftp.LogicalDirection; TextPointerContext symbolType = ((ITextPointer)ftp).GetPointerContext(textdir); if (ftp.FlowPosition.IsBoundary || symbolType == TextPointerContext.None) { return _GetFirstFixedPosition(ftp, out fixedp); } if (symbolType == TextPointerContext.ElementStart || symbolType == TextPointerContext.ElementEnd) { //Try to find the first valid insertion position if exists switch (symbolType) { case TextPointerContext.ElementStart: textdir = LogicalDirection.Forward; break; case TextPointerContext.ElementEnd: textdir = LogicalDirection.Backward; break; } FixedTextPointer nav = new FixedTextPointer(true, textdir, (FlowPosition)ftp.FlowPosition.Clone()); _SkipFormattingTags(nav); symbolType = ((ITextPointer)nav).GetPointerContext(textdir); if (symbolType != TextPointerContext.Text && symbolType != TextPointerContext.EmbeddedElement) { //Try moving to the next insertion position if (((ITextPointer)nav).MoveToNextInsertionPosition(textdir) && this.Container.GetPageNumber(nav) == this.PageIndex) { return Container.FixedTextBuilder.GetFixedPosition(nav.FlowPosition, textdir, out fixedp); } else { fixedp = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0); return false; } } else { ftp = nav; } } Debug.Assert(symbolType == TextPointerContext.Text || symbolType == TextPointerContext.EmbeddedElement); return Container.FixedTextBuilder.GetFixedPosition(ftp.FlowPosition, textdir, out fixedp); }
/// <summary> /// Retrieves an oriented text position matching position advanced by /// a number of lines from its initial position. /// </summary> /// <param name="position"> /// Initial text position of an object/character. /// </param> /// <param name="suggestedX"> /// The suggested X offset, in pixels, of text position on the destination /// line. If suggestedX is set to Double.NaN it will be ignored, otherwise /// the method will try to find a position on the destination line closest /// to suggestedX. /// </param> /// <param name="count"> /// Number of lines to advance. Negative means move backwards. /// </param> /// <param name="newSuggestedX"> /// newSuggestedX is the offset at the position moved (useful when moving /// between columns or pages). /// </param> /// <param name="linesMoved"> /// linesMoved indicates the number of lines moved, which may be less /// than count if there is no more content. /// </param> /// <returns> /// A TextPointer and its orientation matching suggestedX on the /// destination line. /// </returns> /// <exception cref="System.InvalidOperationException"> /// Throws InvalidOperationException if IsValid is false. /// If IsValid returns false, Validate method must be called before /// calling this method. /// </exception> internal override ITextPointer GetPositionAtNextLine(ITextPointer position, double suggestedX, int count, out double newSuggestedX, out int linesMoved) { newSuggestedX = suggestedX; linesMoved = 0; #if DEBUG DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("FixedTextView.MoveToLine {0}, {1}, {2}, {3}", (FixedTextPointer)position, position.LogicalDirection, suggestedX, count)); #endif FixedPosition fixedp; LogicalDirection edge = position.LogicalDirection; LogicalDirection scanDir = LogicalDirection.Forward; ITextPointer pos = position; FixedTextPointer ftp = Container.VerifyPosition(position); FixedTextPointer nav = new FixedTextPointer(true, edge, (FlowPosition)ftp.FlowPosition.Clone()); //Skip any formatting tags _SkipFormattingTags(nav); bool gotFixedPosition = false; if ( count == 0 || ((gotFixedPosition = _GetFixedPosition(nav, out fixedp)) && fixedp.Page != this.PageIndex ) ) { //Invalid text position, so do nothing. PS #963924 return position; } if (count < 0) { count = -count; scanDir = LogicalDirection.Backward; } if (!gotFixedPosition) { // move to next insertion position in direction, provided we're in this view if (this.Contains(position)) { nav = new FixedTextPointer(true, scanDir, (FlowPosition)ftp.FlowPosition.Clone()); ((ITextPointer)nav).MoveToInsertionPosition(scanDir); ((ITextPointer)nav).MoveToNextInsertionPosition(scanDir); if (this.Contains(nav)) { // make sure we haven't changed pages linesMoved = (scanDir == LogicalDirection.Forward) ? 1 : -1; return nav; } } return position; } if (DoubleUtil.IsNaN(suggestedX)) { suggestedX = 0; } while (count > linesMoved) { if (!_GetNextLineGlyphs(ref fixedp, ref edge, suggestedX, scanDir)) break; linesMoved++; } if (linesMoved == 0) { pos = position.CreatePointer(); return pos; } if (scanDir == LogicalDirection.Backward) { linesMoved = -linesMoved; } pos = _CreateTextPointer(fixedp, edge); Debug.Assert(pos != null); if (pos.CompareTo(position) == 0) { linesMoved = 0; } return pos; }
//----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors // Ctor always set mutable flag to false internal FixedElement(ElementType type, FixedTextPointer start, FixedTextPointer end, int pageIndex) { _type = type; #if DEBUG if (_type == ElementType.Object) // is EmbeddedObject { Debug.Assert((object)_start == (object)_end); } _children = new List<FixedElement>(); #endif _start = start; _end = end; _pageIndex = pageIndex; }
private static void _GetFirstPageSearchPointers ( ITextPointer start, ITextPointer end, int pageNumber, bool matchLast, out ITextPointer firstSearchPageStart, out ITextPointer firstSearchPageEnd) { if (matchLast) { //The page in question is the last page //Need to search between the start of the last page and the end pointer DocumentSequenceTextPointer endAsDSTP = end as DocumentSequenceTextPointer; if (endAsDSTP != null) { FlowPosition pageStartFlowPosition = ((FixedTextContainer)(endAsDSTP.ChildBlock.ChildContainer)).FixedTextBuilder.GetPageStartFlowPosition(pageNumber); firstSearchPageStart = new DocumentSequenceTextPointer(endAsDSTP.ChildBlock, new FixedTextPointer(false, LogicalDirection.Forward,pageStartFlowPosition)); } else { FixedTextPointer endAsFTP = end as FixedTextPointer; Debug.Assert(endAsFTP != null); firstSearchPageStart = new FixedTextPointer(false, LogicalDirection.Forward, endAsFTP.FixedTextContainer.FixedTextBuilder.GetPageStartFlowPosition(pageNumber)); } firstSearchPageEnd = end; } else { //The page in question is the first page //Need to search between the start pointer and the end of the first page DocumentSequenceTextPointer startAsDSTP = start as DocumentSequenceTextPointer; if (startAsDSTP != null) { FlowPosition pageEndFlowPosition = ((FixedTextContainer)startAsDSTP.ChildBlock.ChildContainer).FixedTextBuilder.GetPageEndFlowPosition(pageNumber); firstSearchPageEnd = new DocumentSequenceTextPointer( startAsDSTP.ChildBlock, new FixedTextPointer(false, LogicalDirection.Backward, pageEndFlowPosition)); } else { FixedTextPointer startAsFTP = start as FixedTextPointer; Debug.Assert(startAsFTP != null); firstSearchPageEnd = new FixedTextPointer(false, LogicalDirection.Backward, startAsFTP.FixedTextContainer.FixedTextBuilder.GetPageEndFlowPosition(pageNumber)); } firstSearchPageStart = start; } }
//Searches for the specified pattern and updates start *or* end pointers depending on search direction //At the end of the operation, start or end should be pointing to the beginning/end of the page //of occurance of pattern respectively internal static TextRange Find ( ITextPointer start, ITextPointer end, string findPattern, CultureInfo cultureInfo, bool matchCase, bool matchWholeWord, bool matchLast, bool matchDiacritics, bool matchKashida, bool matchAlefHamza) { Debug.Assert(start != null); Debug.Assert(end != null); Debug.Assert( ((start is DocumentSequenceTextPointer) && (end is DocumentSequenceTextPointer)) || ((start is FixedTextPointer) && (end is FixedTextPointer)) ); Debug.Assert(findPattern != null); if (findPattern.Length == 0) { return null; } IDocumentPaginatorSource paginatorSource = start.TextContainer.Parent as IDocumentPaginatorSource; DynamicDocumentPaginator paginator = paginatorSource.DocumentPaginator as DynamicDocumentPaginator; Debug.Assert(paginator != null); int pageNumber = -1; int endPageNumber = -1; if (matchLast) { endPageNumber = paginator.GetPageNumber( (ContentPosition) start); pageNumber = paginator.GetPageNumber( (ContentPosition) end); } else { endPageNumber = paginator.GetPageNumber( (ContentPosition) end); pageNumber = paginator.GetPageNumber( (ContentPosition) start); } TextRange result = null; CompareInfo compareInfo = cultureInfo.CompareInfo; bool replaceAlefWithAlefHamza = false; CompareOptions compareOptions = _InitializeSearch(cultureInfo, matchCase, matchAlefHamza, matchDiacritics, ref findPattern, out replaceAlefWithAlefHamza); //Translate the page number int translatedPageNumber = pageNumber; //If this is a DocumentSequence, we need to pass translated page number to the below call FixedDocumentSequence documentSequence = paginatorSource as FixedDocumentSequence; DynamicDocumentPaginator childPaginator = null; if (documentSequence != null) { documentSequence.TranslatePageNumber(pageNumber, out childPaginator, out translatedPageNumber); } if (pageNumber - endPageNumber != 0) { ITextPointer firstSearchPageStart = null; ITextPointer firstSearchPageEnd = null; _GetFirstPageSearchPointers(start, end, translatedPageNumber, matchLast, out firstSearchPageStart, out firstSearchPageEnd); Debug.Assert(firstSearchPageStart != null); Debug.Assert(firstSearchPageEnd != null); //Need to search the first page using TextFindEngine to start exactly from the requested search location to avoid false positives result = TextFindEngine.InternalFind( firstSearchPageStart, firstSearchPageEnd, findPattern, cultureInfo, matchCase, matchWholeWord, matchLast, matchDiacritics, matchKashida, matchAlefHamza); if (result == null) { //Start from the next page and check all pages until the end pageNumber = matchLast ? pageNumber-1 : pageNumber+1; int increment = matchLast ? -1 : 1; for (; matchLast ? pageNumber >= endPageNumber : pageNumber <= endPageNumber; pageNumber+=increment) { FixedDocument fixedDoc = null; translatedPageNumber = pageNumber; childPaginator = null; if (documentSequence != null) { documentSequence.TranslatePageNumber(pageNumber, out childPaginator, out translatedPageNumber); fixedDoc = (FixedDocument) childPaginator.Source; } else { fixedDoc = paginatorSource as FixedDocument; } Debug.Assert(fixedDoc != null); String pageString = _GetPageString(fixedDoc, translatedPageNumber, replaceAlefWithAlefHamza); if (pageString == null) { //This is not a page-per-stream //Default back to slow search return TextFindEngine.InternalFind( start, end, findPattern, cultureInfo, matchCase, matchWholeWord, matchLast, matchDiacritics, matchKashida, matchAlefHamza); } if ( _FoundOnPage(pageString, findPattern, cultureInfo, compareOptions) ) { //Update end or start pointer depending on search direction if (documentSequence != null) { ChildDocumentBlock childBlock = documentSequence.TextContainer.FindChildBlock(fixedDoc.DocumentReference); if (matchLast) { end = new DocumentSequenceTextPointer(childBlock, new FixedTextPointer(false, LogicalDirection.Backward, fixedDoc.FixedContainer.FixedTextBuilder.GetPageEndFlowPosition(translatedPageNumber))); start = new DocumentSequenceTextPointer(childBlock, new FixedTextPointer(false, LogicalDirection.Forward, fixedDoc.FixedContainer.FixedTextBuilder.GetPageStartFlowPosition(translatedPageNumber))); } else { start = new DocumentSequenceTextPointer(childBlock, new FixedTextPointer(false, LogicalDirection.Forward, fixedDoc.FixedContainer.FixedTextBuilder.GetPageStartFlowPosition(translatedPageNumber))); end = new DocumentSequenceTextPointer(childBlock, new FixedTextPointer(false, LogicalDirection.Backward, fixedDoc.FixedContainer.FixedTextBuilder.GetPageEndFlowPosition(translatedPageNumber))); } } else { //We are working on a FixedDocument FixedTextBuilder textBuilder = ((FixedDocument)(paginatorSource)).FixedContainer.FixedTextBuilder; if (matchLast) { end = new FixedTextPointer(false, LogicalDirection.Backward, textBuilder.GetPageEndFlowPosition(pageNumber)); start = new FixedTextPointer(false, LogicalDirection.Forward, textBuilder.GetPageStartFlowPosition(pageNumber)); } else { start = new FixedTextPointer(false, LogicalDirection.Forward, textBuilder.GetPageStartFlowPosition(pageNumber)); end = new FixedTextPointer(false, LogicalDirection.Backward, textBuilder.GetPageEndFlowPosition(pageNumber)); } } result = TextFindEngine.InternalFind( start, end, findPattern, cultureInfo, matchCase, matchWholeWord, matchLast, matchDiacritics, matchKashida, matchAlefHamza); //If the result is null, this means we had a false positive if (result != null) { return result; } } } } } else { //Make sure fast search result and slow search result are consistent FixedDocument fixedDoc = childPaginator != null ? childPaginator.Source as FixedDocument : paginatorSource as FixedDocument; String pageString = _GetPageString(fixedDoc, translatedPageNumber, replaceAlefWithAlefHamza); if (pageString == null || _FoundOnPage(pageString, findPattern, cultureInfo, compareOptions)) { //The search is only limited to the current page result = TextFindEngine.InternalFind( start, end, findPattern, cultureInfo, matchCase, matchWholeWord, matchLast, matchDiacritics, matchKashida, matchAlefHamza); } } return result; }
/// <summary> /// <see cref="DynamicDocumentPaginator.GetObjectPosition"/> /// </summary> /// <exception cref="ArgumentNullException">element is NULL.</exception> internal ContentPosition GetObjectPosition(Object o) { if (o == null) { throw new ArgumentNullException("o"); } DependencyObject element = o as DependencyObject; if (element == null) { throw new ArgumentException(SR.Get(SRID.FixedDocumentExpectsDependencyObject)); } DocumentsTrace.FixedFormat.IDF.Trace(string.Format("IDF.GetContentPositionForElement({0})", element)); // Make sure that the call is in the right context. // Dispatcher.VerifyAccess(); // walk up the logical parent chain to find the containing page FixedPage fixedPage = null; int pageIndex = -1; if (element != this) { DependencyObject el = element; while (el != null) { fixedPage = el as FixedPage; if (fixedPage != null) { pageIndex = GetIndexOfPage(fixedPage); if (pageIndex >= 0) { break; } el = fixedPage.Parent; } else { el = LogicalTreeHelper.GetParent(el); } } } else if (this.Pages.Count > 0) { // if FixedDocument is requested, return ContentPosition for the first page. pageIndex = 0; } // get FixedTextPointer for element or page index FixedTextPointer fixedTextPointer = null; if (pageIndex >= 0) { FixedPosition fixedPosition; FlowPosition flowPosition=null; System.Windows.Shapes.Path p = element as System.Windows.Shapes.Path; if (element is Glyphs || element is Image || (p != null && p.Fill is ImageBrush)) { fixedPosition = new FixedPosition(fixedPage.CreateFixedNode(pageIndex, (UIElement)element), 0); flowPosition = FixedContainer.FixedTextBuilder.CreateFlowPosition(fixedPosition); } if (flowPosition == null) { flowPosition = FixedContainer.FixedTextBuilder.GetPageStartFlowPosition(pageIndex); } fixedTextPointer = new FixedTextPointer(true, LogicalDirection.Forward, flowPosition); } return (fixedTextPointer != null) ? fixedTextPointer : ContentPosition.Missing; }
// Get the highlights, in Glyphs granularity, that covers this range internal void GetMultiHighlights(FixedTextPointer start, FixedTextPointer end, Dictionary<FixedPage, ArrayList> highlights, FixedHighlightType t, Brush foregroundBrush, Brush backgroundBrush) { Debug.Assert(highlights != null); if (start.CompareTo(end) > 0) { // make sure start <= end FixedTextPointer temp = start; start = end; end = temp; } FixedSOMElement[] elements; //Start and end indices in selection for first and last FixedSOMElements respectively int startIndex = 0; int endIndex = 0; if (_GetFixedNodesForFlowRange(start, end, out elements, out startIndex, out endIndex)) { for(int i=0; i<elements.Length; i++) { FixedSOMElement elem = elements[i]; FixedNode fn = elem.FixedNode; // Get the FixedPage if possible FixedPage page = this.FixedDocument.SyncGetPageWithCheck(fn.Page); if (page == null) { continue; } DependencyObject o = page.GetElement(fn); if (o == null) { continue; } int beginOffset = 0; int endOffset; UIElement e; if (o is Image || o is Path) { e = (UIElement)o; endOffset = 1; } else { Glyphs g = o as Glyphs; if (g == null) { continue; } e = (UIElement)o; beginOffset = elem.StartIndex; endOffset = elem.EndIndex; } if (i == 0) { beginOffset = startIndex; } if (i == elements.Length - 1) { endOffset = endIndex; } ArrayList lfs; if (highlights.ContainsKey(page)) { lfs = highlights[page]; } else { lfs = new ArrayList(); highlights.Add(page, lfs); } FixedSOMTextRun textRun = elem as FixedSOMTextRun; if (textRun != null && textRun.IsReversed) { int oldBeginOffset = beginOffset; beginOffset = elem.EndIndex - endOffset; endOffset = elem.EndIndex - oldBeginOffset; } FixedHighlight fh = new FixedHighlight(e, beginOffset, endOffset, t, foregroundBrush, backgroundBrush); lfs.Add(fh); } } }
//Find the first valid insertion position after or before the boundary node private bool _GetFirstFixedPosition(FixedTextPointer ftp, out FixedPosition fixedP) { LogicalDirection dir = LogicalDirection.Forward; if (ftp.FlowPosition.FlowNode.Fp != 0) { //End boundary dir = LogicalDirection.Backward; } FlowPosition flowP = (FlowPosition) ftp.FlowPosition.Clone(); //Get the first node that comes before or after the boundary node(probably a start or end node) flowP.Move(dir); FixedTextPointer nav = new FixedTextPointer(true, dir, flowP); if (flowP.IsStart || flowP.IsEnd) { ((ITextPointer)nav).MoveToNextInsertionPosition(dir); } if (this.Container.GetPageNumber(nav) == this.PageIndex) { return Container.FixedTextBuilder.GetFixedPosition(nav.FlowPosition, dir, out fixedP); } else { //This position is on another page. fixedP = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0); return false; } }