/// <summary>
        ///     Method used to draw the actual text data for the Control
        /// </summary>
        private void OnDisplayText(PaintEventArgs e)
        {
            if (reformatLines)
            {
                InitializeDisplayLines();
                TotalDisplayLines = FormatLines(totalLines, 1, 0);
                UpdateScrollBar(TotalDisplayLines, 0);
                reformatLines = false;
            }

            try
            {
                var g = e.Graphics; //using "using" allow auto dispose

                int startY;
                var startX = 0;
                int linesToDraw;

                var buildString = new StringBuilder();

                int curLine;
                int curForeColor, curBackColor;
                var pastForeColor = -1;
                //remember what is the text color before highlighting. Hint: the code is looping from left char to right char
                char[] ch;

                var displayRect = new Rectangle(0, 0, Width, Height);
                //Bitmap buffer = new Bitmap(this.Width, this.Height, e.Graphics);

                //g.Clear(IrcColor.colors[backColor]);

                if (BackgroundImage != null)
                {
                    g.FillRectangle(new SolidBrush(TextColor.GetColor(backColor)), displayRect);
                    g.DrawImage(BackgroundImage, displayRect.Left, displayRect.Top, displayRect.Width, displayRect.Height);
                }
                else g.FillRectangle(new SolidBrush(TextColor.GetColor(backColor)), displayRect);

                /*g.InterpolationMode = InterpolationMode.Low;
                    g.SmoothingMode = SmoothingMode.HighSpeed;
                    g.PixelOffsetMode = PixelOffsetMode.None;
                    g.CompositingQuality = CompositingQuality.HighSpeed;
                    g.TextRenderingHint = TextRenderingHint.SystemDefault;*/

                if (totalLines == 0) return;

                else
                {
                    var val = vScrollBar.Value;

                    linesToDraw = Math.Min(showMaxLines, val);
                    //Math.Min is faster and more readable than if-else, Reference:http://stackoverflow.com/questions/5478877/math-max-vs-inline-if-what-are-the-differences

                    curLine = val - linesToDraw;

                    if (singleLine)
                    {
                        startY = 0;
                        linesToDraw = 1;
                        curLine = 0;
                    }
                    else startY = Height - LineSize * linesToDraw - LineSize / 2;

                    var lineCounter = 0;

                    var underline = false;
                    var isInUrl = false;
                    var font = new Font(Font, FontStyle.Regular);

                    var redline = -1;
                    if (ShowUnreadLine)
                    {
                        for (int i = TotalDisplayLines - 1, j = 0; i >= 0; --i)
                        {
                            if (!displayLines[i].Previous)
                            {
                                ++j;
                                if (j == unreadMarker)
                                {
                                    redline = i;
                                    break;
                                }
                            }
                        }
                    }

                    while (lineCounter < linesToDraw) //iterate over all rows
                    {
                        int i = 0, j = 0;
                        var highlight = false;
                        var oldHighlight = false;

                        if (redline == curLine)
                        {
                            using (var p = new Pen(Color.Red))
                            {
                                g.DrawLine(p, 0, startY, Width, startY);
                            }
                        }

                        lineCounter++;

                        curForeColor = displayLines[curLine].TextColor;
                        var line = new StringBuilder();

                        line.Append(displayLines[curLine].Line);
                        curBackColor = backColor;

                        //check if in a url, cancel underline if not
                        if (!isInUrl)
                        {
                            underline = false;
                            font.SafeDispose();
                            font = new Font(Font, FontStyle.Regular);
                        }

                        if (line.Length > 0)
                        {
                            do //iterate over every character in a line
                            {
                                ch = line.ToString().Substring(i, 1).ToCharArray();
                                switch (ch[0])
                                {
                                    case TextColor.EmotChar: //this header is added by SaidLine.cs & SaidLineEx.cs
                                        //draws an emoticon
                                        //[]001
                                        var emotNumber = Convert.ToInt32(line.ToString().Substring(i + 1, 3));
                                        line.Remove(0, i + 4);
                                        i = -1;
                                        
                                        //draw text (that wasn't yet drawn up to *this* point)
                                        startX = DT(g, buildString, Font, startX, startY, curForeColor, curBackColor);

                                        //draw an emoticon
                                        g.DrawImage(TextImage.GetImage(emotNumber), startX, startY, 16, 16);
                                        startX += 16;

                                        buildString.Clear(); //reset the content (because we already draw it for user)


                                        break;
                                    case TextColor.UrlStart:
                                        startX = DT(g, buildString, font, startX, startY, curForeColor, curBackColor);

                                        buildString.Clear();

                                        //remove whats drawn from string
                                        line.Remove(0, i);
                                        line.Remove(0, 1);
                                        i = -1;
                                        font.SafeDispose();
                                        font = new Font(Font, FontStyle.Underline);
                                        isInUrl = true;
                                        break;

                                    case TextColor.UrlEnd:
                                        startX = DT(g, buildString, font, startX, startY, curForeColor, curBackColor);
                                        buildString.Clear();

                                        //remove whats drawn from string
                                        line.Remove(0, i);
                                        line.Remove(0, 1);
                                        i = -1;
                                        font.SafeDispose();
                                        font = new Font(Font, FontStyle.Regular);
                                        isInUrl = false;
                                        break;
                                    case TextColor.UnderlineChar:
                                        startX = DT(g, buildString, font, startX, startY, curForeColor, curBackColor);
                                        buildString.Clear();

                                        //remove whats drawn from string
                                        line.Remove(0, i);
                                        line.Remove(0, 1);
                                        i = -1;

                                        underline = !underline;
                                        font.SafeDispose();
                                        if (underline) font = new Font(Font, FontStyle.Underline);
                                        else
                                        {
                                            font = new Font(Font, FontStyle.Regular);
                                        }
                                        break;
                                    case TextColor.NewColorChar:
                                        //draw whats previously in the string
                                        startX = DT(g, buildString, font, startX, startY, curForeColor, curBackColor);
                                        //is slow for slow gpu IMO
                                        buildString.Clear();

                                        //remove whats drawn from string
                                        line.Remove(0, i);

                                        //get the new fore and back colors
                                        if (!highlight)
                                        {
                                            curForeColor = Convert.ToInt32(line.ToString().Substring(1, 2));
                                            curBackColor = Convert.ToInt32(line.ToString().Substring(3, 2));

                                            //check to make sure that FC and BC are in range 0-32
                                            if (curForeColor > TextColor.colorRange) curForeColor = displayLines[curLine].TextColor;
                                            if (curBackColor > TextColor.colorRange) curBackColor = backColor;
                                        }
                                        else //if highlighting then:
                                        {
                                            pastForeColor = Convert.ToInt32(line.ToString().Substring(1, 2));
                                            //remember what color this text suppose to be (will be restored to the text on the right if highlighting only happen to text on the left) 

                                            //check to make sure that FC and BC are in range 0-32
                                            if (pastForeColor > TextColor.colorRange) pastForeColor = displayLines[curLine].TextColor;
                                            //only happen on exceptional case (this is only for safety, no significant whatsoever)
                                        }

                                        //remove the color codes from the string
                                        line.Remove(0, 5);
                                        i = -1;
                                        break;

                                    default:
                                        //curLine is "the line being processed here" (not user's line)
                                        //startHightLine is "the line where highlight start"
                                        //curHighLine is "the line where highlight end"
                                        //startHighChar is "the char where highlight start"
                                        //curHighChar is "the char where highlight end"
                                        //j is "the char being processed here"
                                        if (startHighLine >= 0 && //highlight is active
                                            ((curLine >= startHighLine && curLine <= curHighLine) ||
                                             //processing in between highlight (if highlight is upward)
                                             (curLine <= startHighLine && curLine >= curHighLine)))
                                        //processing in between highlight (if highlight is downward)
                                        {
                                            if ((curLine > startHighLine && curLine < curHighLine) ||
                                                (curLine == startHighLine && j >= startHighChar &&
                                                 (curLine <= curHighLine && j < curHighChar || curLine < curHighLine)) ||
                                                (curLine == curHighLine && j < curHighChar &&
                                                 (curLine >= startHighLine && j >= startHighChar || curLine > startHighLine)))
                                            {
                                                highlight = true;
                                            }
                                            else if ((curLine < startHighLine && curLine > curHighLine) ||
                                                     (curLine == startHighLine && j < startHighChar &&
                                                      (curLine >= curHighLine && j >= curHighChar || curLine > curHighLine)) ||
                                                     (curLine == curHighLine && j >= curHighChar &&
                                                      (curLine <= startHighLine && j < startHighChar || curLine < startHighLine)))
                                            {
                                                highlight = true;
                                            }
                                            else highlight = false;
                                        }
                                        else highlight = false;
                                        ++j;

                                        if (highlight != oldHighlight)
                                        //at highlight border (where left & right is highlight or not highlight)
                                        {
                                            oldHighlight = highlight;


                                            //draw text (that wasn't yet drawn up to *this* point)
                                            startX = DT(g, buildString, font, startX, startY, curForeColor, curBackColor);
                                            buildString.Clear(); //reset the content (because we already draw it for user)

                                            //remove whats drawn from string
                                            line.Remove(0, i);
                                            i = 0;
                                            if (highlight)
                                            {
                                                pastForeColor = curForeColor; //remember previous text color
                                                curForeColor = TextColor.background; //white (defined in TextColor.cs)
                                                curBackColor = TextColor.text; //black (defined in TextColor.cs)
                                            }
                                            else
                                            {
                                                curForeColor = pastForeColor; //restore intended text color
                                                curBackColor = backColor;
                                            }
                                        }
                                        buildString.Append(ch[0]);
                                        break;
                                }
                                i++;
                            } while (line.Length > 0 && i != line.Length); //loop character
                        }

                        //draw anything that is left over                
                        if (i == line.Length && line.Length > 0) DT(g, buildString, font, startX, startY, curForeColor, curBackColor);

                        startY += LineSize;
                        startX = 0;
                        curLine++;
                        buildString.Clear();
                    } //loop line
                    font.Dispose();
                    //e.Graphics.DrawImageUnscaled(buffer, 0, 0);
                }
                // var coords = displayRect
                ButtonRenderer.DrawButton(g,
                    new Rectangle(displayRect.Right - 200, displayRect.Top - 50, 100, 30),
                    "Hide",
                    Font,
                    false,
                    PushButtonState.Normal);
                buildString = null;
            }
            catch (Exception ee)
            {
                Trace.WriteLine("TextWindow OnDisplayText Error:" + ee.Message, ee.StackTrace);
            }
        }
        /// <summary>
        /// Method used to draw the actual text data for the Control
        /// </summary>
        void OnDisplayText(PaintEventArgs e)
        {
            if (reformatLines)
            {
                InitializeDisplayLines();
                TotalDisplayLines = FormatLines(totalLines, 1, 0);
                UpdateScrollBar(TotalDisplayLines,0);
                reformatLines = false;
            }

            try
            {
                using (var buffer = new Bitmap(Width, Height, PixelFormat.Format32bppPArgb))
                using (var sf = StringFormat.GenericTypographic)
                using (var g = Graphics.FromImage(buffer)) //using "using" allow auto dispose
                {
                    sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;

                    int startY;
                    float startX = 0;
                    int linesToDraw;

                    var buildString = new StringBuilder();
                    int textSize;

                    int curLine;
                    int curForeColor, curBackColor;
                    int pastForeColor=-1; //remember what is the text color before highlighting. Hint: the code is looping from left char to right char
                    char[] ch;

                    var displayRect = new Rectangle(0, 0, Width, Height);
                    //Bitmap buffer = new Bitmap(this.Width, this.Height, e.Graphics);

                    //g.Clear(IrcColor.colors[backColor]);

                    if (BackgroundImage != null)
                    {
                        g.FillRectangle(new SolidBrush(TextColor.GetColor(backColor)), displayRect);
                        g.DrawImage(BackgroundImage, displayRect.Left, displayRect.Top, displayRect.Width, displayRect.Height);
                    }
                    else g.FillRectangle(new SolidBrush(TextColor.GetColor(backColor)), displayRect);

                    g.InterpolationMode = InterpolationMode.Low;
                    g.SmoothingMode = SmoothingMode.HighSpeed;
                    g.PixelOffsetMode = PixelOffsetMode.None;
                    g.CompositingQuality = CompositingQuality.HighSpeed;
                    g.TextRenderingHint = TextRenderingHint.SystemDefault;


                    if (totalLines == 0) e.Graphics.DrawImageUnscaled(buffer, 0, 0);
                    else
                    {
                        var val = vScrollBar.Value;

                        linesToDraw = Math.Min(showMaxLines, val); //Math.Min is faster and more readable than if-else, Reference:http://stackoverflow.com/questions/5478877/math-max-vs-inline-if-what-are-the-differences

                        curLine = val - linesToDraw;

                        if (singleLine)
                        {
                            startY = 0;
                            linesToDraw = 1;
                            curLine = 0;
                        }
                        else startY = Height - (LineSize*linesToDraw) - (LineSize/2);

                        var lineCounter = 0;

                        var underline = false;
                        var isInUrl = false;
                        var font = new Font(Font.Name, Font.Size, Font.Style);

                        var redline = -1;
                        if (ShowUnreadLine)
                        {
                            for (int i = TotalDisplayLines - 1, j = 0; i >= 0; --i)
                            {
                                if (!displayLines[i].Previous)
                                {
                                    ++j;
                                    if (j == unreadMarker)
                                    {
                                        redline = i;
                                        break;
                                    }
                                }
                            }
                        }

                        while (lineCounter < linesToDraw) //iterate over all rows
                        {
                            int i = 0, j = 0;
                            var highlight = false;
                            var oldHighlight = false;

                            if (redline == curLine)
                            {
                                using (var p = new Pen(Color.Red)) {
                                    g.DrawLine(p, 0, startY, Width, startY);
                                }
                            }

                            lineCounter++;

                            curForeColor = displayLines[curLine].TextColor;
                            var line = new StringBuilder();

                            line.Append(displayLines[curLine].Line);
                            curBackColor = backColor;

                            //check if in a url, cancel underline if not
                            if (!isInUrl)
                            {
                                underline = false;
                                font.SafeDispose();
                                font = new Font(Font.Name, Font.Size, Font.Style);
                            }

                            if (line.Length > 0)
                            {
                                do //iterate over every character in a line
                                {
                                    using (SolidBrush backColorBrush = new SolidBrush(TextColor.GetColor(curBackColor))) //refresh backcolor
                                    {
                                        ch = line.ToString().Substring(i, 1).ToCharArray();
                                        switch (ch[0])
                                        {
                                            case TextColor.EmotChar: //this header is added by SaidLine.cs & SaidLineEx.cs
                                                //draws an emoticon
                                                //[]001
                                                var emotNumber = Convert.ToInt32(line.ToString().Substring(i + 1, 3));

                                                line.Remove(0, 3);
                                                if (!isInUrl)
                                                {
                                                    //select the emoticon here
                                                    var bm = TextImage.GetImage(emotNumber);

                                                    if (curBackColor != backColor)
                                                    {
                                                        textSize = (int)g.MeasureString(buildString.ToString(), Font, 0, sf).Width + 1;
                                                        var r = new Rectangle((int)startX, startY, textSize + 1, LineSize + 1);
                                                        g.FillRectangle(backColorBrush, r); //draw white (or black) rectangle
                                                    }

                                                    g.DrawImage(bm, //draw an emoticon
                                                                startX + g.MeasureString(buildString.ToString(), Font, 0, sf).Width,
                                                                startY,
                                                                16,
                                                                16);

                                                    using (var brush = new SolidBrush(TextColor.GetColor(curForeColor))) {
                                                        g.DrawString(buildString.ToString(), //draw text (that wasn't yet drawn up to *this* point)
                                                                        Font,
                                                                        brush,
                                                                        startX,
                                                                        startY,
                                                                        sf);
                                                    }

                                                    startX += bm.Width + g.MeasureString(buildString.ToString(), Font, 0, sf).Width;

                                                    buildString.Clear(); //reset the content (because we already draw it for user)
                                                }
                                                break;
                                            case TextColor.UrlStart:
                                                if (curBackColor != backColor)
                                                {
                                                    textSize = (int)g.MeasureString(buildString.ToString(), Font, 0, sf).Width + 1;
                                                    var r = new Rectangle((int)startX, startY, textSize + 1, LineSize + 1);
                                                    g.FillRectangle(backColorBrush, r);
                                                }
                                                using (var brush = new SolidBrush(TextColor.GetColor(curForeColor))) {
                                                    g.DrawString(buildString.ToString(),
                                                                    font,
                                                                    brush,
                                                                    startX,
                                                                    startY,
                                                                    sf);
                                                }
                                                // TextRenderer.DrawText(g, buildString.ToString(), font, new Point((int)startX, startY), TextColor.GetColor(curForeColor), TextColor.GetColor(curBackColor)); //is slow for slow gpu IMO

                                                startX += g.MeasureString(buildString.ToString(), font, 0, sf).Width; //textSizes[32]

                                                buildString.Clear();

                                                //remove whats drawn from string
                                                line.Remove(0, i);
                                                line.Remove(0, 1);
                                                i = -1;
                                                font.SafeDispose();
                                                font = new Font(Font.Name, Font.Size, Font.Style | FontStyle.Underline);
                                                isInUrl = true;
                                                break;

                                            case TextColor.UrlEnd:
                                                if (curBackColor != backColor)
                                                {
                                                    textSize = (int)g.MeasureString(buildString.ToString(), font, 0, sf).Width + 1;
                                                    var r = new Rectangle((int)startX, startY, textSize + 1, LineSize + 1);
                                                    g.FillRectangle(backColorBrush, r);
                                                }
                                                // TextRenderer.DrawText(g, buildString.ToString(), font, new Point((int)startX, startY), TextColor.GetColor(curForeColor), TextColor.GetColor(curBackColor)); //is slow for slow gpu IMO
                                                using (var brush = new SolidBrush(TextColor.GetColor(curForeColor))) {
                                                    g.DrawString(buildString.ToString(),
                                                                    font,
                                                                    brush,
                                                                    startX,
                                                                    startY,
                                                                    sf);
                                                }

                                                startX += g.MeasureString(buildString.ToString(), font, 0, sf).Width; //textSizes[32]

                                                buildString.Clear();

                                                //remove whats drawn from string
                                                line.Remove(0, i);
                                                line.Remove(0, 1);
                                                i = -1;
                                                font.SafeDispose();
                                                font = new Font(Font.Name, Font.Size, Font.Style);
                                                isInUrl = false;
                                                break;
                                            case TextColor.UnderlineChar:
                                                if (curBackColor != backColor)
                                                {
                                                    textSize = (int)g.MeasureString(buildString.ToString(), font, 0, sf).Width + 1;
                                                    var r = new Rectangle((int)startX, startY, textSize + 1, LineSize + 1);
                                                    g.FillRectangle(backColorBrush, r);
                                                }
                                                // TextRenderer.DrawText(g, buildString.ToString(), font, new Point((int)startX, startY), TextColor.GetColor(curForeColor), TextColor.GetColor(curBackColor)); //is slow for slow gpu IMO
                                                using (var brush = new SolidBrush(TextColor.GetColor(curForeColor))) {
                                                    g.DrawString(buildString.ToString(),
                                                                    font,
                                                                    brush,
                                                                    startX,
                                                                    startY,
                                                                    sf);
                                                }

                                                startX += g.MeasureString(buildString.ToString(), font, 0, sf).Width; //textSizes[32]

                                                buildString.Clear();

                                                //remove whats drawn from string
                                                line.Remove(0, i);
                                                line.Remove(0, 1);
                                                i = -1;

                                                underline = !underline;
                                                font.SafeDispose();
                                                if (underline) font = new Font(Font.Name, Font.Size, Font.Style | FontStyle.Underline);
                                                else {font = new Font(Font.Name, Font.Size, Font.Style);}
                                                break;
                                            case TextColor.NewColorChar:
                                                //draw whats previously in the string
                                                if (curBackColor != backColor)
                                                {
                                                    textSize = (int)g.MeasureString(buildString.ToString(), font, 0, sf).Width + 1;
                                                    var r = new Rectangle((int)startX, startY, textSize + 1, LineSize + 1);
                                                    g.FillRectangle(backColorBrush, r);
                                                }
                                                // TextRenderer.DrawText(g, buildString.ToString(), font, new Point((int)startX, startY), TextColor.GetColor(curForeColor), TextColor.GetColor(curBackColor)); //is slow for slow gpu IMO
                                                using (var brush = new SolidBrush(TextColor.GetColor(curForeColor))) {
                                                    g.DrawString(buildString.ToString(),
                                                                    font,
                                                                    brush,
                                                                    startX,
                                                                    startY,
                                                                    sf);
                                                }

                                                startX += g.MeasureString(buildString.ToString(), font, 0, sf).Width; //textSizes[32]

                                                buildString.Clear();

                                                //remove whats drawn from string
                                                line.Remove(0, i);

                                                //get the new fore and back colors
                                                if (!highlight)
                                                {
                                                    curForeColor = Convert.ToInt32(line.ToString().Substring(1, 2));
                                                    curBackColor = Convert.ToInt32(line.ToString().Substring(3, 2));

                                                    //check to make sure that FC and BC are in range 0-32
                                                    if (curForeColor > TextColor.colorRange) curForeColor = displayLines[curLine].TextColor;
                                                    if (curBackColor > TextColor.colorRange) curBackColor = backColor;
                                                }
                                                else //if highlighting then:
                                                {
                                                    pastForeColor = Convert.ToInt32(line.ToString().Substring(1, 2)); //remember what color this text suppose to be (will be restored to the text on the right if highlighting only happen to text on the left) 
                                                    
                                                    //check to make sure that FC and BC are in range 0-32
                                                    if (pastForeColor > TextColor.colorRange) pastForeColor = displayLines[curLine].TextColor; //only happen on exceptional case (this is only for safety, no significant whatsoever)
                                                }

                                                //remove the color codes from the string
                                                line.Remove(0, 5);
                                                i = -1;
                                                break;

                                            default:
                                                //random symbol safety check (symbols to skip drawing)
                                                if((int)ch[0] > Int16.MaxValue) //random symbol can mess up graphic object "g" in Linux! which cause nothing to be drawn after the symbol
                                                {
                                                    if (curBackColor != backColor)
                                                    {
                                                        textSize = (int)g.MeasureString(buildString.ToString(), Font, 0, sf).Width + 1;
                                                        var r = new Rectangle((int)startX, startY, textSize + 1, LineSize + 1);
                                                        g.FillRectangle(backColorBrush, r);
                                                    }
                                                    using (var brush = new SolidBrush(TextColor.GetColor(curForeColor))) {
                                                        g.DrawString(buildString.ToString(),
                                                                     font,
                                                                     brush,
                                                                     startX,
                                                                     startY,
                                                                     sf);
                                                    }
                                                    startX += g.MeasureString(buildString.ToString(), font, 0, sf).Width;
                                                    float symbolWidth;
                                                    using (var tmpBuffer = new Bitmap(LineSize,LineSize, PixelFormat.Format32bppPArgb))
                                                    using (var tmpG = Graphics.FromImage(tmpBuffer)) //temporary graphic object that can be messed up independently
                                                    {
                                                        var randomChar = ch[0].ToString();
                                                        symbolWidth = tmpG.MeasureString(randomChar, font, 0, sf).Width;
                                                        if (symbolWidth > 0) //don't draw when symbol width == 0 (symptom obtained from trial-n-error)
                                                        {
                                                            using (var brush = new SolidBrush(TextColor.GetColor(curForeColor)))
                                                            {
                                                                g.DrawString(randomChar,
                                                                             font,
                                                                             brush,
                                                                             startX,
                                                                             startY,
                                                                             sf);
                                                            }
                                                        }
                                                    }
                                                    startX += symbolWidth;

                                                    line.Remove(0, i);
                                                    line.Remove(0, 1);
                                                    i= -1;

                                                    buildString.Clear();

                                                    break;
                                                }

                                                //curLine is "the line being processed here" (not user's line)
                                                //startHightLine is "the line where highlight start"
                                                //curHighLine is "the line where highlight end"
                                                //startHighChar is "the char where highlight start"
                                                //curHighChar is "the char where highlight end"
                                                //j is "the char being processed here"
                                                if (startHighLine >= 0 && //highlight is active
                                                    ((curLine >= startHighLine && curLine <= curHighLine) || //processing in between highlight (if highlight is upward)
                                                        (curLine <= startHighLine && curLine >= curHighLine)))  //processing in between highlight (if highlight is downward)
                                                {
                                                    if ((curLine > startHighLine && curLine < curHighLine) ||
                                                        (curLine == startHighLine && j >= startHighChar && (curLine <= curHighLine && j < curHighChar || curLine < curHighLine)) ||
                                                        (curLine == curHighLine && j < curHighChar && (curLine >= startHighLine && j >= startHighChar || curLine > startHighLine)))
                                                    {
                                                        highlight = true;
                                                    }
                                                    else if ((curLine < startHighLine && curLine > curHighLine) ||
                                                                (curLine == startHighLine && j < startHighChar && (curLine >= curHighLine && j >= curHighChar || curLine > curHighLine)) ||
                                                                (curLine == curHighLine && j >= curHighChar && (curLine <= startHighLine && j < startHighChar || curLine < startHighLine)))
                                                    {
                                                        highlight = true;
                                                    }
                                                    else highlight = false;
                                                }
                                                else highlight = false;
                                                ++j;

                                                if (highlight != oldHighlight) //at highlight border (where left & right is highlight or not highlight)
                                                {
                                                    oldHighlight = highlight;

                                                    //draw whats previously in the string                                
                                                    if (curBackColor != backColor)
                                                    {
                                                        textSize = (int)g.MeasureString(buildString.ToString(), font, 0, sf).Width + 1;
                                                        var r = new Rectangle((int)startX, startY, textSize + 1, LineSize + 1);
                                                        g.FillRectangle(backColorBrush, r); //draw black (or white) rectangle
                                                    }
                                                    /* //GDI example:
                                                        TextRenderer.DrawText(g,
                                                                        buildString.ToString(),
                                                                        font,
                                                                        new Point((int)startX, startY),
                                                                        TextColor.GetColor(curForeColor),
                                                                        TextColor.GetColor(curBackColor));
                                                    */
                                                    using (var solidBrush = new SolidBrush(TextColor.GetColor(curForeColor))) {
                                                        g.DrawString(buildString.ToString(), //draw text (that wasn't yet drawn up to *this* point)
                                                                        font,
                                                                        solidBrush,
                                                                        startX,
                                                                        startY,
                                                                        sf);
                                                    }

                                                    startX += g.MeasureString(buildString.ToString(), font, 0, sf).Width; //textSizes[32]

                                                    buildString.Clear();//reset the content (because we already draw it for user)

                                                    //remove whats drawn from string
                                                    line.Remove(0, i);
                                                    i = 0;
                                                    if (highlight)
                                                    {
                                                        pastForeColor = curForeColor; //remember previous text color
                                                        curForeColor = TextColor.background; //white (defined in TextColor.cs)
                                                        curBackColor = TextColor.text; //black (defined in TextColor.cs)
                                                    }
                                                    else
                                                    {
                                                        curForeColor = pastForeColor; //restore intended text color
                                                        curBackColor = backColor;
                                                    }
                                                }
                                                buildString.Append(ch[0]);
                                                break;
                                        }
                                        i++;
                                    }
                                } while (line.Length > 0 && i != line.Length); //loop character
                            }

                            //draw anything that is left over                
                            if (i == line.Length && line.Length > 0)
                            {
                                if (curBackColor != backColor)
                                {
                                    textSize = (int)g.MeasureString(buildString.ToString(), font, 0, sf).Width + 1;
                                    var r = new Rectangle((int)startX, startY, textSize + 1, LineSize + 1);
                                    using (var brush = new SolidBrush(TextColor.GetColor(curBackColor))) g.FillRectangle(brush, r);
                                }
                                // TextRenderer.DrawText(g, buildString.ToString(), font, new Point((int)startX, startY), TextColor.GetColor(curForeColor), TextColor.GetColor(curBackColor));
                                using (var brush = new SolidBrush(TextColor.GetColor(curForeColor))) {
                                    g.DrawString(buildString.ToString(), font, brush, startX, startY, sf);
                                }
                            }

                            startY += LineSize;
                            startX = 0;
                            curLine++;
                            buildString.Clear();
                        } //loop line
                        font.Dispose();
                        e.Graphics.DrawImageUnscaled(buffer, 0, 0);
                    }
                    // var coords = displayRect
                    ButtonRenderer.DrawButton(g,
                                              new Rectangle(displayRect.Right - 200, displayRect.Top - 50, 100, 30),
                                              "Hide",
                                              Font,
                                              false,
                                              PushButtonState.Normal);
                    buildString = null;
                }
            }
            catch (Exception ee)
            {
                Trace.WriteLine("TextWindow OnDisplayText Error:" + ee.Message, ee.StackTrace);
            }
        }