public unsafe void Render(IntPtr hdc, int vpx, int vpy, Size size)
            {
                #region Initialize GDI resources

                if (this._brushCurrentLine == null)
                {
                    var colorWithoutTransparency = Color.FromArgb(this.TextView.LineHighlightColor.R, this.TextView.LineHighlightColor.G, this.TextView.LineHighlightColor.B);
                    this._brushCurrentLine = new SafeHandleGDI(SafeNativeMethods.CreateSolidBrush(ColorTranslator.ToWin32(colorWithoutTransparency)));
                }

                #endregion

                var styleSelection = this.TextView.GetTextStyle("Selection");
                var styleDefault   = this.TextView.GetTextStyle("Default");

                var rs = new RendererState(this.TextView.GetTextRectangle(false), this.TextView.LineHeight);
                rs.TextView    = this.TextView;
                rs.RenderState = new RenderState(this.TextView, styleDefault);
                rs.ViewportX   = vpx - rs.TextRectangle.Left;
                rs.ViewportY   = vpy;

                ITextSegmentStyled selectionSegment = null;
                ITextSegment       firstVisibleLine = null;

                //var foundActiveLine = this.TextView.LineHighlightColor.A == Color.Transparent.A || this.TextView.LineHighlightColor == Color.Empty;

                var textColumnIndex = this.TextView.CurrentTextColumnIndex;

                var sri = new StyleRenderInfo(this.FocusedStyledSegment);

                // TODO: Paint some nice graphics for the current text column index, when it is stable enough.
                var clientSize        = this.TextView.ClientSize;
                var lineCount         = this.Strategy.Lines.Count;
                var firstCharIndex    = this.TextView.GetFirstCharIndexFromLine(this.TextView.GetCurrentLine());
                var lineIndexPhysical = 0;
                for (rs.LineIndexPhysical = 0; rs.LineIndexPhysical < lineCount; lineIndexPhysical++, rs.LineIndexPhysical++)
                {
                    if (rs.Y > rs.ViewportY + size.Height)
                    {
                        // This line is after the viewport and does not need painting.
                        break;
                    }

                    rs.Line = this.Strategy.Lines[lineIndexPhysical];
                    var visualInfo      = this.TextView.GetVisualInformation(lineIndexPhysical);
                    var lineCountVisual = visualInfo.GetLineCountVisual(textColumnIndex);
                    var linesHeight     = lineCountVisual * rs.LineHeight;

                    if (rs.Y + linesHeight <= rs.ViewportY)
                    {
                        // This line is before the viewport.
                        rs.Y += linesHeight;
                        rs.LineIndexVirtual += lineCountVisual;
                        continue;
                    }

                    if (rs.Line.Index >= firstCharIndex && rs.Line.Index <= (this.TextView.SelectionStart + this.TextView.SelectionLength))
                    {
                        rs.LineIndexVirtualFocused = rs.LineIndexVirtual;

                        if (this.TextView.SelectionLength == 0)
                        {
                            this.RenderSelectedLineBackground(hdc, rs);
                        }
                    }

                    var textPoints = new Dictionary <int, List <ITextSegmentStyled> >();

                    if (firstVisibleLine == null)
                    {
                        firstVisibleLine = rs.Line;

                        #region Special handling for selection

                        if (this.TextView.SelectionLength > 0)
                        {
                            if (this.TextView.SelectionStart < rs.Line.Index && this.TextView.SelectionStart + this.TextView.SelectionLength >= rs.Line.Index)
                            {
                                // The selection begins on the line before this.
                                selectionSegment       = new TextAnchor(styleSelection);
                                selectionSegment.Index = firstVisibleLine.Index;

                                var textPointIndex = rs.Line.Index;
                                if (textPoints.ContainsKey(textPointIndex) == false)
                                {
                                    textPoints.Add(textPointIndex, new List <ITextSegmentStyled>());
                                }

                                textPoints[textPointIndex].Add(selectionSegment);
                            }
                        }

                        #endregion
                    }

                    var lineLength = rs.Line.GetLength(textColumnIndex);
                    if (this.TextView.SelectionLength > 0)
                    {
                        #region Special handling for selection

                        if (this.TextView.SelectionStart >= rs.Line.Index && this.TextView.SelectionStart <= rs.Line.Index + lineLength)
                        {
                            // The selection begins on this line.
                            selectionSegment       = new TextAnchor(styleSelection);
                            selectionSegment.Index = rs.Line.Index;
                            selectionSegment.SetLength(textColumnIndex, this.TextView.SelectionLength);

                            var textPointIndex = this.TextView.SelectionStart;
                            if (textPoints.ContainsKey(textPointIndex) == false)
                            {
                                textPoints.Add(textPointIndex, new List <ITextSegmentStyled>());
                            }

                            textPoints[textPointIndex].Add(selectionSegment);
                        }

                        if (this.TextView.SelectionStart + this.TextView.SelectionLength >= rs.Line.Index &&
                            this.TextView.SelectionStart + this.TextView.SelectionLength <= rs.Line.Index + lineLength)
                        {
                            // The selection ends on this line.
                            var textPointIndex = -(this.TextView.SelectionStart + this.TextView.SelectionLength);
                            if (textPoints.ContainsKey(textPointIndex) == false)
                            {
                                textPoints.Add(textPointIndex, new List <ITextSegmentStyled>());
                            }

                            textPoints[textPointIndex].Add(selectionSegment);
                        }

                        #endregion
                    }

                    var textLine = (TextLine)rs.Line;
                    if (textLine.StyledTextSegments != null && textLine.StyledTextSegments.Count > 0)
                    {
                        foreach (var textSegment in textLine.StyledTextSegments)
                        {
                            var textPointStartIndex = textLine.Index + textSegment.Index;
                            if (textPoints.ContainsKey(textPointStartIndex) == false)
                            {
                                textPoints.Add(textPointStartIndex, new List <ITextSegmentStyled>());
                            }

                            textPoints[textPointStartIndex].Add(textSegment);

                            var textPointEndIndex = -(textLine.Index + textSegment.Index + textSegment.GetLength(textColumnIndex));
                            if (textPoints.ContainsKey(textPointEndIndex) == false)
                            {
                                textPoints.Add(textPointEndIndex, new List <ITextSegmentStyled>());
                            }

                            textPoints[textPointEndIndex].Add(textSegment);
                        }
                    }

                    var wordWrapIndex = 0;
                    var tabIndex      = 0;
                    rs.X = 0;
                    var previousTextIndex = 0;
                    //var textLength = rs.Line.GetLength(textColumnIndex);
                    var lineSplitIndexes = visualInfo.GetLineSplitIndexes(textColumnIndex);
                    for (var textIndex = 0; textIndex <= lineLength; textIndex++)
                    {
                        var isLastIndex = textIndex == lineLength;

                        var isNewline = lineSplitIndexes != null;
                        if (isNewline)
                        {
                            isNewline = wordWrapIndex < lineSplitIndexes.Length && lineSplitIndexes[wordWrapIndex] == textIndex;

                            if (isNewline)
                            {
                                wordWrapIndex++;
                            }
                        }

                        var isTab = visualInfo.GetTabSplitIndexes(textColumnIndex) != null;
                        if (isTab)
                        {
                            isTab = tabIndex < visualInfo.GetTabSplitIndexes(textColumnIndex).Length&& visualInfo.GetTabSplitIndexes(textColumnIndex)[tabIndex] == textIndex;

                            if (isTab)
                            {
                                tabIndex++;
                            }
                        }

                        var globalIndex = rs.Line.Index + textIndex;
                        var styleStart  = textPoints.ContainsKey(globalIndex) ? textPoints[globalIndex] : null;
                        var styleEnd    = globalIndex != 0 && textPoints.ContainsKey(-globalIndex) ? textPoints[-globalIndex] : null;

                        if ((isLastIndex || isNewline || isTab || styleStart != null || styleEnd != null) == false)
                        {
                            // This is a regular character, and no change is done for it.
                            continue;
                        }

                        var start  = previousTextIndex;
                        var length = textIndex - start;

                        var outputText = rs.Line.GetText(textColumnIndex);

                        #region Add empty space at end of text if selection goes beyond current line

                        if (start + length == lineLength)
                        {
                            foreach (var rsi in rs.RenderState.GetRenderStateItems())
                            {
                                if (rsi.Segment.Style.NameKey != styleSelection.NameKey)
                                {
                                    continue;
                                }

                                if (styleEnd != null)
                                {
                                    var isStyleSelection = false;
                                    foreach (var se in styleEnd)
                                    {
                                        if (se.Style.NameKey == styleSelection.NameKey)
                                        {
                                            isStyleSelection = true;
                                            break;
                                        }
                                    }

                                    if (isStyleSelection)
                                    {
                                        break;
                                    }
                                }

                                outputText += " ";
                                length++;

                                break;
                            }
                        }

                        #endregion

                        fixed(char *c = outputText)
                        {
                            SafeNativeMethods.TextOut(hdc, rs.TextRectangle.Left + (rs.X - rs.ViewportX), rs.TextRectangle.Top + rs.Y - rs.ViewportY, c + start, length);

                            if ((isNewline == false && isLastIndex == false) || styleEnd != null)
                            {
                                rs.X += rs.Line.GetSize(hdc, rs.X, start, length, visualInfo.GetVisualInfo(textColumnIndex)).Width;
                            }

                            if (styleEnd != null)
                            {
                                foreach (var t in styleEnd)
                                {
                                    switch (t.Style.PaintMode)
                                    {
                                    case TextStylePaintMode.Custom:
                                    {
                                        t.Style.Paint(hdc, t, this.TextView, visualInfo.GetVisualInfo(textColumnIndex),
                                                      rs.TextRectangle.Left + (rs.X - rs.ViewportX),
                                                      rs.TextRectangle.Top + rs.Y - rs.ViewportY,
                                                      rs.LineHeight,
                                                      sri);
                                    }
                                    break;
                                    }
                                }
                            }
                        }

                        if (isNewline)
                        {
                            this.RenderLineColumns(hdc, clientSize, rs);
                            rs.X = 0;
                            rs.LineIndexVirtual++;
                            rs.Y += rs.LineHeight;
                        }

                        if (styleStart != null)
                        {
                            foreach (var t in styleStart)
                            {
                                rs.RenderState.Add(this.TextView, t);
                            }

                            rs.RenderState.Apply(hdc);
                        }

                        if (styleEnd != null)
                        {
                            foreach (var t in styleEnd)
                            {
                                rs.RenderState.Remove(t);
                            }

                            rs.RenderState.Apply(hdc);
                        }

                        previousTextIndex = textIndex;
                    }

                    if (this.TextView.WordWrapGlyphs && lineCountVisual > 1)
                    {
                        RenderWordWrapGlyph(hdc, rs.ViewportY, rs.Y, rs.TextRectangle, rs.LineHeight);
                    }

                    this.RenderLineColumns(hdc, clientSize, rs);
                    rs.X = 0;
                    rs.LineIndexVirtual++;
                    rs.Y += rs.LineHeight;
                }

                this.PaintTooltipOverlay(hdc);
            }