/// <summary> /// Returns an ArrayList of rectangles (Rect) that form the bounds of the region specified between /// the start and end points /// </summary> /// <param name="cp"></param> /// int offset indicating the starting point of the region for which bounds are required /// <param name="cch"> /// Length in characters of the region for which bounds are required /// </param> /// <param name="xOffset"> /// Offset of line in x direction, to be added to line bounds to get actual rectangle for line /// </param> /// <param name="yOffset"> /// Offset of line in y direction, to be added to line bounds to get actual rectangle for line /// </param> /// <remarks> /// This function calls GetTextBounds for the line, and then checks if there are text run bounds. If they exist, /// it uses those as the bounding rectangles. If not, it returns the rectangle for the first (and only) element /// of the text bounds. /// </remarks> internal List <Rect> GetRangeBounds(int cp, int cch, double xOffset, double yOffset) { List <Rect> rectangles = new List <Rect>(); // Adjust x offset for trailing spaces double delta = CalculateXOffsetShift(); double adjustedXOffset = xOffset + delta; IList <TextBounds> textBounds; if (_line.HasOverflowed && _owner.ParagraphProperties.TextTrimming != TextTrimming.None) { // We should not shift offset in this case Invariant.Assert(DoubleUtil.AreClose(delta, 0)); System.Windows.Media.TextFormatting.TextLine line = _line.Collapse(GetCollapsingProps(_wrappingWidth, _owner.ParagraphProperties)); Invariant.Assert(line.HasCollapsed, "Line has not been collapsed"); textBounds = line.GetTextBounds(cp, cch); } else { textBounds = _line.GetTextBounds(cp, cch); } Invariant.Assert(textBounds.Count > 0); for (int boundIndex = 0; boundIndex < textBounds.Count; boundIndex++) { Rect rect = textBounds[boundIndex].Rectangle; rect.X += adjustedXOffset; rect.Y += yOffset; rectangles.Add(rect); } return(rectangles); }
//------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods // ------------------------------------------------------------------ // Retrieve bounds of an object/character at specified text index. // // cp - character index of an object/character // cch - number of positions occupied by object/character // flowDirection - flow direction of object/character // // Returns: Bounds of an object/character. // ------------------------------------------------------------------ protected Rect GetBoundsFromPosition(int cp, int cch, out FlowDirection flowDirection) { Rect rect; // Adjust x offset for trailing spaces double delta = CalculateXOffsetShift(); IList <TextBounds> textBounds; if (_line.HasOverflowed && _owner.ParagraphProperties.TextTrimming != TextTrimming.None) { // We should not shift offset in this case Invariant.Assert(DoubleUtil.AreClose(delta, 0)); System.Windows.Media.TextFormatting.TextLine line = _line.Collapse(GetCollapsingProps(_wrappingWidth, _owner.ParagraphProperties)); Invariant.Assert(line.HasCollapsed, "Line has not been collapsed"); textBounds = line.GetTextBounds(cp, cch); } else { textBounds = _line.GetTextBounds(cp, cch); } Invariant.Assert(textBounds != null && textBounds.Count == 1, "Expecting exactly one TextBounds for a single text position."); IList <TextRunBounds> runBounds = textBounds[0].TextRunBounds; if (runBounds != null) { Debug.Assert(runBounds.Count == 1, "Expecting exactly one TextRunBounds for a single text position."); rect = runBounds[0].Rectangle; } else { rect = textBounds[0].Rectangle; } rect.X += delta; flowDirection = textBounds[0].FlowDirection; return(rect); }
private List<textView.TextBounds> GetTextBoundsOnLine(TextLine textLine, Double horizontalOffset, Int32 startIndex, Int32 endIndex) { var list = new List<textView.TextBounds>(); if (startIndex == endIndex) { Double distanceFromCharacterHit = textLine.GetDistanceFromCharacterHit(new CharacterHit(startIndex, 0)); list.Add(new textView.TextBounds((distanceFromCharacterHit + horizontalOffset) + this.HorizontalOffset, this.VerticalOffset, 0, this.Height)); return list; } foreach (textFormatting.TextBounds bounds in textLine.GetTextBounds(startIndex, endIndex - startIndex)) { list.Add(new textView.TextBounds(bounds.Rectangle.Left + horizontalOffset, bounds.Rectangle.Top + this.VerticalOffset, bounds.Rectangle.Width, this.Height)); } return list; }