Beispiel #1
0
 /// <summary>
 /// ����̑ΏۂɂȂ�h�L�������g�ƕ����̃G���R�[�f�B���O��w�肵�č\�z
 /// </summary>
 public AbstractTerminal(ConnectionTag tag, ICharDecoder decoder)
 {
     _tag = tag;
     _decoder = decoder;
     _terminalMode = TerminalMode.Normal;
     _currentdecoration = TextDecoration.Default;
     _manipulator = new GLineManipulator(80);
     _bufferForMacro = new StringBuilder();
     _signalForMacro = new AutoResetEvent(false);
 }
Beispiel #2
0
 /// <summary>
 /// 文字列、デコレーション、オフセットを指定するコンストラクタ。TypeはNormalになる。
 /// </summary>
 internal GWord(TextDecoration d, int o, CharGroup chargroup)
 {
     Debug.Assert(d != null);
     _offset            = o;
     _decoration        = d;
     _next              = null;
     _charGroup         = chargroup;
     nextOffsetCache    = -1;
     displayLengthCache = -1;
 }
        public object Clone()
        {
            TextDecoration t = new TextDecoration();

            t._bgColorType   = _bgColorType;
            t._bgColor       = _bgColor;
            t._textColorType = _textColorType;
            t._textColor     = _textColor;
            t._bold          = _bold;
            t._underline     = _underline;
            return(t);
        }
Beispiel #4
0
 public void FillSpace(int from, int to, TextDecoration dec)
 {
     if (to > _text.Length)
     {
         to = _text.Length;
     }
     for (int i = from; i < to; i++)
     {
         _text[i]        = ' ';
         _decorations[i] = dec;
     }
 }
        internal void ClearRange(int from, int to, TextDecoration dec)
        {
            GLine l = FindLineOrEdge(from);

            if (l == null)
            {
                return;
            }

            while (l.ID < to)
            {
                l.Clear(dec);
                InvalidateLine(l.ID);
                l = l.NextLine;
            }
            AssertValid();
        }
        internal void ClearAfter(int from, TextDecoration dec)
        {
            if (from > _lastLine.ID)
            {
                return;
            }
            GLine l = FindLineOrEdge(from);

            if (l == null)
            {
                return;
            }

            while (l != null)
            {
                l.Clear(dec);
                l = l.NextLine;
            }

            AssertValid();
            _invalidatedAll = true;
        }
Beispiel #7
0
 public object Clone()
 {
     TextDecoration t = new TextDecoration();
     t._bgColorType = _bgColorType;
     t._bgColor = _bgColor;
     t._textColorType = _textColorType;
     t._textColor = _textColor;
     t._bold = _bold;
     t._underline = _underline;
     return t;
 }
Beispiel #8
0
        internal Color CalcTextColor(TextDecoration dec)
        {
            if(_brush==null) CreateBrushes();
            if(dec==null) return _forecolor;

            switch(dec.TextColorType) {
                case ColorType.Custom:
                    return dec.TextColor;
                case ColorType.DefaultBack:
                    return _bgcolor;
                case ColorType.DefaultText:
                    return _forecolor;
                default:
                    throw new Exception("Unexpected decoration object");
            }
        }
Beispiel #9
0
        internal Brush CalcTextBrush(TextDecoration dec)
        {
            if(_brush==null) CreateBrushes();
            if(dec==null) return _brush;

            switch(dec.TextColorType) {
                case ColorType.Custom:
                    return new SolidBrush(dec.TextColor);
                case ColorType.DefaultBack:
                    return _bgbrush;
                case ColorType.DefaultText:
                    return _brush;
                default:
                    throw new Exception("Unexpected decoration object");
            }
        }
Beispiel #10
0
 internal IntPtr CalcHFONT_NoUnderline(TextDecoration dec, CharGroup cg)
 {
     return CalcFontInternal(dec, cg, true).HFONT;
 }
Beispiel #11
0
        private FontHandle CalcFontInternal(TextDecoration dec, CharGroup cg, bool ignore_underline)
        {
            if(_font==null) CreateFonts();

            if(cg==CharGroup.TwoBytes) {
                if(dec==null) return _japaneseFont;

                if(dec.Bold) {
                    if(!ignore_underline && dec.Underline)
                        return _japaneseBoldunderlinefont;
                    else
                        return _japaneseBoldfont;
                }
                else if(!ignore_underline && dec.Underline)
                    return _japaneseUnderlinefont;
                else
                    return _japaneseFont;
            }
            else {
                if(dec==null) return _font;

                if(dec.Bold) {
                    if(!ignore_underline && dec.Underline)
                        return _boldunderlinefont;
                    else
                        return _boldfont;
                }
                else if(!ignore_underline && dec.Underline)
                    return _underlinefont;
                else
                    return _font;
            }
        }
