internal PhysicalLineInfo(TextRange lineRange) { if (lineRange == null) { throw new ArgumentNullException("lineRange"); } TextPointerOperations.DebugAssertIsSingleLine(lineRange); var charPositions = TextPointerOperations.GetInsertionPositions(lineRange, LogicalDirection.Forward); var charPositionPairs = PrevNext <TextPointer> .AsPrevNext(charPositions); this.charHitTestInfo = from pair in charPositionPairs select new PhysicalCharInfo(pair.Prev, pair.Next); }
internal static IEnumerable <Rect> GetHighlightRects(TextRange range, IContentHost contentHost) { #if USE_APPROXIMATE_HIGHLIGHT_RECT return(TextPointerOperations.GetHighlightRectanglesWithContentHost( range, TextPointerOperations.GetApproximateHighlightRectangles, contentHost )); #else return(TextPointerOperations.GetHighlightRectanglesWithContentHost( range, TextPointerOperations.GetHighlightRectangles, contentHost )); #endif }
private static IEnumerable <Rect> GetHighlightRectangleFromLines( TextRange range, Func <TextRange, IEnumerable <Rect> > getHilightRectFromLineRange ) { Assert.IsNotNull(range); Assert.IsNotNull(getHilightRectFromLineRange); IEnumerable <Rect[]> rectsPerLine = from lineRange in TextPointerOperations.GetLineRanges(range) select getHilightRectFromLineRange(lineRange).ToArray(); Rect[][] rectsPerLineArray = rectsPerLine.ToArray(); AlignLineTops(rectsPerLineArray); return(MergeConsecutiveAdjacentRects(rectsPerLineArray.SelectMany(x => x))); }
/// <remarks> /// Can be quite slow for very, very long lines of text /// </remarks> private static TextPointer GetPositionFromPointByLinearScan(Point point, TextRange range, bool snapToText) { PhysicalCharInfo result = null; var lineInfos = TextPointerOperations.GetPhysicalLines(range).ToArray(); switch (lineInfos.Length) { case 0: { result = snapToText ? new PhysicalCharInfo(range.Start) : null; break; } case 1: { result = TopToBottomLineHitTest(lineInfos.First(), point, snapToText, range.Start); break; } default: { // Optimization, scan the last line to quickly determine if the point is below the bottom line result = BottomToTopLineHitTest(lineInfos.Last(), point, snapToText, range.End); if (result == null) { // scan lines from top to bottom var fwdLineResults = from lineInfo in lineInfos.Take(lineInfos.Length - 1) select TopToBottomLineHitTest(lineInfo, point, snapToText, range.Start); result = fwdLineResults.FirstOrDefault(x => x != null); } break; } } Assert.Implies(snapToText, result != null); return((result != null) ? result.NearPosition : null); }