Beispiel #1
0
        private void redraw()
        {
            Dispatcher.VerifyAccess();

            var context = RenderOpen();

            try
            {
                if (line == null)
                {
                    return;
                }

                TextDecorationCollection textDecorations = null;
                // Stores the previously formatted run
                FormattedText prevFt = null;

                var drawPoint = new System.Windows.Point(0, 0);
                int index     = 0;
                foreach (var run in line.Runs)
                {
                    if (run.Font.Hidden && Line.Runs[Line.Runs.Count - 1] == run)
                    {
                        break;
                    }

                    SolidColorBrush foreground;
                    SolidColorBrush background;
                    if (run.Font.Inverse)
                    {
                        foreground = Terminal.GetFontBackgroundBrush(run.Font);
                        background = Terminal.GetFontForegroundBrush(run.Font);
                    }
                    else
                    {
                        foreground = Terminal.GetFontForegroundBrush(run.Font);
                        background = Terminal.GetFontBackgroundBrush(run.Font);
                    }

                    // Format the text for this run.  However, this is drawn NEXT run.  The
                    // background is drawn one run ahead of the text so the text doesn't get
                    // clipped.
                    var ft = new FormattedText(
                        run.Text,
                        System.Globalization.CultureInfo.CurrentUICulture,
                        Terminal.FlowDirection,
                        Terminal.GetFontTypeface(run.Font),
                        Terminal.FontSize,
                        foreground,
                        new NumberSubstitution(),
                        TextFormattingMode.Ideal
                        );

                    if (run.Font.Underline || run.Font.Strike)
                    {
                        if (textDecorations == null)
                        {
                            textDecorations = new TextDecorationCollection(2);
                        }
                        else
                        {
                            textDecorations.Clear();
                        }

                        if (run.Font.Underline)
                        {
                            textDecorations.Add(TextDecorations.Underline);
                        }
                        if (run.Font.Strike)
                        {
                            textDecorations.Add(TextDecorations.Strikethrough);
                        }

                        ft.SetTextDecorations(textDecorations);
                    }

                    // Draw the background and border for the current run
                    Pen border = null;
                    if (Terminal.DrawRunBoxes)
                    {
                        border = new Pen(DebugColors.GetBrush(index), 1);
                    }

                    var backgroundTopLeft = new System.Windows.Point(Math.Floor(drawPoint.X), Math.Floor(drawPoint.Y));
                    if (prevFt != null)
                    {
                        backgroundTopLeft.X += prevFt.WidthIncludingTrailingWhitespace;
                    }
                    var backgroundSize = new Vector(Math.Ceiling(ft.WidthIncludingTrailingWhitespace + 1), Math.Ceiling(ft.Height + 1));
                    context.DrawRectangle(background, border, new Rect(backgroundTopLeft, backgroundSize));

                    if (prevFt != null)
                    {
                        context.DrawText(prevFt, drawPoint);
                        drawPoint.X += prevFt.WidthIncludingTrailingWhitespace;
                    }
                    prevFt = ft;

                    index++;
                }

                if (prevFt != null)
                {
                    context.DrawText(prevFt, drawPoint);
                }

                // TODO: This selection drawing logic doesn't account for multi-width characters.
                if (SelectionStart != SelectionEnd)
                {
                    if (prevFt != null)
                    {
                        drawPoint.X += prevFt.WidthIncludingTrailingWhitespace;
                    }

                    var selectRect = new Rect(
                        new System.Windows.Point(Math.Floor(Math.Min(drawPoint.X, Terminal.CharWidth * SelectionStart)), 0.0),
                        new System.Windows.Point(Math.Ceiling(Math.Min(drawPoint.X, Terminal.CharWidth * SelectionEnd)), Math.Ceiling(Terminal.CharHeight)));

                    var brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(128, 90, 180, 230));
                    context.DrawRectangle(brush, null, selectRect);
                }
            }
            finally
            {
                context.Close();
            }
        }