Beispiel #12
0
        internal void ClearRange(int from, int to, TextDecoration dec)
        {
            GLine l = FindLineOrEdge(from);
            if(l==null) return;

            while(l.ID < to) {
                l.Clear(dec);
                InvalidateLine(l.ID);
                l = l.NextLine;
            }
            AssertValid();
        }
Beispiel #13
0
 /// <summary>
 /// ������A�f�R���[�V�����A�I�t�Z�b�g��w�肷��R���X�g���N�^�BType��Normal�ɂȂ�B
 /// </summary>
 internal GWord(TextDecoration d, int o, CharGroup chargroup)
 {
     Debug.Assert(d!=null);
     _offset = o;
     _decoration = d;
     _next = null;
     _charGroup = chargroup;
     nextOffsetCache = -1;
     displayLengthCache = -1;
 }
Beispiel #14
0
        internal GLine InverseRange(int from, int to)
        {
            ExpandBuffer(Math.Max(from+1,to)); //���������T�C�Y�����Ƃ��Ȃǂɂ��̏�����������Ȃ����Ƃ�����
            Debug.Assert(from>=0 && from<_text.Length);
            if(from<_text.Length && _text[from]==WIDECHAR_PAD) from--;
            if(to>0 && to-1<_text.Length && _text[to-1]==WIDECHAR_PAD) to--;

            GLine ret = new GLine(_text, null);
            ret.ID = _id;
            ret.EOLType = _eolType;
            //�����̔z���Z�b�g
            TextDecoration[] dec = new TextDecoration[_text.Length];
            GWord w = _firstWord;
            while(w!=null) {
                Debug.Assert(w.Decoration!=null);
                dec[w.Offset] = w.Decoration;
                w = w.Next;
            }

            //���]�J�n�_
            TextDecoration original = null;
            TextDecoration inverse = null;
            for(int i=from; i>=0; i--) {
                if(dec[i]!=null) {
                    original = dec[i];
                    break;
                }
            }
            Debug.Assert(original!=null);
            inverse = (TextDecoration)original.Clone();
            inverse.Inverse();
            dec[from] = inverse;

            //�͈͂ɓn���Ĕ��]���
            for(int i=from+1; i<to; i++) {
                if(i<dec.Length && dec[i]!=null) {
                    original = dec[i];
                    inverse = (TextDecoration)original.Clone();
                    inverse.Inverse();
                    dec[i] = inverse;
                }
            }

            if(to<dec.Length && dec[to]==null) dec[to] = original;

            //����ɏ]����GWord����
            w = null;
            for(int i=dec.Length-1; i>=0; i--) {
                char ch = _text[i];
                if(dec[i]!=null && ch!='\0') {
                    int j = i;
                    if(ch==WIDECHAR_PAD) j++;
                    GWord ww = new GWord(dec[i], j, CalcCharGroup(ch));
                    ww.Next = w;
                    w = ww;
                }
            }
            ret.Append(w);

            return ret;
        }
Beispiel #15
0
 internal void Clear(TextDecoration dec)
 {
     for(int i=0; i<_text.Length; i++)
         _text[i] = ' ';
     _firstWord = new GWord(dec, 0, CharGroup.SingleByte);
 }
Beispiel #16
0
 public void SetDecoration(TextDecoration dec)
 {
     if(_caretColumn<_decorations.Length)
         _decorations[_caretColumn] = dec;
 }
