// 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 }