private void DrawLines(Graphics g, RenderParameter param)
        {
            RenderProfile prof = GetRenderProfile();

            //Rendering Core
            if (param.LineFrom <= _document.LastLineNumber)
            {
                IntPtr hdc          = g.GetHdc();
                IntPtr gdipgraphics = IntPtr.Zero;
                try {
                    if (prof.UseClearType)
                    {
                        Win32.GdipCreateFromHDC(hdc, ref gdipgraphics);
                        Win32.GdipSetTextRenderingHint(gdipgraphics, 5); //5はTextRenderingHintClearTypeGridFit
                    }

                    float y = (prof.Pitch.Height + prof.LineSpacing) * param.LineFrom + BORDER;
                    for (int i = 0; i < _transientLines.Count; i++)
                    {
                        GLine line = _transientLines[i];
                        line.Render(hdc, prof, BORDER, (int)y);
                        y += prof.Pitch.Height + prof.LineSpacing;
                    }
                }
                finally {
                    if (gdipgraphics != IntPtr.Zero)
                    {
                        Win32.GdipDeleteGraphics(gdipgraphics);
                    }
                    g.ReleaseHdc(hdc);
                }
            }
        }
예제 #2
0
        private void DrawLines(Graphics g, RenderParameter param, Color baseBackColor)
        {
            RenderProfile prof  = GetRenderProfile();
            Caret         caret = _caret;

            //Rendering Core
            if (param.LineFrom <= _document.LastLineNumber)
            {
                IntPtr hdc = g.GetHdc();
                try {
                    float y = (prof.Pitch.Height + prof.LineSpacing) * param.LineFrom + BORDER;
                    for (int i = 0; i < _transientLines.Count; i++)
                    {
                        GLine line = _transientLines[i];
                        line.Render(hdc, prof, caret, baseBackColor, BORDER, (int)y);
                        if (line.IsPeriodicRedrawRequired())
                        {
                            _requiresPeriodicRedraw = true;
                        }
                        y += prof.Pitch.Height + prof.LineSpacing;
                    }
                }
                finally {
                    g.ReleaseHdc(hdc);
                }
            }
        }
        private void DrawBoldUnderlineCaret(Graphics g, RenderParameter param, int x, int y)
        {
            RenderProfile profile = GetRenderProfile();
            float         xchar   = BORDER + profile.Pitch.Width * x;
            float         ychar   = BORDER + (profile.Pitch.Height + profile.LineSpacing) * y;

            this.DrawCaret_Box(g, xchar, ychar + profile.Pitch.Height - 3, profile.Pitch.Width, 3.0f);
        }
        private void DrawBarCaret(Graphics g, RenderParameter param, int x, int y)
        {
            RenderProfile profile = GetRenderProfile();
            float         xchar   = BORDER + profile.Pitch.Width * x;
            float         ychar   = BORDER + (profile.Pitch.Height + profile.LineSpacing) * y;

            //this.DrawCaret_Box(g,xchar,ychar+2,2.0f,profile.Pitch.Height-1);
            this.DrawCaret_Box(g, xchar, ychar + 1, 2.0f, profile.Pitch.Height - 1);
        }
        private void DrawUnderLineCaret(Graphics g, RenderParameter param, int x, int y)
        {
            RenderProfile profile = GetRenderProfile();
            PointF        pt1     = new PointF(profile.Pitch.Width * x + BORDER + 2, (profile.Pitch.Height + profile.LineSpacing) * y + BORDER + profile.Pitch.Height);
            PointF        pt2     = new PointF(pt1.X + profile.Pitch.Width - 2, pt1.Y);
            Pen           p       = _caret.ToPen(profile);

            g.DrawLine(p, pt1, pt2);
            pt1.Y += 1;
            pt2.Y += 1;
            g.DrawLine(p, pt1, pt2);
        }
        private void BuildTransientDocument(PaintEventArgs e, RenderParameter param)
        {
            Rectangle     clip    = e.ClipRectangle;
            RenderProfile profile = GetRenderProfile();

            _transientLines.Clear();

            //Win32.SystemMetrics sm = GEnv.SystemMetrics;
            //param.TargetRect = new Rectangle(sm.ControlBorderWidth+1, sm.ControlBorderHeight,
            //	this.Width - _VScrollBar.Width - sm.ControlBorderWidth + 8, //この8がない値が正当だが、.NETの文字サイズ丸め問題のため行の最終文字が表示されないことがある。これを回避するためにちょっと増やす
            //	this.Height - sm.ControlBorderHeight);
            param.TargetRect = this.ClientRectangle;

            int offset1 = (int)Math.Floor((clip.Top - BORDER) / (profile.Pitch.Height + profile.LineSpacing));

            if (offset1 < 0)
            {
                offset1 = 0;
            }
            param.LineFrom = offset1;
            int offset2 = (int)Math.Floor((clip.Bottom - BORDER) / (profile.Pitch.Height + profile.LineSpacing));

            if (offset2 < 0)
            {
                offset2 = 0;
            }

            param.LineCount = offset2 - offset1 + 1;
            //Debug.WriteLine(String.Format("{0} {1} ", param.LineFrom, param.LineCount));

            int   topline_id = GetTopLine().ID;
            GLine l          = _document.FindLineOrNull(topline_id + param.LineFrom);

            if (l != null)
            {
                for (int i = param.LineFrom; i < param.LineFrom + param.LineCount; i++)
                {
                    _transientLines.Add(l.Clone()); //TODO クローンはきついよなあ だが描画の方が時間かかるので、その間ロックをしないためには仕方ない点もある
                    l = l.NextLine;
                    if (l == null)
                    {
                        break;
                    }
                }
            }

            //以下、_transientLinesにはparam.LineFromから示される値が入っていることに注意

            //選択領域の描画
            if (!_textSelection.IsEmpty)
            {
                TextSelection.TextPoint from = _textSelection.HeadPoint;
                TextSelection.TextPoint to   = _textSelection.TailPoint;
                l = _document.FindLineOrNull(from.Line);
                GLine t = _document.FindLineOrNull(to.Line);
                if (l != null && t != null)   //本当はlがnullではいけないはずだが、それを示唆するバグレポートがあったので念のため
                {
                    t = t.NextLine;
                    int pos = from.Column; //たとえば左端を越えてドラッグしたときの選択範囲は前行末になるので pos==TerminalWidthとなるケースがある。
                    do
                    {
                        int index = l.ID - (topline_id + param.LineFrom);
                        if (pos >= 0 && pos < l.DisplayLength && index >= 0 && index < _transientLines.Count)
                        {
                            GLine r = null;
                            if (l.ID == to.Line)
                            {
                                if (pos != to.Column)
                                {
                                    r = _transientLines[index].CreateInvertedClone(pos, to.Column);
                                }
                            }
                            else
                            {
                                r = _transientLines[index].CreateInvertedClone(pos, l.DisplayLength);
                            }

                            if (r != null)
                            {
                                _transientLines[index] = r;
                            }
                        }
                        pos = 0; //2行目からの選択は行頭から
                        l   = l.NextLine;
                    } while (l != t);
                }
            }

            AdjustCaret(_caret);
            _caret.Enabled = _caret.Enabled && (param.LineFrom <= _caret.Y && _caret.Y < param.LineFrom + param.LineCount);

            //Caret画面外にあるなら処理はしなくてよい。2番目の条件は、Attach-ResizeTerminalの流れの中でこのOnPaintを実行した場合にTerminalHeight>lines.Countになるケースがあるのを防止するため
            if (_caret.Enabled)
            {
                //ヒクヒク問題のため、キャレットを表示しないときでもこの操作は省けない
                if (_caret.Style == CaretType.Box)
                {
                    int y = _caret.Y - param.LineFrom;
                    if (y >= 0 && y < _transientLines.Count)
                    {
                        _transientLines[y].InvertCharacter(_caret.X, _caret.IsActiveTick, _caret.Color);
                    }
                }
            }
        }
        //描画の本体
        protected override sealed void OnPaint(PaintEventArgs e)
        {
#if ONPAINT_TIME_MEASUREMENT
            Stopwatch onPaintSw = (_onPaintTimeObserver != null) ? Stopwatch.StartNew() : null;
#endif

            base.OnPaint(e);

            try {
                if (_document != null)
                {
                    ShowVScrollBar();
                }
                else
                {
                    HideVScrollBar();
                }

                if (_enabled && !this.DesignMode)
                {
                    Rectangle     clip       = e.ClipRectangle;
                    Graphics      g          = e.Graphics;
                    RenderProfile profile    = GetRenderProfile();
                    int           paneheight = GetHeightInLines();

                    // determine background color of the view
                    Color backColor;
                    if (_document.IsApplicationMode)
                    {
                        backColor = _document.ApplicationModeBackColor;
                        if (backColor.IsEmpty)
                        {
                            backColor = profile.BackColor;
                        }
                    }
                    else
                    {
                        backColor = profile.BackColor;
                    }

                    if (this.BackColor != backColor)
                    {
                        this.BackColor = backColor; // set background color of the view
                    }
                    // draw background image if it is required.
                    if (!_document.IsApplicationMode)
                    {
                        Image img = profile.GetImage();
                        if (img != null)
                        {
                            DrawBackgroundImage(g, img, profile.ImageStyle, clip);
                        }
                    }

                    //描画用にテンポラリのGLineを作り、描画中にdocumentをロックしないようにする
                    //!!ここは実行頻度が高いのでnewを毎回するのは避けたいところだ
                    RenderParameter param = new RenderParameter();
                    _caret.Enabled = _caret.Enabled && this.Focused; //TODO さらにIME起動中はキャレットを表示しないように. TerminalControlだったらAdjustCaretでIMEをみてるので問題はない
                    lock (_document) {
                        CommitTransientScrollBar();
                        BuildTransientDocument(e, param);
                    }

                    DrawLines(g, param, backColor);

                    if (_caret.Enabled && (!_caret.Blink || _caret.IsActiveTick))   //点滅しなければEnabledによってのみ決まる
                    {
                        if (_caret.Style == CaretType.Line)
                        {
                            DrawBarCaret(g, param, _caret.X, _caret.Y);
                        }
                        else if (_caret.Style == CaretType.Underline)
                        {
                            DrawUnderLineCaret(g, param, _caret.X, _caret.Y);
                        }
                    }
                }
                //マークの描画
                _splitMark.OnPaint(e);
            }
            catch (Exception ex) {
                if (!_errorRaisedInDrawing)   //この中で一度例外が発生すると繰り返し起こってしまうことがままある。なので初回のみ表示してとりあえず切り抜ける
                {
                    _errorRaisedInDrawing = true;
                    RuntimeUtil.ReportException(ex);
                }
            }

#if ONPAINT_TIME_MEASUREMENT
            if (onPaintSw != null)
            {
                onPaintSw.Stop();
                if (_onPaintTimeObserver != null)
                {
                    _onPaintTimeObserver(onPaintSw);
                }
            }
#endif
        }
 private void DrawUnderLineCaret(Graphics g, RenderParameter param, int x, int y) {
     RenderProfile profile = GetRenderProfile();
     PointF pt1 = new PointF(profile.Pitch.Width * x + BORDER + 2, (profile.Pitch.Height + profile.LineSpacing) * y + BORDER + profile.Pitch.Height);
     PointF pt2 = new PointF(pt1.X + profile.Pitch.Width - 2, pt1.Y);
     Pen p = _caret.ToPen(profile);
     g.DrawLine(p, pt1, pt2);
     pt1.Y += 1;
     pt2.Y += 1;
     g.DrawLine(p, pt1, pt2);
 }
 private void DrawLines(Graphics g, RenderParameter param, Color baseBackColor) {
     RenderProfile prof = GetRenderProfile();
     //Rendering Core
     if (param.LineFrom <= _document.LastLineNumber) {
         IntPtr hdc = g.GetHdc();
         try {
             float y = (prof.Pitch.Height + prof.LineSpacing) * param.LineFrom + BORDER;
             for (int i = 0; i < _transientLines.Count; i++) {
                 GLine line = _transientLines[i];
                 line.Render(hdc, prof, baseBackColor, BORDER, (int)y);
                 y += prof.Pitch.Height + prof.LineSpacing;
             }
         }
         finally {
             g.ReleaseHdc(hdc);
         }
     }
 }