Beispiel #17
0
        public void PutChar(char ch, TextDecoration dec)
        {
            Debug.Assert(dec!=null);
            Debug.Assert(_caretColumn>=0);
            Debug.Assert(_caretColumn<_text.Length);

            //�ȉ��킩��ɂ������A�v�͏ꍇ�����B����̎d�l���������������
            bool onZenkakuRight = (_text[_caretColumn] == GLine.WIDECHAR_PAD);
            bool onZenkaku = onZenkakuRight || (_text.Length>_caretColumn+1 && _text[_caretColumn+1] == GLine.WIDECHAR_PAD);

            if(onZenkaku) {
                //�S�p�̏�ɏ���
                if(!onZenkakuRight) {
                    _text[_caretColumn] = ch;
                    _decorations[_caretColumn] = dec;
                    if(GLine.CalcDisplayLength(ch)==1) {
                        //�S�p�̏�ɔ��p��������ꍇ�A�ׂɃX�y�[�X�����Ȃ��ƕ\���������
                        if(_caretColumn+1<_text.Length) _text[_caretColumn+1] = ' ';
                        _caretColumn++;
                    }
                    else {
                        _decorations[_caretColumn+1] = dec;
                        _caretColumn+=2;
                    }
                }
                else {
                    _text[_caretColumn-1] = ' ';
                    _text[_caretColumn]   = ch;
                    _decorations[_caretColumn] = dec;
                    if(GLine.CalcDisplayLength(ch)==2) {
                        if(GLine.CalcDisplayLength(_text[_caretColumn+1])==2)
                            if(_caretColumn+2<_text.Length) _text[_caretColumn+2] = ' ';
                        _text[_caretColumn+1] = GLine.WIDECHAR_PAD;
                        _decorations[_caretColumn+1] = _decorations[_caretColumn];
                        _caretColumn += 2;
                    }
                    else
                        _caretColumn++;
                }
            }
            else { //���p�̏�ɏ���
                _text[_caretColumn] = ch;
                _decorations[_caretColumn] = dec;
                if(GLine.CalcDisplayLength(ch)==2) {
                    if(GLine.CalcDisplayLength(_text[_caretColumn+1])==2) //���p�A�S�p�ƂȂ��Ă���Ƃ���ɑS�p���������
                        if(_caretColumn+2<_text.Length) _text[_caretColumn+2] = ' ';
                    _text[_caretColumn+1] = GLine.WIDECHAR_PAD;
                    _decorations[_caretColumn+1] = _decorations[_caretColumn];
                    _caretColumn += 2;
                }
                else
                    _caretColumn++; //���ꂪ�ł�common�ȃP�[�X����
            }
        }
Beispiel #18
0
        public void PutChar(char ch, TextDecoration dec)
        {
            Debug.Assert(dec != null);
            Debug.Assert(_caretColumn >= 0);
            Debug.Assert(_caretColumn < _text.Length);

            //以下わかりにくいが、要は場合分け。これの仕様を書いた資料あり
            bool onZenkakuRight = (_text[_caretColumn] == GLine.WIDECHAR_PAD);
            bool onZenkaku      = onZenkakuRight || (_text.Length > _caretColumn + 1 && _text[_caretColumn + 1] == GLine.WIDECHAR_PAD);

            if (onZenkaku)
            {
                //全角の上に書く
                if (!onZenkakuRight)
                {
                    _text[_caretColumn]        = ch;
                    _decorations[_caretColumn] = dec;
                    if (GLine.CalcDisplayLength(ch) == 1)
                    {
                        //全角の上に半角を書いた場合、隣にスペースを入れないと表示が乱れる
                        if (_caretColumn + 1 < _text.Length)
                        {
                            _text[_caretColumn + 1] = ' ';
                        }
                        _caretColumn++;
                    }
                    else
                    {
                        _decorations[_caretColumn + 1] = dec;
                        _caretColumn += 2;
                    }
                }
                else
                {
                    _text[_caretColumn - 1]    = ' ';
                    _text[_caretColumn]        = ch;
                    _decorations[_caretColumn] = dec;
                    if (GLine.CalcDisplayLength(ch) == 2)
                    {
                        if (GLine.CalcDisplayLength(_text[_caretColumn + 1]) == 2)
                        {
                            if (_caretColumn + 2 < _text.Length)
                            {
                                _text[_caretColumn + 2] = ' ';
                            }
                        }
                        _text[_caretColumn + 1]        = GLine.WIDECHAR_PAD;
                        _decorations[_caretColumn + 1] = _decorations[_caretColumn];
                        _caretColumn += 2;
                    }
                    else
                    {
                        _caretColumn++;
                    }
                }
            }
            else               //半角の上に書く
            {
                _text[_caretColumn]        = ch;
                _decorations[_caretColumn] = dec;
                if (GLine.CalcDisplayLength(ch) == 2)
                {
                    if (GLine.CalcDisplayLength(_text[_caretColumn + 1]) == 2)                //半角、全角となっているところに全角を書いたら
                    {
                        if (_caretColumn + 2 < _text.Length)
                        {
                            _text[_caretColumn + 2] = ' ';
                        }
                    }
                    _text[_caretColumn + 1]        = GLine.WIDECHAR_PAD;
                    _decorations[_caretColumn + 1] = _decorations[_caretColumn];
                    _caretColumn += 2;
                }
                else
                {
                    _caretColumn++;                     //これが最もcommonなケースだが
                }
            }
        }
