예제 #1
0
 /// <summary>
 ///	Sets the character at the specified index in this line using the given font.
 /// </summary>
 /// <param name="index"></param>
 /// <param name="c"></param>
 /// <param name="font">Not Implemented</param>
 public void SetCharacter(int index, char c, TerminalFont font)
 {
     SetCharacters(index, new[] { c }, font);
 }
예제 #2
0
 public void SetCharacters(int index, char[] chars, TerminalFont font)
 {
     SetCharacters(index, new string(chars), font);
 }
예제 #3
0
        /// <summary>
        /// Replaces the characters on this line in the range [<paramref name="index"/>,
        /// <paramref name="index"/> + <paramref name="chars"/>.Length) with those in
        /// <paramref name="chars"/>.
        ///
        /// If the run at (<paramref name="index"/> - 1) or (<paramref name="index"/> +
        /// <paramref name="chars"/>.Length) has the same font as <paramref name="font"/>,
        /// it will be extended to include the new characters.  Otherwise, a new run will
        /// be created.
        /// </summary>
        /// <param name="index"></param>
        /// <param name="chars"></param>
        /// <param name="font"></param>
        public void SetCharacters(int index, string chars, TerminalFont font)
        {
            lock (this)
            {
                if (chars.Length == 0)
                {
                    return;
                }
                if (length < index + chars.Length)
                {
                    extend(index + chars.Length);
                }

                int totalIndex = 0;
                for (int i = 0; i < runs.Count; ++i)
                {
                    var run = runs[i];

                    // Completely replacing an existing run
                    if (index == totalIndex && chars.Length == run.Text.Length)
                    {
                        run.Text = chars;
                        run.Font = font;

                        break;
                    }
                    // Inside an existing run
                    else if (index >= totalIndex && index < totalIndex + run.Text.Length)
                    {
                        int newLength = Math.Min(chars.Length, totalIndex + run.Text.Length - index);
                        var newRun    = new TerminalRun()
                        {
                            Text = chars.Substring(0, newLength),
                            Font = font
                        };

                        var splitRun = new TerminalRun()
                        {
                            Text = run.Text.Substring(index - totalIndex + newLength),
                            Font = run.Font
                        };
                        run.Text = run.Text.Substring(0, index - totalIndex);
                        if (run.Text.Length == 0)
                        {
                            run.Text = newRun.Text;
                            run.Font = newRun.Font;

                            if (splitRun.Text.Length > 0)
                            {
                                runs.Insert(i + 1, splitRun);
                            }
                        }
                        else if (splitRun.Text.Length > 0)
                        {
                            runs.InsertRange(i + 1, new[] { newRun, splitRun });
                        }
                        else
                        {
                            runs.Insert(i + 1, newRun);
                        }

                        if (newLength != chars.Length)
                        {
                            SetCharacters(index + newLength, chars.Substring(newLength), font);
                        }

                        break;
                    }
                    totalIndex += run.Text.Length;
                }

                Color black = Color.FromRgb(0, 0, 0);

                for (int i = 0; i < runs.Count - 1; ++i)
                {
                    var run1 = runs[i];
                    var run2 = runs[i + 1];

                    bool specialMerge =
                        run1.Font.Background == run2.Font.Background &&
                        run1.Font.Inverse == run2.Font.Inverse &&
                        (run2.Font.Hidden || run2.Text == " ");

                    if (run1.Font == run2.Font || specialMerge)
                    {
                        if (specialMerge)
                        {
                            run1.Text += new string(' ', run2.Text.Length);
                        }
                        else
                        {
                            run1.Text += run2.Text;
                        }
                        runs.RemoveAt(i + 1);
                        i--;
                    }
                }
                savedRuns = null;
            }

            if (RunsChanged != null)
            {
                RunsChanged(this, EventArgs.Empty);
            }
        }
예제 #4
0
        public void InsertCharacters(int index, string chars, TerminalFont font)
        {
            lock (this)
            {
                if (chars.Length == 0)
                {
                    return;
                }
                if (length < index)
                {
                    extend(index);
                }

                int runIndex = 0;
                for (int i = 0; i < runs.Count; ++i)
                {
                    var run = runs[i];

                    if (runIndex + run.Text.Length >= index)
                    {
                        if (run.Font == font)
                        {
                            run.Text = run.Text.Insert(index - runIndex, chars);
                        }
                        else
                        {
                            var newRun = new TerminalRun()
                            {
                                Text = chars,
                                Font = font
                            };

                            var splitRun = new TerminalRun()
                            {
                                Text = run.Text.Substring(index - runIndex),
                                Font = run.Font
                            };
                            run.Text = run.Text.Substring(0, index - runIndex);
                            if (run.Text.Length == 0)
                            {
                                run.Text = newRun.Text;
                                run.Font = newRun.Font;

                                if (splitRun.Text.Length > 0)
                                {
                                    runs.Insert(i + 1, splitRun);
                                }
                            }
                            else if (splitRun.Text.Length > 0)
                            {
                                runs.InsertRange(i + 1, new[] { newRun, splitRun });
                            }
                            else
                            {
                                runs.Insert(i + 1, newRun);
                            }
                        }
                        break;
                    }

                    runIndex += run.Text.Length;
                }
                savedRuns = null;
            }

            if (RunsChanged != null)
            {
                RunsChanged(this, EventArgs.Empty);
            }
        }