예제 #10
0
        private void BuildTransientDocument(PaintEventArgs e, RenderParameter param) {
            Rectangle clip = e.ClipRectangle;
            RenderProfile profile = GetRenderProfile();
            _transientLines.Clear();

            //Win32.SystemMetrics sm = GEnv.SystemMetrics;
            //param.TargetRect = new Rectangle(sm.ControlBorderWidth+1, sm.ControlBorderHeight,
            //	this.Width - _VScrollBar.Width - sm.ControlBorderWidth + 8, //この8がない値が正当だが、.NETの文字サイズ丸め問題のため行の最終文字が表示されないことがある。これを回避するためにちょっと増やす
            //	this.Height - sm.ControlBorderHeight);
            param.TargetRect = this.ClientRectangle;

            int offset1 = (int)Math.Floor((clip.Top - BORDER) / (profile.Pitch.Height + profile.LineSpacing));
            if (offset1 < 0)
                offset1 = 0;
            param.LineFrom = offset1;
            int offset2 = (int)Math.Floor((clip.Bottom - BORDER) / (profile.Pitch.Height + profile.LineSpacing));
            if (offset2 < 0)
                offset2 = 0;

            param.LineCount = offset2 - offset1 + 1;
            //Debug.WriteLine(String.Format("{0} {1} ", param.LineFrom, param.LineCount));

            int topline_id = GetTopLine().ID;
            GLine l = _document.FindLineOrNull(topline_id + param.LineFrom);
            if (l != null) {
                for (int i = param.LineFrom; i < param.LineFrom + param.LineCount; i++) {
                    _transientLines.Add(l.Clone()); //TODO クローンはきついよなあ だが描画の方が時間かかるので、その間ロックをしないためには仕方ない点もある
                    l = l.NextLine;
                    if (l == null)
                        break;
                }
            }

            //以下、_transientLinesにはparam.LineFromから示される値が入っていることに注意

            //選択領域の描画
            if (!_textSelection.IsEmpty) {
                TextSelection.TextPoint from = _textSelection.HeadPoint;
                TextSelection.TextPoint to = _textSelection.TailPoint;
                l = _document.FindLineOrNull(from.Line);
                GLine t = _document.FindLineOrNull(to.Line);
                if (l != null && t != null) { //本当はlがnullではいけないはずだが、それを示唆するバグレポートがあったので念のため
                    t = t.NextLine;
                    int pos = from.Column; //たとえば左端を越えてドラッグしたときの選択範囲は前行末になるので pos==TerminalWidthとなるケースがある。
                    do {
                        int index = l.ID - (topline_id + param.LineFrom);
                        if (pos >= 0 && pos < l.DisplayLength && index >= 0 && index < _transientLines.Count) {
                            GLine r = null;
                            if (l.ID == to.Line) {
                                if (pos != to.Column)
                                    r = _transientLines[index].CreateInvertedClone(pos, to.Column);
                            }
                            else
                                r = _transientLines[index].CreateInvertedClone(pos, l.DisplayLength);

                            if (r != null) {
                                _transientLines[index] = r;
                            }
                        }
                        pos = 0; //2行目からの選択は行頭から
                        l = l.NextLine;
                    } while (l != t);
                }
            }

            AdjustCaret(_caret);
            _caret.Enabled = _caret.Enabled && (param.LineFrom <= _caret.Y && _caret.Y < param.LineFrom + param.LineCount);

            //Caret画面外にあるなら処理はしなくてよい。2番目の条件は、Attach-ResizeTerminalの流れの中でこのOnPaintを実行した場合にTerminalHeight>lines.Countになるケースがあるのを防止するため
            if (_caret.Enabled) {
                //ヒクヒク問題のため、キャレットを表示しないときでもこの操作は省けない
                if (_caret.Style == CaretType.Box) {
                    int y = _caret.Y - param.LineFrom;
                    if (y >= 0 && y < _transientLines.Count)
                        _transientLines[y].InvertCharacter(_caret.X, _caret.IsActiveTick, _caret.Color);
                }
            }
        }
