Beispiel #1
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            Debug.Print("DiffControl OnRender");

#if DEBUG
            MeasureRendeTime();
#endif

            // Fill background
            drawingContext.DrawRectangle(AppSettings.FullMatchBackground, null, new Rect(0, 0, this.ActualWidth, this.ActualHeight));

            if (Lines.Count == 0)
            {
                return;
            }

            typeface = new Typeface(this.FontFamily, this.FontStyle, this.FontWeight, this.FontStretch);

            Matrix m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
            dpiScale = 1 / m.M11;

            TextUtils.CreateGlyphRun("W", typeface, this.FontSize, dpiScale, out characterWidth);
            characterHeight = Math.Ceiling(TextUtils.FontHeight(typeface, this.FontSize, dpiScale) / dpiScale) * dpiScale;

            Brush activeDiffBrush = new SolidColorBrush(Color.FromRgb(220, 220, 220));
            activeDiffBrush.Freeze();

            Pen borderPen = new Pen(SystemColors.ScrollBarBrush, RoundToWholePixels(1));
            borderPen.Freeze();
            GuidelineSet borderGuide = CreateGuidelineSet(borderPen);

            textMargin       = RoundToWholePixels(4);
            lineNumberMargin = RoundToWholePixels(characterWidth * Lines.Count.ToString().Length) + (2 * textMargin) + borderPen.Thickness;

            VisibleLines       = (int)(ActualHeight / characterHeight + 1);
            MaxVerialcalScroll = Lines.Count - VisibleLines + 1;

            drawingContext.DrawRectangle(SystemColors.ControlBrush, null, new Rect(0, 0, lineNumberMargin, this.ActualHeight));

            for (int i = 0; i < VisibleLines; i++)
            {
                int lineIndex = i + VerticalOffset;

                if (lineIndex >= Lines.Count)
                {
                    break;
                }

                Line line = Lines[lineIndex];

                // Line Y offset
                drawingContext.PushTransform(new TranslateTransform(0, characterHeight * i));
                {
                    // Draw line number
                    SolidColorBrush lineNumberColor = SystemColors.ControlDarkBrush;

                    if (lineIndex >= CurrentDiff && lineIndex < CurrentDiff + CurrentDiffLength && !Edited)
                    {
                        lineNumberColor = SystemColors.ControlDarkDarkBrush;
                        drawingContext.DrawRectangle(activeDiffBrush, null, new Rect(0, 0, lineNumberMargin, characterHeight));
                    }

                    // Draw line background
                    if (line.Type != TextState.FullMatch)
                    {
                        drawingContext.DrawRectangle(line.BackgroundBrush, null, new Rect(lineNumberMargin, 0, Math.Max(this.ActualWidth - lineNumberMargin, 0), characterHeight));
                    }

                    if (line.LineIndex != null)
                    {
                        GlyphRun rowNumberRun = line.GetRenderedLineIndexText(typeface, this.FontSize, dpiScale, out double rowNumberWidth);

                        drawingContext.PushTransform(new TranslateTransform(lineNumberMargin - rowNumberWidth - textMargin - borderPen.Thickness, 0));
                        drawingContext.DrawGlyphRun(lineNumberColor, rowNumberRun);
                        drawingContext.Pop();
                    }

                    // Text clipping rect
                    drawingContext.PushClip(new RectangleGeometry(new Rect(lineNumberMargin + textMargin, 0, Math.Max(ActualWidth - lineNumberMargin - textMargin * 2, 0), ActualHeight)));
                    {
                        // Line X offset
                        drawingContext.PushTransform(new TranslateTransform(lineNumberMargin + textMargin - HorizontalOffset, 0));
                        {
                            // Draw line
                            if (line.Text != "")
                            {
                                double nextPosition = 0;
                                foreach (TextSegment textSegment in line.TextSegments)
                                {
                                    drawingContext.PushTransform(new TranslateTransform(nextPosition, 0));

                                    GlyphRun segmentRun = textSegment.GetRenderedText(typeface, this.FontSize, dpiScale, AppSettings.ShowWhiteSpaceCharacters, AppSettings.TabSize, out double runWidth);

                                    if (nextPosition - HorizontalOffset < ActualWidth && nextPosition + runWidth - HorizontalOffset > 0)
                                    {
                                        if (line.Type != textSegment.Type && AppSettings.ShowLineChanges)
                                        {
                                            drawingContext.DrawRectangle(textSegment.BackgroundBrush, null, new Rect(nextPosition == 0 ? -textMargin : 0, 0, runWidth + (nextPosition == 0 ? textMargin : 0), characterHeight));
                                        }

                                        drawingContext.DrawGlyphRun(AppSettings.ShowLineChanges ? textSegment.ForegroundBrush : line.ForegroundBrush, segmentRun);
                                    }
                                    nextPosition += runWidth;

                                    drawingContext.Pop();
                                }
                                maxTextwidth = Math.Max(maxTextwidth, nextPosition);
                            }

                            // Draw cursor
                            if (EditMode && this.IsFocused && cursorLine == lineIndex && cursorBlink)
                            {
                                drawingContext.DrawRectangle(Brushes.Black, null, new Rect(CharacterPosition(lineIndex, cursorCharacter), 0, RoundToWholePixels(1), characterHeight));
                            }
                        }
                        drawingContext.Pop();                 // Line X offset
                    }
                    drawingContext.Pop();                     // Text clipping rect

                    // Text area clipping rect
                    drawingContext.PushClip(new RectangleGeometry(new Rect(lineNumberMargin, 0, Math.Max(ActualWidth - lineNumberMargin, 0), ActualHeight)));
                    {
                        // Line X offset 2
                        drawingContext.PushTransform(new TranslateTransform(lineNumberMargin + textMargin - HorizontalOffset, 0));
                        {
                            // Draw selection
                            if (Selection != null && lineIndex >= Selection.TopLine && lineIndex <= Selection.BottomLine)
                            {
                                Rect selectionRect = new Rect(0 - textMargin + HorizontalOffset, 0, this.ActualWidth + HorizontalOffset, characterHeight);
                                if (Selection.TopLine == lineIndex && Selection.TopCharacter > 0)
                                {
                                    selectionRect.X = Math.Max(0, CharacterPosition(lineIndex, Selection.TopCharacter));
                                }
                                if (Selection.BottomLine == lineIndex)
                                {
                                    selectionRect.Width = Math.Max(0, CharacterPosition(lineIndex, Selection.BottomCharacter) - selectionRect.X);
                                }
                                drawingContext.DrawRectangle(AppSettings.SelectionBackground, null, selectionRect);
                            }
                        }
                        drawingContext.Pop();         // Line X offset 2
                    }
                    drawingContext.Pop();             // Text area clipping rect
                }
                drawingContext.Pop();                 // Line Y offset
            }

            // Draw line number border
            drawingContext.PushGuidelineSet(borderGuide);
            {
                drawingContext.DrawLine(borderPen, new Point(lineNumberMargin, -1), new Point(lineNumberMargin, this.ActualHeight));
            }
            drawingContext.Pop();

            TextAreaWidth       = (int)(ActualWidth - lineNumberMargin - (textMargin * 2));
            MaxHorizontalScroll = (int)(maxTextwidth - TextAreaWidth + textMargin);

#if DEBUG
            ReportRenderTime();
#endif
        }