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);
                    }
                }
            }
        }