Exemplo n.º 1
0
        // returns the iLine of the last line we drew
        internal static int DrawLines(PaintEventArgs e, FastColoredTextBox textbox, Pen servicePen)
        {
            Graphics graphics = e.Graphics;

            Brush changedLineBrush = new SolidBrush(textbox.ChangedLineColor);
            Brush currentLineBrush = new SolidBrush(Color.FromArgb(textbox.CurrentLineColor.A == 255 ? 50 : textbox.CurrentLineColor.A, textbox.CurrentLineColor));

            //create dictionary of bookmarks
            var bookmarksByLineIndex = new Dictionary<int, Bookmark>();
            foreach (Bookmark item in textbox.Bookmarks)
            {
                bookmarksByLineIndex[item.LineIndex] = item;
            }

            int firstChar = (Math.Max(0, textbox.HorizontalScroll.Value - textbox.Paddings.Left)) / textbox.CharWidth; // when drawing a line start at this character
            int lastChar = (textbox.HorizontalScroll.Value + textbox.ClientSize.Width) / textbox.CharWidth; // when drawing a line draw until this character

            // x-coordinate of where we can start drawing
            var x = textbox.LeftIndent + textbox.Paddings.Left - textbox.HorizontalScroll.Value;
            if (x < textbox.LeftIndent)
                firstChar++;

            // y-coordinate to line index
            int startLine = textbox.YtoLineIndex(textbox.VerticalScroll.Value);
            int iLine; // remember the last iLine we drew
            for (iLine = startLine; iLine < textbox.lines.Count; iLine++)
            {
                Line line = textbox.lines[iLine];
                LineInfo lineInfo = textbox.LineInfos[iLine];
                //
                if (lineInfo.startY > textbox.VerticalScroll.Value + textbox.ClientSize.Height)
                    break; // out of the drawing range
                if (lineInfo.startY + lineInfo.WordWrapStringsCount * textbox.CharHeight < textbox.VerticalScroll.Value)
                    continue; // skip
                if (lineInfo.VisibleState == VisibleState.Hidden)
                    continue; // skip

                int y = lineInfo.startY - textbox.VerticalScroll.Value;
                //
                graphics.SmoothingMode = SmoothingMode.None;
                //draw line background
                if (lineInfo.VisibleState == VisibleState.Visible)
                {
                    if (line.BackgroundBrush != null)
                    {
                        var rect = new Rectangle(textbox.TextAreaRect.Left, y, textbox.TextAreaRect.Width,
                                                 textbox.CharHeight*lineInfo.WordWrapStringsCount);
                        graphics.FillRectangle(line.BackgroundBrush, rect);
                    }
                }

                //draw current line background
                if (textbox.CurrentLineColor != Color.Transparent && iLine == textbox.Selection.Start.iLine)
                {
                    if (textbox.Selection.IsEmpty)
                    {
                        graphics.FillRectangle(currentLineBrush,
                                               new Rectangle(textbox.TextAreaRect.Left, y, textbox.TextAreaRect.Width,
                                                             textbox.CharHeight));
                    }
                }

                //draw changed line marker
                if (textbox.ChangedLineColor != Color.Transparent && line.IsChanged)
                {
                    graphics.FillRectangle(changedLineBrush,
                                           new RectangleF(-10, y,
                                                          textbox.LeftIndent - FastColoredTextBox.MIN_LEFT_INDENT - 2 + 10,
                                                          textbox.CharHeight + 1));
                }
                //
                graphics.SmoothingMode = SmoothingMode.AntiAlias;
                //
                //draw bookmark
                if (bookmarksByLineIndex.ContainsKey(iLine))
                {
                    bookmarksByLineIndex[iLine].Paint(graphics,
                                                              new Rectangle(textbox.LeftIndent, y, textbox.Width,
                                                                            textbox.CharHeight*
                                                                            lineInfo.WordWrapStringsCount));
                }
                //OnPaintLine event
                if (lineInfo.VisibleState == VisibleState.Visible)
                {
                    textbox.OnPaintLine(new PaintLineEventArgs(iLine,
                                                               new Rectangle(textbox.LeftIndent, y, textbox.Width,
                                                                             textbox.CharHeight * lineInfo.WordWrapStringsCount),
                                                               e.Graphics, e.ClipRectangle));
                }
                //draw line number
                if (textbox.ShowLineNumbers)
                {
                    using (var lineNumberBrush = new SolidBrush(textbox.LineNumberColor))
                    {
                        graphics.DrawString((iLine + textbox.lineNumberStartValue).ToString(), textbox.Font, lineNumberBrush,
                                              new RectangleF(-10, y, textbox.LeftIndent - FastColoredTextBox.MIN_LEFT_INDENT - 2 + 10, textbox.CharHeight),
                                              new StringFormat(StringFormatFlags.DirectionRightToLeft));
                    }
                }
                //create markers
                if (lineInfo.VisibleState == VisibleState.StartOfHiddenBlock)
                {
                    textbox.visibleMarkers.Add(new ExpandFoldingMarker(iLine,
                                                                       new Rectangle(textbox.LeftIndentLine - 4,
                                                                                     y + textbox.CharHeight / 2 - 3, 8,
                                                                                     8)));
                }
                if (!string.IsNullOrEmpty(line.FoldingStartMarker) && lineInfo.VisibleState == VisibleState.Visible &&
                    string.IsNullOrEmpty(line.FoldingEndMarker))
                {
                    textbox.visibleMarkers.Add(new CollapseFoldingMarker(iLine,
                                                                         new Rectangle(textbox.LeftIndentLine - 4,
                                                                                       y + textbox.CharHeight / 2 - 3,
                                                                                       8, 8)));
                }
                if (lineInfo.VisibleState == VisibleState.Visible && !string.IsNullOrEmpty(line.FoldingEndMarker) &&
                    string.IsNullOrEmpty(line.FoldingStartMarker))
                {
                    graphics.DrawLine(servicePen, textbox.LeftIndentLine, y + textbox.CharHeight * lineInfo.WordWrapStringsCount - 1,
                                        textbox.LeftIndentLine + 4, y + textbox.CharHeight * lineInfo.WordWrapStringsCount - 1);
                }
                //draw wordwrap strings of line
                for (int iWordWrapLine = 0; iWordWrapLine < lineInfo.WordWrapStringsCount; iWordWrapLine++)
                {
                    y = lineInfo.startY + iWordWrapLine * textbox.CharHeight - textbox.VerticalScroll.Value;
                    //indent
                    var indent = iWordWrapLine == 0 ? 0 : lineInfo.wordWrapIndent * textbox.CharWidth;
                    //draw chars
                    Rendering.DrawLineChars(graphics, textbox, firstChar, lastChar, iLine, iWordWrapLine, x + indent, y);
                }
            }

            currentLineBrush.Dispose();
            changedLineBrush.Dispose();

            return iLine - 1; // correct with -1 because it contains the index of the last lien we didn't draw
        }