Revision: 8724 https://osdn.net/projects/ttssh2/scm/svn/commits/8724 Author: zmatsuo Date: 2020-04-13 01:41:38 +0900 (Mon, 13 Apr 2020) Log Message: ----------- ANSI文字の処理を修正 - buff_char_t にメンバー変数 ansi_char を追加 - 2byte(2セル)文字の場合は、1セル目に文字が保存されて、2セル目は空き - ANSI文字の結合処理 - vtterm.cのUnicode結合文字関連の関数をunicode.cに移動 - GetPrecomposedChar() -> UnicodeGetPrecomposedChar() - GetIndexOfCombiningFirstCode() -> UnicodeGetIndexOfCombiningFirstCode() - UnicodeCombining() 追加 - 文字情報ポップアップ - 表示内容を整理 - "Press shift for sending to clipboard" 表示を追加 - shiftを押したとき(クリップボードにコピーしたとき) - 音を出すようにした(MessageBeep(MB_OK)) - ポップアップを消すようにした Modified Paths: -------------- branches/unicode_buf_2/teraterm/teraterm/buffer.c branches/unicode_buf_2/teraterm/teraterm/unicode.cpp branches/unicode_buf_2/teraterm/teraterm/unicode.h branches/unicode_buf_2/teraterm/teraterm/vtterm.c branches/unicode_buf_2/teraterm/teraterm/vtwin.cpp -------------- next part -------------- Modified: branches/unicode_buf_2/teraterm/teraterm/buffer.c =================================================================== --- branches/unicode_buf_2/teraterm/teraterm/buffer.c 2020-04-12 16:41:30 UTC (rev 8723) +++ branches/unicode_buf_2/teraterm/teraterm/buffer.c 2020-04-12 16:41:38 UTC (rev 8724) @@ -171,6 +171,26 @@ case 2: break; } + + if (u32 < 0x80) { + p->ansi_char = (unsigned short)u32; + } + else { + char strA[4]; + size_t lenA = UTF32ToMBCP(u32, CP_ACP, strA, sizeof(strA)); + switch (lenA) { + case 0: + default: + p->ansi_char = 0; + break; + case 1: + p->ansi_char = (unsigned char)strA[0]; + break; + case 2: + p->ansi_char = (unsigned char)strA[1] | ((unsigned char)strA[0] << 8); + break; + } + } } static void BuffSetChar3(buff_char_t *buff, char32_t u32, unsigned char fg, unsigned char bg, char property) @@ -1955,6 +1975,9 @@ * FALSE \x95\xB6\x8E\x9A\x82\xF0\x93W\x8AJ\x82ł\xAB\x82\xBD * @retrun \x95\xB6\x8E\x9A\x90\x94 \x8Fo\x97͕\xB6\x8E\x9A\x90\x94 * 0\x82̂Ƃ\xAB\x81A\x95\xB6\x8E\x9A\x8Fo\x97͂Ȃ\xB5 + * + * TODO + * GetWCS() \x82Ɠ\xAF\x82\xB6? */ static size_t expand_wchar(const buff_char_t *b, wchar_t *buf, size_t buf_size, BOOL *too_samll) { @@ -3125,6 +3148,14 @@ } } +/** + * 1\x83Z\x83\x8B\x95\xAA\x82\xF0wchar_t\x95\xB6\x8E\x9A\x97\xF1\x82ɓW\x8AJ\x82\xB7\x82\xE9 + * @param[in] b 1\x83Z\x83\x8B\x95\xAA\x82̕\xB6\x8E\x9A\x8F\xEE\x95\xF1\x82ւ̃|\x83C\x83\x93\x83^ + * @retval \x93W\x8AJ\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1 + * + * TODO + * expand_wchar() \x82Ɠ\xAF\x82\xB6? + */ static wchar_t *GetWCS(const buff_char_t *b) { size_t len = (b->wc2[1] == 0) ? 2 : 3; @@ -3201,7 +3232,11 @@ return p != NULL; } -static unsigned short ConverACPChar(const buff_char_t *b) +/** + * Unicode\x82\xA9\x82\xE7 ANSI \x82ɕϊ\xB7\x82\xB7\x82\xE9 + * \x8C\x8B\x8D\x87\x95\xB6\x8E\x9A(combining character)\x82\xE0\x8Ds\x82\xA4 + */ +static unsigned short ConvertACPChar(const buff_char_t *b) { size_t pool_lenW = 128; wchar_t *strW = (wchar_t *)malloc(pool_lenW * sizeof(wchar_t)); @@ -3212,16 +3247,33 @@ expand_wchar(b, strW, lenW, &too_small); } + if (lenW >= 2) { + // WideCharToMultiByte() \x82ł͌\x8B\x8D\x87\x8F\x88\x97\x9D\x82͍s\x82\xED\x82\xEA\x82Ȃ\xA2 + // \x8E\xA9\x97͂Ō\x8B\x8D\x87\x8F\x88\x97\x9D\x82\xF0\x8Ds\x82\xA4\x81B\x82\xBD\x82\xBE\x82\xB5\x81A\x8Dŏ\x89\x82\xCC2\x95\xB6\x8E\x9A\x82\xBE\x82\xAF + // \x97\xE11: + // U+307B(\x82\xD9) + U+309A(\x81K) \x82\xCD + // Shift jis \x82\xCC 0x82d9(\x82\xD9) \x82\xC6 0x814b(\x81K) \x82ɕϊ\xB7\x82\xB3\x82\xEA + // 0x82db(\x82\xDB) \x82ɂ͕ϊ\xB7\x82\xB3\x82\xEA\x82Ȃ\xA2 + // \x97\\x82\xDF U+307D(\x82\xDB)\x82ɐ\xB3\x8BK\x89\xBB\x82\xB5\x82Ă\xA8\x82\xAD + // \x97\xE12: + // U+0061 U+0302 -> U+00E2 (latin small letter a with circumflex) (a+^) + unsigned short c = UnicodeCombining(strW[0], strW[1]); + if (c != 0) { + // \x8C\x8B\x8D\x87\x82ł\xAB\x82\xBD + strW[0] = c; + strW[1] = 0; + } + } size_t lenA; char *strA = _WideCharToMultiByte(strW, lenW, CP_ACP, &lenA); - unsigned short chA = *strA; - if (!IsDBCSLeadByte((BYTE)(*strA))) { + unsigned short chA = *(unsigned char *)strA; + if (!IsDBCSLeadByte((BYTE)chA)) { // 1byte\x95\xB6\x8E\x9A chA = strA[0]; } else { // 2byte\x95\xB6\x8E\x9A - chA = strA[0] | (strA[1] << 8); + chA = (chA << 8) | ((unsigned char)strA[1]); } free(strA); free(strW); @@ -3246,7 +3298,6 @@ // PCHAR AttrLineBG = &AttrBuffBG[LinePtr]; buff_char_t * CodeLineW = &CodeBuffW[LinePtr]; #endif - BYTE b1, b2; int move_x = 0; static BOOL show_str_change = FALSE; buff_char_t *p; @@ -3254,6 +3305,8 @@ assert(Attr.Attr == (Attr.AttrEx & 0xff)); +#if 0 + BYTE b1, b2; // TODO \x93\xFC\x97͕\xB6\x8E\x9A\x82\xF0 CP932 \x82ɕϊ\xB7\x82\xB5\x82Ă\xA8\x82\xAD\x81A\x94p\x8E~\x97\\x92\xE8 if (u32 < 0x80) { b1 = (BYTE)u32; @@ -3277,6 +3330,7 @@ ret = 2; } } +#endif #if 0 OutputDebugPrintfW(L"BuffPutUnicode(U+%06x,(%d,%d)\n", u32, CursorX, CursorY); @@ -3328,6 +3382,9 @@ StrChangeStart = CursorX - StrChangeCount; } } + + // ANSI\x95\xB6\x8E\x9A\x83R\x81[\x83h\x82\xF0\x8DX\x90V + p->ansi_char = ConvertACPChar(p); } else { char width_property; @@ -3682,7 +3739,7 @@ if (count == 0) { // \x8Dŏ\x89\x82\xCC1\x95\xB6\x8E\x9A\x96\xDA int ptr = TmpPtr + istart + count; - if (b->u32 == 0) { // TODO IsBuffPadding() + if (IsBuffPadding(b)) { // \x8Dŏ\x89\x82ɕ\\x8E\xA6\x82\xB5\x82悤\x82Ƃ\xB5\x82\xBD\x95\xB6\x8E\x9A\x82\xAA\x91S\x8Ap\x82̉E\x82\xBE\x82\xC1\x82\xBD\x8Fꍇ ptr--; } @@ -3696,15 +3753,7 @@ CurSelected = CheckSelect(istart+count,SY); } - ansi_char = CodeBuffW[TmpPtr + istart + count].ansi_char; - bufA[lenA] = ansi_char & 0xff; - lenA++; - if (ansi_char > 0x100) { - bufA[lenA] = ansi_char & 0xff; - lenA++; - } - - if (b->u32 == 0) { // TODO IsBuffPadding() + if (IsBuffPadding(b)) { // \x91S\x8Ap\x82̎\x9F\x82̕\xB6\x8E\x9A,\x8F\x88\x97\x9D\x95s\x97v } else { if (count == 0) { @@ -3756,6 +3805,18 @@ lenW += b->CombinationCharCount16; DrawFlag = TRUE; // \x83R\x83\x93\x83r\x83l\x81[\x83V\x83\x87\x83\x93\x82\xAA\x82\xA0\x82\xE9\x8Fꍇ\x82͂\xB7\x82\xAE\x95`\x89\xE6 } + + ansi_char = CodeBuffW[TmpPtr + istart + count].ansi_char; + if (ansi_char < 0x100) { + bufA[lenA] = ansi_char & 0xff; + lenA++; + } + else { + bufA[lenA] = (ansi_char >> 8) & 0xff; + lenA++; + bufA[lenA] = ansi_char & 0xff; + lenA++; + } } // \x8DŌ\xE3\x82܂ŃX\x83L\x83\x83\x83\x93\x82\xB5\x82\xBD? @@ -3776,7 +3837,7 @@ #endif DispSetupDC(CurAttr, CurSelected); -#if UNICODE_INTERNAL_BUFF && UNICODE_DISPLAY +#if UNICODE_DISPLAY DispStrW(bufW, bufWW, lenW, Y, &X); #else DispStr(bufA, lenA, Y, &X); @@ -3801,11 +3862,12 @@ // XEnd: x position of the lower-right corner (last character) // YEnd: y position { - int i, j; +// int i; + int j; int IStart, IEnd; int X, Y; LONG TmpPtr; - TCharAttr TempAttr; +// TCharAttr TempAttr; BOOL TempSel, Caret; if (XStart >= WinOrgX+WinWidth) { @@ -3841,7 +3903,7 @@ XEnd - XStart + 1, YEnd - YStart + 1); #endif - TempAttr = DefCharAttr; +// TempAttr = DefCharAttr; TempSel = FALSE; Caret = IsCaretOn(); @@ -3861,7 +3923,7 @@ X = (IStart-WinOrgX)*FontWidth; - i = IStart; +// i = IStart; BuffDrawLineI(X, Y, j, IStart, IEnd); Y = Y + FontHeight; TmpPtr = NextLinePtr(TmpPtr); @@ -5855,12 +5917,10 @@ wchar_t *BuffGetLineStrW(int Sy, int *cx, size_t *lenght) { size_t total_len = 0; - size_t i = 0; LONG Ptr = GetLinePtr(PageStart + Sy); buff_char_t* b = &CodeBuffW[Ptr]; int x; int cx_pos = cx != NULL ? *cx : 0; - int cx_char_count = 0; size_t idx; wchar_t *result; for(x = 0; x < NumOfColumns; x++) { @@ -5954,11 +6014,34 @@ } /** + * \x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x98A\x8C\x8B\x82\xB7\x82\xE9 + * @param[in] dest malloc\x82\xB3\x82ꂽ\x97̈\xE6 + * *dest == NULL\x82̏ꍇ\x82͐V\x82\xBD\x82ȗ̈悪\x8Am\x95ۂ\xB3\x82\xEA\x82\xE9 + * \x95s\x97v\x82ɂȂ\xC1\x82\xBD\x82\xE7 free() \x82\xB7\x82邱\x82\xC6 + * @param[in] add \x98A\x8C\x8B\x82\xB3\x82\xEA\x82镶\x8E\x9A\x97\xF1 + */ +static void awcscat(wchar_t **dest, const wchar_t *add) +{ + if (*dest == NULL) { + *dest = wcsdup(add); + return; + } + else { + size_t dest_len = wcslen(*dest); + size_t add_len = wcslen(add); + size_t new_len = dest_len + add_len + 1; + wchar_t *new_dest = realloc(*dest, sizeof(wchar_t ) * new_len); + wcscat(new_dest, add); + *dest = new_dest; + } +} + +/** * \x8Ew\x92\xE8\x88ʒu\x82̕\xB6\x8E\x9A\x8F\xEE\x95\xF1\x82\x9A\x97\xF1\x82ŕԂ\xB7 * \x83f\x83o\x83O\x97p\x93r * - * @param Xw, Yw \x83E\x83B\x83\x93\x83h\x83E\x8F\xE3\x82\xCCX,Y(pixel),\x83}\x83E\x83X\x83|\x83C\x83\x93\x83^\x82̈ʒu - * @reterm \x95\xB6\x8E\x9A\x97\xF1(\x95s\x97v\x82ɂȂ\xC1\x82\xBD\x82\xE7free()\x82\xB7\x82邱\x82\xC6) + * @param Xw, Yw \x83E\x83B\x83\x93\x83h\x83E\x8F\xE3\x82\xCCX,Y(pixel),\x83}\x83E\x83X\x83|\x83C\x83\x93\x83^\x82̈ʒu + * @return \x95\xB6\x8E\x9A\x97\xF1(\x95s\x97v\x82ɂȂ\xC1\x82\xBD\x82\xE7free()\x82\xB7\x82邱\x82\xC6) */ wchar_t *BuffGetCharInfo(int Xw, int Yw) { @@ -5966,13 +6049,10 @@ int ScreenY; LONG TmpPtr; BOOL Right; - unsigned char c; - char cs[4]; wchar_t *str_ptr; - size_t str_len; - unsigned char mb[2]; - wchar_t *mb_str; + const buff_char_t *b; + DispConvWinToScreen(Xw, Yw, &X, &ScreenY, &Right); Y = PageStart + ScreenY; @@ -5987,67 +6067,27 @@ TmpPtr = GetLinePtr(Y); LockBuffer(); + b = &CodeBuffW[TmpPtr+X]; - c = (unsigned char)CodeBuffW[TmpPtr+X].ansi_char; - if (c < 0x20) { - cs[0] = '.'; - cs[1] = 0; - mb[0] = c; - mb[1] = 0; - } else if ((CodeBuffW[TmpPtr+X].attr & AttrKanji) == 0) { - // not DBCS(?TODO) - if (_ismbblead(c)) { - cs[0] = '*'; - cs[1] = 0; - } - else { - cs[0] = c; - cs[1] = 0; - } - mb[0] = c; - mb[1] = 0; - } else { - if (X+1 < NumOfColumns) { - char c2 = (CodeBuffW[TmpPtr+X].ansi_char >> 8); - if (_ismbblead(c) && _ismbbtrail(c2)) { - cs[0] = c; - cs[1] = c2; - cs[2] = 0; - mb[0] = c; - mb[1] = c2; - } else { - cs[0] = '*'; - cs[1] = 0; - mb[0] = c; - mb[1] = 0; - } - } else { - // \x88\xEA\x94ԉE\x92[ - mb[0] = c; - mb[1] = 0; - if (_ismbblead(c)) { - cs[0] = '*'; - cs[1] = 0; - } else { - cs[0] = c; - cs[1] = 0; - } - } - } + wchar_t *pos_str; + aswprintf(&pos_str, + L"ch(%d,%d(%d)) px(%d,%d)\n", + X, ScreenY, Y, + Xw, Yw); - if (mb[1] == 0) { - aswprintf(&mb_str, L"0x%02x", mb[0]); - } else { - aswprintf(&mb_str, L"0x%02x%02x", mb[0], mb[1]); - } + wchar_t *attr_str; { - const unsigned char attr = CodeBuffW[TmpPtr+X].attr; - wchar_t *attr_str; + const unsigned char attr = b->attr; + wchar_t *attr1_1_str; + wchar_t *attr1_str; + wchar_t *attr2_str; + wchar_t *width_property; + if (attr == 0) { - attr_str = _wcsdup(L""); + attr1_1_str = _wcsdup(L""); } else { - aswprintf(&attr_str, - L"(%S%S%S%S%S%S%S%S)\n", + aswprintf(&attr1_1_str, + L"(%S%S%S%S%S%S%S%S)", (attr & AttrBold) != 0 ? "AttrBold " : "", (attr & AttrUnder) != 0 ? "AttrUnder " : "", (attr & AttrSpecial) != 0 ? "AttrSpecial ": "", @@ -6055,53 +6095,15 @@ (attr & AttrReverse) != 0 ? "AttrReverse ": "", (attr & AttrLineContinued) != 0 ? "AttrLineContinued ": "", (attr & AttrURL) != 0 ? "AttrURL ": "", - (attr & AttrKanji) != 0 ? "AttrKanji ": "" - ); + (attr & AttrKanji) != 0 ? "AttrKanji ": ""); } - str_len = - aswprintf(&str_ptr, - L"ch(%d,%d(%d)) px(%d,%d)\n" - L"attr 0x%02x%s%s\n" - L"attr2 0x%02x\n" -// L"attrFore 0x%02x\n" -// L"attrBack 0x%02x\n" -// L"CodeLine %s('%hs')", - L"CodeLine %s", - X, ScreenY, Y, - Xw, Yw, - attr, (attr != 0) ? L"\n " : L"", attr_str, - (unsigned char)CodeBuffW[TmpPtr+X].attr2, -// (unsigned char)AttrBuffFG[TmpPtr+X], -// (unsigned char)AttrBuffBG[TmpPtr+X], -// mb_str, cs - mb_str - ); - free(attr_str); - } - free(mb_str); - { - const buff_char_t *b = &CodeBuffW[TmpPtr+X]; - wchar_t *wcs = GetWCS(b); - wchar_t *codes_ptr; - wchar_t *str2_ptr; - size_t str2_len; - int i; - wchar_t *width_property; + aswprintf(&attr1_str, + L"attr 0x%02x%s%s\n" + L"attr2 0x%02x\n", + attr, (attr != 0) ? L"\n " : L"", attr1_1_str, + (unsigned char)CodeBuffW[TmpPtr+X].attr2); - { - size_t codes_len = 10 * (b->CombinationCharCount16 + 1); - codes_ptr = malloc(sizeof(wchar_t) * codes_len); - _snwprintf_s(codes_ptr, codes_len, _TRUNCATE, L"U+%06x", b->u32); - for (i=0; i<b->CombinationCharCount32; i++) { - wchar_t *code_str; - aswprintf(&code_str, L"U+%06x", b->pCombinationChars16[i]); - wcscat_s(codes_ptr, codes_len, L"\n"); - wcscat_s(codes_ptr, codes_len, code_str); - free(code_str); - } - } - width_property = b->WidthProperty == 'F' ? L"Fullwidth" : b->WidthProperty == 'H' ? L"Halfwidth" : @@ -6111,42 +6113,86 @@ b->WidthProperty == 'N' ? L"Neutral" : L"?"; - str2_len = aswprintf(&str2_ptr, - L"\n" - L"attrFore 0x%02x\n" - L"attrBack 0x%02x\n" - L"\n" - L"%s\n" - L"'%s'\n" - L"WidthProperty %s\n" - L"Half %s\n" - L"Padding %s", - b->fg, b->bg, - codes_ptr, - wcs, - width_property, - (b->HalfWidth ? L"TRUE" : L"FALSE"), - (b->Padding ? L"TRUE" : L"FALSE") - ); - free(codes_ptr); - free(wcs); + aswprintf(&attr2_str, + L"attrFore 0x%02x\n" + L"attrBack 0x%02x\n" + L"WidthProperty %s(%hc)\n" + L"Half %s\n" + L"Padding %s\n", + b->fg, b->bg, + width_property, b->WidthProperty, + (b->HalfWidth ? L"TRUE" : L"FALSE"), + (b->Padding ? L"TRUE" : L"FALSE")); - str_len = str_len + str2_len - 1; // -1 = remove one '\0' - str_ptr = realloc(str_ptr, sizeof(wchar_t) * str_len); - wcscat_s(str_ptr, str_len, str2_ptr); - free(str2_ptr); + free(attr1_1_str); + + attr_str = NULL; + awcscat(&attr_str, attr1_str); + awcscat(&attr_str, attr2_str); + free(attr1_str); + free(attr2_str); } -#if 0 + wchar_t *ansi_str; { - wchar_t *p = BuffGetCurrentLineDataW(ScreenY, NULL, NULL); - OutputDebugPrintfW(L"BuffGetCurrentLineDataW(%d)='%s'\n", Yw, p); - free(p); + unsigned char mb[4]; + unsigned short c = b->ansi_char; + if (c == 0) { + mb[0] = 0; + } + else if (c < 0x100) { + mb[0] = c < 0x20 ? '.' : (c & 0xff); + mb[1] = 0; + } + else { + mb[0] = ((c >> 8) & 0xff); + mb[1] = (c & 0xff); + mb[2] = 0; + } + + aswprintf(&ansi_str, + L"ansi:\n" + L" '%hs'\n" + L" 0x%04x\n", mb, c); } -#endif + wchar_t *unicode_str; + { + wchar_t *wcs = GetWCS(b); + wchar_t *codes_ptr; + int i; + size_t codes_len = 20 + 12 * (b->CombinationCharCount16 + 1); + codes_ptr = malloc(sizeof(wchar_t) * codes_len); + _snwprintf_s(codes_ptr, codes_len, _TRUNCATE, + L"unicode:\n" + L" '%s'\n" + L" U+%06x", + wcs, + b->u32); + for (i=0; i<b->CombinationCharCount32; i++) { + wchar_t *code_str; + aswprintf(&code_str, L" U+%06x", b->pCombinationChars16[i]); + wcscat_s(codes_ptr, codes_len, L"\n"); + wcscat_s(codes_ptr, codes_len, code_str); + free(code_str); + } + free(wcs); + unicode_str = codes_ptr; + } + UnlockBuffer(); + + str_ptr = NULL; + awcscat(&str_ptr, pos_str); + awcscat(&str_ptr, attr_str); + awcscat(&str_ptr, ansi_str); + awcscat(&str_ptr, unicode_str); + free(pos_str); + free(attr_str); + free(ansi_str); + free(unicode_str); + awcscat(&str_ptr, L"\n\nPress shift for sending to clipboard"); return str_ptr; } Modified: branches/unicode_buf_2/teraterm/teraterm/unicode.cpp =================================================================== --- branches/unicode_buf_2/teraterm/teraterm/unicode.cpp 2020-04-12 16:41:30 UTC (rev 8723) +++ branches/unicode_buf_2/teraterm/teraterm/unicode.cpp 2020-04-12 16:41:38 UTC (rev 8724) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 TeraTerm Project + * Copyright (C) 2019-2020 TeraTerm Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,10 +26,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#pragma warning(push, 0) #include <stdlib.h> #include <stdio.h> -#pragma warning(pop) #include "unicode.h" @@ -191,3 +189,76 @@ return 0; } #endif + +// +// Unicode Combining Character Support +// +#include "uni_combining.map" + +unsigned short UnicodeGetPrecomposedChar(int start_index, unsigned short first_code, unsigned short code) +{ + const combining_map_t *table = mapCombiningToPrecomposed; + int tmax = _countof(mapCombiningToPrecomposed); + unsigned short result = 0; + int i; + + for (i = start_index ; i < tmax ; i++) { + if (table[i].first_code != first_code) { // 1\x95\xB6\x8E\x9A\x96ڂ\xAA\x88قȂ\xE9\x82Ȃ\xE7\x81A\x88ȍ~\x82͂\xE0\x82\xA4\x92\xB2\x82ׂȂ\xAD\x82Ă悢\x81B + break; + } + + if (table[i].second_code == code) { + result = table[i].precomposed; + break; + } + } + + return (result); +} + +int UnicodeGetIndexOfCombiningFirstCode(unsigned short code) +{ + const combining_map_t *table = mapCombiningToPrecomposed; + int tmax = _countof(mapCombiningToPrecomposed); + int low, mid, high; + int index = -1; + + low = 0; + high = tmax - 1; + + // binary search + while (low < high) { + mid = (low + high) / 2; + if (table[mid].first_code < code) { + low = mid + 1; + } else { + high = mid; + } + } + + if (table[low].first_code == code) { + while (low >= 0 && table[low].first_code == code) { + index = low; + low--; + } + } + + return (index); +} + +/** + * Unicode\x82̌\x8B\x8D\x87\x8F\x88\x97\x9D\x82\xF0\x8Ds\x82\xA4 + * @param[in] first_code + * @param[in] code + * @retval 0 \x8C\x8B\x8D\x87\x82ł\xAB\x82Ȃ\xA2 + * @retval \x88ȊO \x8C\x8B\x8D\x87\x82\xB5\x82\xBDUnicode + */ +unsigned short UnicodeCombining(unsigned short first_code, unsigned short code) +{ + int first_code_index = UnicodeGetIndexOfCombiningFirstCode(first_code); + if (first_code_index == -1) { + return 0; + } + unsigned short cset = UnicodeGetPrecomposedChar(first_code_index, first_code, code); + return cset; +} Modified: branches/unicode_buf_2/teraterm/teraterm/unicode.h =================================================================== --- branches/unicode_buf_2/teraterm/teraterm/unicode.h 2020-04-12 16:41:30 UTC (rev 8723) +++ branches/unicode_buf_2/teraterm/teraterm/unicode.h 2020-04-12 16:41:38 UTC (rev 8724) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 TeraTerm Project + * Copyright (C) 2019-2020 TeraTerm Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,10 +30,13 @@ extern "C" { #endif +unsigned short UnicodeGetPrecomposedChar(int start_index, unsigned short first_code, unsigned short code); +int UnicodeGetIndexOfCombiningFirstCode(unsigned short code); char UnicodeGetWidthProperty(unsigned long u32); int UnicodeIsCombiningCharacter(unsigned long u32); int UnicodeIsVariationSelector(unsigned long u32); int UnicodeIsEmoji(unsigned long u32); +unsigned short UnicodeCombining(unsigned short first_code, unsigned short code); #ifdef __cplusplus } Modified: branches/unicode_buf_2/teraterm/teraterm/vtterm.c =================================================================== --- branches/unicode_buf_2/teraterm/teraterm/vtterm.c 2020-04-12 16:41:30 UTC (rev 8723) +++ branches/unicode_buf_2/teraterm/teraterm/vtterm.c 2020-04-12 16:41:38 UTC (rev 8724) @@ -64,7 +64,6 @@ void ParseFirst(BYTE b); -#define MAPSIZE(x) (sizeof(x)/sizeof((x)[0])) #define Accept8BitCtrl ((VTlevel >= 2) && (ts.TermFlag & TF_ACCEPT8BITCTRL)) /* Parsing modes */ @@ -5712,59 +5711,6 @@ } } -// -// Unicode Combining Character Support -// -#include "uni_combining.map" - -static unsigned short GetPrecomposedChar(int start_index, unsigned short first_code, unsigned short code, - const combining_map_t *table, int tmax) -{ - unsigned short result = 0; - int i; - - for (i = start_index ; i < tmax ; i++) { - if (table[i].first_code != first_code) { // 1\x95\xB6\x8E\x9A\x96ڂ\xAA\x88قȂ\xE9\x82Ȃ\xE7\x81A\x88ȍ~\x82͂\xE0\x82\xA4\x92\xB2\x82ׂȂ\xAD\x82Ă悢\x81B - break; - } - - if (table[i].second_code == code) { - result = table[i].precomposed; - break; - } - } - - return (result); -} - -static int GetIndexOfCombiningFirstCode(unsigned short code, const combining_map_t *table, int tmax) -{ - int low, mid, high; - int index = -1; - - low = 0; - high = tmax - 1; - - // binary search - while (low < high) { - mid = (low + high) / 2; - if (table[mid].first_code < code) { - low = mid + 1; - } else { - high = mid; - } - } - - if (table[low].first_code == code) { - while (low >= 0 && table[low].first_code == code) { - index = low; - low--; - } - } - - return (index); -} - // unicode(UTF-32,wchar_t)\x82\xF0\x83o\x83b\x83t\x83@\x82֏\x91\x82\xAB\x8D\x9E\x82\xDE // TODO @@ #if UNICODE_INTERNAL_BUFF @@ -6067,9 +6013,8 @@ if (proc_combining == 1) { if (can_combining == 0) { - if ((first_code_index = GetIndexOfCombiningFirstCode( - code, mapCombiningToPrecomposed, MAPSIZE(mapCombiningToPrecomposed) - )) != -1) { + first_code_index = UnicodeGetIndexOfCombiningFirstCode(code); + if (first_code_index != -1) { can_combining = 1; first_code = code; count = 0; @@ -6077,16 +6022,14 @@ } } else { can_combining = 0; - cset = GetPrecomposedChar(first_code_index, first_code, code, mapCombiningToPrecomposed, MAPSIZE(mapCombiningToPrecomposed)); + cset = UnicodeGetPrecomposedChar(first_code_index, first_code, code); if (cset != 0) { // success code = cset; } else { // error // 2\x82߂̕\xB6\x8E\x9A\x82\xAA\x94\xBC\x91\xF7\x93_\x82\xCC1\x95\xB6\x8E\x9A\x96ڂɑ\x8A\x93\x96\x82\xB7\x82\xE9\x8Fꍇ\x82́A\x8Dēx\x8C\x9F\x8D\xF5\x82𑱂\xAF\x82\xE9\x81B(2005.10.15 yutaka) - if ((first_code_index = GetIndexOfCombiningFirstCode( - code, mapCombiningToPrecomposed, MAPSIZE(mapCombiningToPrecomposed) - )) != -1) { - + first_code_index = UnicodeGetIndexOfCombiningFirstCode(code); + if (first_code_index != -1) { // 1\x82߂̕\xB6\x8E\x9A\x82͂\xBB\x82̂܂o\x97͂\xB7\x82\xE9 UnicodeToCP932(first_code); Modified: branches/unicode_buf_2/teraterm/teraterm/vtwin.cpp =================================================================== --- branches/unicode_buf_2/teraterm/teraterm/vtwin.cpp 2020-04-12 16:41:30 UTC (rev 8723) +++ branches/unicode_buf_2/teraterm/teraterm/vtwin.cpp 2020-04-12 16:41:38 UTC (rev 8724) @@ -2156,6 +2156,10 @@ wchar_t *buf = BuffGetCharInfo(pos.x, pos.y); CBSetTextW(HVTWin, buf, 0); free(buf); + MessageBeep(MB_OK); + TipWinDestroy(TipWinCodeDebug); + TipWinCodeDebug = NULL; + CtrlKeyState = 0; } #endif switch (KeyDown(HVTWin,nChar,nRepCnt,nFlags & 0x1ff)) {