예제 #11
0
        //描画の本体
        protected override sealed void OnPaint(PaintEventArgs e) {
#if ONPAINT_TIME_MEASUREMENT
            Stopwatch onPaintSw = (_onPaintTimeObserver != null) ? Stopwatch.StartNew() : null;
#endif

            base.OnPaint(e);

            try {
                if (_document != null)
                    ShowVScrollBar();
                else
                    HideVScrollBar();

                if (_enabled && !this.DesignMode) {
                    Rectangle clip = e.ClipRectangle;
                    Graphics g = e.Graphics;
                    RenderProfile profile = GetRenderProfile();
                    int paneheight = GetHeightInLines();

                    // determine background color of the view
                    Color backColor;
                    if (_document.IsApplicationMode) {
                        backColor = _document.ApplicationModeBackColor;
                        if (backColor.IsEmpty)
                            backColor = profile.BackColor;
                    }
                    else {
                        backColor = profile.BackColor;
                    }

                    if (this.BackColor != backColor)
                        this.BackColor = backColor; // set background color of the view

                    // draw background image if it is required.
                    if (!_document.IsApplicationMode) {
                        Image img = profile.GetImage();
                        if (img != null) {
                            DrawBackgroundImage(g, img, profile.ImageStyle, clip);
                        }
                    }

                    //描画用にテンポラリのGLineを作り、描画中にdocumentをロックしないようにする
                    //!!ここは実行頻度が高いのでnewを毎回するのは避けたいところだ
                    RenderParameter param = new RenderParameter();
                    _caret.Enabled = _caret.Enabled && this.Focused; //TODO さらにIME起動中はキャレットを表示しないように. TerminalControlだったらAdjustCaretでIMEをみてるので問題はない
                    lock (_document) {
                        CommitTransientScrollBar();
                        BuildTransientDocument(e, param);
                    }

                    DrawLines(g, param, backColor);

                    if (_caret.Enabled && (!_caret.Blink || _caret.IsActiveTick)) { //点滅しなければEnabledによってのみ決まる
                        if (_caret.Style == CaretType.Line)
                            DrawBarCaret(g, param, _caret.X, _caret.Y);
                        else if (_caret.Style == CaretType.Underline)
                            DrawUnderLineCaret(g, param, _caret.X, _caret.Y);
                    }
                }
                //マークの描画
                _splitMark.OnPaint(e);
            }
            catch (Exception ex) {
                if (!_errorRaisedInDrawing) { //この中で一度例外が発生すると繰り返し起こってしまうことがままある。なので初回のみ表示してとりあえず切り抜ける
                    _errorRaisedInDrawing = true;
                    RuntimeUtil.ReportException(ex);
                }
            }

#if ONPAINT_TIME_MEASUREMENT
            if (onPaintSw != null) {
                onPaintSw.Stop();
                if (_onPaintTimeObserver != null) {
                    _onPaintTimeObserver(onPaintSw);
                }
            }
#endif
        }
        //描画の本体
        protected override sealed void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            try {
                if (_document != null)
                {
                    ShowVScrollBar();
                }
                else
                {
                    HideVScrollBar();
                }

                if (_enabled && !this.DesignMode)
                {
                    Rectangle     clip       = e.ClipRectangle;
                    Graphics      g          = e.Graphics;
                    RenderProfile profile    = GetRenderProfile();
                    int           paneheight = GetHeightInLines();

                    if (_document.BackColor != profile.BackColor)
                    {
                        if (_document.IsApplicationMode)
                        {
                            if (this.BackColor != _document.BackColor)
                            {
                                this.BackColor = _document.BackColor;
                                _drawbgImage   = false;
                            }
                        }
                        else
                        {
                            this.BackColor      = profile.BackColor;
                            _document.BackColor = profile.BackColor;
                            _drawbgImage        = true;
                        }
                    }
                    if (_drawbgImage)
                    {
                        Image img = profile.GetImage();
                        if (img != null)
                        {
                            DrawBackgroundImage(g, img, profile.ImageStyle, clip);
                        }
                    }

                    //描画用にテンポラリのGLineを作り、描画中にdocumentをロックしないようにする
                    //!!ここは実行頻度が高いのでnewを毎回するのは避けたいところだ
                    RenderParameter param = new RenderParameter();
                    _caret.Enabled = _caret.Enabled && this.Focused; //TODO さらにIME起動中はキャレットを表示しないように. TerminalControlだったらAdjustCaretでIMEをみてるので問題はない
                    lock (_document) {
                        CommitTransientScrollBar();
                        BuildTransientDocument(e, param);
                    }

                    DrawLines(g, param);

                    if (_caret.Enabled && (!_caret.Blink || _caret.IsActiveTick)) //点滅しなければEnabledによってのみ決まる
                    {
                        if (_caret.Style == CaretType.Line)
                        {
                            DrawBarCaret(g, param, _caret.X, _caret.Y);
                        }
                        else if (_caret.Style == CaretType.Underline)
                        {
                            DrawUnderLineCaret(g, param, _caret.X, _caret.Y);
                        }
                        else if (_caret.Style == CaretType.BoldUnderline)
                        {
                            DrawBoldUnderlineCaret(g, param, _caret.X, _caret.Y);
                        }
                    }
                }
                //マークの描画
                _splitMark.OnPaint(e);
            }
            catch (Exception ex) {
                if (!_errorRaisedInDrawing) //この中で一度例外が発生すると繰り返し起こってしまうことがままある。なので初回のみ表示してとりあえず切り抜ける
                {
                    _errorRaisedInDrawing = true;
                    RuntimeUtil.ReportException(ex);
                }
            }
        }