/// 文字列、デコレーション、オフセットを指定するコンストラクタ。 public GWord(TextDecoration d, int o, CharGroup chargroup) { Debug.Assert(d != null); _offset = o; _decoration = d; _next = null; _charGroup = chargroup; }
private static string TestPutChar(string initial, int col, char ch) { GLineManipulator m = new GLineManipulator(); m.Load(GLine.ToCharArray(initial), col); //Debug.WriteLine(String.Format("Test{0} [{1}] col={2} char={3}", num, SafeString(m._text), m.CaretColumn, ch)); m.PutChar(ch, TextDecoration.ClonedDefault()); //Debug.WriteLine(String.Format("Result [{0}] col={1}", SafeString(m._text), m.CaretColumn)); return(SafeString(m.InternalBuffer)); }
public static GLine CreateSimpleGLine(string text, TextDecoration dec) { char[] buff = new char[text.Length * 2]; int offset = 0; int start = 0; CharGroup prevType = CharGroup.LatinHankaku; GWord firstWord = null; GWord lastWord = null; for (int i = 0; i < text.Length; i++) { char originalChar = text[i]; char privateChar = Unicode.ToPrivate(originalChar); CharGroup nextType = Unicode.GetCharGroup(privateChar); int size = CharGroupUtil.GetColumnsPerCharacter(nextType); if (nextType != prevType) { if (offset > start) { GWord newWord = new GWord(dec, start, prevType); if (lastWord == null) { firstWord = lastWord = newWord; } else { lastWord.Next = newWord; lastWord = newWord; } } prevType = nextType; start = offset; } buff[offset++] = originalChar; if (size == 2) { buff[offset++] = WIDECHAR_PAD; } } GWord w = new GWord(dec, start, prevType); if (lastWord == null) { firstWord = w; } else { lastWord.Next = w; } return(new GLine(buff, offset, firstWord)); }
public void Clear(TextDecoration dec) { TextDecoration fillDec = (dec != null) ? dec.RetainBackColor() : TextDecoration.Default; char fill = fillDec.IsDefault ? '\0' : ' '; // 色指定付きのことがあるのでスペース for (int i = 0; i < _text.Length; i++) { _text[i] = fill; } _displayLength = fillDec.IsDefault ? 0 : _text.Length; _firstWord = new GWord(fillDec, 0, CharGroup.LatinHankaku); }
//テキストファイルから読み出す。装飾はムリだけど public void LoadForTest(string filename) { StreamReader r = null; try { r = new StreamReader(filename, Encoding.Default); TextDecoration dec = TextDecoration.Default; string line = r.ReadLine(); while (line != null) { this.AddLine(GLine.CreateSimpleGLine(line, dec)); line = r.ReadLine(); } } finally { if (r != null) { r.Close(); } } }
/// <summary> /// <ja> /// 指定範囲を半角スペースで埋めます。 /// </ja> /// <en> /// Fill the range of specification with space. /// </en> /// </summary> /// <param name="from"><ja>埋める開始位置(この位置を含みます)</ja><en>Start position(include this position)</en></param> /// <param name="to"><ja>埋める終了位置(この位置は含みません)</ja><en>End position(exclude this position)</en></param> /// <param name="dec"><ja>テキスト書式を指定するTextDecorationオブジェクト</ja><en>TextDecoration object that specifies text format /// </en></param> public void FillSpace(int from, int to, TextDecoration dec) { if (to > _text.Length) { to = _text.Length; } TextDecoration fillDec = dec; if (fillDec != null) { fillDec = fillDec.RetainBackColor(); if (fillDec.IsDefault) { fillDec = null; } } for (int i = from; i < to; i++) { _text[i] = ' '; _attrs[i] = new CharAttr(fillDec, CharGroup.LatinHankaku); } }
//テキストファイルから読み出す。装飾はムリだけど public void LoadForTest(string filename) { StreamReader r = null; try { r = new StreamReader(filename, Encoding.Default); TextDecoration dec = TextDecoration.Default; string line = r.ReadLine(); while (line != null) { //GWordへの分割はしてない、注意 CharGroup cg = line.Length > 0? GLine.CalcCharGroup(line[0]) : CharGroup.Hankaku; this.AddLine(new GLine(GLine.ToCharArray(line), new GWord(dec, 0, cg))); line = r.ReadLine(); } } finally { if (r != null) { r.Close(); } } }
//startからcount文字を消去して詰める。右端にはnullを入れる /// <summary> /// <ja> /// 指定された場所から指定された文字数を削除し、その後ろを詰めます。 /// </ja> /// <en> /// The number of characters specified from the specified place is deleted, and the furnace is packed afterwards. /// </en> /// </summary> /// <param name="start"><ja>削除する開始位置</ja><en>Start position</en></param> /// <param name="count"><ja>削除する文字数</ja><en>Count to delete</en></param> /// <param name="dec"><ja>末尾の新しい空白領域のテキスト装飾</ja><en>text decoration for the new empty spaces at the tail of the line</en></param> public void DeleteChars(int start, int count, TextDecoration dec) { char fillChar; TextDecoration fillDec = dec; if (fillDec != null) { fillDec = fillDec.RetainBackColor(); if (fillDec.IsDefault) { fillDec = null; fillChar = '\0'; } else { fillChar = ' '; } } else { fillChar = '\0'; } for (int i = start; i < _text.Length; i++) { int j = i + count; if (j < _text.Length) { _text[i] = _text[j]; _attrs[i] = _attrs[j]; } else { _text[i] = fillChar; _attrs[i] = new CharAttr(fillDec, CharGroup.LatinHankaku); } } }
private TextDecoration SelectForeColor(TextDecoration dec, int index) { RenderProfile prof = GetRenderProfile(); ESColor c = prof.ESColorSet[index]; return dec.GetCopyWithTextColor(c.Color); }
public AbstractTerminal(TerminalInitializeInfo info) { TerminalEmulatorPlugin.Instance.LaterInitialize(); _session = info.Session; //_invalidateParam = new InvalidateParam(); _document = new TerminalDocument(info.InitialWidth, info.InitialHeight); _document.SetOwner(_session.ISession); _afterExitLockActions = new List<AfterExitLockDelegate>(); _decoder = new ISO2022CharDecoder(this, EncodingProfile.Get(info.Session.TerminalSettings.Encoding)); _terminalMode = TerminalMode.Normal; _currentdecoration = TextDecoration.Default; _manipulator = new GLineManipulator(); _scrollBarValues = new ScrollBarValues(); _logService = new LogService(info.TerminalParameter, _session.TerminalSettings); _promptRecognizer = new PromptRecognizer(this); _intelliSense = new IntelliSense(this); _commandResultRecognizer = new PopupStyleCommandResultRecognizer(this); if (info.Session.TerminalSettings.LogSettings != null) _logService.ApplyLogSettings(_session.TerminalSettings.LogSettings, false); //event handlers ITerminalSettings ts = info.Session.TerminalSettings; ts.ChangeEncoding += delegate(EncodingType t) { this.Reset(); }; ts.ChangeRenderProfile += delegate(RenderProfile prof) { TerminalControl tc = _session.TerminalControl; if (tc != null) tc.ApplyRenderProfile(prof); }; }
private FontHandle CalcFontInternal(TextDecoration dec, CharGroup cg, bool ignore_underline) { if (_font == null) CreateFonts(); if (CharGroupUtil.IsCJK(cg)) { if (dec == null) return _cjkFont; if (CalcBold(dec)) { if (!ignore_underline && dec.Underline) return _cjkBoldUnderlinefont; else return _cjkBoldfont; } else if (!ignore_underline && dec.Underline) return _cjkUnderlinefont; else return _cjkFont; } else { if (dec == null) return _font; if (CalcBold(dec)) { if (!ignore_underline && dec.Underline) return _boldunderlinefont; else return _boldfont; } else if (!ignore_underline && dec.Underline) return _underlinefont; else return _font; } }
/// <summary> /// /// </summary> /// <param name="dec"></param> /// <param name="cg"></param> /// <returns></returns> /// <exclude/> public IntPtr CalcHFONT_NoUnderline(TextDecoration dec, CharGroup cg) { return CalcFontInternal(dec, cg, true).HFONT; }
/// <summary> /// /// </summary> /// <param name="dec"></param> /// <param name="cg"></param> /// <returns></returns> /// <exclude/> public Font CalcFont(TextDecoration dec, CharGroup cg) { return CalcFontInternal(dec, cg, false).Font; }
/// <summary> /// Invert text attribute at the specified position. /// </summary> /// <remarks> /// <para>If doInvert was false, only splitting of GWords will be performed. /// It is required to avoid problem when the text which conatins blinking cursor is drawn by DrawWord().</para> /// <para>DrawWord() draws contiguous characters at once, /// and the character pitch depends how the character in the font was designed.</para> /// <para>By split GWord even if inversion is not required, /// the position of a character of the blinking cursor will be constant.</para> /// </remarks> /// <param name="index">Column index to invert.</param> /// <param name="doInvert">Whether inversion is really applied.</param> /// <param name="color">Background color of the inverted character.</param> internal void InvertCharacter(int index, bool doInvert, Color color) { //先にデータのあるところより先の位置を指定されたらバッファを広げておく if (index >= _displayLength) { int prevLength = _displayLength; ExpandBuffer(index + 1); for (int i = prevLength; i < index + 1; i++) { _text[i] = ' '; } _displayLength = index + 1; this.LastWord.Next = new GWord(TextDecoration.Default, prevLength, CharGroup.LatinHankaku); } if (_text[index] == WIDECHAR_PAD) { index--; } GWord prev = null; GWord word = _firstWord; int nextoffset = 0; while (word != null) { nextoffset = GetNextOffset(word); if (word.Offset <= index && index < nextoffset) { GWord next = word.Next; //キャレットの反転 TextDecoration inv_dec = word.Decoration; if (doInvert) { inv_dec = inv_dec.GetInvertedCopyForCaret(color); } //GWordは最大3つ(head:indexの前、middle:index、tail:indexの次)に分割される GWord head = word.Offset < index ? new GWord(word.Decoration, word.Offset, word.CharGroup) : null; GWord mid = new GWord(inv_dec, index, word.CharGroup); int nextIndex = index + CharGroupUtil.GetColumnsPerCharacter(word.CharGroup); GWord tail = nextIndex < nextoffset ? new GWord(word.Decoration, nextIndex, word.CharGroup) : null; //連結 head,tailはnullのこともあるのでややこしい List <GWord> list = new List <GWord>(3); if (head != null) { list.Add(head); head.Next = mid; } list.Add(mid); mid.Next = tail == null ? next : tail; if (tail != null) { list.Add(tail); } //前後との連結 if (prev == null) { _firstWord = list[0]; } else { prev.Next = list[0]; } list[list.Count - 1].Next = next; break; } prev = word; word = word.Next; } }
/// <summary> /// <ja> /// 指定範囲を半角スペースで埋めます。 /// </ja> /// <en> /// Fill the range of specification with space. /// </en> /// </summary> /// <param name="from"><ja>埋める開始位置(この位置を含みます)</ja><en>Start position(include this position)</en></param> /// <param name="to"><ja>埋める終了位置(この位置は含みません)</ja><en>End position(exclude this position)</en></param> /// <param name="dec"><ja>テキスト書式を指定するTextDecorationオブジェクト</ja><en>TextDecoration object that specifies text format /// </en></param> public void FillSpace(int from, int to, TextDecoration dec) { if (to > _text.Length) to = _text.Length; TextDecoration fillDec = dec; if (fillDec != null) { fillDec = fillDec.RetainBackColor(); if (fillDec.IsDefault) fillDec = null; } for (int i = from; i < to; i++) { _text[i] = ' '; _attrs[i] = new CharAttr(fillDec, CharGroup.LatinHankaku); } }
/// <summary> /// <ja> /// 指定位置に1文字書き込みます。 /// </ja> /// <en> /// Write one character to specified position. /// </en> /// </summary> /// <param name="ch"><ja>書き込む文字</ja><en>Character to write.</en></param> /// <param name="dec"><ja>テキスト書式を指定するTextDecorationオブジェクト</ja> /// <en>TextDecoration object that specifies text format /// </en></param> public void PutChar(char ch, TextDecoration dec) { Debug.Assert(dec != null); Debug.Assert(_caretColumn >= 0); Debug.Assert(_caretColumn < _text.Length); char originalChar = Unicode.ToOriginal(ch); CharGroup charGroup = Unicode.GetCharGroup(ch); bool onZenkaku = (_attrs[_caretColumn].CharGroup == CharGroup.CJKZenkaku); bool onZenkakuRight = (_text[_caretColumn] == GLine.WIDECHAR_PAD); if (onZenkaku) { //全角の上に書く if (!onZenkakuRight) { _text[_caretColumn] = originalChar; _attrs[_caretColumn] = new CharAttr(dec, charGroup); if (CharGroupUtil.GetColumnsPerCharacter(charGroup) == 1) { //全角の上に半角を書いた場合、隣にスペースを入れないと表示が乱れる _caretColumn++; if (_caretColumn < _text.Length) { _text[_caretColumn] = ' '; _attrs[_caretColumn].CharGroup = CharGroup.LatinHankaku; } } else { _attrs[_caretColumn + 1] = new CharAttr(dec, charGroup); _caretColumn += 2; } } else { _text[_caretColumn - 1] = ' '; _attrs[_caretColumn - 1].CharGroup = CharGroup.LatinHankaku; _text[_caretColumn] = originalChar; _attrs[_caretColumn] = new CharAttr(dec, charGroup); if (CharGroupUtil.GetColumnsPerCharacter(charGroup) == 2) { if (CharGroupUtil.GetColumnsPerCharacter(_attrs[_caretColumn + 1].CharGroup) == 2) { if (_caretColumn + 2 < _text.Length) { _text[_caretColumn + 2] = ' '; _attrs[_caretColumn + 2].CharGroup = CharGroup.LatinHankaku; } } _text[_caretColumn + 1] = GLine.WIDECHAR_PAD; _attrs[_caretColumn + 1] = _attrs[_caretColumn]; _caretColumn += 2; } else { _caretColumn++; } } } else //半角の上に書く { _text[_caretColumn] = originalChar; _attrs[_caretColumn] = new CharAttr(dec, charGroup); if (CharGroupUtil.GetColumnsPerCharacter(charGroup) == 2) { if (CharGroupUtil.GetColumnsPerCharacter(_attrs[_caretColumn + 1].CharGroup) == 2) //半角、全角となっているところに全角を書いたら { if (_caretColumn + 2 < _text.Length) { _text[_caretColumn + 2] = ' '; _attrs[_caretColumn + 2].CharGroup = CharGroup.LatinHankaku; } } _text[_caretColumn + 1] = GLine.WIDECHAR_PAD; _attrs[_caretColumn + 1] = _attrs[_caretColumn]; _caretColumn += 2; } else { _caretColumn++; //これが最もcommonなケースだが } } }
public static GLine CreateSimpleGLine(string text, TextDecoration dec) { char[] buff = new char[text.Length * 2]; int offset = 0; int start = 0; CharGroup prevType = CharGroup.LatinHankaku; GWord firstWord = null; GWord lastWord = null; for (int i = 0; i < text.Length; i++) { char originalChar = text[i]; char privateChar = Unicode.ToPrivate(originalChar); CharGroup nextType = Unicode.GetCharGroup(privateChar); int size = CharGroupUtil.GetColumnsPerCharacter(nextType); if (nextType != prevType) { if (offset > start) { GWord newWord = new GWord(dec, start, prevType); if (lastWord == null) { firstWord = lastWord = newWord; } else { lastWord.Next = newWord; lastWord = newWord; } } prevType = nextType; start = offset; } buff[offset++] = originalChar; if (size == 2) buff[offset++] = WIDECHAR_PAD; } GWord w = new GWord(dec, start, prevType); if (lastWord == null) { firstWord = w; } else { lastWord.Next = w; } return new GLine(buff, offset, firstWord); }
/// <summary> /// <ja>指定位置に指定された数だけの半角スペースを挿入します。</ja> /// <en>The half angle space only of the number specified for a specified position is inserted. </en> /// </summary> /// <param name="start"><ja>削除する開始位置</ja><en>Start position</en></param> /// <param name="count"><ja>挿入する半角スペースの数</ja><en>Count space to insert</en></param> /// <param name="dec"><ja>空白領域のテキスト装飾</ja><en>text decoration for the new empty spaces</en></param> public void InsertBlanks(int start, int count, TextDecoration dec) { TextDecoration fillDec = dec; if (fillDec != null) { fillDec = fillDec.RetainBackColor(); if (fillDec.IsDefault) fillDec = null; } for (int i = _text.Length - 1; i >= _caretColumn; i--) { int j = i - count; if (j >= _caretColumn) { _text[i] = _text[j]; _attrs[i] = _attrs[j]; } else { _text[i] = ' '; _attrs[i] = new CharAttr(fillDec, CharGroup.LatinHankaku); } } }
private TextDecoration SetForeColorByRGB(TextDecoration dec, int r, int g, int b) { return dec.GetCopyWithTextColor(Color.FromArgb(r, g, b)); }
public CharAttr(TextDecoration dec, CharGroup cg) { Decoration = dec; CharGroup = cg; }
/// <summary> /// Clone this instance that text attributes in the specified range are inverted. /// </summary> /// <param name="from">start column index of the range. (inclusive)</param> /// <param name="to">end column index of the range. (exclusive)</param> /// <returns>new instance</returns> internal GLine CreateInvertedClone(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 < _text.Length && _text[to] == WIDECHAR_PAD) { to++; } const int PHASE_LEFT = 0; const int PHASE_MIDDLE = 1; const int PHASE_RIGHT = 2; int phase = PHASE_LEFT; int inverseIndex = from; GWord first = null; GWord last = null; for (GWord word = _firstWord; word != null; word = word.Next) { TextDecoration originalDecoration = word.Decoration; if (originalDecoration == null) { originalDecoration = TextDecoration.Default; } int wordStart = word.Offset; int wordEnd = GetNextOffset(word); do { GWord newWord; if (phase == PHASE_RIGHT || inverseIndex < wordStart || wordEnd <= inverseIndex) { TextDecoration newDec = (phase == PHASE_MIDDLE) ? originalDecoration.GetInvertedCopy() : originalDecoration; newWord = new GWord(newDec, wordStart, word.CharGroup); wordStart = wordEnd; } else { TextDecoration leftDec = (phase == PHASE_LEFT) ? originalDecoration : originalDecoration.GetInvertedCopy(); if (wordStart < inverseIndex) { newWord = new GWord(leftDec, wordStart, word.CharGroup); } else { newWord = null; } wordStart = inverseIndex; // update phase if (phase == PHASE_LEFT) { phase = PHASE_MIDDLE; inverseIndex = to; } else if (phase == PHASE_MIDDLE) { phase = PHASE_RIGHT; } } // append new GWord to the list. if (newWord != null) { if (last == null) { first = newWord; } else { last.Next = newWord; } last = newWord; } } while (wordStart < wordEnd); } GLine ret = new GLine((char[])_text.Clone(), _displayLength, first); ret.ID = _id; ret.EOLType = _eolType; return(ret); }
private TextDecoration SelectBackgroundColor(TextDecoration dec, int index) { RenderProfile prof = GetRenderProfile(); ESColor c = prof.ESColorSet[index]; Color color; if (prof.DarkenEsColorForBackground && !c.IsExactColor) color = DrawUtil.DarkColor(c.Color); else color = c.Color; return dec.GetCopyWithBackColor(color); }
/// <summary> /// <ja> /// 指定位置に1文字書き込みます。 /// </ja> /// <en> /// Write one character to specified position. /// </en> /// </summary> /// <param name="ch"><ja>書き込む文字</ja><en>Character to write.</en></param> /// <param name="dec"><ja>テキスト書式を指定するTextDecorationオブジェクト</ja> /// <en>TextDecoration object that specifies text format /// </en></param> public void PutChar(char ch, TextDecoration dec) { Debug.Assert(dec != null); Debug.Assert(_caretColumn >= 0); Debug.Assert(_caretColumn < _text.Length); char originalChar = Unicode.ToOriginal(ch); CharGroup charGroup = Unicode.GetCharGroup(ch); bool onZenkaku = (_attrs[_caretColumn].CharGroup == CharGroup.CJKZenkaku); bool onZenkakuRight = (_text[_caretColumn] == GLine.WIDECHAR_PAD); if (onZenkaku) { //全角の上に書く if (!onZenkakuRight) { _text[_caretColumn] = originalChar; _attrs[_caretColumn] = new CharAttr(dec, charGroup); if (CharGroupUtil.GetColumnsPerCharacter(charGroup) == 1) { //全角の上に半角を書いた場合、隣にスペースを入れないと表示が乱れる _caretColumn++; if (_caretColumn < _text.Length) { _text[_caretColumn] = ' '; _attrs[_caretColumn].CharGroup = CharGroup.LatinHankaku; } } else { _attrs[_caretColumn + 1] = new CharAttr(dec, charGroup); _caretColumn += 2; } } else { _text[_caretColumn - 1] = ' '; _attrs[_caretColumn - 1].CharGroup = CharGroup.LatinHankaku; _text[_caretColumn] = originalChar; _attrs[_caretColumn] = new CharAttr(dec, charGroup); if (CharGroupUtil.GetColumnsPerCharacter(charGroup) == 2) { if (CharGroupUtil.GetColumnsPerCharacter(_attrs[_caretColumn + 1].CharGroup) == 2) { if (_caretColumn + 2 < _text.Length) { _text[_caretColumn + 2] = ' '; _attrs[_caretColumn + 2].CharGroup = CharGroup.LatinHankaku; } } _text[_caretColumn + 1] = GLine.WIDECHAR_PAD; _attrs[_caretColumn + 1] = _attrs[_caretColumn]; _caretColumn += 2; } else { _caretColumn++; } } } else { //半角の上に書く _text[_caretColumn] = originalChar; _attrs[_caretColumn] = new CharAttr(dec, charGroup); if (CharGroupUtil.GetColumnsPerCharacter(charGroup) == 2) { if (CharGroupUtil.GetColumnsPerCharacter(_attrs[_caretColumn + 1].CharGroup) == 2) { //半角、全角となっているところに全角を書いたら if (_caretColumn + 2 < _text.Length) { _text[_caretColumn + 2] = ' '; _attrs[_caretColumn + 2].CharGroup = CharGroup.LatinHankaku; } } _text[_caretColumn + 1] = GLine.WIDECHAR_PAD; _attrs[_caretColumn + 1] = _attrs[_caretColumn]; _caretColumn += 2; } else { _caretColumn++; //これが最もcommonなケースだが } } }
/// <summary> /// <ja> /// �w��ʒu��1�����������݂܂��B /// </ja> /// <en> /// Write one character to specified position. /// </en> /// </summary> /// <param name="ch"><ja>�������ޕ���</ja><en>Character to write.</en></param> /// <param name="dec"><ja>�e�L�X�g������w�肷��TextDecoration�I�u�W�F�N�g</ja> /// <en>TextDecoration object that specifies text format /// </en></param> public void PutChar(char ch, TextDecoration dec) { Debug.Assert(dec != null); Debug.Assert(_caretColumn >= 0); Debug.Assert(_caretColumn < _text.Length); char originalChar = Unicode.ToOriginal(ch); CharGroup charGroup = Unicode.GetCharGroup(ch); bool onZenkaku = (_attrs[_caretColumn].CharGroup == CharGroup.CJKZenkaku); bool onZenkakuRight = (_text[_caretColumn] == GLine.WIDECHAR_PAD); if (onZenkaku) { //�S�p�̏�ɏ��� if (!onZenkakuRight) { _text[_caretColumn] = originalChar; _attrs[_caretColumn] = new CharAttr(dec, charGroup); if (CharGroupUtil.GetColumnsPerCharacter(charGroup) == 1) { //�S�p�̏�ɔ��p��������ꍇ�A�ׂɃX�y�[�X�����Ȃ��ƕ\��������� _caretColumn++; if (_caretColumn < _text.Length) { _text[_caretColumn] = ' '; _attrs[_caretColumn].CharGroup = CharGroup.LatinHankaku; } } else { _attrs[_caretColumn + 1] = new CharAttr(dec, charGroup); _caretColumn += 2; } } else { _text[_caretColumn - 1] = ' '; _attrs[_caretColumn - 1].CharGroup = CharGroup.LatinHankaku; _text[_caretColumn] = originalChar; _attrs[_caretColumn] = new CharAttr(dec, charGroup); if (CharGroupUtil.GetColumnsPerCharacter(charGroup) == 2) { if (CharGroupUtil.GetColumnsPerCharacter(_attrs[_caretColumn + 1].CharGroup) == 2) { if (_caretColumn + 2 < _text.Length) { _text[_caretColumn + 2] = ' '; _attrs[_caretColumn + 2].CharGroup = CharGroup.LatinHankaku; } } _text[_caretColumn + 1] = GLine.WIDECHAR_PAD; _attrs[_caretColumn + 1] = _attrs[_caretColumn]; _caretColumn += 2; } else { _caretColumn++; } } } else { //���p�̏�ɏ��� _text[_caretColumn] = originalChar; _attrs[_caretColumn] = new CharAttr(dec, charGroup); if (CharGroupUtil.GetColumnsPerCharacter(charGroup) == 2) { if (CharGroupUtil.GetColumnsPerCharacter(_attrs[_caretColumn + 1].CharGroup) == 2) { //���p�A�S�p�ƂȂ��Ă���Ƃ���ɑS�p��������� if (_caretColumn + 2 < _text.Length) { _text[_caretColumn + 2] = ' '; _attrs[_caretColumn + 2].CharGroup = CharGroup.LatinHankaku; } } _text[_caretColumn + 1] = GLine.WIDECHAR_PAD; _attrs[_caretColumn + 1] = _attrs[_caretColumn]; _caretColumn += 2; } else { _caretColumn++; //���ꂪ�ł�common�ȃP�[�X���� } } }
protected void ProcessSGRParameterANSI(int code, ref TextDecoration dec) { switch (code) { case 0: // default rendition (implementation-defined) (ECMA-48,VT100,VT220) dec = TextDecoration.Default; break; case 1: // bold or increased intensity (ECMA-48,VT100,VT220) dec = dec.GetCopyWithBold(true); break; case 2: // faint, decreased intensity or second colour (ECMA-48) dec = dec.GetCopyWithTextColor(DrawUtil.DarkColor(dec.TextColor)); break; case 3: // italicized (ECMA-48) break; case 4: // singly underlined (ECMA-48,VT100,VT220) dec = dec.GetCopyWithUnderline(true); break; case 5: // slowly blinking (ECMA-48,VT100,VT220) case 6: // rapidly blinking (ECMA-48) // use bold instead of blinking dec = dec.GetCopyWithBold(true); break; case 7: // negative image (ECMA-48,VT100,VT220) dec = dec.GetInvertedCopy(); break; case 8: // concealed characters (ECMA-48,VT300) case 9: // crossed-out (ECMA-48) case 10: // primary (default) font (ECMA-48) case 11: // first alternative font (ECMA-48) case 12: // second alternative font (ECMA-48) case 13: // third alternative font (ECMA-48) case 14: // fourth alternative font (ECMA-48) case 15: // fifth alternative font (ECMA-48) case 16: // sixth alternative font (ECMA-48) case 17: // seventh alternative font (ECMA-48) case 18: // eighth alternative font (ECMA-48) case 19: // ninth alternative font (ECMA-48) case 20: // Fraktur (Gothic) (ECMA-48) case 21: // doubly underlined (ECMA-48) break; case 22: // normal colour or normal intensity (neither bold nor faint) (ECMA-48,VT220,VT300) dec = TextDecoration.Default; break; case 23: // not italicized, not fraktur (ECMA-48) break; case 24: // not underlined (neither singly nor doubly) (ECMA-48,VT220,VT300) dec = dec.GetCopyWithUnderline(false); break; case 25: // steady (not blinking) (ECMA-48,VT220,VT300) // disable bold instead of disabling blinking dec = dec.GetCopyWithBold(false); break; case 26: // reserved (ECMA-48) break; case 27: // positive image (ECMA-48,VT220,VT300) // actually, there is no guarantee that this operation displays a positive attributes... dec = dec.GetInvertedCopy(); break; case 28: // revealed characters (ECMA-48) case 29: // not crossed out (ECMA-48) break; case 30: // black display (ECMA-48) case 31: // red display (ECMA-48) case 32: // green display (ECMA-48) case 33: // yellow display (ECMA-48) case 34: // blue display (ECMA-48) case 35: // magenta display (ECMA-48) case 36: // cyan display (ECMA-48) case 37: // white display (ECMA-48) dec = SelectForeColor(dec, code - 30); break; case 38: // reserved (ECMA-48) break; case 39: // default display colour (implementation-defined) (ECMA-48) dec = dec.GetCopyWithDefaultTextColor(); break; case 40: // black background (ECMA-48) case 41: // red background (ECMA-48) case 42: // green background (ECMA-48) case 43: // yellow background (ECMA-48) case 44: // blue background (ECMA-48) case 45: // magenta background (ECMA-48) case 46: // cyan background (ECMA-48) case 47: // white background (ECMA-48) dec = SelectBackgroundColor(dec, code - 40); break; case 48: // reserved (ECMA-48) break; case 49: // default background colour (implementation-defined) (ECMA-48) dec = dec.GetCopyWithDefaultBackColor(); break; case 50: // reserved (ECMA-48) case 51: // framed (ECMA-48) case 52: // encircled (ECMA-48) case 53: // overlined (ECMA-48) case 54: // not framed, not encircled (ECMA-48) case 55: // not overlined (ECMA-48) case 56: // reserved (ECMA-48) case 57: // reserved (ECMA-48) case 58: // reserved (ECMA-48) case 59: // reserved (ECMA-48) case 60: // ideogram underline or right side line (ECMA-48) case 61: // ideogram double underline or double line on the right side (ECMA-48) case 62: // ideogram overline or left side line (ECMA-48) case 63: // ideogram double overline or double line on the left side (ECMA-48) case 64: // ideogram stress marking (ECMA-48) case 65: // cancels the effect of the rendition aspects established by parameter values 60 to 64 (ECMA-48) break; default: // other values are ignored without notification to the user Debug.WriteLine("unknown SGR code (ANSI) : {0}", code); break; } }
//startからcount文字を消去して詰める。右端にはnullを入れる /// <summary> /// <ja> /// 指定された場所から指定された文字数を削除し、その後ろを詰めます。 /// </ja> /// <en> /// The number of characters specified from the specified place is deleted, and the furnace is packed afterwards. /// </en> /// </summary> /// <param name="start"><ja>削除する開始位置</ja><en>Start position</en></param> /// <param name="count"><ja>削除する文字数</ja><en>Count to delete</en></param> /// <param name="dec"><ja>末尾の新しい空白領域のテキスト装飾</ja><en>text decoration for the new empty spaces at the tail of the line</en></param> public void DeleteChars(int start, int count, TextDecoration dec) { char fillChar; TextDecoration fillDec = dec; if (fillDec != null) { fillDec = fillDec.RetainBackColor(); if (fillDec.IsDefault) { fillDec = null; fillChar = '\0'; } else { fillChar = ' '; } } else { fillChar = '\0'; } for (int i = start; i < _text.Length; i++) { int j = i + count; if (j < _text.Length) { _text[i] = _text[j]; _attrs[i] = _attrs[j]; } else { _text[i] = fillChar; _attrs[i] = new CharAttr(fillDec, CharGroup.LatinHankaku); } } }
internal void Render(IntPtr hdc, RenderProfile prof, Color baseBackColor, int x, int y) { if (_text.Length == 0 || _text[0] == '\0') { return; //何も描かなくてよい。これはよくあるケース } float fx0 = (float)x; float fx1 = fx0; int y1 = y; int y2 = y1 + (int)prof.Pitch.Height; float pitch = prof.Pitch.Width; int defaultBackColorArgb = baseBackColor.ToArgb(); Win32.SetBkMode(hdc, Win32.TRANSPARENT); GWord word = _firstWord; while (word != null) { TextDecoration dec = word.Decoration; IntPtr hFont = prof.CalcHFONT_NoUnderline(dec, word.CharGroup); Win32.SelectObject(hdc, hFont); uint foreColorRef = DrawUtil.ToCOLORREF(prof.CalcTextColor(dec)); Win32.SetTextColor(hdc, foreColorRef); Color bkColor = prof.CalcBackColor(dec); bool isOpaque = (bkColor.ToArgb() != defaultBackColorArgb); if (isOpaque) { uint bkColorRef = DrawUtil.ToCOLORREF(bkColor); Win32.SetBkColor(hdc, bkColorRef); } int nextOffset = GetNextOffset(word); float fx2 = fx0 + pitch * nextOffset; if (prof.CalcBold(dec) || CharGroupUtil.IsCJK(word.CharGroup)) { // It is not always true that width of a character in the CJK font is twice of a character in the ASCII font. // Characters are drawn one by one to adjust pitch. int step = CharGroupUtil.GetColumnsPerCharacter(word.CharGroup); float charPitch = pitch * step; int offset = word.Offset; float fx = fx1; if (isOpaque) { // If background fill is required, we call ExtTextOut() with ETO_OPAQUE to draw the first character. if (offset < nextOffset) { Win32.RECT rect = new Win32.RECT((int)fx1, y1, (int)fx2, y2); char ch = _text[offset]; Debug.Assert(ch != GLine.WIDECHAR_PAD); unsafe { Win32.ExtTextOut(hdc, rect.left, rect.top, Win32.ETO_OPAQUE, &rect, &ch, 1, null); } } offset += step; fx += charPitch; } for (; offset < nextOffset; offset += step) { char ch = _text[offset]; Debug.Assert(ch != GLine.WIDECHAR_PAD); unsafe { Win32.ExtTextOut(hdc, (int)fx, y1, 0, null, &ch, 1, null); } fx += charPitch; } } else { int offset = word.Offset; int displayLength = nextOffset - offset; if (isOpaque) { Win32.RECT rect = new Win32.RECT((int)fx1, y1, (int)fx2, y2); unsafe { fixed(char *p = &_text[offset]) { Win32.ExtTextOut(hdc, rect.left, rect.top, Win32.ETO_OPAQUE, &rect, p, displayLength, null); } } } else { unsafe { fixed(char *p = &_text[offset]) { Win32.ExtTextOut(hdc, (int)fx1, y1, 0, null, p, displayLength, null); } } } } if (dec.Underline) { DrawUnderline(hdc, foreColorRef, (int)fx1, y2 - 1, (int)fx2 - (int)fx1); } fx1 = fx2; word = word.Next; } }
public void Clear(TextDecoration dec) { TextDecoration fillDec = (dec != null) ? dec.RetainBackColor() : TextDecoration.Default; char fill = fillDec.IsDefault ? '\0' : ' '; // 色指定付きのことがあるのでスペース for (int i = 0; i < _text.Length; i++) _text[i] = fill; _displayLength = fillDec.IsDefault ? 0 : _text.Length; _firstWord = new GWord(fillDec, 0, CharGroup.LatinHankaku); }
public void ClearAfter(int from, TextDecoration dec) { GLine l = FindLineOrNullClipTop(from); if (l == null) return; while (l != null) { l.Clear(dec); l = l.NextLine; } _invalidatedRegion.InvalidatedAll = true; }
public CharAttr(TextDecoration dec, CharGroup cg) { Decoration = dec; CharGroup = cg; }
public void ClearRange(int from, int to, TextDecoration dec) { GLine l = FindLineOrNullClipTop(from); if (l == null) return; while (l != null && l.ID < to) { l.Clear(dec); _invalidatedRegion.InvalidateLine(l.ID); l = l.NextLine; } }
public void Load(char[] text, int cc) { _text = text; _decorations = new TextDecoration[text.Length]; _eolType = EOLType.Continue; _caretColumn = cc; }
/// <summary> /// /// </summary> /// <param name="dec"></param> /// <returns></returns> /// <exclude/> public Color CalcBackColor(TextDecoration dec) { if (_brush == null) CreateBrushes(); if (dec == null) return _bgcolor; switch (dec.BackColorType) { case ColorType.Custom: return dec.BackColor; case ColorType.DefaultBack: return _bgcolor; case ColorType.DefaultText: return _forecolor; default: throw new Exception("Unexpected decoration object"); } }
/// <summary> /// <ja> /// テキスト書式を指定するTextDecorationオブジェクトを設定します。 /// </ja> /// <en> /// Set the TextDecoration object that specifies the text format. /// </en> /// </summary> /// <param name="dec"><ja>設定するTextDecorationオブジェクト</ja><en>Set TextDecoration object</en></param> public void SetDecoration(TextDecoration dec) { if (_caretColumn < _attrs.Length) _attrs[_caretColumn].Decoration = dec; }
/// <summary> /// /// </summary> /// <param name="dec"></param> /// <returns></returns> /// <exclude/> public bool CalcBold(TextDecoration dec) { if (_forceBoldStyle) return true; if (_enableBoldStyle) return dec.Bold; else return false; }