Beispiel #19
0
 public void FillSpace(int from, int to, TextDecoration dec)
 {
     if(to>_text.Length) to = _text.Length;
     for(int i=from; i<to; i++) {
         _text[i] = ' ';
         _decorations[i] = dec;
     }
 }
Beispiel #20
0
        //indexの位置の表示を反転した新しいGLineを返す
        //inverseがfalseだと、GWordの分割はするがDecorationの反転はしない。ヒクヒク問題の対処として実装。
        internal GLine InverseCaret(int index, bool inverse, bool underline)
        {
            ExpandBuffer(index + 1);
            if (_text[index] == WIDECHAR_PAD)
            {
                index--;
            }
            GLine ret = new GLine(_text, null);

            ret.ID      = _id;
            ret.EOLType = _eolType;

            GWord w          = _firstWord;
            int   nextoffset = 0;

            while (w != null)
            {
                nextoffset = WordNextOffset(w);
                if (w.Offset <= index && index < nextoffset)
                {
                    //!!tailから順に連結した方が効率はよい
                    if (w.Offset < index)
                    {
                        GWord head = new GWord(w.Decoration, w.Offset, w.CharGroup);
                        ret.Append(head);
                    }

                    TextDecoration dec = (TextDecoration)w.Decoration.Clone();
                    if (inverse)
                    {
                        //色つきキャレットのサポート
                        dec.ToCaretStyle();
                    }
                    if (underline)
                    {
                        dec.Underline = true;
                    }
                    GWord mid = new GWord(dec, index, w.CharGroup);
                    ret.Append(mid);

                    if (index + CalcDisplayLength(_text[index]) < nextoffset)
                    {
                        GWord tail = new GWord(w.Decoration, index + CalcDisplayLength(_text[index]), w.CharGroup);
                        ret.Append(tail);
                    }
                }
                else
                {
                    ret.Append(w.StandAloneClone());
                }

                w = w.Next;
            }

            //!!この、キャレット位置にスペースを入れるのはInverseとは違う処理であるから分離すること
            if (nextoffset <= index)
            {
                while (nextoffset <= index)
                {
                    Debug.Assert(nextoffset < ret.Text.Length);
                    ret.Text[nextoffset++] = ' ';
                }
                TextDecoration dec = TextDecoration.ClonedDefault();
                if (inverse)
                {
                    dec.ToCaretStyle();
                }
                if (underline)
                {
                    dec.Underline = true;
                }
                ret.Append(new GWord(dec, index, CharGroup.SingleByte));
            }

            return(ret);
        }
