/// <summary> /// charIndex,戻り値はblockで0起点の値. /// </summary> public Rectangle[] GetStringRect(Graphics g, Block block, int charIndex, int length) { int startLineIndex, startColumnIndex; var startLine = block.GetLineSegmentAtLocal(charIndex, out startLineIndex, out startColumnIndex); var startVisLines = _visualLineCache.GetVisualLines(g, startLine); var startVisLine = GetVisualLineAt(g, startLine, startColumnIndex); var endCharIndex = charIndex + length - 1; int endLineIndex, endColumnIndex; var endLine = block.GetLineSegmentAtLocal(endCharIndex, out endLineIndex, out endColumnIndex); var endVisLines = _visualLineCache.GetVisualLines(g, endLine); var endVisLine = GetVisualLineAt(g, endLine, endColumnIndex); var blockBounds = _boundsCache.GetBounds(g, block); if (startLineIndex == endLineIndex) { /// 最初のLineと最後のLineが同じ場合 var startLineBounds = _boundsCache.GetBounds(g, startLine); var rects = GetStringRectsInLine(g, startLine, startColumnIndex, length); return(RectUtil.Translate(rects, (Size)startLineBounds.Location - (Size)blockBounds.Location)); } else { /// 最初の行と最後の行が異なる場合 var ret = new List <Rectangle>(); /// 最初の行 var startLineBounds = _boundsCache.GetBounds(g, startLine); var startLineStringRects = GetStringRectsInLine( g, startLine, startColumnIndex, startLine.Length - startColumnIndex ); ret.AddRange( RectUtil.Translate( startLineStringRects, (Size)startLineBounds.Location - (Size)blockBounds.Location ) ); /// 間の行 for (int i = startLineIndex + 1; i < endLineIndex; ++i) { var line = block.LineSegments.ElementAt(i); var lineBounds = _boundsCache.GetBounds(g, line); var visLines = _visualLineCache.GetVisualLines(g, line); var rects = visLines.Select( visLine => RectUtil.Translate( visLine.Bounds, (Size)lineBounds.Location - (Size)blockBounds.Location ) ); ret.AddRange(rects); } /// 最後の行 var endLineBounds = _boundsCache.GetBounds(g, endLine); var endLineStringRects = GetStringRectsInLine( g, endLine, 0, endColumnIndex + 1 ); ret.AddRange( RectUtil.Translate( endLineStringRects, (Size)endLineBounds.Location - (Size)blockBounds.Location ) ); return(ret.ToArray()); } }