예제 #5
0
        bool handleCsiSgr(int?[] codes)
        {
            if (codes.Length == 0)
            {
                codes = new int?[] { 0 }
            }
            ;
            else
            {
                // I don't know how these would be combined with other codes, so do them here
                if (codes[0] == 38 && getAtOrDefault(codes, 1, 0) == 5)
                {
                    font.Foreground = TerminalColors.GetXtermColor(getAtOrDefault(codes, 2, 0));
                    return(true);
                }
                else if (codes[0] == 48 && getAtOrDefault(codes, 1, 0) == 5)
                {
                    font.Background = TerminalColors.GetXtermColor(getAtOrDefault(codes, 2, 0));
                    return(true);
                }
            }

            foreach (int?code in codes)
            {
                int sgr = code.GetValueOrDefault(0);

                if (sgr == 0)
                {
                    font = DefaultFont;
                }
                else if (sgr == 1)
                {
                    font.Bold = true;
                }
                else if (sgr == 2)
                {
                    font.Faint = true;
                }
                else if (sgr == 3)
                {
                    font.Italic = true;
                }
                else if (sgr == 4)
                {
                    font.Underline = true;
                }
                else if (sgr == 7)
                {
                    font.Inverse = true;
                }
                else if (sgr == 8)
                {
                    font.Hidden = true;
                }
                else if (sgr == 9)
                {
                    font.Strike = true;
                }
                else if (sgr == 22)
                {
                    font.Bold = false;
                }
                else if (sgr == 23)
                {
                    font.Italic = false;
                }
                else if (sgr == 24)
                {
                    font.Underline = false;
                }
                else if (sgr == 27)
                {
                    font.Inverse = false;
                }
                else if (sgr == 28)
                {
                    font.Hidden = false;
                }
                else if (sgr == 29)
                {
                    font.Strike = false;
                }
                else if (sgr >= 30 && sgr <= 37)
                {
                    font.Foreground = TerminalColors.GetBasicColor(sgr - 30);
                }
                else if (sgr == 39)
                {
                    font.Foreground = DefaultFont.Foreground;
                }
                else if (sgr >= 40 && sgr <= 47)
                {
                    font.Background = TerminalColors.GetBasicColor(sgr - 40);
                }
                else if (sgr == 49)
                {
                    font.Background = DefaultFont.Background;
                }
                else if (sgr >= 90 && sgr <= 97)
                {
                    font.Foreground = TerminalColors.GetBasicColor(sgr - 90);
                }
                else if (sgr >= 100 && sgr <= 107)
                {
                    font.Background = TerminalColors.GetBasicColor(sgr - 100);
                }
                else
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #6
0
        public void SetCharacters(string text, TerminalFont font, bool advanceCursor = true, bool wrapAround = true)
        {
            int textIndex = 0;
            int col       = cursorCol;

            while (textIndex < text.Length)
            {
                if (godDamnSpecialCaseWraparoundBullshit)
                {
                    if (col == Size.Col - 1 && text[0] != '\r')
                    {
                        col = 0;
                        advanceCursorRow();
                    }
                    godDamnSpecialCaseWraparoundBullshit = false;
                }

                int  lineEnd       = text.IndexOf('\r', textIndex, Math.Min(text.Length - textIndex, Size.Col - col + 1));
                bool carriageFound = false;
                if (lineEnd == -1)
                {
                    lineEnd = text.Length;
                }
                else
                {
                    carriageFound = true;
                }
                lineEnd = textIndex + Math.Min(lineEnd - textIndex, Size.Col - col);

                lines[CursorPos.Row].SetCharacters(col, text.Substring(textIndex, lineEnd - textIndex), font);
                if (advanceCursor && !font.Hidden)
                {
                    col += lineEnd - textIndex;
                }
                textIndex = lineEnd;

                //bool allowScroll = wrapAround || cursorRow != Size.Row - 1;
                if (!wrapAround && col == Size.Col)
                {
                    godDamnSpecialCaseWraparoundBullshit = true;
                    col--;
                }
                if (col == Size.Col && (!AutoWrapMode || (false && !wrapAround && cursorRow == Size.Row - 1)))
                {
                    col--;
                }

                bool endOfLine = (col == Size.Col);
                bool nextRow   = endOfLine;
                if (carriageFound)
                {
                    if (text[textIndex] != '\r')
                    {
                        textIndex++;
                    }
                    textIndex++;
                    col     = 0;
                    nextRow = false;
                }

                if (nextRow && advanceCursor)
                {
                    col = 0;
                    advanceCursorRow();
                }
            }

            cursorCol = col;

            if (advanceCursor)
            {
                notifyCursorPosChanged();
            }
        }
예제 #7
0
 public void InsertCharacters(string text, TerminalFont font)
 {
     lines[CursorPos.Row].InsertCharacters(CursorPos.Col, text, font);
 }
예제 #8
0
 public TerminalRun(string text, TerminalFont font)
 {
     Text = text;
     Font = font;
 }