Beispiel #2
0
        private void redraw(TerminalRun[] runs)
        {
            Dispatcher.VerifyAccess();

            //drawnRuns = new List<VisualRun>(runs.Length);
            //for (int i = 0; i < runs.Length; ++i)
            //{
            //	drawnRuns.Add(new VisualRun() { Run = runs[i], Text = null });
            //}
            bool changed = false;

            for (int i = 0; i < Math.Min(drawnRuns.Count, runs.Length); ++i)
            {
                if (drawnRuns[i].Run.Text != runs[i].Text || drawnRuns[i].Run.Font != runs[i].Font)
                {
                    drawnRuns[i] = new VisualRun()
                    {
                        Run = runs[i], Text = null
                    };
                    changed = true;
                }
            }

            if (drawnRuns.Count > runs.Length)
            {
                drawnRuns.RemoveRange(runs.Length, drawnRuns.Count - runs.Length);
            }
            else if (drawnRuns.Count < runs.Length)
            {
                drawnRuns.AddRange(runs.Skip(drawnRuns.Count).Select(x => new VisualRun()
                {
                    Run = x
                }));
            }
            else if (!changed && !selectionChanged)
            {
                return;
            }
            selectionChanged = false;

            for (int i = 0; i < drawnRuns.Count; ++i)
            {
                var run = drawnRuns[i].Run;
                if (drawnRuns[i].Text != null)
                {
                    continue;
                }

                SolidColorBrush foreground = Terminal.GetFontForegroundBrush(run.Font);

                // Format the text for this run.  However, this is drawn NEXT run.  The
                // background is drawn one run ahead of the text so the text doesn't get
                // clipped.
                var ft = new FormattedText(
                    run.Text,
                    System.Globalization.CultureInfo.CurrentUICulture,
                    Terminal.FlowDirection,
                    Terminal.GetFontTypeface(run.Font),
                    Terminal.FontSize,
                    foreground,
                    new NumberSubstitution(),
                    TextFormattingMode.Ideal
                    );

                if (run.Font.Underline || run.Font.Strike)
                {
                    var textDecorations = new TextDecorationCollection(2);

                    if (run.Font.Underline)
                    {
                        textDecorations.Add(TextDecorations.Underline);
                    }
                    if (run.Font.Strike)
                    {
                        textDecorations.Add(TextDecorations.Strikethrough);
                    }

                    ft.SetTextDecorations(textDecorations);
                }

                drawnRuns[i] = new VisualRun()
                {
                    Run = drawnRuns[i].Run, Text = ft
                };
            }

            var context = RenderOpen();

            try
            {
                var drawPoint = new System.Windows.Point(0, 0);
                int index     = 0;
                foreach (var run in drawnRuns)
                {
                    if (run.Run.Font.Hidden && index == drawnRuns.Count - 1)
                    {
                        break;
                    }

                    SolidColorBrush background = Terminal.GetFontBackgroundBrush(run.Run.Font);

                    // Draw the background and border for the current run
                    Pen border = null;
                    if (Terminal.DrawRunBoxes)
                    {
                        border = new Pen(DebugColors.GetBrush(index), 1);
                    }

                    var backgroundTopLeft = new System.Windows.Point(Math.Floor(drawPoint.X), Math.Floor(drawPoint.Y));
                    var backgroundSize    = new Vector(Math.Floor(run.Text.WidthIncludingTrailingWhitespace), Math.Ceiling(run.Text.Height));
                    context.DrawRectangle(background, border, new Rect(backgroundTopLeft, backgroundSize));

                    drawPoint.X += run.Text.WidthIncludingTrailingWhitespace;

                    index++;
                }

                drawPoint = new System.Windows.Point(0, 0);
                index     = 0;
                foreach (var run in drawnRuns)
                {
                    if (run.Run.Font.Hidden && index == drawnRuns.Count - 1)
                    {
                        break;
                    }

                    context.DrawText(run.Text, drawPoint);
                    drawPoint.X += run.Text.WidthIncludingTrailingWhitespace;

                    index++;
                }

                // TODO: This selection drawing logic doesn't account for multi-width characters.
                if (SelectionStart != SelectionEnd)
                {
                    var selectRect = new Rect(
                        new System.Windows.Point(Math.Floor(Math.Min(drawPoint.X, Terminal.CharWidth * SelectionStart)), 0.0),
                        new System.Windows.Point(Math.Ceiling(Math.Min(drawPoint.X, Terminal.CharWidth * SelectionEnd)), Math.Ceiling(Terminal.CharHeight)));

                    var brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(128, 90, 180, 230));
                    context.DrawRectangle(brush, null, selectRect);
                }
            }
            finally
            {
                context.Close();
            }
        }