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> /// 指定位置に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なケースだが } } }