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); }
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; }
//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); }
//index�̈ʒu�̕\���]�����V����GLine��Ԃ� //inverse��false���ƁAGWord�̕����͂��邪Decoration�̔��]�͂��Ȃ��B�q�N�q�N���̑Ώ��Ƃ��Ď����B 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���珇�ɘA���������������͂悢 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) { //�F���L�����b�g�̃T�|�[�g 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; } //!!���́A�L�����b�g�ʒu�ɃX�y�[�X������̂�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; }