Beispiel #21
0
        internal void Render(IntPtr hdc, RenderParameter param, RenderProfile prof, int y)
        {
            if (_text[0] == '\0')
            {
                return;                            //何も描かなくてよい
            }
            float fx = (float)param.TargetRect.Left;

            RectangleF rect = new RectangleF();

            rect.Y      = param.TargetRect.Top + y;
            rect.Height = prof.Pitch.Height;

            GWord word = _firstWord;

            while (word != null)
            {
                rect.X     = fx /*- prof.CharGap*/;             //Nativeな描画では不要?
                rect.Width = param.TargetRect.Right - rect.X;
                int ix = (int)rect.X;
                int iy = (int)rect.Y;

                TextDecoration dec = word.Decoration;

                //Brush brush = prof.CalcTextBrush(dec);
                uint   forecolorref = DrawUtil.ToCOLORREF(prof.CalcTextColor(dec));
                Color  bkcolor      = prof.CalcBackColor(dec);
                uint   bkcolorref   = DrawUtil.ToCOLORREF(bkcolor);
                IntPtr hfont        = prof.CalcHFONT_NoUnderline(dec, word.CharGroup);
                Win32.SelectObject(hdc, hfont);
                Win32.SetTextColor(hdc, forecolorref);
                Win32.SetBkColor(hdc, bkcolorref);
                Win32.SetBkMode(hdc, bkcolor == prof.BackColor? 1 : 2);               //基本背景色と一緒ならTRANSPARENT, 異なればOPAQUE
                IntPtr bkbrush = bkcolor == prof.BackColor? IntPtr.Zero : Win32.CreateSolidBrush(bkcolorref);

                int display_length = WordDisplayLength(word);
                if (word.Decoration == null)                //装飾なし
                //g.DrawString(WordText(word), font, brush, rect);
                {
                    DrawWord(hdc, ix, iy, word);
                }
                else
                {
                    //if(dec.Bold || (!prof.UsingIdenticalFont && word.CharGroup==CharGroup.TwoBytes))
                    if (dec.Bold || word.CharGroup == CharGroup.TwoBytes)                  //同じフォント指定でも日本語が半角の2倍でない場合あり。パフォーマンス問題はクリアされつつあるので確実に1文字ずつ描画
                    {
                        DrawStringByOneChar2(hdc, word, display_length, bkbrush, rect.X, iy, prof);
                    }
                    else
                    {
                        DrawWord(hdc, ix, iy, word);                         //いまやアホな描画エンジンの問題からは解放された!
                    }
                }
                //Debug.WriteLine("PW="+p.Pitch.Width+",TL="+(pb.Text.Length*p.Pitch.Width)+", real="+g.MeasureString(pb.Text, p.Font).Width);
                if (dec.Underline)
                {
                    DrawUnderline(hdc, forecolorref, ix, iy + (int)prof.Pitch.Height - 1, (int)(prof.Pitch.Width * display_length));
                }

                fx  += prof.Pitch.Width * display_length;
                word = word.Next;
                if (bkbrush != IntPtr.Zero)
                {
                    Win32.DeleteObject(bkbrush);
                }
            }
        }
Beispiel #22
0
 internal Font CalcFont(TextDecoration dec, CharGroup cg)
 {
     return CalcFontInternal(dec, cg, false).Font;
 }
Beispiel #23
0
        internal GLine InverseRange(int from, int to)
        {
            ExpandBuffer(Math.Max(from + 1, to));          //激しくリサイズしたときなどにこの条件が満たせないことがある
            Debug.Assert(from >= 0 && from < _text.Length);
            if (from < _text.Length && _text[from] == WIDECHAR_PAD)
            {
                from--;
            }
            if (to > 0 && to - 1 < _text.Length && _text[to - 1] == WIDECHAR_PAD)
            {
                to--;
            }

            GLine ret = new GLine(_text, null);

            ret.ID      = _id;
            ret.EOLType = _eolType;
            //装飾の配列をセット
            TextDecoration[] dec = new TextDecoration[_text.Length];
            GWord            w   = _firstWord;

            while (w != null)
            {
                Debug.Assert(w.Decoration != null);
                dec[w.Offset] = w.Decoration;
                w             = w.Next;
            }

            //反転開始点
            TextDecoration original = null;
            TextDecoration inverse  = null;

            for (int i = from; i >= 0; i--)
            {
                if (dec[i] != null)
                {
                    original = dec[i];
                    break;
                }
            }
            Debug.Assert(original != null);
            inverse = (TextDecoration)original.Clone();
            inverse.Inverse();
            dec[from] = inverse;

            //範囲に渡って反転作業
            for (int i = from + 1; i < to; i++)
            {
                if (i < dec.Length && dec[i] != null)
                {
                    original = dec[i];
                    inverse  = (TextDecoration)original.Clone();
                    inverse.Inverse();
                    dec[i] = inverse;
                }
            }

            if (to < dec.Length && dec[to] == null)
            {
                dec[to] = original;
            }

            //これに従ってGWordを作る
            w = null;
            for (int i = dec.Length - 1; i >= 0; i--)
            {
                char ch = _text[i];
                if (dec[i] != null && ch != '\0')
                {
                    int j = i;
                    if (ch == WIDECHAR_PAD)
                    {
                        j++;
                    }
                    GWord ww = new GWord(dec[i], j, CalcCharGroup(ch));
                    ww.Next = w;
                    w       = ww;
                }
            }
            ret.Append(w);

            return(ret);
        }
Beispiel #24
0
        internal void ClearAfter(int from, TextDecoration dec)
        {
            if(from > _lastLine.ID) return;
            GLine l = FindLineOrEdge(from);
            if(l==null) return;

            while(l!=null) {
                l.Clear(dec);
                l = l.NextLine;
            }

            AssertValid();
            _invalidatedAll = true;
        }