private List <Rect> CalculateSelectionRects(ICaret caret, ITextComponentWrapper text, Vector2 offset)
        {
            List <Rect> highlightRects = new List <Rect>();

            int start = Mathf.Min(caret.GetIndex(), caret.GetSelectionIndex()) - _drawStart;

            start = Mathf.Clamp(start, 0, text.DisplayedTextLength);
            int end = Mathf.Max(caret.GetIndex(), caret.GetSelectionIndex()) - _drawStart;

            end = Mathf.Clamp(end, 0, text.DisplayedTextLength);

            int startLine = text.GetLineByCharIndex(start);
            int endLine   = text.GetLineByCharIndex(end);

            if (startLine == endLine)
            {
                highlightRects.Add(HightedLineRect(start, end, text.LineHeight(startLine), text));
            }
            else
            {
                int currentLineEndIndex = text.LineEndIndex(startLine);
                highlightRects.Add(HightedLineRect(start, currentLineEndIndex, text.LineHeight(startLine), text));

                while (startLine < endLine - 1)
                {
                    startLine++;
                    highlightRects.Add(HightedLineRect(
                                           text.LineStartIndex(startLine),
                                           text.LineEndIndex(startLine),
                                           text.LineHeight(startLine),
                                           text));
                }

                highlightRects.Add(HightedLineRect(
                                       text.LineStartIndex(endLine), end, text.LineHeight(endLine), text));
            }
            return(highlightRects);
        }
        protected override string ProcessText(ITextComponentWrapper text, ICaret caret)
        {
            Vector2 extents = text.DisplayRect.size;

            int caretLine = text.GetLineByCharIndex(caret.GetIndex());

            if (caret.GetIndex() > _drawEnd)
            {
                _drawEnd = text.LineEndIndex(caretLine);
                float bottomY = text.LineTop(caretLine) - text.LineHeight(caretLine);
                // TODO: Remove interline spacing on last line.
                int startLine = caretLine;
                while (startLine > 0)
                {
                    float topY = text.LineTop(startLine - 1);
                    if (topY - bottomY > extents.y)
                    {
                        break;
                    }
                    startLine--;
                }
                _drawStart = text.LineStartIndex(startLine);
            }
            else
            {
                if (caret.GetIndex() < _drawStart)
                {
                    _drawStart = text.LineStartIndex(caretLine);
                }

                int startLine = text.GetLineByCharIndex(_drawStart);
                int endLine   = startLine;

                float topY    = text.LineTop(startLine);
                float bottomY = text.LineTop(endLine) - text.LineHeight(endLine);

                // TODO: Remove interline spacing on last line.

                while (endLine < text.LineCount - 1)
                {
                    bottomY = text.LineTop(endLine + 1) - text.LineHeight(endLine + 1);
                    // TODO: Remove interline spacing on last line.
                    if (topY - bottomY > extents.y)
                    {
                        break;
                    }
                    ++endLine;
                }

                _drawEnd = text.LineEndIndex(endLine);

                while (startLine > 0)
                {
                    topY = text.LineTop(startLine - 1);
                    if (topY - bottomY > extents.y)
                    {
                        break;
                    }

                    startLine--;
                }

                _drawStart = text.LineStartIndex(startLine);
            }
            return(TextValue.Substring(_drawStart, _drawEnd - _drawStart));
        }