//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 Methods // //------------------------------------------------------------------- #region Internal Methods /// <summary> /// Retrieves a position matching a point. /// </summary> /// <param name="point"> /// Point in pixel coordinates to test. /// </param> /// <param name="snapToText"> /// If true, this method must always return a positioned text position /// (the closest position as calculated by the control's heuristics) /// unless the point is outside the boundaries of the page. /// If false, this method should return null position, if the test /// point does not fall within any character bounding box. /// </param> /// <returns> /// A text position and its orientation matching or closest to the point. /// </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 GetTextPositionFromPoint(Point point, bool snapToText) { //Return ITextPointer to the end of this view in this special case if (point.Y == Double.MaxValue && point.X == Double.MaxValue) { FixedPosition fixedp; ITextPointer textPos = this.End; if (_GetFixedPosition(this.End, out fixedp)) { textPos = _CreateTextPointer(fixedp, LogicalDirection.Backward); if (textPos == null) { textPos = this.End; } } return(textPos); } ITextPointer pos = null; UIElement e; bool isHit = _HitTest(point, out e); if (isHit) { Glyphs g = e as Glyphs; if (g != null) { pos = _CreateTextPointerFromGlyphs(g, point); } else if (e is Image) { Image im = (Image)e; FixedPosition fixedp = new FixedPosition(this.FixedPage.CreateFixedNode(this.PageIndex, im), 0); pos = _CreateTextPointer(fixedp, LogicalDirection.Forward); } else if (e is Path) { Path p = (Path)e; if (p.Fill is ImageBrush) { FixedPosition fixedp = new FixedPosition(this.FixedPage.CreateFixedNode(this.PageIndex, p), 0); pos = _CreateTextPointer(fixedp, LogicalDirection.Forward); } } } if (snapToText && pos == null) { pos = _SnapToText(point); Debug.Assert(pos != null); } DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("GetTextPositionFromPoint P{0}, STT={1}, CP={2}", point, snapToText, pos == null ? "null" : ((FixedTextPointer)pos).ToString())); return(pos); }
// Token: 0x06002EF8 RID: 12024 RVA: 0x000D4754 File Offset: 0x000D2954 private ITextPointer _CreateTextPointer(FixedPosition fixedPosition, LogicalDirection edge) { FlowPosition flowPosition = this.Container.FixedTextBuilder.CreateFlowPosition(fixedPosition); if (flowPosition != null) { return(new FixedTextPointer(true, edge, flowPosition)); } return(null); }
// Token: 0x0600350E RID: 13582 RVA: 0x000F0634 File Offset: 0x000EE834 private ITextPointer _GetTextPosition(FixedNode node, int charIndex) { FixedPosition fixedPosition = new FixedPosition(node, charIndex); FlowPosition flowPosition = this._panel.FixedContainer.FixedTextBuilder.CreateFlowPosition(fixedPosition); if (flowPosition != null) { return(new FixedTextPointer(false, LogicalDirection.Forward, flowPosition)); } return(null); }
//-------------------------------------------------------------------- // 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)); }
// Token: 0x06002EF1 RID: 12017 RVA: 0x000D3FAC File Offset: 0x000D21AC private ITextPointer _SnapToText(Point point) { FixedNode[] line = this.Container.FixedTextBuilder.GetLine(this.PageIndex, point); ITextPointer textPointer; if (line != null && line.Length != 0) { double num = double.MaxValue; double xoffset = 0.0; Glyphs glyphs = null; FixedNode fixedNode = line[0]; foreach (FixedNode fixedNode2 in line) { Glyphs glyphsElement = this.FixedPage.GetGlyphsElement(fixedNode2); GeneralTransform generalTransform = this.FixedPage.TransformToDescendant(glyphsElement); Point inPoint = point; if (generalTransform != null) { generalTransform.TryTransform(inPoint, out inPoint); } GlyphRun glyphRun = glyphsElement.ToGlyphRun(); Rect rect = glyphRun.ComputeAlignmentBox(); rect.Offset(glyphsElement.OriginX, glyphsElement.OriginY); double num2 = Math.Max(0.0, (inPoint.X > rect.X) ? (inPoint.X - rect.Right) : (rect.X - inPoint.X)); double num3 = Math.Max(0.0, (inPoint.Y > rect.Y) ? (inPoint.Y - rect.Bottom) : (rect.Y - inPoint.Y)); double num4 = num2 + num3; if (glyphs == null || num4 < num) { num = num4; glyphs = glyphsElement; fixedNode = fixedNode2; xoffset = inPoint.X; } } int offset; LogicalDirection edge; this._GlyphRunHitTest(glyphs, xoffset, out offset, out edge); FixedPosition fixedPosition = new FixedPosition(fixedNode, offset); textPointer = this._CreateTextPointer(fixedPosition, edge); } else if (point.Y < this.FixedPage.Height / 2.0) { textPointer = ((ITextPointer)this.Start).CreatePointer(LogicalDirection.Forward); textPointer.MoveToInsertionPosition(LogicalDirection.Forward); } else { textPointer = ((ITextPointer)this.End).CreatePointer(LogicalDirection.Backward); textPointer.MoveToInsertionPosition(LogicalDirection.Backward); } return(textPointer); }
//-------------------------------------------------------------------- // FixedPosition --> ITextPointer //--------------------------------------------------------------------- // Create a text position from description of a fixed position. // This is primarily called from HitTesting code private ITextPointer _CreateTextPointer(FixedPosition fixedPosition, LogicalDirection edge) { // Create a FlowPosition to represent this fixed position FlowPosition flowHit = Container.FixedTextBuilder.CreateFlowPosition(fixedPosition); if (flowHit != null) { DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("_CreatetTextPointer {0}:{1}", fixedPosition.ToString(), flowHit.ToString())); // Create a TextPointer from the flow position return(new FixedTextPointer(true, edge, flowHit)); } return(null); }
private ITextPointer _GetTextPosition(FixedNode node, int charIndex) { FixedPosition fixedPosition = new FixedPosition(node, charIndex); // Create a FlowPosition to represent this fixed position FlowPosition flowHit = _panel.FixedContainer.FixedTextBuilder.CreateFlowPosition(fixedPosition); if (flowHit != null) { // Create a TextPointer from the flow position return(new FixedTextPointer(false, LogicalDirection.Forward, flowHit)); } return(null); }
// Token: 0x06002EDE RID: 11998 RVA: 0x000D3528 File Offset: 0x000D1728 internal override ITextPointer GetTextPositionFromPoint(Point point, bool snapToText) { if (point.Y == 1.7976931348623157E+308 && point.X == 1.7976931348623157E+308) { ITextPointer textPointer = this.End; FixedPosition fixedPosition; if (this._GetFixedPosition(this.End, out fixedPosition)) { textPointer = this._CreateTextPointer(fixedPosition, LogicalDirection.Backward); if (textPointer == null) { textPointer = this.End; } } return(textPointer); } ITextPointer textPointer2 = null; UIElement uielement; bool flag = this._HitTest(point, out uielement); if (flag) { Glyphs glyphs = uielement as Glyphs; if (glyphs != null) { textPointer2 = this._CreateTextPointerFromGlyphs(glyphs, point); } else if (uielement is Image) { Image e = (Image)uielement; FixedPosition fixedPosition2 = new FixedPosition(this.FixedPage.CreateFixedNode(this.PageIndex, e), 0); textPointer2 = this._CreateTextPointer(fixedPosition2, LogicalDirection.Forward); } else if (uielement is Path) { Path path = (Path)uielement; if (path.Fill is ImageBrush) { FixedPosition fixedPosition3 = new FixedPosition(this.FixedPage.CreateFixedNode(this.PageIndex, path), 0); textPointer2 = this._CreateTextPointer(fixedPosition3, LogicalDirection.Forward); } } } if (snapToText && textPointer2 == null) { textPointer2 = this._SnapToText(point); } return(textPointer2); }
// Token: 0x06002EF9 RID: 12025 RVA: 0x000D4780 File Offset: 0x000D2980 private ITextPointer _CreateTextPointerFromGlyphs(Glyphs g, Point point) { GeneralTransform generalTransform = this.VisualRoot.TransformToDescendant(g); if (generalTransform != null) { generalTransform.TryTransform(point, out point); } int offset; LogicalDirection edge; this._GlyphRunHitTest(g, point.X, out offset, out edge); FixedPosition fixedPosition = new FixedPosition(this.FixedPage.CreateFixedNode(this.PageIndex, g), offset); return(this._CreateTextPointer(fixedPosition, edge)); }
// Create a text position from description of a fixed position. // This is primarily called from HitTesting code private ITextPointer _CreateTextPointerFromGlyphs(Glyphs g, Point point) { GeneralTransform transform = this.VisualRoot.TransformToDescendant(g); if (transform != null) { transform.TryTransform(point, out point); } int charIndex; LogicalDirection edge; _GlyphRunHitTest(g, point.X, out charIndex, out edge); FixedPosition fixedp = new FixedPosition(this.FixedPage.CreateFixedNode(this.PageIndex, g), charIndex); return(_CreateTextPointer(fixedp, edge)); }
// 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)); }
// 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: 0x06002EF2 RID: 12018 RVA: 0x000D4194 File Offset: 0x000D2394 private bool _GetNextLineGlyphs(ref FixedPosition fixedp, ref LogicalDirection edge, double suggestedX, LogicalDirection scanDir) { int num = 1; int page = fixedp.Page; bool result = false; FixedNode[] nextLine = this.Container.FixedTextBuilder.GetNextLine(fixedp.Node, scanDir == LogicalDirection.Forward, ref num); if (nextLine != null && nextLine.Length != 0) { FixedPage fixedPage = this.Container.FixedDocument.SyncGetPage(page, false); if (double.IsInfinity(suggestedX)) { suggestedX = 0.0; } Point point = new Point(suggestedX, 0.0); Point point2 = new Point(suggestedX, 1000.0); FixedNode fixedNode = nextLine[0]; Glyphs g = null; double num2 = double.MaxValue; double xoffset = 0.0; for (int i = nextLine.Length - 1; i >= 0; i--) { FixedNode fixedNode2 = nextLine[i]; Glyphs glyphsElement = fixedPage.GetGlyphsElement(fixedNode2); if (glyphsElement != null) { GeneralTransform generalTransform = fixedPage.TransformToDescendant(glyphsElement); Point inPoint = point; Point inPoint2 = point2; if (generalTransform != null) { generalTransform.TryTransform(inPoint, out inPoint); generalTransform.TryTransform(inPoint2, out inPoint2); } double num3 = (inPoint2.X - inPoint.X) / (inPoint2.Y - inPoint.Y); GlyphRun glyphRun = glyphsElement.ToGlyphRun(); Rect rect = glyphRun.ComputeAlignmentBox(); rect.Offset(glyphsElement.OriginX, glyphsElement.OriginY); double num4; double num5; if (num3 > 1000.0 || num3 < -1000.0) { num4 = 0.0; num5 = ((inPoint.Y > rect.Y) ? (inPoint.Y - rect.Bottom) : (rect.Y - inPoint.Y)); } else { double num6 = (rect.Top + rect.Bottom) / 2.0; num4 = inPoint.X + num3 * (num6 - inPoint.Y); num5 = ((num4 > rect.X) ? (num4 - rect.Right) : (rect.X - num4)); } if (num5 < num2) { num2 = num5; xoffset = num4; fixedNode = fixedNode2; g = glyphsElement; if (num5 <= 0.0) { break; } } } } int offset; this._GlyphRunHitTest(g, xoffset, out offset, out edge); fixedp = new FixedPosition(fixedNode, offset); result = true; } return(result); }
// If return false, nothing has been modified, which implies out of page boundary // The input of suggestedX is in the VisualRoot's cooridnate system private bool _GetNextLineGlyphs(ref FixedPosition fixedp, ref LogicalDirection edge, double suggestedX, LogicalDirection scanDir) { int count = 1; int pageIndex = fixedp.Page; bool moved = false; FixedNode[] fixedNodes = Container.FixedTextBuilder.GetNextLine(fixedp.Node, (scanDir == LogicalDirection.Forward), ref count); if (fixedNodes != null && fixedNodes.Length > 0) { FixedPage page = Container.FixedDocument.SyncGetPage(pageIndex, false); // This line contains multiple Glyhs. Scan backward // util we hit the first one whose OriginX is smaller // then suggestedX; if (Double.IsInfinity(suggestedX)) { suggestedX = 0; } Point topOfPage = new Point(suggestedX, 0); Point secondPoint = new Point(suggestedX, 1000); FixedNode hitNode = fixedNodes[0]; Glyphs hitGlyphs = null; double closestDistance = Double.MaxValue; double xoffset = 0; for (int i = fixedNodes.Length - 1; i >= 0; i--) { FixedNode node = fixedNodes[i]; Glyphs g = page.GetGlyphsElement(node); if (g != null) { GeneralTransform transform = page.TransformToDescendant(g); Point pt1 = topOfPage; Point pt2 = secondPoint; if (transform != null) { transform.TryTransform(pt1, out pt1); transform.TryTransform(pt2, out pt2); } double invSlope = (pt2.X - pt1.X) / (pt2.Y - pt1.Y); double xoff, distance; GlyphRun run = g.ToGlyphRun(); Rect box = run.ComputeAlignmentBox(); box.Offset(g.OriginX, g.OriginY); if (invSlope > 1000 || invSlope < -1000) { // special case for vertical text xoff = 0; distance = (pt1.Y > box.Y) ? (pt1.Y - box.Bottom) : (box.Y - pt1.Y); } else { double centerY = (box.Top + box.Bottom) / 2; xoff = pt1.X + invSlope * (centerY - pt1.Y); distance = (xoff > box.X) ? (xoff - box.Right) : (box.X - xoff); } if (distance < closestDistance) { closestDistance = distance; xoffset = xoff; hitNode = node; hitGlyphs = g; if (distance <= 0) { break; } } } } Debug.Assert(hitGlyphs != null); int charIdx; _GlyphRunHitTest(hitGlyphs, xoffset, out charIdx, out edge); fixedp = new FixedPosition(hitNode, charIdx); moved = true; } return moved; }
private ITextPointer _SnapToText(Point point) { ITextPointer itp = null; FixedNode[] fixedNodes = Container.FixedTextBuilder.GetLine(this.PageIndex, point); if (fixedNodes != null && fixedNodes.Length > 0) { double closestDistance = Double.MaxValue; double xoffset = 0; Glyphs closestGlyphs = null; FixedNode closestNode = fixedNodes[0]; foreach (FixedNode node in fixedNodes) { Glyphs startGlyphs = this.FixedPage.GetGlyphsElement(node); GeneralTransform tranToGlyphs = this.FixedPage.TransformToDescendant(startGlyphs); Point transformedPt = point; if (tranToGlyphs != null) { tranToGlyphs.TryTransform(transformedPt, out transformedPt); } GlyphRun run = startGlyphs.ToGlyphRun(); Rect alignmentRect = run.ComputeAlignmentBox(); alignmentRect.Offset(startGlyphs.OriginX, startGlyphs.OriginY); double horizontalDistance = Math.Max(0, (transformedPt.X > alignmentRect.X) ? (transformedPt.X - alignmentRect.Right) : (alignmentRect.X - transformedPt.X)); double verticalDistance = Math.Max(0, (transformedPt.Y > alignmentRect.Y) ? (transformedPt.Y - alignmentRect.Bottom) : (alignmentRect.Y - transformedPt.Y)); double manhattanDistance = horizontalDistance + verticalDistance; if (closestGlyphs == null || manhattanDistance < closestDistance) { closestDistance = manhattanDistance; closestGlyphs = startGlyphs; closestNode = node; xoffset = transformedPt.X; } } int index; LogicalDirection dir; _GlyphRunHitTest(closestGlyphs, xoffset, out index, out dir); FixedPosition fixedp = new FixedPosition(closestNode, index); itp = _CreateTextPointer(fixedp, dir); Debug.Assert(itp != null); } else { // // That condition is only possible when there is no line in the page // if (point.Y < this.FixedPage.Height / 2) { itp = ((ITextPointer)this.Start).CreatePointer(LogicalDirection.Forward); itp.MoveToInsertionPosition(LogicalDirection.Forward); } else { itp = ((ITextPointer)this.End).CreatePointer(LogicalDirection.Backward); itp.MoveToInsertionPosition(LogicalDirection.Backward); } } return itp; }
//------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods /// <summary> /// Retrieves a position matching a point. /// </summary> /// <param name="point"> /// Point in pixel coordinates to test. /// </param> /// <param name="snapToText"> /// If true, this method must always return a positioned text position /// (the closest position as calculated by the control's heuristics) /// unless the point is outside the boundaries of the page. /// If false, this method should return null position, if the test /// point does not fall within any character bounding box. /// </param> /// <returns> /// A text position and its orientation matching or closest to the point. /// </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 GetTextPositionFromPoint(Point point, bool snapToText) { //Return ITextPointer to the end of this view in this special case if (point.Y == Double.MaxValue && point.X == Double.MaxValue) { FixedPosition fixedp; ITextPointer textPos = this.End; if (_GetFixedPosition(this.End, out fixedp)) { textPos = _CreateTextPointer(fixedp, LogicalDirection.Backward); if (textPos == null) { textPos = this.End; } } return textPos; } ITextPointer pos = null; UIElement e; bool isHit = _HitTest(point, out e); if (isHit) { Glyphs g = e as Glyphs; if (g != null) { pos = _CreateTextPointerFromGlyphs(g, point); } else if (e is Image) { Image im = (Image)e; FixedPosition fixedp = new FixedPosition(this.FixedPage.CreateFixedNode(this.PageIndex, im), 0); pos = _CreateTextPointer(fixedp, LogicalDirection.Forward); } else if (e is Path) { Path p = (Path)e; if (p.Fill is ImageBrush) { FixedPosition fixedp = new FixedPosition(this.FixedPage.CreateFixedNode(this.PageIndex, p), 0); pos = _CreateTextPointer(fixedp, LogicalDirection.Forward); } } } if (snapToText && pos == null) { pos = _SnapToText(point); Debug.Assert(pos != null); } DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("GetTextPositionFromPoint P{0}, STT={1}, CP={2}", point, snapToText, pos == null ? "null" : ((FixedTextPointer)pos).ToString())); return pos; }
// Create a text position from description of a fixed position. // This is primarily called from HitTesting code private ITextPointer _CreateTextPointerFromGlyphs(Glyphs g, Point point) { GeneralTransform transform = this.VisualRoot.TransformToDescendant(g); if (transform != null) { transform.TryTransform(point, out point); } int charIndex; LogicalDirection edge; _GlyphRunHitTest(g, point.X, out charIndex, out edge); FixedPosition fixedp = new FixedPosition(this.FixedPage.CreateFixedNode(this.PageIndex, g), charIndex); return _CreateTextPointer(fixedp, edge); }
//-------------------------------------------------------------------- // FixedPosition --> ITextPointer //--------------------------------------------------------------------- // Create a text position from description of a fixed position. // This is primarily called from HitTesting code private ITextPointer _CreateTextPointer(FixedPosition fixedPosition, LogicalDirection edge) { // Create a FlowPosition to represent this fixed position FlowPosition flowHit = Container.FixedTextBuilder.CreateFlowPosition(fixedPosition); if (flowHit != null) { DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("_CreatetTextPointer {0}:{1}", fixedPosition.ToString(), flowHit.ToString())); // Create a TextPointer from the flow position return new FixedTextPointer(true, edge, flowHit); } return null; }
private ITextPointer _SnapToText(Point point) { ITextPointer itp = null; FixedNode[] fixedNodes = Container.FixedTextBuilder.GetLine(this.PageIndex, point); if (fixedNodes != null && fixedNodes.Length > 0) { double closestDistance = Double.MaxValue; double xoffset = 0; Glyphs closestGlyphs = null; FixedNode closestNode = fixedNodes[0]; foreach (FixedNode node in fixedNodes) { Glyphs startGlyphs = this.FixedPage.GetGlyphsElement(node); GeneralTransform tranToGlyphs = this.FixedPage.TransformToDescendant(startGlyphs); Point transformedPt = point; if (tranToGlyphs != null) { tranToGlyphs.TryTransform(transformedPt, out transformedPt); } GlyphRun run = startGlyphs.ToGlyphRun(); Rect alignmentRect = run.ComputeAlignmentBox(); alignmentRect.Offset(startGlyphs.OriginX, startGlyphs.OriginY); double horizontalDistance = Math.Max(0, (transformedPt.X > alignmentRect.X) ? (transformedPt.X - alignmentRect.Right) : (alignmentRect.X - transformedPt.X)); double verticalDistance = Math.Max(0, (transformedPt.Y > alignmentRect.Y) ? (transformedPt.Y - alignmentRect.Bottom) : (alignmentRect.Y - transformedPt.Y)); double manhattanDistance = horizontalDistance + verticalDistance; if (closestGlyphs == null || manhattanDistance < closestDistance) { closestDistance = manhattanDistance; closestGlyphs = startGlyphs; closestNode = node; xoffset = transformedPt.X; } } int index; LogicalDirection dir; _GlyphRunHitTest(closestGlyphs, xoffset, out index, out dir); FixedPosition fixedp = new FixedPosition(closestNode, index); itp = _CreateTextPointer(fixedp, dir); Debug.Assert(itp != null); } else { // // That condition is only possible when there is no line in the page // if (point.Y < this.FixedPage.Height / 2) { itp = ((ITextPointer)this.Start).CreatePointer(LogicalDirection.Forward); itp.MoveToInsertionPosition(LogicalDirection.Forward); } else { itp = ((ITextPointer)this.End).CreatePointer(LogicalDirection.Backward); itp.MoveToInsertionPosition(LogicalDirection.Backward); } } return(itp); }
/// <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; }
private ITextPointer _GetTextPosition(FixedNode node, int charIndex) { FixedPosition fixedPosition = new FixedPosition(node, charIndex); // Create a FlowPosition to represent this fixed position FlowPosition flowHit = _panel.FixedContainer.FixedTextBuilder.CreateFlowPosition(fixedPosition); if (flowHit != null) { // Create a TextPointer from the flow position return new FixedTextPointer(false, LogicalDirection.Forward, flowHit); } return null; }
//-------------------------------------------------------------------- // 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); }
//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; } }
// If return false, nothing has been modified, which implies out of page boundary // The input of suggestedX is in the VisualRoot's cooridnate system private bool _GetNextLineGlyphs(ref FixedPosition fixedp, ref LogicalDirection edge, double suggestedX, LogicalDirection scanDir) { int count = 1; int pageIndex = fixedp.Page; bool moved = false; FixedNode[] fixedNodes = Container.FixedTextBuilder.GetNextLine(fixedp.Node, (scanDir == LogicalDirection.Forward), ref count); if (fixedNodes != null && fixedNodes.Length > 0) { FixedPage page = Container.FixedDocument.SyncGetPage(pageIndex, false); // This line contains multiple Glyhs. Scan backward // util we hit the first one whose OriginX is smaller // then suggestedX; if (Double.IsInfinity(suggestedX)) { suggestedX = 0; } Point topOfPage = new Point(suggestedX, 0); Point secondPoint = new Point(suggestedX, 1000); FixedNode hitNode = fixedNodes[0]; Glyphs hitGlyphs = null; double closestDistance = Double.MaxValue; double xoffset = 0; for (int i = fixedNodes.Length - 1; i >= 0; i--) { FixedNode node = fixedNodes[i]; Glyphs g = page.GetGlyphsElement(node); if (g != null) { GeneralTransform transform = page.TransformToDescendant(g); Point pt1 = topOfPage; Point pt2 = secondPoint; if (transform != null) { transform.TryTransform(pt1, out pt1); transform.TryTransform(pt2, out pt2); } double invSlope = (pt2.X - pt1.X) / (pt2.Y - pt1.Y); double xoff, distance; GlyphRun run = g.ToGlyphRun(); Rect box = run.ComputeAlignmentBox(); box.Offset(g.OriginX, g.OriginY); if (invSlope > 1000 || invSlope < -1000) { // special case for vertical text xoff = 0; distance = (pt1.Y > box.Y) ? (pt1.Y - box.Bottom) : (box.Y - pt1.Y); } else { double centerY = (box.Top + box.Bottom) / 2; xoff = pt1.X + invSlope * (centerY - pt1.Y); distance = (xoff > box.X) ? (xoff - box.Right) : (box.X - xoff); } if (distance < closestDistance) { closestDistance = distance; xoffset = xoff; hitNode = node; hitGlyphs = g; if (distance <= 0) { break; } } } } Debug.Assert(hitGlyphs != null); int charIdx; _GlyphRunHitTest(hitGlyphs, xoffset, out charIdx, out edge); fixedp = new FixedPosition(hitNode, charIdx); moved = true; } return(moved); }
// Token: 0x06002CC1 RID: 11457 RVA: 0x000C9D38 File Offset: 0x000C7F38 internal ContentPosition GetObjectPosition(object o) { if (o == null) { throw new ArgumentNullException("o"); } DependencyObject dependencyObject = o as DependencyObject; if (dependencyObject == null) { throw new ArgumentException(SR.Get("FixedDocumentExpectsDependencyObject")); } FixedPage fixedPage = null; int num = -1; if (dependencyObject != this) { DependencyObject dependencyObject2 = dependencyObject; while (dependencyObject2 != null) { fixedPage = (dependencyObject2 as FixedPage); if (fixedPage != null) { num = this.GetIndexOfPage(fixedPage); if (num >= 0) { break; } dependencyObject2 = fixedPage.Parent; } else { dependencyObject2 = LogicalTreeHelper.GetParent(dependencyObject2); } } } else if (this.Pages.Count > 0) { num = 0; } FixedTextPointer fixedTextPointer = null; if (num >= 0) { FlowPosition flowPosition = null; System.Windows.Shapes.Path path = dependencyObject as System.Windows.Shapes.Path; if (dependencyObject is Glyphs || dependencyObject is Image || (path != null && path.Fill is ImageBrush)) { FixedPosition fixedPosition = new FixedPosition(fixedPage.CreateFixedNode(num, (UIElement)dependencyObject), 0); flowPosition = this.FixedContainer.FixedTextBuilder.CreateFlowPosition(fixedPosition); } if (flowPosition == null) { flowPosition = this.FixedContainer.FixedTextBuilder.GetPageStartFlowPosition(num); } fixedTextPointer = new FixedTextPointer(true, LogicalDirection.Forward, flowPosition); } if (fixedTextPointer == null) { return(ContentPosition.Missing); } return(fixedTextPointer); }