Revision: 7810 https://osdn.net/projects/ttssh2/scm/svn/commits/7810 Author: zmatsuo Date: 2019-06-25 23:05:37 +0900 (Tue, 25 Jun 2019) Log Message: ----------- 内部バッファUnicode化テストブランチ Modified Paths: -------------- branches/unicode_buf/teraterm/common/tipwin.cpp branches/unicode_buf/teraterm/common/tipwin.h branches/unicode_buf/teraterm/common/ttlib.c branches/unicode_buf/teraterm/common/ttlib.h branches/unicode_buf/teraterm/teraterm/CMakeLists.txt branches/unicode_buf/teraterm/teraterm/buffer.c branches/unicode_buf/teraterm/teraterm/buffer.h branches/unicode_buf/teraterm/teraterm/ttermpro.v10.vcxproj branches/unicode_buf/teraterm/teraterm/ttermpro.v11.vcxproj branches/unicode_buf/teraterm/teraterm/ttermpro.v12.vcxproj branches/unicode_buf/teraterm/teraterm/ttermpro.v14.vcxproj branches/unicode_buf/teraterm/teraterm/ttermpro.v15.vcxproj branches/unicode_buf/teraterm/teraterm/ttermpro.v16.vcxproj branches/unicode_buf/teraterm/teraterm/ttermpro.v9.vcproj branches/unicode_buf/teraterm/teraterm/ttermpro.vcproj branches/unicode_buf/teraterm/teraterm/vtdisp.c branches/unicode_buf/teraterm/teraterm/vtdisp.h branches/unicode_buf/teraterm/teraterm/vtterm.c branches/unicode_buf/teraterm/teraterm/vtwin.cpp branches/unicode_buf/teraterm/ttpcmn/ttcmn.c Added Paths: ----------- branches/unicode_buf/teraterm/teraterm/unicode/ branches/unicode_buf/teraterm/teraterm/unicode/get_combine_table.md branches/unicode_buf/teraterm/teraterm/unicode/get_combine_table.pl branches/unicode_buf/teraterm/teraterm/unicode/get_f_w_a.md branches/unicode_buf/teraterm/teraterm/unicode/get_f_w_a.pl branches/unicode_buf/teraterm/teraterm/unicode.cpp branches/unicode_buf/teraterm/teraterm/unicode.h branches/unicode_buf/teraterm/teraterm/unicode_asian_width.tbl branches/unicode_buf/teraterm/teraterm/unicode_combine.tbl branches/unicode_buf/teraterm/teraterm/unicode_test.h -------------- next part -------------- Modified: branches/unicode_buf/teraterm/common/tipwin.cpp =================================================================== --- branches/unicode_buf/teraterm/common/tipwin.cpp 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/common/tipwin.cpp 2019-06-25 14:05:37 UTC (rev 7810) @@ -55,15 +55,24 @@ */ /* based on windows/sizetip.c from PuTTY 0.60 */ +#define UNICODE +#define _UNICODE + #include <windows.h> #include <stdio.h> #include <tchar.h> #include <assert.h> +#include <crtdbg.h> #include "ttlib.h" // for GetMessageboxFont() #include "tipwin.h" +#if defined(_DEBUG) && !defined(_CRTDBG_MAP_ALLOC) +#define malloc(l) _malloc_dbg((l), _NORMAL_BLOCK, __FILE__, __LINE__) +#define free(p) _free_dbg((p), _NORMAL_BLOCK) +#endif + #define FRAME_WIDTH 6 static ATOM tip_class = 0; @@ -246,7 +255,7 @@ GetMessageboxFont(&logfont); logfont.lfWidth = MulDiv(logfont.lfWidth, uDpi, 96); logfont.lfHeight = MulDiv(logfont.lfHeight, uDpi, 96); - pTipWin->tip_font = CreateFontIndirect(&logfont); + pTipWin->tip_font = CreateFontIndirectA(&logfont); CalcStrRect(pTipWin); pTipWin->hParentWnd = src; create_tipwin(pTipWin, hInst, cx, cy); @@ -257,18 +266,30 @@ return pTipWin; } -void TipWinSetPos(int x, int y) +void TipWinSetTextW(TipWin *tWin, const wchar_t *text) { + if (tWin != NULL) { + HWND tip_wnd = tWin->tip_wnd; + SetWindowTextW(tip_wnd, text); + } } -void TipWinSetText(TipWin *tWin, TCHAR *text) +void TipWinSetTextA(TipWin *tWin, const char *text) { if (tWin != NULL) { HWND tip_wnd = tWin->tip_wnd; - SetWindowText(tip_wnd, text); + SetWindowTextA(tip_wnd, text); } } +void TipWinSetPos(TipWin *tWin, int x, int y) +{ + if (tWin != NULL) { + HWND tip_wnd = tWin->tip_wnd; + SetWindowPos(tip_wnd, 0, x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); + } +} + void TipWinDestroy(TipWin *tWin) { if (tWin != NULL) { Modified: branches/unicode_buf/teraterm/common/tipwin.h =================================================================== --- branches/unicode_buf/teraterm/common/tipwin.h 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/common/tipwin.h 2019-06-25 14:05:37 UTC (rev 7810) @@ -1,3 +1,30 @@ +/* + * Copyright (C) 2018-2019 TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include <windows.h> #include <tchar.h> @@ -9,9 +36,18 @@ typedef struct tagTipWinData TipWin; TipWin *TipWinCreate(HWND src, int cx, int cy, const TCHAR *str); -void TipWinSetText(TipWin *tWin, TCHAR *text); +void TipWinSetTextW(TipWin *tWin, const wchar_t *text); +void TipWinSetTextA(TipWin *tWin, const char *text); +void TipWinSetPos(TipWin *tWin, int x, int y); void TipWinDestroy(TipWin *tWin); +#if defined(UNICODE) +#define TipWinSetText(p1, p2) TipWinSetTextW(p1, p2) +#else +#define TipWinSetText(p1, p2) TipWinSetTextA(p1, p2) +#endif + + #ifdef __cplusplus } #endif Modified: branches/unicode_buf/teraterm/common/ttlib.c =================================================================== --- branches/unicode_buf/teraterm/common/ttlib.c 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/common/ttlib.c 2019-06-25 14:05:37 UTC (rev 7810) @@ -44,6 +44,8 @@ #include "tttypes.h" #include "compat_win.h" +#include "../teraterm/unicode_test.h" + /* OS version with GetVersionEx(*1) dwMajorVersion dwMinorVersion dwPlatformId @@ -1086,7 +1088,7 @@ OutputDebugStringA(tmp); } -#if defined(UNICODE) +#if UNICODE_API // defined(UNICODE) void OutputDebugPrintfW(const wchar_t *fmt, ...) { wchar_t tmp[1024]; Modified: branches/unicode_buf/teraterm/common/ttlib.h =================================================================== --- branches/unicode_buf/teraterm/common/ttlib.h 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/common/ttlib.h 2019-06-25 14:05:37 UTC (rev 7810) @@ -85,6 +85,7 @@ int get_lang_font(PCHAR key, HWND dlg, PLOGFONT logfont, HFONT *font, const char *iniFile); DllExport BOOL doSelectFolder(HWND hWnd, char *path, int pathlen, const char *def, const char *msg); DllExport void OutputDebugPrintf(const char *fmt, ...); +DllExport void OutputDebugPrintfW(const wchar_t *fmt, ...); DllExport DWORD get_OPENFILENAME_SIZEA(); DllExport DWORD get_OPENFILENAME_SIZEW(); DllExport BOOL IsWindows95(); Modified: branches/unicode_buf/teraterm/teraterm/CMakeLists.txt =================================================================== --- branches/unicode_buf/teraterm/teraterm/CMakeLists.txt 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/CMakeLists.txt 2019-06-25 14:05:37 UTC (rev 7810) @@ -140,6 +140,11 @@ # ${COMMON_SRC} ${TTDLG_SRC} + # + unicode.h + unicode.cpp + unicode_asian_width.tbl + unicode_combine.tbl ) include_directories( Modified: branches/unicode_buf/teraterm/teraterm/buffer.c =================================================================== --- branches/unicode_buf/teraterm/teraterm/buffer.c 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/buffer.c 2019-06-25 14:05:37 UTC (rev 7810) @@ -1,6 +1,6 @@ /* * Copyright (C) 1994-1998 T. Teranishi - * (C) 2004-2017 TeraTerm Project + * (C) 2004-2019 TeraTerm Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,11 +28,17 @@ */ /* TERATERM.EXE, scroll buffer routines */ +#undef UNICODE +#undef _UNICODE #include "teraterm.h" #include "tttypes.h" #include <string.h> #include <stdio.h> +#include <windows.h> +#include <crtdbg.h> +#include <mbstring.h> +#include <assert.h> #include "ttwinman.h" #include "teraprn.h" @@ -40,9 +46,38 @@ #include "clipboar.h" #include "telnet.h" #include "ttplug.h" /* TTPLUG */ +#include "codeconv.h" +#include "unicode.h" #include "buffer.h" +#ifdef _DEBUG +#define malloc(l) _malloc_dbg((l), _NORMAL_BLOCK, __FILE__, __LINE__) +#define realloc(p, l) _realloc_dbg((p), (l), _NORMAL_BLOCK, __FILE__, __LINE__) +#define free(p) _free_dbg((p), _NORMAL_BLOCK) +#endif + +#include "unicode_test.h" + +#if UNICODE_INTERNAL_BUFF + +typedef unsigned long char32_t; // C++11 + +// \x83o\x83b\x83t\x83@\x93\xE0\x82̔\xBC\x8Ap1\x95\xB6\x8E\x9A\x95\xAA\x82̏\xEE\x95\xF1 +typedef struct { + char32_t u32; + char32_t u32_last; + char WidthProperty; // 'W' or 'H' or 'A' + char CombinationCharCount16; + char CombinationCharSize16; + char CombinationCharCount32; + char CombinationCharSize32; + wchar_t *pCombinationChars16; + char32_t *pCombinationChars32; + wchar_t wc2[2]; +} buff_char_t; +#endif + // URL\x82\xF0\x8B\xAD\x92\xB2\x82\xB7\x82\xE9\x81i\x90莁\x83p\x83b\x83` 2005/4/2\x81j #define URL_EMPHASIS 1 @@ -80,6 +115,10 @@ static PCHAR AttrLine2; static PCHAR AttrLineFG; static PCHAR AttrLineBG; +#if UNICODE_INTERNAL_BUFF +static buff_char_t *CodeBuffW; +static buff_char_t *CodeLineW; +#endif static LONG LinePtr; static LONG BufferSize; static int NumOfLinesInBuff; @@ -94,10 +133,96 @@ static TCharAttr CurCharAttr; -HANDLE SaveBuff = NULL; -int SaveBuffX; -int SaveBuffY; +static char *SaveBuff = NULL; +static int SaveBuffX; +static int SaveBuffY; +#if UNICODE_INTERNAL_BUFF +static void BuffSetChar(buff_char_t *buff, char32_t u32, char property) +{ + size_t wstr_len; + buff_char_t *p = buff; + if (p->pCombinationChars16 != NULL) { + free(p->pCombinationChars16); + p->pCombinationChars16 = NULL; + } + p->CombinationCharCount16 = 0; + p->CombinationCharSize16 = 0; + if (p->pCombinationChars32 != NULL) { + free(p->pCombinationChars32); + p->pCombinationChars32 = NULL; + } + p->CombinationCharCount32 = 0; + p->CombinationCharSize32 = 0; + p->WidthProperty = property; + p->u32 = u32; + p->u32_last = u32; + wstr_len = UTF32ToUTF16(u32, &p->wc2[0], 2); + switch (wstr_len) { + case 0: + default: + p->wc2[0] = 0; + p->wc2[1] = 0; + break; + case 1: + p->wc2[1] = 0; + break; + case 2: + break; + } +} + +static void BuffAddChar(buff_char_t *buff, char32_t u32, char property) +{ + buff_char_t *p = buff; + assert(p->u32 != 0); + // \x8C\xE3\x82ɑ\xB1\x82\xAD\x95\xB6\x8E\x9A\x97̈\xE6\x82\xF0\x8Ag\x91傷\x82\xE9 + if (p->CombinationCharSize16 < p->CombinationCharCount16 + 2) { + size_t new_size = p->CombinationCharSize16; + new_size = new_size == 0 ? 5 : new_size * 2; + p->pCombinationChars16 = realloc(p->pCombinationChars16, sizeof(wchar_t) * new_size); + p->CombinationCharSize16 = (char)new_size; + } + if (p->CombinationCharSize32 < p->CombinationCharCount32 + 2) { + size_t new_size = p->CombinationCharSize32; + new_size = new_size == 0 ? 5 : new_size * 2; + p->pCombinationChars32 = realloc(p->pCombinationChars32, sizeof(char32_t) * new_size); + p->CombinationCharSize32 = (char)new_size; + } + + // UTF-32 + p->u32_last = u32; + p->pCombinationChars32[p->CombinationCharCount32] = u32; + p->CombinationCharCount32++; + + // UTF-16 + { + wchar_t *u16 = &p->pCombinationChars16[p->CombinationCharCount16]; + size_t wlen = UTF32ToUTF16(u32, u16, 2); + p->CombinationCharCount16 += (char)wlen; + } +} + +static void memcpyW(buff_char_t *dest, const buff_char_t *src, size_t count) +{ + memcpy(dest, src, count * sizeof(buff_char_t)); +} + +static void memsetW(buff_char_t *dest, wchar_t ch, size_t count) +{ + size_t i; + for (i=0; i<count; i++) { + BuffSetChar(dest, ch, 'H'); + dest++; + } +} + +static void memmoveW(buff_char_t *dest, const buff_char_t *src, size_t count) +{ + memmove(dest, src, count * sizeof(buff_char_t)); +} +#endif + LONG GetLinePtr(int Line) { LONG Ptr; @@ -135,6 +260,10 @@ PCHAR CodeDest, AttrDest, AttrDest2, AttrDestFG, AttrDestBG; LONG SrcPtr, DestPtr; WORD LockOld; +#if UNICODE_INTERNAL_BUFF + buff_char_t *CodeDestW; + buff_char_t *CodeWNew; +#endif if (Nx > BuffXMax) { Nx = BuffXMax; @@ -157,6 +286,9 @@ HAttr2New = NULL; HAttrFGNew = NULL; HAttrBGNew = NULL; +#if UNICODE_INTERNAL_BUFF + CodeWNew = NULL; +#endif if ((HCodeNew=GlobalAlloc(GMEM_MOVEABLE, NewSize)) == NULL || (CodeDest=GlobalLock(HCodeNew)) == NULL) { goto allocate_error; @@ -173,8 +305,16 @@ if ((HAttrBGNew=GlobalAlloc(GMEM_MOVEABLE, NewSize)) == NULL || (AttrDestBG=GlobalLock(HAttrBGNew)) == NULL) { goto allocate_error; } +#if UNICODE_INTERNAL_BUFF + CodeWNew = malloc(NewSize * sizeof(buff_char_t)); + CodeDestW = CodeWNew; +#endif memset(&CodeDest[0], 0x20, NewSize); +#if UNICODE_INTERNAL_BUFF + memset(&CodeDestW[0], 0, NewSize * sizeof(buff_char_t)); + memsetW(&CodeDestW[0], 0x20, NewSize); +#endif memset(&AttrDest[0], AttrDefault, NewSize); memset(&AttrDest2[0], AttrDefault, NewSize); memset(&AttrDestFG[0], AttrDefaultFG, NewSize); @@ -199,6 +339,9 @@ DestPtr = 0; for (i = 1 ; i <= NyCopy ; i++) { memcpy(&CodeDest[DestPtr],&CodeBuff[SrcPtr],NxCopy); +#if UNICODE_INTERNAL_BUFF + memcpyW(&CodeDestW[DestPtr],&CodeBuffW[SrcPtr],NxCopy); +#endif memcpy(&AttrDest[DestPtr],&AttrBuff[SrcPtr],NxCopy); memcpy(&AttrDest2[DestPtr],&AttrBuff2[SrcPtr],NxCopy); memcpy(&AttrDestFG[DestPtr],&AttrBuffFG[SrcPtr],NxCopy); @@ -240,6 +383,9 @@ HAttrBuff2 = HAttr2New; HAttrBuffFG = HAttrFGNew; HAttrBuffBG = HAttrBGNew; +#if UNICODE_INTERNAL_BUFF + CodeBuffW = CodeWNew; +#endif BufferSize = NewSize; NumOfLinesInBuff = Ny; BuffStartAbs = 0; @@ -262,6 +408,9 @@ AttrBuffFG = (PCHAR)GlobalLock(HAttrBuffFG); AttrBuffBG = (PCHAR)GlobalLock(HAttrBuffBG); CodeLine = CodeBuff; +#if UNICODE_INTERNAL_BUFF + CodeLineW = CodeBuffW; +#endif AttrLine = AttrBuff; AttrLine2 = AttrBuff2; AttrLineFG = AttrBuffFG; @@ -285,6 +434,9 @@ if (AttrDestFG) GlobalUnlock(HAttrFGNew); if (AttrDestBG) GlobalUnlock(HAttrBGNew); if (HCodeNew) GlobalFree(HCodeNew); +#if UNICODE_INTERNAL_BUFF + if (CodeWNew) free(CodeWNew); +#endif if (HAttrNew) GlobalFree(HAttrNew); if (HAttr2New) GlobalFree(HAttr2New); if (HAttrFGNew) GlobalFree(HAttrFGNew); @@ -332,7 +484,7 @@ StatusLine = 0; } -void NewLine(int Line) +static void NewLine(int Line) { LinePtr = GetLinePtr(Line); CodeLine = &CodeBuff[LinePtr]; @@ -340,6 +492,9 @@ AttrLine2 = &AttrBuff2[LinePtr]; AttrLineFG = &AttrBuffFG[LinePtr]; AttrLineBG = &AttrBuffBG[LinePtr]; +#if UNICODE_INTERNAL_BUFF + CodeLineW = &CodeBuffW[LinePtr]; +#endif } void LockBuffer() @@ -390,6 +545,12 @@ GlobalFree(HCodeBuff); HCodeBuff = NULL; } +#if UNICODE_INTERNAL_BUFF + if (CodeBuffW != NULL) { + free(CodeBuffW); + CodeBuffW = NULL; + } +#endif if (HAttrBuff!=NULL) { GlobalFree(HAttrBuff); HAttrBuff = NULL; @@ -496,11 +657,17 @@ SrcPtr = GetLinePtr(PageStart+NumOfLines-1); for (i=NumOfLines-1; i>=Bottom+1; i--) { memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns); +#if UNICODE_INTERNAL_BUFF + memcpyW(&(CodeBuffW[DestPtr]),&(CodeBuffW[SrcPtr]),NumOfColumns); +#endif memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns); memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns); memcpy(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns); memcpy(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns); memset(&(CodeBuff[SrcPtr]),0x20,NumOfColumns); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[SrcPtr]),0x20,NumOfColumns); +#endif memset(&(AttrBuff[SrcPtr]),AttrDefault,NumOfColumns); memset(&(AttrBuff2[SrcPtr]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns); memset(&(AttrBuffFG[SrcPtr]),CurCharAttr.Fore,NumOfColumns); @@ -512,6 +679,9 @@ } for (i = 1 ; i <= n ; i++) { memset(&CodeBuff[DestPtr],0x20,NumOfColumns); +#if UNICODE_INTERNAL_BUFF + memsetW(&CodeBuffW[DestPtr],0x20,NumOfColumns); +#endif memset(&AttrBuff[DestPtr],AttrDefault,NumOfColumns); memset(&AttrBuff2[DestPtr],CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns); memset(&AttrBuffFG[DestPtr],CurCharAttr.Fore,NumOfColumns); @@ -558,6 +728,9 @@ AttrLine2 = &AttrBuff2[LinePtr]; AttrLineFG = &AttrBuffFG[LinePtr]; AttrLineBG = &AttrBuffBG[LinePtr]; +#if UNICODE_INTERNAL_BUFF + CodeLineW = &CodeBuffW[LinePtr]; +#endif } void PrevLine() @@ -568,6 +741,9 @@ AttrLine2 = &AttrBuff2[LinePtr]; AttrLineFG = &AttrBuffFG[LinePtr]; AttrLineBG = &AttrBuffBG[LinePtr]; +#if UNICODE_INTERNAL_BUFF + CodeLineW = &CodeBuffW[LinePtr]; +#endif } void EraseKanji(int LR) @@ -604,17 +780,29 @@ pos = ptr + CursorLeftM-1; if (CursorLeftM>0 && (AttrBuff[pos] & AttrKanji)) { CodeBuff[pos] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[pos], 0x20, 'H'); +#endif AttrBuff[pos] &= ~AttrKanji; pos++; CodeBuff[pos] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[pos], 0x20, 'H'); +#endif AttrBuff[pos] &= ~AttrKanji; } pos = ptr + CursorRightM; if (CursorRightM < NumOfColumns-1 && (AttrBuff[pos] & AttrKanji)) { CodeBuff[pos] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[pos], 0x20, 'H'); +#endif AttrBuff[pos] &= ~AttrKanji; pos++; CodeBuff[pos] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[pos], 0x20, 'H'); +#endif AttrBuff[pos] &= ~AttrKanji; } ptr = NextLinePtr(ptr); @@ -638,6 +826,9 @@ if (CursorRightM < NumOfColumns-1 && (AttrLine[CursorRightM] & AttrKanji)) { CodeLine[CursorRightM+1] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeLineW[CursorRightM + 1], 0x20, 'H'); +#endif AttrLine[CursorRightM+1] &= ~AttrKanji; extr = 1; } @@ -649,6 +840,9 @@ if (MoveLen > 0) { memmove(&(CodeLine[CursorX+Count]), &(CodeLine[CursorX]), MoveLen); +#if UNICODE_INTERNAL_BUFF + memmoveW(&(CodeLineW[CursorX+Count]), &(CodeLineW[CursorX]), MoveLen); +#endif memmove(&(AttrLine[CursorX+Count]), &(AttrLine[CursorX]), MoveLen); memmove(&(AttrLine2[CursorX+Count]), &(AttrLine2[CursorX]), MoveLen); memmove(&(AttrLineFG[CursorX+Count]), &(AttrLineFG[CursorX]), MoveLen); @@ -655,6 +849,9 @@ memmove(&(AttrLineBG[CursorX+Count]), &(AttrLineBG[CursorX]), MoveLen); } memset(&(CodeLine[CursorX]), 0x20, Count); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeLineW[CursorX]), 0x20, Count); +#endif memset(&(AttrLine[CursorX]), AttrDefault, Count); memset(&(AttrLine2[CursorX]), CurCharAttr.Attr2 & Attr2ColorMask, Count); memset(&(AttrLineFG[CursorX]), CurCharAttr.Fore, Count); @@ -663,6 +860,9 @@ if ((AttrLine[CursorRightM] & AttrKanji) != 0) { /* then delete it */ CodeLine[CursorRightM] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeLineW[CursorRightM], 0x20, 'H'); +#endif AttrLine[CursorRightM] &= ~AttrKanji; } BuffUpdateRect(CursorX, CursorY, CursorRightM+extr, CursorY); @@ -687,6 +887,9 @@ } for (i = CursorY ; i <= YEnd ; i++) { memset(&(CodeBuff[TmpPtr+offset]),0x20,NumOfColumns-offset); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[TmpPtr+offset]),0x20,NumOfColumns-offset); +#endif memset(&(AttrBuff[TmpPtr+offset]),AttrDefault,NumOfColumns-offset); memset(&(AttrBuff2[TmpPtr+offset]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns-offset); memset(&(AttrBuffFG[TmpPtr+offset]),CurCharAttr.Fore,NumOfColumns-offset); @@ -722,6 +925,9 @@ offset = CursorX+1; } memset(&(CodeBuff[TmpPtr]),0x20,offset); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[TmpPtr]),0x20,offset); +#endif memset(&(AttrBuff[TmpPtr]),AttrDefault,offset); memset(&(AttrBuff2[TmpPtr]),CurCharAttr.Attr2 & Attr2ColorMask, offset); memset(&(AttrBuffFG[TmpPtr]),CurCharAttr.Fore,offset); @@ -756,6 +962,9 @@ linelen = CursorRightM - CursorLeftM + 1; for (i= YEnd-Count ; i>=CursorY ; i--) { memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen); +#if UNICODE_INTERNAL_BUFF + memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen); +#endif memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen); memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen); memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen); @@ -765,6 +974,9 @@ } for (i = 1 ; i <= Count ; i++) { memset(&(CodeBuff[DestPtr]), 0x20, linelen); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen); +#endif memset(&(AttrBuff[DestPtr]), AttrDefault, linelen); memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen); memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen); @@ -794,6 +1006,9 @@ NewLine(PageStart+CursorY); memset(&(CodeLine[XStart]),0x20,Count); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeLineW[XStart]),0x20,Count); +#endif memset(&(AttrLine[XStart]),AttrDefault,Count); memset(&(AttrLine2[XStart]),CurCharAttr.Attr2 & Attr2ColorMask, Count); memset(&(AttrLineFG[XStart]),CurCharAttr.Fore,Count); @@ -835,6 +1050,9 @@ linelen = CursorRightM - CursorLeftM + 1; for (i=CursorY ; i<= YEnd-Count ; i++) { memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen); +#if UNICODE_INTERNAL_BUFF + memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen); +#endif memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen); memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen); memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen); @@ -844,6 +1062,9 @@ } for (i = YEnd+1-Count ; i<=YEnd ; i++) { memset(&(CodeBuff[DestPtr]), 0x20, linelen); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen); +#endif memset(&(AttrBuff[DestPtr]), AttrDefault, linelen); memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen); memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen); @@ -875,6 +1096,9 @@ if (CursorRightM < NumOfColumns-1 && (AttrLine[CursorRightM] & AttrKanji)) { CodeLine[CursorRightM] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeLineW[CursorRightM], 0x20, 'H'); +#endif AttrLine[CursorRightM] &= ~AttrKanji; CodeLine[CursorRightM+1] = 0x20; AttrLine[CursorRightM+1] &= ~AttrKanji; @@ -888,6 +1112,9 @@ if (MoveLen > 0) { memmove(&(CodeLine[CursorX]), &(CodeLine[CursorX+Count]), MoveLen); +#if UNICODE_INTERNAL_BUFF + memmoveW(&(CodeLineW[CursorX]), &(CodeLineW[CursorX+Count]), MoveLen); +#endif memmove(&(AttrLine[CursorX]), &(AttrLine[CursorX+Count]), MoveLen); memmove(&(AttrLine2[CursorX]), &(AttrLine2[CursorX+Count]), MoveLen); memmove(&(AttrLineFG[CursorX]), &(AttrLineFG[CursorX+Count]), MoveLen); @@ -894,6 +1121,9 @@ memmove(&(AttrLineBG[CursorX]), &(AttrLineBG[CursorX+Count]), MoveLen); } memset(&(CodeLine[CursorX + MoveLen]), 0x20, Count); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeLineW[CursorX + MoveLen]), 0x20, Count); +#endif memset(&(AttrLine[CursorX + MoveLen]), AttrDefault, Count); memset(&(AttrLine2[CursorX + MoveLen]), CurCharAttr.Attr2 & Attr2ColorMask, Count); memset(&(AttrLineFG[CursorX + MoveLen]), CurCharAttr.Fore, Count); @@ -917,6 +1147,9 @@ Count = NumOfColumns-CursorX; } memset(&(CodeLine[CursorX]),0x20,Count); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeLineW[CursorX]),0x20,Count); +#endif memset(&(AttrLine[CursorX]),AttrDefault,Count); memset(&(AttrLine2[CursorX]),CurCharAttr.Attr2 & Attr2ColorMask, Count); memset(&(AttrLineFG[CursorX]),CurCharAttr.Fore,Count); @@ -935,6 +1168,9 @@ TmpPtr = GetLinePtr(PageStart); for (i = 0 ; i <= NumOfLines-1-StatusLine ; i++) { memset(&(CodeBuff[TmpPtr]),'E',NumOfColumns); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[TmpPtr]),'E',NumOfColumns); +#endif memset(&(AttrBuff[TmpPtr]),AttrDefault,NumOfColumns); memset(&(AttrBuff2[TmpPtr]),AttrDefault,NumOfColumns); memset(&(AttrBuffFG[TmpPtr]),AttrDefaultFG,NumOfColumns); @@ -974,6 +1210,9 @@ } Ptr = GetLinePtr(PageStart+Y); memset(&(CodeBuff[Ptr+CursorX]),'q',C); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[Ptr+CursorX]),'q',C); +#endif memset(&(AttrBuff[Ptr+CursorX]),Attr.Attr,C); memset(&(AttrBuff2[Ptr+CursorX]),Attr.Attr2,C); memset(&(AttrBuffFG[Ptr+CursorX]),Attr.Fore,C); @@ -1002,6 +1241,9 @@ } for (i=1; i<=C; i++) { CodeBuff[Ptr+X] = 'x'; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[Ptr+X], 0x20, 'H'); +#endif AttrBuff[Ptr+X] = Attr.Attr; AttrBuff2[Ptr+X] = Attr.Attr2; AttrBuffFG[Ptr+X] = Attr.Fore; @@ -1037,6 +1279,9 @@ if ((XStart>0) && ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) { CodeBuff[Ptr+XStart-1] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[Ptr+XStart-1], 0x20, 'H'); +#endif AttrBuff[Ptr+XStart-1] = CurCharAttr.Attr; AttrBuff2[Ptr+XStart-1] = CurCharAttr.Attr2; AttrBuffFG[Ptr+XStart-1] = CurCharAttr.Fore; @@ -1045,6 +1290,9 @@ if ((XStart+C<NumOfColumns) && ((AttrBuff[Ptr+XStart+C-1] & AttrKanji) != 0)) { CodeBuff[Ptr+XStart+C] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[Ptr+XStart+C], 0x20, 'H'); +#endif AttrBuff[Ptr+XStart+C] = CurCharAttr.Attr; AttrBuff2[Ptr+XStart+C] = CurCharAttr.Attr2; AttrBuffFG[Ptr+XStart+C] = CurCharAttr.Fore; @@ -1051,6 +1299,9 @@ AttrBuffBG[Ptr+XStart+C] = CurCharAttr.Back; } memset(&(CodeBuff[Ptr+XStart]),0x20,C); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[Ptr+XStart]),0x20,C); +#endif memset(&(AttrBuff[Ptr+XStart]),AttrDefault,C); memset(&(AttrBuff2[Ptr+XStart]),CurCharAttr.Attr2 & Attr2ColorMask, C); memset(&(AttrBuffFG[Ptr+XStart]),CurCharAttr.Fore,C); @@ -1083,13 +1334,22 @@ if ((XStart>0) && ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) { CodeBuff[Ptr+XStart-1] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeLineW[Ptr + XStart - 1], 0x20, 'H'); +#endif AttrBuff[Ptr+XStart-1] ^= AttrKanji; } if ((XStart+Cols<NumOfColumns) && ((AttrBuff[Ptr+XStart+Cols-1] & AttrKanji) != 0)) { CodeBuff[Ptr+XStart+Cols] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeLineW[Ptr + XStart + Cols], 0x20, 'H'); +#endif } memset(&(CodeBuff[Ptr+XStart]), ch, Cols); +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeLineW[Ptr + XStart], 0x20, 'H'); +#endif memset(&(AttrBuff[Ptr+XStart]), CurCharAttr.Attr, Cols); memset(&(AttrBuff2[Ptr+XStart]), CurCharAttr.Attr2, Cols); memset(&(AttrBuffFG[Ptr+XStart]), CurCharAttr.Fore, Cols); @@ -1145,6 +1405,9 @@ DPtr = GetLinePtr(PageStart+DstY); for (i=0; i<L; i++) { memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C); +#if UNICODE_INTERNAL_BUFF + memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C); +#endif memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C); memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C); memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C); @@ -1158,6 +1421,9 @@ DPtr = GetLinePtr(PageStart+DstY+L-1); for (i=L; i>0; i--) { memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C); +#if UNICODE_INTERNAL_BUFF + memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C); +#endif memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C); memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C); memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C); @@ -1171,6 +1437,9 @@ DPtr = GetLinePtr(PageStart+DstY); for (i=0; i<L; i++) { memmove(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C); +#if UNICODE_INTERNAL_BUFF + memmoveW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C); +#endif memmove(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C); memmove(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C); memmove(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C); @@ -1386,7 +1655,7 @@ BuffUpdateRect(0, YStart, NumOfColumns-1, YEnd); } -int LeftHalfOfDBCS(LONG Line, int CharPtr) +static int LeftHalfOfDBCS(LONG Line, int CharPtr) // If CharPtr is on the right half of a DBCS character, // return pointer to the left half // Line: points to a line in CodeBuff @@ -1400,7 +1669,7 @@ return CharPtr; } -int MoveCharPtr(LONG Line, int *x, int dx) +static int MoveCharPtr(LONG Line, int *x, int dx) // move character pointer x by dx character unit // in the line specified by Line // Line: points to a line in CodeBuff @@ -2002,6 +2271,242 @@ } } +/** + * \x83\x86\x83j\x83R\x81[\x83h\x83L\x83\x83\x83\x89\x83N\x83^\x82\xF01\x95\xB6\x8E\x9A\x83o\x83b\x83t\x83@\x82֓\xFC\x97͂\xB7\x82\xE9 + * @param[in] uc unicode character + * @param[in] Attr attributes + * @param[in] Insert Insert flag + */ +#if UNICODE_INTERNAL_BUFF +char BuffPutUnicode(unsigned int uc, TCharAttr Attr, BOOL Insert) +{ +// int XStart, LineEnd, MoveLen; +// int extr = 0; +// unsigned int w = uc; + int ret; +// wchar_t wchar = (wchar_t)uc; + BYTE b1, b2; + unsigned int u32 = uc; + char retval = 'h'; + BOOL half_width = TRUE; + + if (uc < 0x80) { + b1 = (BYTE)uc; + b2 = 0; + ret = 1; + } else { + char mbchar[2]; + ret = UTF32ToCP932(uc, mbchar, 2); + if (ret == 0) { + b1 = '?'; + b2 = 0; + ret = 1; + } else if (ret == 1) { + b1 = mbchar[0]; + b2 = 0; + } else { // ret == 2 + b1 = mbchar[0]; + b2 = mbchar[1]; + ret = 2; + } + } + +#if 0 + OutputDebugPrintf("BuffPutUnicode(%06x(%02x,%02x)\n", + uc, b1, b2); +#endif + + if (ts.EnableContinuedLineCopy && CursorX == 0 && (AttrLine[0] & AttrLineContinued)) { + Attr.Attr |= AttrLineContinued; + } + + if (Insert) { + assert(FALSE); +#if 0 + if (CursorX > CursorRightM) + LineEnd = NumOfColumns - 1; + else + LineEnd = CursorRightM; + + if (LineEnd < NumOfColumns - 1 && (AttrLine[LineEnd] & AttrKanji)) { + CodeLine[LineEnd] = 0x20; + CodeLineW[LineEnd].wc = 0x20; + CodeLineW[LineEnd].u32 = 0x20; + AttrLine[LineEnd] &= ~AttrKanji; + CodeLine[LineEnd+1] = 0x20; + AttrLine[LineEnd+1] &= ~AttrKanji; + extr = 1; + } + + MoveLen = LineEnd - CursorX - 1; + if (MoveLen > 0) { + memmove(&CodeLine[CursorX+2], &CodeLine[CursorX], MoveLen); + memmove(&CodeLineW[CursorX+2], &CodeLineW[CursorX], MoveLen * sizeof(wchar_t)); + memmove(&AttrLine[CursorX+2], &AttrLine[CursorX], MoveLen); + memmove(&AttrLine2[CursorX+2], &AttrLine2[CursorX], MoveLen); + memmove(&AttrLineFG[CursorX+2], &AttrLineFG[CursorX], MoveLen); + memmove(&AttrLineBG[CursorX+2], &AttrLineBG[CursorX], MoveLen); + } + + if (HIBYTE(w) == 0) { + int a = 0; + } + CodeLine[CursorX] = HIBYTE(w); + CodeLineW[CursorX].wc = u16_high; + CodeLineW[CursorX].u32 = u32; + AttrLine[CursorX] = Attr.Attr; + AttrLine2[CursorX] = Attr.Attr2; + AttrLineFG[CursorX] = Attr.Fore; + AttrLineBG[CursorX] = Attr.Back; + if (CursorX < LineEnd) { + CodeLine[CursorX+1] = LOBYTE(w); + CodeLineW[CursorX + 1].wc = u16_low; + CodeLineW[CursorX + 1].u32 = 0; + // CodeLineW[CursorX+1] = 0; + AttrLine[CursorX+1] = Attr.Attr; + AttrLine2[CursorX+1] = Attr.Attr2; + AttrLineFG[CursorX+1] = Attr.Fore; + AttrLineBG[CursorX+1] = Attr.Back; + } + /* begin - ishizaki */ + markURL(CursorX); + markURL(CursorX+1); + /* end - ishizaki */ + + /* last char in current line is kanji first? */ + if ((AttrLine[LineEnd] & AttrKanji) != 0) { + /* then delete it */ + CodeLine[LineEnd] = 0x20; + BuffSetChar(&CodeLineW[LineEnd], 0x20, 'H'); + AttrLine[LineEnd] = CurCharAttr.Attr; + AttrLine2[LineEnd] = CurCharAttr.Attr2; + AttrLineFG[LineEnd] = CurCharAttr.Fore; + AttrLineBG[LineEnd] = CurCharAttr.Back; + } + + if (StrChangeCount==0) { + XStart = CursorX; + } + else { + XStart = StrChangeStart; + } + StrChangeCount = 0; + BuffUpdateRect(XStart, CursorY, LineEnd+extr, CursorY); +#endif + } else { + buff_char_t *p; + + if (UnicodeIsVariationSelector(u32)) { + retval = 'V'; + } else if (UnicodeIsCombiningCharacter(u32)) { + retval = '0'; + } else if (u32 == 0x200d) { + retval = '0'; + } else { + retval = UnicodeGetWidthProperty(u32); + half_width = (retval == 'H') ? TRUE : FALSE; + } + + // \x91O\x82̕\xB6\x8E\x9A + p = NULL; // NULL\x82̂Ƃ\xAB\x81A\x91O\x82̕\xB6\x8E\x9A\x82͂Ȃ\xA2 + if (CursorX >= 1 && CodeLineW[CursorX - 1].u32 != 0) { + p = &CodeLineW[CursorX - 1]; + } else if (CursorX >= 2 && CodeLineW[CursorX - 2].u32 != 0) { + p = &CodeLineW[CursorX - 2]; + } + if (p != NULL && p->u32_last == 0x200d) { + retval = '0'; + } + + if (retval == 'V' || retval == '0') { + // \x91O\x82̕\xB6\x8E\x9A\x82ɂ\xAD\x82\xC1\x82\xAF\x82\xE9 + // VariationSelector or + // CombiningCharacter or + // ZERO WIDTH JOINER(ZWJ) + + if (p != NULL) { + // \x91O\x82̕\xB6\x8E\x9A\x82ɂ\xAD\x82\xC1\x82\xAF\x82\xE9 + BuffAddChar(p, uc, retval); + AttrLine[CursorX] = Attr.Attr; // | AttrKanji; /* DBCS first byte */ + AttrLine2[CursorX] = Attr.Attr2; + AttrLineFG[CursorX] = Attr.Fore; + AttrLineBG[CursorX] = Attr.Back; + } else { + // \x91O\x82\xAA\x82Ȃ\xA2\x82̂ɂ\xAD\x82\xC1\x82\xAD\x95\xB6\x8E\x9A\x82\xAA\x8Fo\x82Ă\xAB\x82\xBD\x82Ƃ\xAB + // \x82Ƃ肠\x82\xA6\x82\xB8\x83X\x83y\x81[\x83X\x82ɂ\xAD\x82\xC1\x82\xAF\x82\xE9 + p = &CodeLineW[CursorX]; + BuffSetChar(p, ' ', 'H'); + BuffAddChar(p, uc, retval); + AttrLine[CursorX] = Attr.Attr; + AttrLine2[CursorX] = Attr.Attr2; + AttrLineFG[CursorX] = Attr.Fore; + AttrLineBG[CursorX] = Attr.Back; + } + } else { + // \x90V\x82\xB5\x82\xA2\x95\xB6\x8E\x9A\x92lj\xC1 + CodeLine[CursorX] = b1; + BuffSetChar(&CodeLineW[CursorX], u32, retval); + AttrLine[CursorX] = Attr.Attr; // | AttrKanji; /* DBCS first byte */ + AttrLine2[CursorX] = Attr.Attr2; + AttrLineFG[CursorX] = Attr.Fore; + AttrLineBG[CursorX] = Attr.Back; + + if (!half_width) { + // \x91S\x8Ap\x82̎\x9E\x82͎\x9F\x82̕\xB6\x8E\x9A\x83R\x81[\x83h\x82\xC90\x82\xF0\x93\xFC\x82\xEA\x82\xE9 + if (CursorX < NumOfColumns-1) { + BuffSetChar(&CodeLineW[CursorX+1], 0, 'H'); + CodeLine[CursorX+1] = b2; + AttrLine[CursorX+1] = Attr.Attr; + AttrLine2[CursorX+1] = Attr.Attr2; + AttrLineFG[CursorX+1] = Attr.Fore; + AttrLineBG[CursorX+1] = Attr.Back; + } + } + } + + /* begin - ishizaki */ +// markURL(CursorX); +// markURL(CursorX+1); + /* end - ishizaki */ + + if (StrChangeCount==0) { + StrChangeStart = CursorX; + } + if (retval == '0' || retval == 'V') { + if (StrChangeCount == 0) { + StrChangeCount = 1; + } + } else if (retval == 'H') { + // \x94\xBC\x8Ap + StrChangeCount = StrChangeCount + 1; + } else if (retval == 'A') { + // \x93\xC1\x90\xAB\x92lA(\x9EB\x96\x86)\x82\xF0\x8E\x9D\x82\xB6\x8E\x9A\x82́A\x91S\x8Ap\x82̕\xB6\x8E\x9A (fullwidth) \x82Ƃ\xB5\x82Ĉ\xB5\x82\xA4\x81B + StrChangeCount = StrChangeCount + 2; + } else { + // \x91S\x8Ap ('F' or 'W') + StrChangeCount = StrChangeCount + 2; + } +#if 0 + { + char ba[128]; + memcpy(ba, &CodeLine[0], _countof(ba)-1); + ba[127] = 0; + OutputDebugPrintf("A '%s'\n", ba); + wchar_t bb[128]; + memcpy(bb, &CodeLineW[0], _countof(bb)-1); + bb[127] = 0; + OutputDebugPrintfW(L"W '%s'\n", bb); + } +#endif + } + +#if 0 + OutputDebugPrintf("BuffPutUnicode leave\n"); +#endif + return retval; +} +#endif + BOOL CheckSelect(int x, int y) // subroutine called by BuffUpdateRect { @@ -2024,6 +2529,143 @@ } } +#if UNICODE_INTERNAL_BUFF +/* + * DrawX,Y Clint\x97̈\xE6\x95`\x89\xE6\x88ʒu(pixel) + * SY \x83X\x83N\x83\x8A\x81[\x83\x93\x8F\xE3\x82̈ʒu(Charactor) + * PageStart + YStart \x82Ȃ\xC7 + * IStart,IEnd \x83X\x83N\x83\x8A\x81[\x83\x93\x8F\xE3\x82̈ʒu(Charactor) + */ +static void BuffDrawLineI(int DrawX, int DrawY, int SY, int IStart, int IEnd) +{ + int X = DrawX; + int Y = DrawY; + const LONG TmpPtr = GetLinePtr(SY); + int istart = IStart; + char bufA[TermWidthMax]; + wchar_t bufW[TermWidthMax]; + char bufWW[TermWidthMax]; + int lenW = 0; + int lenA = 0; + TCharAttr CurAttr; + BOOL ConbinationCharInclude = FALSE; + + int count = 0; // index; + while (istart + count <= IEnd) { + buff_char_t *b; + TCharAttr TempAttr; + BOOL DrawFlag = FALSE; + BOOL Conbination = FALSE; + + // \x83A\x83g\x83\x8A\x83r\x83\x85\x81[\x83g\x8E擾 + TempAttr.Attr = AttrBuff[TmpPtr+istart+count] & ~ AttrKanji; + TempAttr.Attr2 = AttrBuff2[TmpPtr+istart+count]; + TempAttr.Fore = AttrBuffFG[TmpPtr+istart+count]; + TempAttr.Back = AttrBuffBG[TmpPtr+istart+count]; + + bufA[lenA] = CodeBuff[TmpPtr + istart + count]; + lenA++; + + b = &CodeBuffW[TmpPtr + istart + count]; + if (b->u32 != 0) { + if (b->u32 < 0x10000) { + bufW[lenW] = b->wc2[0]; + bufWW[lenW] = b->WidthProperty; + lenW++; + } else { + bufW[lenW] = b->wc2[0]; + bufWW[lenW] = b->WidthProperty; + lenW++; + bufW[lenW] = b->wc2[1]; + bufWW[lenW] = '0'; + lenW++; + Conbination = TRUE; + DrawFlag = TRUE; + } + if ((b->WidthProperty == 'W' || b->WidthProperty == 'H') && + b->CombinationCharCount16 != 0) + { + int i; + for (i = 0 ; i < (int)b->CombinationCharCount16; i++) { + bufW[lenW+i] = b->pCombinationChars16[i]; + bufWW[lenW + i] = '0'; + } + lenW += b->CombinationCharCount16; + Conbination = TRUE; + DrawFlag = TRUE; + } + } + + if (count == 0) { + // \x8Dŏ\x89\x82\xCC1\x95\xB6\x8E\x9A\x96\xDA + CurAttr = TempAttr; + } + + if (DrawFlag) { + ; + } else if (istart + count == IEnd) { + // \x8DŌ\xE3\x82܂ŃX\x83L\x83\x83\x83\x93\x82\xB5\x82\xBD + DrawFlag = TRUE; + } else if (b->u32 != 0) { + // \x8E\x9F\x82̕\xB6\x8E\x9A\x82ŃA\x83g\x83\x8A\x83r\x83\x85\x81[\x83g\x82\xAA\x95ω\xBB\x82\xB7\x82\xE9? + if (count > 0 && TCharAttrCmp(CurAttr, TempAttr) != 0) { + // \x83A\x83g\x83\x8A\x83r\x83\x85\x81[\x83g\x82\xAA\x95ω\xBB\x82\xB5\x82\xBD + DrawFlag = TRUE; + lenA--; + lenW--; + } else if ((b->WidthProperty == 'W' || b->WidthProperty == 'H' ) + && b->CombinationCharCount16 != 0) + { + // \x83A\x83g\x83\x8A\x83r\x83\x85\x81[\x83g(unicode\x8F\xF3\x91\xD4)\x82\xAA\x95ω\xBB\x82\xB5\x82\xBD + DrawFlag = TRUE; + lenA--; + lenW--; + } else { + if (Conbination == FALSE) { + if (ConbinationCharInclude) { + // not \x8C\x8B\x8D\x87\x95\xB6\x8E\x9A && \x8C\x8B\x8D\x87\x95\xB6\x8E\x9A\x97\xF1? + DrawFlag = TRUE; + lenA--; + lenW--; + } + } + else { + ConbinationCharInclude = TRUE; + } + } + } + + if (DrawFlag) { + // \x95`\x89悷\x82\xE9 + bufA[lenA] = 0; + bufW[lenW] = 0; + bufWW[lenW] = 0; + +#if 0 + OutputDebugPrintf("A[%d] '%s'\n", lenA, bufA); + OutputDebugPrintfW(L"W[%d] '%s'\n", lenW, bufW); +#endif + + DispSetupDC(CurAttr, FALSE); +#if UNICODE_INTERNAL_BUFF && UNICODE_DISPLAY + DispStrW(bufW, bufWW, lenW, Y, &X); +#else + DispStr(bufA, lenA, Y, &X); +#endif + + lenA = 0; + lenW = 0; + DrawFlag = FALSE; + istart += (count+1); + count = 0; + ConbinationCharInclude = FALSE; + } else { + count++; + } + } +} +#endif + void BuffUpdateRect (int XStart, int YStart, int XEnd, int YEnd) // Display text in a rectangular region in the screen @@ -2036,8 +2678,18 @@ int IStart, IEnd; int X, Y; LONG TmpPtr; - TCharAttr CurAttr, TempAttr; - BOOL CurSel, TempSel, Caret; + TCharAttr TempAttr; +#if !UNICODE_INTERNAL_BUFF + TCharAttr CurAttr; + BOOL CurSel; +#endif + BOOL TempSel, Caret; +#if UNICODE_INTERNAL_BUFF +// char bufA[256]; +// wchar_t bufW[256]; +// int lenW = 0; +// int lenA = 0; +#endif if (XStart >= WinOrgX+WinWidth) { return; @@ -2065,6 +2717,13 @@ YEnd = WinOrgY+WinHeight-1; } +#if 0 + OutputDebugPrintf("BuffUpdateRect (%d,%d)-(%d,%d) [%d,%d]\n", + XStart, YStart, + XEnd, YEnd, + XEnd - XStart + 1, YEnd - YStart + 1); +#endif + TempAttr = DefCharAttr; TempSel = FALSE; @@ -2086,6 +2745,7 @@ X = (IStart-WinOrgX)*FontWidth; i = IStart; +#if !UNICODE_INTERNAL_BUFF do { CurAttr.Attr = AttrBuff[TmpPtr+i] & ~ AttrKanji; CurAttr.Attr2 = AttrBuff2[TmpPtr+i]; @@ -2113,6 +2773,11 @@ i = i+count; } while (i<=IEnd); +#else + { + BuffDrawLineI(X, Y, j, IStart, IEnd); + } +#endif Y = Y + FontHeight; TmpPtr = NextLinePtr(TmpPtr); } @@ -2125,7 +2790,9 @@ // Display not-yet-displayed string { int X, Y; +#if !UNICODE_INTERNAL_BUFF TCharAttr TempAttr; +#endif int pos, len; if (StrChangeCount==0) { @@ -2138,6 +2805,7 @@ return; } +#if !UNICODE_INTERNAL_BUFF TempAttr.Attr = AttrLine[StrChangeStart]; TempAttr.Attr2 = AttrLine2[StrChangeStart]; TempAttr.Fore = AttrLineFG[StrChangeStart]; @@ -2172,7 +2840,9 @@ DispSetupDC(TempAttr, FALSE); DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X); } - +#else + BuffDrawLineI(X, Y, PageStart+CursorY, StrChangeStart, StrChangeStart + StrChangeCount - 1); +#endif StrChangeCount = 0; } @@ -2261,6 +2931,9 @@ for (i = CursorBottom-1 ; i >= CursorTop ; i--) { SrcPtr = PrevLinePtr(DestPtr); memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen); +#if UNICODE_INTERNAL_BUFF + memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen); +#endif memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen); memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen); memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen); @@ -2268,6 +2941,9 @@ DestPtr = SrcPtr; } memset(&(CodeBuff[SrcPtr]), 0x20, linelen); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[SrcPtr]), 0x20, linelen); +#endif memset(&(AttrBuff[SrcPtr]), AttrDefault, linelen); memset(&(AttrBuff2[SrcPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen); memset(&(AttrBuffFG[SrcPtr]), CurCharAttr.Fore, linelen); @@ -2332,6 +3008,9 @@ SrcPtr = GetLinePtr(PageStart+CursorTop+n) + (LONG)CursorLeftM; for (i = CursorTop+n ; i<=CursorBottom ; i++) { memmove(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen); +#if UNICODE_INTERNAL_BUFF + memmoveW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen); +#endif memmove(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen); memmove(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen); memmove(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen); @@ -2345,6 +3024,9 @@ } for (i = CursorBottom+1-n ; i<=CursorBottom; i++) { memset(&(CodeBuff[DestPtr]), 0x20, linelen); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen); +#endif memset(&(AttrBuff[DestPtr]), AttrDefault, linelen); memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen); memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen); @@ -2393,6 +3075,9 @@ SrcPtr = GetLinePtr(PageStart+CursorTop+n) + CursorLeftM; for (i = CursorTop+n ; i<=CursorBottom ; i++) { memmove(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen); +#if UNICODE_INTERNAL_BUFF + memmoveW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen); +#endif memmove(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen); memmove(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen); memmove(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen); @@ -2406,6 +3091,9 @@ } for (i = CursorBottom+1-n ; i<=CursorBottom; i++) { memset(&(CodeBuff[DestPtr]), 0x20, linelen); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen); +#endif memset(&(AttrBuff[DestPtr]), AttrDefault, linelen); memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen); memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen); @@ -2445,6 +3133,9 @@ SrcPtr = GetLinePtr(PageStart+CursorBottom-n) + CursorLeftM; for (i=CursorBottom-n ; i>=CursorTop ; i--) { memmove(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen); +#if UNICODE_INTERNAL_BUFF + memmoveW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen); +#endif memmove(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen); memmove(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen); memmove(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen); @@ -2458,6 +3149,9 @@ } for (i = CursorTop+n-1; i>=CursorTop; i--) { memset(&(CodeBuff[DestPtr]), 0x20, linelen); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen); +#endif memset(&(AttrBuff[DestPtr]), AttrDefault, linelen); memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen); memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen); @@ -2505,7 +3199,7 @@ // called by BuffDblClk // check if a character is the word delimiter -BOOL IsDelimiter(LONG Line, int CharPtr) +static BOOL IsDelimiter(LONG Line, int CharPtr) { if ((AttrBuff[Line+CharPtr] & AttrKanji) !=0) { return (ts.DelimDBCS!=0); @@ -3473,6 +4167,9 @@ NewLine(0); memset(&CodeBuff[0],0x20,BufferSize); +#if UNICODE_INTERNAL_BUFF + memsetW(&CodeBuffW[0],0x20,BufferSize); +#endif memset(&AttrBuff[0],AttrDefault,BufferSize); memset(&AttrBuff2[0],CurCharAttr.Attr2 & Attr2ColorMask, BufferSize); memset(&AttrBuffFG[0],CurCharAttr.Fore,BufferSize); @@ -3697,93 +4394,119 @@ void BuffSaveScreen() { PCHAR CodeDest, AttrDest, AttrDest2, AttrDestFG, AttrDestBG; +#if UNICODE_INTERNAL_BUFF + buff_char_t *CodeDestW; +#endif LONG ScrSize; + size_t AllocSize; LONG SrcPtr, DestPtr; int i; if (SaveBuff == NULL) { - ScrSize = NumOfColumns * NumOfLines; - if ((SaveBuff=GlobalAlloc(GMEM_MOVEABLE, ScrSize * 5)) != NULL) { - if ((CodeDest=GlobalLock(SaveBuff)) != NULL) { - AttrDest = CodeDest + ScrSize; - AttrDest2 = AttrDest + ScrSize; - AttrDestFG = AttrDest2 + ScrSize; - AttrDestBG = AttrDestFG + ScrSize; + ScrSize = NumOfColumns * NumOfLines; // 1\x89\xE6\x96ʕ\xAA\x82̃o\x83b\x83t\x83@\x82̕ۑ\xB6\x90\x94 +#if UNICODE_INTERNAL_BUFF + // \x91S\x89\xE6\x96ʕ\xAA\x82̃o\x83C\x83g\x90\x94 + AllocSize = ScrSize * (5+sizeof(buff_char_t)); +#else + AllocSize = ScrSize * 5; +#endif + SaveBuff = malloc(AllocSize); + if (SaveBuff != NULL) { + CodeDest = SaveBuff; + AttrDest = CodeDest + ScrSize; + AttrDest2 = AttrDest + ScrSize; + AttrDestFG = AttrDest2 + ScrSize; + AttrDestBG = AttrDestFG + ScrSize; +#if UNICODE_INTERNAL_BUFF + CodeDestW = (buff_char_t *)(AttrDestBG + ScrSize); +#endif - SaveBuffX = NumOfColumns; - SaveBuffY = NumOfLines; + SaveBuffX = NumOfColumns; + SaveBuffY = NumOfLines; - SrcPtr = GetLinePtr(PageStart); - DestPtr = 0; + SrcPtr = GetLinePtr(PageStart); + DestPtr = 0; - for (i=0; i<NumOfLines; i++) { - memcpy(&CodeDest[DestPtr], &CodeBuff[SrcPtr], NumOfColumns); - memcpy(&AttrDest[DestPtr], &AttrBuff[SrcPtr], NumOfColumns); - memcpy(&AttrDest2[DestPtr], &AttrBuff2[SrcPtr], NumOfColumns); - memcpy(&AttrDestFG[DestPtr], &AttrBuffFG[SrcPtr], NumOfColumns); - memcpy(&AttrDestBG[DestPtr], &AttrBuffBG[SrcPtr], NumOfColumns); - SrcPtr = NextLinePtr(SrcPtr); - DestPtr += NumOfColumns; - } + for (i=0; i<NumOfLines; i++) { + memcpy(&CodeDest[DestPtr], &CodeBuff[SrcPtr], NumOfColumns); +#if UNICODE_INTERNAL_BUFF + memcpyW(&CodeDestW[DestPtr], &CodeBuffW[SrcPtr], NumOfColumns); +#endif + memcpy(&AttrDest[DestPtr], &AttrBuff[SrcPtr], NumOfColumns); + memcpy(&AttrDest2[DestPtr], &AttrBuff2[SrcPtr], NumOfColumns); + memcpy(&AttrDestFG[DestPtr], &AttrBuffFG[SrcPtr], NumOfColumns); + memcpy(&AttrDestBG[DestPtr], &AttrBuffBG[SrcPtr], NumOfColumns); + SrcPtr = NextLinePtr(SrcPtr); + DestPtr += NumOfColumns; } - else { - GlobalFree(SaveBuff); - SaveBuff = NULL; - } } } - return; + _CrtCheckMemory(); } void BuffRestoreScreen() { PCHAR CodeSrc, AttrSrc, AttrSrc2, AttrSrcFG, AttrSrcBG; +#if UNICODE_INTERNAL_BUFF + buff_char_t *CodeSrcW; +#endif LONG ScrSize; LONG SrcPtr, DestPtr; int i, CopyX, CopyY; + _CrtCheckMemory(); if (SaveBuff != NULL) { - if ((CodeSrc=GlobalLock(SaveBuff)) != NULL) { - ScrSize = SaveBuffX * SaveBuffY; + CodeSrc = SaveBuff; + ScrSize = SaveBuffX * SaveBuffY; - AttrSrc = CodeSrc + ScrSize; - AttrSrc2 = AttrSrc + ScrSize; - AttrSrcFG = AttrSrc2 + ScrSize; - AttrSrcBG = AttrSrcFG + ScrSize; + AttrSrc = CodeSrc + ScrSize; + AttrSrc2 = AttrSrc + ScrSize; + AttrSrcFG = AttrSrc2 + ScrSize; + AttrSrcBG = AttrSrcFG + ScrSize; +#if UNICODE_INTERNAL_BUFF + CodeSrcW = (buff_char_t*)(AttrSrcBG + ScrSize); +#endif - CopyX = (SaveBuffX > NumOfColumns) ? NumOfColumns : SaveBuffX; - CopyY = (SaveBuffY > NumOfLines) ? NumOfLines : SaveBuffY; + CopyX = (SaveBuffX > NumOfColumns) ? NumOfColumns : SaveBuffX; + CopyY = (SaveBuffY > NumOfLines) ? NumOfLines : SaveBuffY; - SrcPtr = 0; - DestPtr = GetLinePtr(PageStart); + SrcPtr = 0; + DestPtr = GetLinePtr(PageStart); - for (i=0; i<CopyY; i++) { - memcpy(&CodeBuff[DestPtr], &CodeSrc[SrcPtr], CopyX); - memcpy(&AttrBuff[DestPtr], &AttrSrc[SrcPtr], CopyX); - memcpy(&AttrBuff2[DestPtr], &AttrSrc2[SrcPtr], CopyX); - memcpy(&AttrBuffFG[DestPtr], &AttrSrcFG[SrcPtr], CopyX); - memcpy(&AttrBuffBG[DestPtr], &AttrSrcBG[SrcPtr], CopyX); - if (AttrBuff[DestPtr+CopyX-1] & AttrKanji) { - CodeBuff[DestPtr+CopyX-1] = ' '; - AttrBuff[DestPtr+CopyX-1] ^= AttrKanji; - } - SrcPtr += SaveBuffX; - DestPtr = NextLinePtr(DestPtr); + for (i=0; i<CopyY; i++) { + memcpy(&CodeBuff[DestPtr], &CodeSrc[SrcPtr], CopyX); +#if UNICODE_INTERNAL_BUFF + memcpyW(&CodeBuffW[DestPtr], &CodeSrcW[SrcPtr], CopyX); +#endif + memcpy(&AttrBuff[DestPtr], &AttrSrc[SrcPtr], CopyX); + memcpy(&AttrBuff2[DestPtr], &AttrSrc2[SrcPtr], CopyX); + memcpy(&AttrBuffFG[DestPtr], &AttrSrcFG[SrcPtr], CopyX); + memcpy(&AttrBuffBG[DestPtr], &AttrSrcBG[SrcPtr], CopyX); + if (AttrBuff[DestPtr+CopyX-1] & AttrKanji) { + CodeBuff[DestPtr+CopyX-1] = ' '; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[DestPtr+CopyX-1], 0x20, 'H'); +#endif + AttrBuff[DestPtr+CopyX-1] ^= AttrKanji; } - BuffUpdateRect(WinOrgX,WinOrgY,WinOrgX+WinWidth-1,WinOrgY+WinHeight-1); + SrcPtr += SaveBuffX; + DestPtr = NextLinePtr(DestPtr); } + BuffUpdateRect(WinOrgX,WinOrgY,WinOrgX+WinWidth-1,WinOrgY+WinHeight-1); - GlobalFree(SaveBuff); + free(SaveBuff); SaveBuff = NULL; } - return; + _CrtCheckMemory(); } -void BuffDiscardSavedScreen() { +void BuffDiscardSavedScreen() +{ if (SaveBuff != NULL) { - GlobalFree(SaveBuff); + free(SaveBuff); SaveBuff = NULL; } + _CrtCheckMemory(); } void BuffSelectedEraseCurToEnd() @@ -3809,6 +4532,9 @@ for (j = TmpPtr + offset; j < TmpPtr + NumOfColumns - offset; j++) { if (!(AttrBuff2[j] & Attr2Protect)) { CodeBuff[j] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[j], 0x20, 'H'); +#endif AttrBuff[j] &= AttrSgrMask; } } @@ -3847,6 +4573,9 @@ for (j = TmpPtr; j < TmpPtr + offset; j++) { if (!(AttrBuff2[j] & Attr2Protect)) { CodeBuff[j] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[j], 0x20, 'H'); +#endif AttrBuff[j] &= AttrSgrMask; } } @@ -3887,6 +4616,9 @@ ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0) && ((AttrBuff2[Ptr+XStart-1] & Attr2Protect) == 0)) { CodeBuff[Ptr+XStart-1] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[Ptr+XStart-1], 0x20, 'H'); +#endif AttrBuff[Ptr+XStart-1] &= AttrSgrMask; } if ((XStart+C<NumOfColumns) && @@ -3893,11 +4625,17 @@ ((AttrBuff[Ptr+XStart+C-1] & AttrKanji) != 0) && ((AttrBuff2[Ptr+XStart+C-1] & Attr2Protect) == 0)) { CodeBuff[Ptr+XStart+C] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[Ptr+XStart+C], 0x20, 'H'); +#endif AttrBuff[Ptr+XStart+C] &= AttrSgrMask; } for (j=Ptr+XStart; j<Ptr+XStart+C; j++) { if (!(AttrBuff2[j] & Attr2Protect)) { CodeBuff[j] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[j], 0x20, 'H'); +#endif AttrBuff[j] &= AttrSgrMask; } } @@ -3959,22 +4697,37 @@ if (AttrBuff[LPtr+CursorRightM] & AttrKanji) { CodeBuff[LPtr+CursorRightM] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[LPtr+CursorRightM], 0x20, 'H'); +#endif AttrBuff[LPtr+CursorRightM] &= ~AttrKanji; if (CursorRightM < NumOfColumns-1) { CodeBuff[LPtr+CursorRightM+1] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[LPtr+CursorRightM+1], 0x20, 'H'); +#endif } } if (AttrBuff[Ptr+count-1] & AttrKanji) { CodeBuff[Ptr+count] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[Ptr+count], 0x20, 'H'); +#endif } if (CursorLeftM > 0 && AttrBuff[Ptr-1] & AttrKanji) { CodeBuff[Ptr-1] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[Ptr-1], 0x20, 'H'); +#endif AttrBuff[Ptr-1] &= ~AttrKanji; } memmove(&(CodeBuff[Ptr]), &(CodeBuff[Ptr+count]), MoveLen); +#if UNICODE_INTERNAL_BUFF + memmoveW(&(CodeBuffW[Ptr]), &(CodeBuffW[Ptr+count]), MoveLen); +#endif memmove(&(AttrBuff[Ptr]), &(AttrBuff[Ptr+count]), MoveLen); memmove(&(AttrBuff2[Ptr]), &(AttrBuff2[Ptr+count]), MoveLen); memmove(&(AttrBuffFG[Ptr]), &(AttrBuffFG[Ptr+count]), MoveLen); @@ -3981,6 +4734,9 @@ memmove(&(AttrBuffBG[Ptr]), &(AttrBuffBG[Ptr+count]), MoveLen); memset(&(CodeBuff[Ptr+MoveLen]), 0x20, count); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[Ptr+MoveLen]), 0x20, count); +#endif memset(&(AttrBuff[Ptr+MoveLen]), AttrDefault, count); memset(&(AttrBuff2[Ptr+MoveLen]), CurCharAttr.Attr2 & Attr2ColorMask, count); memset(&(AttrBuffFG[Ptr+MoveLen]), CurCharAttr.Fore, count); @@ -4006,15 +4762,27 @@ if (CursorRightM < NumOfColumns-1 && AttrBuff[LPtr+CursorRightM] & AttrKanji) { CodeBuff[LPtr+CursorRightM+1] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[LPtr+CursorRightM+1], 0x20, 'H'); +#endif } if (CursorLeftM > 0 && AttrBuff[Ptr-1] & AttrKanji) { CodeBuff[Ptr-1] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[Ptr-1], 0x20, 'H'); +#endif AttrBuff[Ptr-1] &= ~AttrKanji; CodeBuff[Ptr] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[Ptr], 0x20, 'H'); +#endif } memmove(&(CodeBuff[Ptr+count]), &(CodeBuff[Ptr]), MoveLen); +#if UNICODE_INTERNAL_BUFF + memmoveW(&(CodeBuffW[Ptr+count]), &(CodeBuffW[Ptr]), MoveLen); +#endif memmove(&(AttrBuff[Ptr+count]), &(AttrBuff[Ptr]), MoveLen); memmove(&(AttrBuff2[Ptr+count]), &(AttrBuff2[Ptr]), MoveLen); memmove(&(AttrBuffFG[Ptr+count]), &(AttrBuffFG[Ptr]), MoveLen); @@ -4021,6 +4789,9 @@ memmove(&(AttrBuffBG[Ptr+count]), &(AttrBuffBG[Ptr]), MoveLen); memset(&(CodeBuff[Ptr]), 0x20, count); +#if UNICODE_INTERNAL_BUFF + memsetW(&(CodeBuffW[Ptr]), 0x20, count); +#endif memset(&(AttrBuff[Ptr]), AttrDefault, count); memset(&(AttrBuff2[Ptr]), CurCharAttr.Attr2 & Attr2ColorMask, count); memset(&(AttrBuffFG[Ptr]), CurCharAttr.Fore, count); @@ -4028,6 +4799,9 @@ if (AttrBuff[LPtr+CursorRightM] & AttrKanji) { CodeBuff[LPtr+CursorRightM] = 0x20; +#if UNICODE_INTERNAL_BUFF + BuffSetChar(&CodeBuffW[LPtr+CursorRightM], 0x20, 'H'); +#endif AttrBuff[LPtr+CursorRightM] &= ~AttrKanji; } @@ -4096,3 +4870,97 @@ return Result; } + +/* \x83f\x83o\x83O\x97p */ +void BuffCheckMouse(int Xw, int Yw, wchar_t *buf, size_t buf_size) +{ + int X, Y; + int ScreenY; + LONG TmpPtr; + BOOL Right; + unsigned char c; + char cs[4]; +#if UNICODE_INTERNAL_BUFF + char32_t u32; + wchar_t wcs[4]; +#endif + + DispConvWinToScreen(Xw, Yw, &X, &ScreenY, &Right); + Y = PageStart + ScreenY; + + if (X < 0) + X = 0; + else if (X > NumOfColumns) + X = NumOfColumns; + if (Y < 0) + Y = 0; + else if (Y >= BuffEnd) + Y = BuffEnd - 1; + + TmpPtr = GetLinePtr(Y); + LockBuffer(); + + c = (unsigned char)CodeBuff[TmpPtr+X]; + if (c < 0x20) { + cs[0] = '.'; + cs[1] = 0; + } else if (!_ismbblead(c)) { + cs[0] = c; + cs[1] = 0; + } else { + cs[0] = c; + cs[1] = CodeBuff[TmpPtr+X+1]; + cs[2] = 0; + } + +#if UNICODE_INTERNAL_BUFF + { + const wchar_t wc1 = CodeBuffW[TmpPtr+X].wc2[0]; + const wchar_t wc2 = CodeBuffW[TmpPtr+X+1].wc2[1]; + u32 = CodeBuffW[TmpPtr+X].u32; + if (u32 < 0x20) { + wcs[0] = '.'; + wcs[1] = 0; + wcs[2] = 0; + } else if (u32 < 0x10000) { + wcs[0] = wc1; + wcs[1] = 0; + wcs[2] = 0; + } else { + // \x83T\x83\x8D\x83Q\x81[\x83g\x83y\x83A + wcs[0] = wc1; + wcs[1] = wc2; + wcs[2] = 0; + } + } +#endif + + swprintf_s(buf, buf_size, + L"ch(%d,%d(%d)) px(%d,%d)\n" + L"attr 0x%02x\n" + L"attr2 0x%02x\n" + L"attrFore 0x%02x\n" + L"attrBack 0x%02x\n" + L"CodeLine 0x%02x('%S')" +#if UNICODE_INTERNAL_BUFF + L"\n" + L"CodeLineW 0+%06x('%s')" +#endif + , + X, ScreenY, Y, + Xw, Yw, + AttrBuff[TmpPtr+X], + AttrBuff2[TmpPtr+X], + AttrBuffFG[TmpPtr+X], + AttrBuffBG[TmpPtr+X], + c, cs +#if UNICODE_INTERNAL_BUFF + , u32, wcs +#endif + ); +#if 0 + OutputDebugPrintfW(buf); +#endif + + UnlockBuffer(); +} Modified: branches/unicode_buf/teraterm/teraterm/buffer.h =================================================================== --- branches/unicode_buf/teraterm/teraterm/buffer.h 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/buffer.h 2019-06-25 14:05:37 UTC (rev 7810) @@ -63,6 +63,7 @@ void BuffDumpCurrentLine(BYTE TERM); void BuffPutChar(BYTE b, TCharAttr Attr, BOOL Insert); void BuffPutKanji(WORD w, TCharAttr Attr, BOOL Insert); +char BuffPutUnicode(unsigned int uc, TCharAttr Attr, BOOL Insert); void BuffUpdateRect(int XStart, int YStart, int XEnd, int YEnd); void UpdateStr(); void UpdateStrUnicode(void); @@ -108,6 +109,7 @@ int BuffGetCurrentLineData(char *buf, int bufsize); int BuffGetAnyLineData(int offset_y, char *buf, int bufsize); BOOL BuffCheckMouseOnURL(int Xw, int Yw); +void BuffCheckMouse(int Xw, int Yw, wchar_t *buf, size_t buf_size); extern int StatusLine; extern int CursorTop, CursorBottom, CursorLeftM, CursorRightM; Modified: branches/unicode_buf/teraterm/teraterm/ttermpro.v10.vcxproj =================================================================== --- branches/unicode_buf/teraterm/teraterm/ttermpro.v10.vcxproj 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/ttermpro.v10.vcxproj 2019-06-25 14:05:37 UTC (rev 7810) @@ -181,6 +181,7 @@ <ClCompile Include="vtwin.cpp" /> <ClCompile Include="winjump.c" /> <ClCompile Include="WSAAsyncGetAddrInfo.c" /> + <ClCompile Include="unicode.cpp" /> <ClInclude Include="..\ttpdlg\dlg_res.h" /> <ClCompile Include="../ttpdlg/ttdlg.c" /> <ClInclude Include="../ttpdlg/ttdlg.h" /> @@ -241,6 +242,7 @@ <ClInclude Include="vtdisp.h" /> <ClInclude Include="vtterm.h" /> <ClInclude Include="vtwin.h" /> + <ClInclude Include="unicode.h" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\svnrev\svnrev.v10.vcxproj"> Modified: branches/unicode_buf/teraterm/teraterm/ttermpro.v11.vcxproj =================================================================== --- branches/unicode_buf/teraterm/teraterm/ttermpro.v11.vcxproj 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/ttermpro.v11.vcxproj 2019-06-25 14:05:37 UTC (rev 7810) @@ -178,6 +178,7 @@ <ClCompile Include="vtwin.cpp" /> <ClCompile Include="winjump.c" /> <ClCompile Include="WSAAsyncGetAddrInfo.c" /> + <ClCompile Include="unicode.cpp" /> <ClInclude Include="..\ttpdlg\dlg_res.h" /> <ClCompile Include="../ttpdlg/ttdlg.c" /> <ClInclude Include="../ttpdlg/ttdlg.h" /> @@ -238,6 +239,7 @@ <ClInclude Include="vtdisp.h" /> <ClInclude Include="vtterm.h" /> <ClInclude Include="vtwin.h" /> + <ClInclude Include="unicode.h" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\svnrev\svnrev.v11.vcxproj"> Modified: branches/unicode_buf/teraterm/teraterm/ttermpro.v12.vcxproj =================================================================== --- branches/unicode_buf/teraterm/teraterm/ttermpro.v12.vcxproj 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/ttermpro.v12.vcxproj 2019-06-25 14:05:37 UTC (rev 7810) @@ -178,6 +178,7 @@ <ClCompile Include="vtwin.cpp" /> <ClCompile Include="winjump.c" /> <ClCompile Include="WSAAsyncGetAddrInfo.c" /> + <ClCompile Include="unicode.cpp" /> <ClInclude Include="..\ttpdlg\dlg_res.h" /> <ClCompile Include="../ttpdlg/ttdlg.c" /> <ClInclude Include="../ttpdlg/ttdlg.h" /> @@ -238,6 +239,7 @@ <ClInclude Include="vtdisp.h" /> <ClInclude Include="vtterm.h" /> <ClInclude Include="vtwin.h" /> + <ClInclude Include="unicode.h" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\svnrev\svnrev.v12.vcxproj"> Modified: branches/unicode_buf/teraterm/teraterm/ttermpro.v14.vcxproj =================================================================== --- branches/unicode_buf/teraterm/teraterm/ttermpro.v14.vcxproj 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/ttermpro.v14.vcxproj 2019-06-25 14:05:37 UTC (rev 7810) @@ -180,6 +180,7 @@ <ClCompile Include="vtwin.cpp" /> <ClCompile Include="winjump.c" /> <ClCompile Include="WSAAsyncGetAddrInfo.c" /> + <ClCompile Include="unicode.cpp" /> <ClInclude Include="..\ttpdlg\dlg_res.h" /> <ClCompile Include="../ttpdlg/ttdlg.c" /> <ClInclude Include="../ttpdlg/ttdlg.h" /> @@ -240,6 +241,7 @@ <ClInclude Include="vtdisp.h" /> <ClInclude Include="vtterm.h" /> <ClInclude Include="vtwin.h" /> + <ClInclude Include="unicode.h" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\svnrev\svnrev.v14.vcxproj"> Modified: branches/unicode_buf/teraterm/teraterm/ttermpro.v15.vcxproj =================================================================== --- branches/unicode_buf/teraterm/teraterm/ttermpro.v15.vcxproj 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/ttermpro.v15.vcxproj 2019-06-25 14:05:37 UTC (rev 7810) @@ -183,6 +183,7 @@ <ClCompile Include="vtwin.cpp" /> <ClCompile Include="winjump.c" /> <ClCompile Include="WSAAsyncGetAddrInfo.c" /> + <ClCompile Include="unicode.cpp" /> <ClInclude Include="../ttpdlg/dlg_res.h" /> <ClCompile Include="../ttpdlg/ttdlg.c" /> <ClInclude Include="../ttpdlg/ttdlg.h" /> @@ -243,6 +244,7 @@ <ClInclude Include="vtdisp.h" /> <ClInclude Include="vtterm.h" /> <ClInclude Include="vtwin.h" /> + <ClInclude Include="unicode.h" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\svnrev\svnrev.v15.vcxproj"> Modified: branches/unicode_buf/teraterm/teraterm/ttermpro.v16.vcxproj =================================================================== --- branches/unicode_buf/teraterm/teraterm/ttermpro.v16.vcxproj 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/ttermpro.v16.vcxproj 2019-06-25 14:05:37 UTC (rev 7810) @@ -183,6 +183,7 @@ <ClCompile Include="vtwin.cpp" /> <ClCompile Include="winjump.c" /> <ClCompile Include="WSAAsyncGetAddrInfo.c" /> + <ClCompile Include="unicode.cpp" /> <ClInclude Include="../ttpdlg/dlg_res.h" /> <ClCompile Include="../ttpdlg/ttdlg.c" /> <ClInclude Include="../ttpdlg/ttdlg.h" /> @@ -243,6 +244,7 @@ <ClInclude Include="vtdisp.h" /> <ClInclude Include="vtterm.h" /> <ClInclude Include="vtwin.h" /> + <ClInclude Include="unicode.h" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\svnrev\svnrev.v16.vcxproj"> @@ -277,4 +279,4 @@ <UserProperties RESOURCE_FILE="ttermpro.rc" /> </VisualStudio> </ProjectExtensions> -</Project> \ No newline at end of file +</Project> Modified: branches/unicode_buf/teraterm/teraterm/ttermpro.v9.vcproj =================================================================== --- branches/unicode_buf/teraterm/teraterm/ttermpro.v9.vcproj 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/ttermpro.v9.vcproj 2019-06-25 14:05:37 UTC (rev 7810) @@ -605,6 +605,14 @@ RelativePath=".\ttdialog.h" > </File> + <File + RelativePath="unicode.h" + > + </File> + <File + RelativePath="unicode.cpp" + > + </File> </Filter> </Files> <Globals> Modified: branches/unicode_buf/teraterm/teraterm/ttermpro.vcproj =================================================================== --- branches/unicode_buf/teraterm/teraterm/ttermpro.vcproj 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/ttermpro.vcproj 2019-06-25 14:05:37 UTC (rev 7810) @@ -606,6 +606,14 @@ RelativePath=".\ttdialog.h" > </File> + <File + RelativePath="unicode.h" + > + </File> + <File + RelativePath="unicode.cpp" + > + </File> </Filter> </Files> <Globals> Added: branches/unicode_buf/teraterm/teraterm/unicode/get_combine_table.md =================================================================== --- branches/unicode_buf/teraterm/teraterm/unicode/get_combine_table.md (rev 0) +++ branches/unicode_buf/teraterm/teraterm/unicode/get_combine_table.md 2019-06-25 14:05:37 UTC (rev 7810) @@ -0,0 +1,21 @@ + +# combining charactors + +- 結合文字 +- 濁点など、前のもじとくっつける + https://en.m.wikipedia.org/wiki/Combining_character + +# テーブルの作り方 + +- あらかじめ NamesList.txt をダウンロードしておく +- 次のように実行する + - `perl get_combine_table.pl > unicode_combine.tbl` + +## original data + +https://unicode.org/Public/UNIDATA/NamesList.txt + + The Unicode Standard 12.1.0 + Unicode 12.1.0 final names list. + + Added: branches/unicode_buf/teraterm/teraterm/unicode/get_combine_table.pl =================================================================== --- branches/unicode_buf/teraterm/teraterm/unicode/get_combine_table.pl (rev 0) +++ branches/unicode_buf/teraterm/teraterm/unicode/get_combine_table.pl 2019-06-25 14:05:37 UTC (rev 7810) @@ -0,0 +1,32 @@ +#!/usr/bin/perl +use utf8; + +open(FILE, "NamesList.txt") || die "Cannot open width file."; +$ostart = 0; +$oend = 0; +while($a = <FILE>) { + if ($a =~ /^([0-9A-F]+)\s+(.*)$/) { + $start = hex $1; + $name = $2; + if ($name =~ /COMBINING/ || $name =~ /EMOJI MODIFIER/) { + if ($ostart == 0) { + $ostart = $start; + $oend = $start; + $comment = $name; + } else { + if ($oend + 1 == $start) { + $oend = $start; + } + } + } else { + if ($ostart != 0) { + printf("{ 0x%06x, 0x%06x }, // '%s'\n", $ostart, $oend, $comment); + $ostart = 0; + } + } + } +} +if ($ostart != 0) { + printf("{ 0x%06x, 0x%06x },\n", $ostart, $oend); +} + Added: branches/unicode_buf/teraterm/teraterm/unicode/get_f_w_a.md =================================================================== --- branches/unicode_buf/teraterm/teraterm/unicode/get_f_w_a.md (rev 0) +++ branches/unicode_buf/teraterm/teraterm/unicode/get_f_w_a.md 2019-06-25 14:05:37 UTC (rev 7810) @@ -0,0 +1,21 @@ + +# unicodeの全角半角 + +- unicode.orgにある East Asian Width に基づいて決める + +# テーブルの作り方 + +- あらかじめ EastAsianWidth.txt をダウンロードしておく +- 次のように実行 + - `perl get_f_w_a.pl > unicode_asian_width.tbl` + +## East Asian Width について + +https://ja.wikipedia.org/wiki/%E6%9D%B1%E3%82%A2%E3%82%B8%E3%82%A2%E3%81%AE%E6%96%87%E5%AD%97%E5%B9%85 + +## original data + +http://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt + + EastAsianWidth-12.1.0.txt + Date: 2019-03-31, 22:01:58 GMT [KW, LI] Added: branches/unicode_buf/teraterm/teraterm/unicode/get_f_w_a.pl =================================================================== --- branches/unicode_buf/teraterm/teraterm/unicode/get_f_w_a.pl (rev 0) +++ branches/unicode_buf/teraterm/teraterm/unicode/get_f_w_a.pl 2019-06-25 14:05:37 UTC (rev 7810) @@ -0,0 +1,41 @@ +#!/usr/bin/perl +use utf8; + +open(FILE, "EastAsianWidth.txt") || die "Cannot open width file."; +$ostart = -1; +while($a = <FILE>) { + if ($a =~ /^([0-9A-F]+)\.\.([0-9A-F]+);([A-Za-z]+)/) { + $start = hex $1; + $end = hex $2; + $type = $3; + } + elsif ($a =~ /^([0-9A-F]+);([A-Za-z]+)/) { + $start = hex $1; + $end = hex $1; + $type = $2; + } else { + next; + } + +# printf("-{ 0x%06x, 0x%06x, $type },\n", $start, $end); + + if ($otype eq $type + #&& $oend+1 == $start # 未定義部を飛ばしてつなげる + ) + { + # 1つ前とつなげる + $oend = $end; + } elsif ($ostart == -1) { + $ostart = $start; + $oend = $end; + $otype = $type; + } else { + if (($otype eq "W") || ($otype eq "F") || ($otype eq "A")) { + printf("{ 0x%06x, 0x%06x, '$otype' },\n", $ostart, $oend); + } + $ostart = $start; + $oend = $end; + $otype = $type; + } +} +printf("{ 0x%06x, 0x%06x, '$type' },\n", $ostart, $oend); Added: branches/unicode_buf/teraterm/teraterm/unicode.cpp =================================================================== --- branches/unicode_buf/teraterm/teraterm/unicode.cpp (rev 0) +++ branches/unicode_buf/teraterm/teraterm/unicode.cpp 2019-06-25 14:05:37 UTC (rev 7810) @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2019 TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * 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" + +/** + * East_Asian_Width \x8EQ\x8Dl\x93\xC1\x90\xAB \x8E擾 + * + * @retval 'F' Fullwidth \x91S\x8Ap + * @retval 'W' Wide \x8DL + * @retval 'A' Ambiguous \x9EB\x96\x86 + * @retval 'H' \x94\xBC\x8Ap\x88\xB5\x82\xA2 (H(Halfwidth \x94\xBC\x8Ap) or Na(Narrow \x8B\xB7) or N(Neutral \x92\x86\x97\xA7)) + */ +char UnicodeGetWidthProperty(unsigned long u32) +{ + typedef struct { + unsigned long code_from; + unsigned long code_to; + char property; + } east_asian_width_map_t; + const static east_asian_width_map_t east_asian_width_map[] = { +#include "unicode_asian_width.tbl" + }; + const east_asian_width_map_t *table = east_asian_width_map; + const size_t table_size = _countof(east_asian_width_map); + + if (u32 < east_asian_width_map[0].code_from) { + return 'H'; + } + if (east_asian_width_map[table_size-1].code_to < u32) { + return 'H'; + } + + size_t low = 0; + size_t high = table_size - 1; + while (low < high) { + size_t mid = (low + high) / 2; + if (table[mid].code_from <= u32 && u32 <= table[mid].code_to) { + return table[mid].property; + } else if (table[mid].code_to < u32) { + low = mid + 1; + } else { + high = mid; + } + } + // \x83e\x81[\x83u\x83\x8B\x82͈̔͊O + return 'H'; +} + +/* + * \x8C\x8B\x8D\x87\x95\xB6\x8E\x9A\x82\xA9\x8C\x9F\x8D\xB8\x82\xB7\x82\xE9 + * EMOJI MODIFIER \x82\xE0\x8C\x8B\x8D\x87\x95\xB6\x8E\x9A\x82Ƃ\xB5\x82Ĉ\xB5\x82\xA4 + * + * @retval 0 \x8C\x8B\x8D\x87\x95\xB6\x8E\x9A\x82ł͂Ȃ\xA2 + * @retval 1 \x8C\x8B\x8D\x87\x95\xB6\x8E\x9A\x82ł\xA0\x82\xE9 + */ +int UnicodeIsCombiningCharacter(unsigned long u32) +{ + typedef struct { + unsigned long code_from; + unsigned long code_to; + } CombiningCharacterList_t; + const static CombiningCharacterList_t CombiningCharacterList[] = { +#include "unicode_combine.tbl" + }; + const CombiningCharacterList_t *table = CombiningCharacterList; + const size_t table_size = _countof(CombiningCharacterList); + if (u32 < CombiningCharacterList[0].code_from) { + return 0; + } + if (u32 > CombiningCharacterList[table_size-1].code_to) { + return 0; + } + size_t low = 0; + size_t high = table_size - 1; + while (low <= high) { + size_t mid = (low + high) / 2; + if (table[mid].code_from <= u32 && u32 <= table[mid].code_to) { + return 1; + } else if (table[mid].code_to < u32) { + low = mid + 1; + } else { + high = mid - 1; + } + } + // \x83e\x81[\x83u\x83\x8B\x82͈̔͊O + return 0; +} + +/** + * \x88ّ̎\x9A\x83Z\x83\x8C\x83N\x83^\x82\xA9\x83`\x83F\x83b\x83N\x82\xB7\x82\xE9 + * + * @retval 0 \x88ّ̎\x9A\x83Z\x83\x8C\x83N\x83^\x82ł͂Ȃ\xA2 + * @retval 1 \x88ّ̎\x9A\x83Z\x83\x8C\x83N\x83^\x82ł\xA0\x82\xE9 + */ +int UnicodeIsVariationSelector(unsigned long u32) +{ + if ((0x00180b <= u32 && u32 <= 0x00180d) || // FVS (Mongolian Free Variation Selector) + (0x00fe00 <= u32 && u32 <= 0x00fe0f) || // SVS VS1\x81`VS16 + (0x0e0100 <= u32 && u32 <= 0x0e01ef)) // IVS VS17\x81`VS256 + { + return 1; + } + return 0; +} + + +#if 0 +int main(int, char *[]) +{ + static const unsigned long codes[] = { +#if 0 + 0, 1, 0x7f, + 0x80, + 0x0e00ff, + 0x0e0100, + 0x10fffd, +#endif + 0x10fffe, + }; + + for (size_t i = 0; i < _countof(codes); i++) { + unsigned long code = codes[i]; + printf("U+%06lx %c\n", code, UnicodeGetWidthProperty(code)); + } + return 0; +} +#endif Added: branches/unicode_buf/teraterm/teraterm/unicode.h =================================================================== --- branches/unicode_buf/teraterm/teraterm/unicode.h (rev 0) +++ branches/unicode_buf/teraterm/teraterm/unicode.h 2019-06-25 14:05:37 UTC (rev 7810) @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019 TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +char UnicodeGetWidthProperty(unsigned long u32); +int UnicodeIsCombiningCharacter(unsigned long u32); +int UnicodeIsVariationSelector(unsigned long u32); + +#ifdef __cplusplus +} +#endif Added: branches/unicode_buf/teraterm/teraterm/unicode_asian_width.tbl =================================================================== --- branches/unicode_buf/teraterm/teraterm/unicode_asian_width.tbl (rev 0) +++ branches/unicode_buf/teraterm/teraterm/unicode_asian_width.tbl 2019-06-25 14:05:37 UTC (rev 7810) @@ -0,0 +1,256 @@ +{ 0x0000a1, 0x0000a1, 'A' }, +{ 0x0000a4, 0x0000a4, 'A' }, +{ 0x0000a7, 0x0000a8, 'A' }, +{ 0x0000aa, 0x0000aa, 'A' }, +{ 0x0000ad, 0x0000ae, 'A' }, +{ 0x0000b0, 0x0000b4, 'A' }, +{ 0x0000b6, 0x0000ba, 'A' }, +{ 0x0000bc, 0x0000bf, 'A' }, +{ 0x0000c6, 0x0000c6, 'A' }, +{ 0x0000d0, 0x0000d0, 'A' }, +{ 0x0000d7, 0x0000d8, 'A' }, +{ 0x0000de, 0x0000e1, 'A' }, +{ 0x0000e6, 0x0000e6, 'A' }, +{ 0x0000e8, 0x0000ea, 'A' }, +{ 0x0000ec, 0x0000ed, 'A' }, +{ 0x0000f0, 0x0000f0, 'A' }, +{ 0x0000f2, 0x0000f3, 'A' }, +{ 0x0000f7, 0x0000fa, 'A' }, +{ 0x0000fc, 0x0000fc, 'A' }, +{ 0x0000fe, 0x0000fe, 'A' }, +{ 0x000101, 0x000101, 'A' }, +{ 0x000111, 0x000111, 'A' }, +{ 0x000113, 0x000113, 'A' }, +{ 0x00011b, 0x00011b, 'A' }, +{ 0x000126, 0x000127, 'A' }, +{ 0x00012b, 0x00012b, 'A' }, +{ 0x000131, 0x000133, 'A' }, +{ 0x000138, 0x000138, 'A' }, +{ 0x00013f, 0x000142, 'A' }, +{ 0x000144, 0x000144, 'A' }, +{ 0x000148, 0x00014b, 'A' }, +{ 0x00014d, 0x00014d, 'A' }, +{ 0x000152, 0x000153, 'A' }, +{ 0x000166, 0x000167, 'A' }, +{ 0x00016b, 0x00016b, 'A' }, +{ 0x0001ce, 0x0001ce, 'A' }, +{ 0x0001d0, 0x0001d0, 'A' }, +{ 0x0001d2, 0x0001d2, 'A' }, +{ 0x0001d4, 0x0001d4, 'A' }, +{ 0x0001d6, 0x0001d6, 'A' }, +{ 0x0001d8, 0x0001d8, 'A' }, +{ 0x0001da, 0x0001da, 'A' }, +{ 0x0001dc, 0x0001dc, 'A' }, +{ 0x000251, 0x000251, 'A' }, +{ 0x000261, 0x000261, 'A' }, +{ 0x0002c4, 0x0002c4, 'A' }, +{ 0x0002c7, 0x0002c7, 'A' }, +{ 0x0002c9, 0x0002cb, 'A' }, +{ 0x0002cd, 0x0002cd, 'A' }, +{ 0x0002d0, 0x0002d0, 'A' }, +{ 0x0002d8, 0x0002db, 'A' }, +{ 0x0002dd, 0x0002dd, 'A' }, +{ 0x0002df, 0x0002df, 'A' }, +{ 0x000300, 0x00036f, 'A' }, +{ 0x000391, 0x0003a9, 'A' }, +{ 0x0003b1, 0x0003c1, 'A' }, +{ 0x0003c3, 0x0003c9, 'A' }, +{ 0x000401, 0x000401, 'A' }, +{ 0x000410, 0x00044f, 'A' }, +{ 0x000451, 0x000451, 'A' }, +{ 0x001100, 0x00115f, 'W' }, +{ 0x002010, 0x002010, 'A' }, +{ 0x002013, 0x002016, 'A' }, +{ 0x002018, 0x002019, 'A' }, +{ 0x00201c, 0x00201d, 'A' }, +{ 0x002020, 0x002022, 'A' }, +{ 0x002024, 0x002027, 'A' }, +{ 0x002030, 0x002030, 'A' }, +{ 0x002032, 0x002033, 'A' }, +{ 0x002035, 0x002035, 'A' }, +{ 0x00203b, 0x00203b, 'A' }, +{ 0x00203e, 0x00203e, 'A' }, +{ 0x002074, 0x002074, 'A' }, +{ 0x00207f, 0x00207f, 'A' }, +{ 0x002081, 0x002084, 'A' }, +{ 0x0020ac, 0x0020ac, 'A' }, +{ 0x002103, 0x002103, 'A' }, +{ 0x002105, 0x002105, 'A' }, +{ 0x002109, 0x002109, 'A' }, +{ 0x002113, 0x002113, 'A' }, +{ 0x002116, 0x002116, 'A' }, +{ 0x002121, 0x002122, 'A' }, +{ 0x002126, 0x002126, 'A' }, +{ 0x00212b, 0x00212b, 'A' }, +{ 0x002153, 0x002154, 'A' }, +{ 0x00215b, 0x00215e, 'A' }, +{ 0x002160, 0x00216b, 'A' }, +{ 0x002170, 0x002179, 'A' }, +{ 0x002189, 0x002189, 'A' }, +{ 0x002190, 0x002199, 'A' }, +{ 0x0021b8, 0x0021b9, 'A' }, +{ 0x0021d2, 0x0021d2, 'A' }, +{ 0x0021d4, 0x0021d4, 'A' }, +{ 0x0021e7, 0x0021e7, 'A' }, +{ 0x002200, 0x002200, 'A' }, +{ 0x002202, 0x002203, 'A' }, +{ 0x002207, 0x002208, 'A' }, +{ 0x00220b, 0x00220b, 'A' }, +{ 0x00220f, 0x00220f, 'A' }, +{ 0x002211, 0x002211, 'A' }, +{ 0x002215, 0x002215, 'A' }, +{ 0x00221a, 0x00221a, 'A' }, +{ 0x00221d, 0x002220, 'A' }, +{ 0x002223, 0x002223, 'A' }, +{ 0x002225, 0x002225, 'A' }, +{ 0x002227, 0x00222c, 'A' }, +{ 0x00222e, 0x00222e, 'A' }, +{ 0x002234, 0x002237, 'A' }, +{ 0x00223c, 0x00223d, 'A' }, +{ 0x002248, 0x002248, 'A' }, +{ 0x00224c, 0x00224c, 'A' }, +{ 0x002252, 0x002252, 'A' }, +{ 0x002260, 0x002261, 'A' }, +{ 0x002264, 0x002267, 'A' }, +{ 0x00226a, 0x00226b, 'A' }, +{ 0x00226e, 0x00226f, 'A' }, +{ 0x002282, 0x002283, 'A' }, +{ 0x002286, 0x002287, 'A' }, +{ 0x002295, 0x002295, 'A' }, +{ 0x002299, 0x002299, 'A' }, +{ 0x0022a5, 0x0022a5, 'A' }, +{ 0x0022bf, 0x0022bf, 'A' }, +{ 0x002312, 0x002312, 'A' }, +{ 0x00231a, 0x00231b, 'W' }, +{ 0x002329, 0x00232a, 'W' }, +{ 0x0023e9, 0x0023ec, 'W' }, +{ 0x0023f0, 0x0023f0, 'W' }, +{ 0x0023f3, 0x0023f3, 'W' }, +{ 0x002460, 0x0024e9, 'A' }, +{ 0x0024eb, 0x00254b, 'A' }, +{ 0x002550, 0x002573, 'A' }, +{ 0x002580, 0x00258f, 'A' }, +{ 0x002592, 0x002595, 'A' }, +{ 0x0025a0, 0x0025a1, 'A' }, +{ 0x0025a3, 0x0025a9, 'A' }, +{ 0x0025b2, 0x0025b3, 'A' }, +{ 0x0025b6, 0x0025b7, 'A' }, +{ 0x0025bc, 0x0025bd, 'A' }, +{ 0x0025c0, 0x0025c1, 'A' }, +{ 0x0025c6, 0x0025c8, 'A' }, +{ 0x0025cb, 0x0025cb, 'A' }, +{ 0x0025ce, 0x0025d1, 'A' }, +{ 0x0025e2, 0x0025e5, 'A' }, +{ 0x0025ef, 0x0025ef, 'A' }, +{ 0x0025fd, 0x0025fe, 'W' }, +{ 0x002605, 0x002606, 'A' }, +{ 0x002609, 0x002609, 'A' }, +{ 0x00260e, 0x00260f, 'A' }, +{ 0x002614, 0x002615, 'W' }, +{ 0x00261c, 0x00261c, 'A' }, +{ 0x00261e, 0x00261e, 'A' }, +{ 0x002640, 0x002640, 'A' }, +{ 0x002642, 0x002642, 'A' }, +{ 0x002648, 0x002653, 'W' }, +{ 0x002660, 0x002661, 'A' }, +{ 0x002663, 0x002665, 'A' }, +{ 0x002667, 0x00266a, 'A' }, +{ 0x00266c, 0x00266d, 'A' }, +{ 0x00266f, 0x00266f, 'A' }, +{ 0x00267f, 0x00267f, 'W' }, +{ 0x002693, 0x002693, 'W' }, +{ 0x00269e, 0x00269f, 'A' }, +{ 0x0026a1, 0x0026a1, 'W' }, +{ 0x0026aa, 0x0026ab, 'W' }, +{ 0x0026bd, 0x0026be, 'W' }, +{ 0x0026bf, 0x0026bf, 'A' }, +{ 0x0026c4, 0x0026c5, 'W' }, +{ 0x0026c6, 0x0026cd, 'A' }, +{ 0x0026ce, 0x0026ce, 'W' }, +{ 0x0026cf, 0x0026d3, 'A' }, +{ 0x0026d4, 0x0026d4, 'W' }, +{ 0x0026d5, 0x0026e1, 'A' }, +{ 0x0026e3, 0x0026e3, 'A' }, +{ 0x0026e8, 0x0026e9, 'A' }, +{ 0x0026ea, 0x0026ea, 'W' }, +{ 0x0026eb, 0x0026f1, 'A' }, +{ 0x0026f2, 0x0026f3, 'W' }, +{ 0x0026f4, 0x0026f4, 'A' }, +{ 0x0026f5, 0x0026f5, 'W' }, +{ 0x0026f6, 0x0026f9, 'A' }, +{ 0x0026fa, 0x0026fa, 'W' }, +{ 0x0026fb, 0x0026fc, 'A' }, +{ 0x0026fd, 0x0026fd, 'W' }, +{ 0x0026fe, 0x0026ff, 'A' }, +{ 0x002705, 0x002705, 'W' }, +{ 0x00270a, 0x00270b, 'W' }, +{ 0x002728, 0x002728, 'W' }, +{ 0x00273d, 0x00273d, 'A' }, +{ 0x00274c, 0x00274c, 'W' }, +{ 0x00274e, 0x00274e, 'W' }, +{ 0x002753, 0x002755, 'W' }, +{ 0x002757, 0x002757, 'W' }, +{ 0x002776, 0x00277f, 'A' }, +{ 0x002795, 0x002797, 'W' }, +{ 0x0027b0, 0x0027b0, 'W' }, +{ 0x0027bf, 0x0027bf, 'W' }, +{ 0x002b1b, 0x002b1c, 'W' }, +{ 0x002b50, 0x002b50, 'W' }, +{ 0x002b55, 0x002b55, 'W' }, +{ 0x002b56, 0x002b59, 'A' }, +{ 0x002e80, 0x002ffb, 'W' }, +{ 0x003000, 0x003000, 'F' }, +{ 0x003001, 0x00303e, 'W' }, +{ 0x003041, 0x003247, 'W' }, +{ 0x003248, 0x00324f, 'A' }, +{ 0x003250, 0x004dbf, 'W' }, +{ 0x004e00, 0x00a4c6, 'W' }, +{ 0x00a960, 0x00a97c, 'W' }, +{ 0x00ac00, 0x00d7a3, 'W' }, +{ 0x00e000, 0x00f8ff, 'A' }, +{ 0x00f900, 0x00faff, 'W' }, +{ 0x00fe00, 0x00fe0f, 'A' }, +{ 0x00fe10, 0x00fe19, 'W' }, +{ 0x00fe30, 0x00fe6b, 'W' }, +{ 0x00ff01, 0x00ff60, 'F' }, +{ 0x00ffe0, 0x00ffe6, 'F' }, +{ 0x00fffd, 0x00fffd, 'A' }, +{ 0x016fe0, 0x01b2fb, 'W' }, +{ 0x01f004, 0x01f004, 'W' }, +{ 0x01f0cf, 0x01f0cf, 'W' }, +{ 0x01f100, 0x01f10a, 'A' }, +{ 0x01f110, 0x01f12d, 'A' }, +{ 0x01f130, 0x01f169, 'A' }, +{ 0x01f170, 0x01f18d, 'A' }, +{ 0x01f18e, 0x01f18e, 'W' }, +{ 0x01f18f, 0x01f190, 'A' }, +{ 0x01f191, 0x01f19a, 'W' }, +{ 0x01f19b, 0x01f1ac, 'A' }, +{ 0x01f200, 0x01f320, 'W' }, +{ 0x01f32d, 0x01f335, 'W' }, +{ 0x01f337, 0x01f37c, 'W' }, +{ 0x01f37e, 0x01f393, 'W' }, +{ 0x01f3a0, 0x01f3ca, 'W' }, +{ 0x01f3cf, 0x01f3d3, 'W' }, +{ 0x01f3e0, 0x01f3f0, 'W' }, +{ 0x01f3f4, 0x01f3f4, 'W' }, +{ 0x01f3f8, 0x01f43e, 'W' }, +{ 0x01f440, 0x01f440, 'W' }, +{ 0x01f442, 0x01f4fc, 'W' }, +{ 0x01f4ff, 0x01f53d, 'W' }, +{ 0x01f54b, 0x01f54e, 'W' }, +{ 0x01f550, 0x01f567, 'W' }, +{ 0x01f57a, 0x01f57a, 'W' }, +{ 0x01f595, 0x01f596, 'W' }, +{ 0x01f5a4, 0x01f5a4, 'W' }, +{ 0x01f5fb, 0x01f64f, 'W' }, +{ 0x01f680, 0x01f6c5, 'W' }, +{ 0x01f6cc, 0x01f6cc, 'W' }, +{ 0x01f6d0, 0x01f6d2, 'W' }, +{ 0x01f6d5, 0x01f6d5, 'W' }, +{ 0x01f6eb, 0x01f6ec, 'W' }, +{ 0x01f6f4, 0x01f6fa, 'W' }, +{ 0x01f7e0, 0x01f7eb, 'W' }, +{ 0x01f90d, 0x01f9ff, 'W' }, +{ 0x01fa70, 0x03fffd, 'W' }, +{ 0x0e0100, 0x10fffd, 'A' }, Added: branches/unicode_buf/teraterm/teraterm/unicode_combine.tbl =================================================================== --- branches/unicode_buf/teraterm/teraterm/unicode_combine.tbl (rev 0) +++ branches/unicode_buf/teraterm/teraterm/unicode_combine.tbl 2019-06-25 14:05:37 UTC (rev 7810) @@ -0,0 +1,37 @@ +{ 0x000300, 0x00036f }, // 'COMBINING GRAVE ACCENT' +{ 0x000483, 0x000489 }, // 'COMBINING CYRILLIC TITLO' +{ 0x0007eb, 0x0007f3 }, // 'NKO COMBINING SHORT HIGH TONE' +{ 0x000c00, 0x000c00 }, // 'TELUGU SIGN COMBINING CANDRABINDU ABOVE' +{ 0x000c04, 0x000c04 }, // 'TELUGU SIGN COMBINING ANUSVARA ABOVE' +{ 0x000d00, 0x000d00 }, // 'MALAYALAM SIGN COMBINING ANUSVARA ABOVE' +{ 0x00135d, 0x00135f }, // 'ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK' +{ 0x001a7f, 0x001a7f }, // 'TAI THAM COMBINING CRYPTOGRAMMIC DOT' +{ 0x001ab0, 0x001abe }, // 'COMBINING DOUBLED CIRCUMFLEX ACCENT' +{ 0x001b6b, 0x001b73 }, // 'BALINESE MUSICAL SYMBOL COMBINING TEGEH' +{ 0x001dc0, 0x001df9 }, // 'COMBINING DOTTED GRAVE ACCENT' +{ 0x0020d0, 0x0020f0 }, // 'COMBINING LEFT HARPOON ABOVE' +{ 0x002cef, 0x002cf1 }, // 'COPTIC COMBINING NI ABOVE' +{ 0x002de0, 0x002dff }, // 'COMBINING CYRILLIC LETTER BE' +{ 0x003099, 0x00309a }, // 'COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK' +{ 0x00a66f, 0x00a672 }, // 'COMBINING CYRILLIC VZMET' +{ 0x00a674, 0x00a67d }, // 'COMBINING CYRILLIC LETTER UKRAINIAN IE' +{ 0x00a69e, 0x00a69f }, // 'COMBINING CYRILLIC LETTER EF' +{ 0x00a6f0, 0x00a6f1 }, // 'BAMUM COMBINING MARK KOQNDON' +{ 0x00a8e0, 0x00a8f1 }, // 'COMBINING DEVANAGARI DIGIT ZERO' +{ 0x00fe20, 0x00fe2f }, // 'COMBINING LIGATURE LEFT HALF' +{ 0x0101fd, 0x0101fd }, // 'PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE' +{ 0x010376, 0x01037a }, // 'COMBINING OLD PERMIC LETTER AN' +{ 0x010f46, 0x010f50 }, // 'SOGDIAN COMBINING DOT BELOW' +{ 0x011300, 0x011300 }, // 'GRANTHA SIGN COMBINING ANUSVARA ABOVE' +{ 0x01133b, 0x01133b }, // 'COMBINING BINDU BELOW' +{ 0x011366, 0x01136c }, // 'COMBINING GRANTHA DIGIT ZERO' +{ 0x016af0, 0x016af4 }, // 'BASSA VAH COMBINING HIGH TONE' +{ 0x01d165, 0x01d169 }, // 'MUSICAL SYMBOL COMBINING STEM' +{ 0x01d16d, 0x01d172 }, // 'MUSICAL SYMBOL COMBINING AUGMENTATION DOT' +{ 0x01d17b, 0x01d182 }, // 'MUSICAL SYMBOL COMBINING ACCENT' +{ 0x01d185, 0x01d18b }, // 'MUSICAL SYMBOL COMBINING DOIT' +{ 0x01d1aa, 0x01d1ad }, // 'MUSICAL SYMBOL COMBINING DOWN BOW' +{ 0x01d242, 0x01d244 }, // 'COMBINING GREEK MUSICAL TRISEME' +{ 0x01e000, 0x01e006 }, // 'COMBINING GLAGOLITIC LETTER AZU' +{ 0x01e8d0, 0x01e8d6 }, // 'MENDE KIKAKUI COMBINING NUMBER TEENS' +{ 0x01f3fb, 0x01f3ff }, // 'EMOJI MODIFIER FITZPATRICK TYPE-1-2' Added: branches/unicode_buf/teraterm/teraterm/unicode_test.h =================================================================== --- branches/unicode_buf/teraterm/teraterm/unicode_test.h (rev 0) +++ branches/unicode_buf/teraterm/teraterm/unicode_test.h 2019-06-25 14:05:37 UTC (rev 7810) @@ -0,0 +1,16 @@ +/* + * \x83e\x83X\x83g\x82̂\xBD\x82߂ɒlj\xC1 + * teraterm.h\x82Ȃǂɓ\xFC\x82\xEA\x82\xE9\x82ƈˑ\xB6\x83t\x83@\x83C\x83\x8B\x82\xAA\x91\xBD\x82\xA2\x82\xBD\x82߃r\x83\x8B\x83h\x82Ɏ\x9E\x8AԂ\xAA\x82\xA9\x82\xA9\x82邽\x82\xDF + * \x83e\x83X\x83g\x97p\x83w\x83b\x83_\x82ɕ\xAA\x97\xA3 + * \x8F\xAB\x97\x88\x82͂Ȃ\xAD\x82Ȃ\xE9 + * + */ +#pragma once + +#define UNICODE_INTERNAL_BUFF 1 // 1 = \x93\xE0\x95\x94\x83o\x83b\x83t\x83 @ unicode\x89\xBB +#define UNICODE_DISPLAY 1 // 0/1 = DispStr()/DispStrW() + +// UNICODE_INTERNAL_BUFF\x82̉e\x8B\xBF\x82\xF0\x8EȂ\xA2 +#define UNICODE_API 1 // UNICODE API\x82\xF0\x8B\x96\x89\xC2 +#define UNICODE_DEBUG 1 // \x83f\x83o\x83O\x97p\x8B@\x94\enable +#define UNICODE_DEBUG_CARET_OFF 0 // \x83J\x81[\x83\\x83\x8B\x93_\x96Ōn\x82\xF0\x8E~\x82߂\xE9\x83f\x83o\x83O\x97p Modified: branches/unicode_buf/teraterm/teraterm/vtdisp.c =================================================================== --- branches/unicode_buf/teraterm/teraterm/vtdisp.c 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/vtdisp.c 2019-06-25 14:05:37 UTC (rev 7810) @@ -43,6 +43,8 @@ #include <locale.h> #include <olectl.h> +#include "unicode_test.h" + #define CurWidth 2 static const BYTE DefaultColorTable[256][3] = { @@ -2203,6 +2205,9 @@ void CaretOn() // Turn on the cursor { +#if UNICODE_DEBUG_CARET_OFF + return; +#endif if (ts.KillFocusCursor == 0 && !Active) return; @@ -2300,6 +2305,9 @@ void DispEnableCaret(BOOL On) { +#if UNICODE_DEBUG_CARET_OFF + On = FALSE; +#endif if (! On) CaretOff(); CaretEnabled = On; } @@ -2758,9 +2766,37 @@ } } -#if 1 -// \x93\x96\x96ʂ͂\xB1\x82\xBF\x82\xE7\x82̊\x94\x82\xF0\x8Eg\x82\xA4\x81B(2004.11.4 yutaka) -void DispStr(PCHAR Buff, int Count, int Y, int* X) +static void DrawTextBGImage(HDC hdcBGBuffer, int X, int Y, int width, int height) +{ + RECT rect; + SetRect(&rect,0,0,width,height); + + //\x91\x8B\x82̈ړ\xAE\x81A\x83\x8A\x83T\x83C\x83Y\x92\x86\x82͔w\x8Ci\x82\xF0 BGBrushInSizeMove \x82œh\x82\xE8\x82Ԃ\xB7 + if(BGInSizeMove) + FillRect(hdcBGBuffer,&rect,BGBrushInSizeMove); + + BitBlt(hdcBGBuffer,0,0,width,height,hdcBG,X,Y,SRCCOPY); + + if(BGReverseText == TRUE) + { + if(BGReverseTextAlpha < 255) + { + BLENDFUNCTION bf; + HBRUSH hbr; + + hbr = CreateSolidBrush(GetBkColor(hdcBGBuffer)); + FillRect(hdcBGWork,&rect,hbr); + DeleteObject(hbr); + + ZeroMemory(&bf,sizeof(bf)); + bf.BlendOp = AC_SRC_OVER; + bf.SourceConstantAlpha = BGReverseTextAlpha; + + BGAlphaBlend(hdcBGBuffer,0,0,width,height,hdcBGWork,0,0,width,height,bf); + } + } +} + // Display a string // Buff: points the string // Y: vertical position in window cordinate @@ -2767,159 +2803,171 @@ // *X: horizontal position // Return: // *X: horizontal position shifted by the width of the string +void DispStr(PCHAR Buff, int Count, int Y, int* X) { - RECT RText; - - if ((ts.Language==IdRussian) && - (ts.RussClient!=ts.RussFont)) - RussConvStr(ts.RussClient,ts.RussFont,Buff,Count); - - RText.top = Y; - RText.bottom = Y+FontHeight; - RText.left = *X; - RText.right = *X + Count*FontWidth; - #ifdef ALPHABLEND_TYPE2 -//<!--by AKASI - if(!BGEnable) - { - ExtTextOut(VTDC,*X+ts.FontDX,Y+ts.FontDY, - ETO_CLIPPED | ETO_OPAQUE, - &RText,Buff,Count,&Dx[0]); - }else{ + const BOOL draw_bg_enable = BGEnable; +#else + const BOOL draw_bg_enable = FALSE; +#endif - int width; - int height; - int eto_options = ETO_CLIPPED; - RECT rect; - HFONT hPrevFont; + { + char b[128]; + memcpy(b, Buff, Count); + b[Count] = 0; + OutputDebugPrintf("(%d,%d)'%s'\n", *X, Y, b); + } - width = Count*FontWidth; - height = FontHeight; - SetRect(&rect,0,0,width,height); + if ((ts.Language==IdRussian) && + (ts.RussClient!=ts.RussFont)) + RussConvStr(ts.RussClient,ts.RussFont,Buff,Count); - //hdcBGBuffer \x82̑\xAE\x90\xAB\x82\xF0\x90ݒ\xE8 - hPrevFont = SelectObject(hdcBGBuffer,GetCurrentObject(VTDC,OBJ_FONT)); - SetTextColor(hdcBGBuffer,GetTextColor(VTDC)); - SetBkColor(hdcBGBuffer,GetBkColor(VTDC)); + if(!draw_bg_enable) + { + RECT RText; + RText.top = Y; + RText.bottom = Y+FontHeight; + RText.left = *X; + RText.right = *X + Count*FontWidth; - //\x91\x8B\x82̈ړ\xAE\x81A\x83\x8A\x83T\x83C\x83Y\x92\x86\x82͔w\x8Ci\x82\xF0 BGBrushInSizeMove \x82œh\x82\xE8\x82Ԃ\xB7 - if(BGInSizeMove) - FillRect(hdcBGBuffer,&rect,BGBrushInSizeMove); + ExtTextOutA(VTDC,*X+ts.FontDX,Y+ts.FontDY, + ETO_CLIPPED | ETO_OPAQUE, + &RText,Buff,Count,&Dx[0]); + } +#ifdef ALPHABLEND_TYPE2 + else { + HFONT hPrevFont; + RECT rect; + int eto_options; + const int width = Count*FontWidth; + const int height = FontHeight; + SetRect(&rect,0,0,width,height); - BitBlt(hdcBGBuffer,0,0,width,height,hdcBG,*X,Y,SRCCOPY); + //hdcBGBuffer \x82̑\xAE\x90\xAB\x82\xF0\x90ݒ\xE8 + hPrevFont = SelectObject(hdcBGBuffer,GetCurrentObject(VTDC,OBJ_FONT)); + SetTextColor(hdcBGBuffer,GetTextColor(VTDC)); + SetBkColor(hdcBGBuffer,GetBkColor(VTDC)); - if(BGReverseText == TRUE) - { - if(BGReverseTextAlpha < 255) - { - BLENDFUNCTION bf; - HBRUSH hbr; + // \x95\xB6\x8E\x9A\x82̔w\x8Ci\x82\xF0\x95`\x89\xE6 + DrawTextBGImage(hdcBGBuffer, *X, Y, width, height); - hbr = CreateSolidBrush(GetBkColor(hdcBGBuffer)); - FillRect(hdcBGWork,&rect,hbr); - DeleteObject(hbr); + // \x95\xB6\x8E\x9A\x82\xF0\x95`\x89\xE6 + eto_options = ETO_CLIPPED; + if(BGReverseText == TRUE && BGReverseTextAlpha < 255) { + eto_options |= ETO_OPAQUE; + } + ExtTextOutA(hdcBGBuffer,ts.FontDX,ts.FontDY,eto_options,&rect,Buff,Count,&Dx[0]); - ZeroMemory(&bf,sizeof(bf)); - bf.BlendOp = AC_SRC_OVER; - bf.SourceConstantAlpha = BGReverseTextAlpha; + // Window\x82ɓ\\x82\xE8\x95t\x82\xAF + BitBlt(VTDC,*X,Y,width,height,hdcBGBuffer,0,0,SRCCOPY); - BGAlphaBlend(hdcBGBuffer,0,0,width,height,hdcBGWork,0,0,width,height,bf); - }else{ - eto_options |= ETO_OPAQUE; - } - } + SelectObject(hdcBGBuffer,hPrevFont); + } +#endif - ExtTextOut(hdcBGBuffer,ts.FontDX,ts.FontDY,eto_options,&rect,Buff,Count,&Dx[0]); - BitBlt(VTDC,*X,Y,width,height,hdcBGBuffer,0,0,SRCCOPY); + *X += Count*FontWidth; - SelectObject(hdcBGBuffer,hPrevFont); - } -//--> -#else - ExtTextOut(VTDC,*X+ts.FontDX,Y+ts.FontDY, - ETO_CLIPPED | ETO_OPAQUE, - &RText,Buff,Count,&Dx[0]); -#endif - *X = RText.right; - - if ((ts.Language==IdRussian) && - (ts.RussClient!=ts.RussFont)) - RussConvStr(ts.RussFont,ts.RussClient,Buff,Count); + if ((ts.Language==IdRussian) && (ts.RussClient!=ts.RussFont)) + RussConvStr(ts.RussFont,ts.RussClient,Buff,Count); } +// DispStr() \x82\xCC wchar_t\x94\xC5 +// TODO: \x8D\xA1\x82̂Ƃ\xB1\x82\xEB ExtTextOutW() \x82Ă\xD1 +#if defined(UNICODE_DISPLAY) +void DispStrW(const wchar_t *StrW, const char *WidthInfo, int Count, int Y, int* X) +{ +#ifdef ALPHABLEND_TYPE2 + const BOOL draw_bg_enable = BGEnable; #else -void DispStr(PCHAR Buff, int Count, int Y, int* X) -// Display a string -// Buff: points the string -// Y: vertical position in window cordinate -// *X: horizontal position -// Return: -// *X: horizontal position shifted by the width of the string -{ - RECT RText; - wchar_t *wc; - int len, wclen; - CHAR ch; + const BOOL draw_bg_enable = FALSE; +#endif #if 0 -#include <crtdbg.h> - _CrtSetBreakAlloc(52); - Buff[0] = 0x82; - Buff[1] = 0xe4; - Buff[2] = 0x82; - Buff[3] = 0xbd; - Buff[4] = 0x82; - Buff[5] = 0xa9; - Count = 6; + { + int b[TermWidthMax]; + memcpy(b, StrW, Count*sizeof(wchar_t)); + b[Count] = 0; + OutputDebugPrintfW(L"(%d,%d)'%s'\n", *X, Y, b); + OutputDebugPrintfW(L" '%hs'\n", WidthInfo); + } #endif - setlocale(LC_ALL, ts.Locale); // TODO \x83R\x81[\x83h\x95ϊ\xB7\x82\xB1\x82\xB1\x82ł\xB7\x82\xE9?,\x96\xB3\x8C\x{27B0B3}\x82ꂽ\x83R\x81[\x83h + int Dx2[TermWidthMax]; + int dx3 = 0; + int HalfCharCount = 0; + int i; + for(i=0; i<Count; i++) { + if (WidthInfo[i] == 'H') { + HalfCharCount++; + dx3++; + Dx2[i] = FontWidth; + } else if (WidthInfo[i] == '0') { + if (i == 0) { + Dx2[i] = 0; + } else { + Dx2[i] = Dx2[i-1]; + Dx2[i-1] = 0; + } + } else { + HalfCharCount += 2; + Dx2[i] = FontWidth * 2; + dx3 += 2; + } + } - ch = Buff[Count]; - Buff[Count] = 0; - len = mbstowcs(NULL, Buff, 0); + if(!draw_bg_enable) + { + RECT RText; + RText.top = Y; + RText.bottom = Y+FontHeight; + RText.left = *X; + RText.right = *X + HalfCharCount * FontWidth; + RText.right = *X + dx3 * FontWidth; - wc = malloc(sizeof(wchar_t) * (len + 1)); - if (wc == NULL) - return; - wclen = mbstowcs(wc, Buff, len + 1); - Buff[Count] = ch; +#if 0 + ExtTextOutW(VTDC, *X + ts.FontDX, Y + ts.FontDY, + ETO_CLIPPED | ETO_OPAQUE, + &RText, Buff, Count, &Dx[0]); +#endif + ExtTextOutW(VTDC, *X + ts.FontDX, Y + ts.FontDY, + ETO_CLIPPED | ETO_OPAQUE, + &RText, StrW, Count, &Dx2[0]); + } +#ifdef ALPHABLEND_TYPE2 + else { + HFONT hPrevFont; + RECT rect; + int eto_options; + const int width = Count*FontWidth*2; + const int height = FontHeight; + SetRect(&rect,0,0,width,height); - if ((ts.Language==IdRussian) && - (ts.RussClient!=ts.RussFont)) - RussConvStr(ts.RussClient,ts.RussFont,Buff,Count); + //hdcBGBuffer \x82̑\xAE\x90\xAB\x82\xF0\x90ݒ\xE8 + hPrevFont = SelectObject(hdcBGBuffer,GetCurrentObject(VTDC,OBJ_FONT)); + SetTextColor(hdcBGBuffer,GetTextColor(VTDC)); + SetBkColor(hdcBGBuffer,GetBkColor(VTDC)); - RText.top = Y; - RText.bottom = Y+FontHeight; - RText.left = *X; - RText.right = *X + Count*FontWidth; // + // \x95\xB6\x8E\x9A\x82̔w\x8Ci\x82\xF0\x95`\x89\xE6 + DrawTextBGImage(hdcBGBuffer, *X, Y, width, height); - // Unicode\x82ŏo\x97͂\xB7\x82\xE9\x81B -#if 1 - // UTF-8\x8A\xAB\x82ɂ\xA8\x82\xA2\x82āAtcsh\x82\xAAEUC\x8Fo\x97͂\xB5\x82\xBD\x8Fꍇ\x81A\x89\xE6\x96ʂɉ\xBD\x82\xE0\x95\\x8E\xA6\x82\xB3\x82\xEA\x82Ȃ\xA2\x82\xB1\x82Ƃ\xAA\x82\xA0\x82\xE9\x81B - // \x83}\x83E\x83X\x82Ńh\x83\x89\x83b\x83O\x82\xB5\x82\xBD\x82\xE8\x81A\x83\x8D\x83O\x83t\x83@\x83C\x83\x8B\x82֕ۑ\xB6\x82\xB5\x82Ă݂\xE9\x82ƁA\x95\xB6\x8E\x9A\x89\xBB\x82\xAF\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82\xF0 - // \x8Am\x94F\x82\xB7\x82邱\x82Ƃ\xAA\x82ł\xAB\x82\xE9\x81B(2004.8.6 yutaka) - ExtTextOutW(VTDC,*X+ts.FontDX,Y+ts.FontDY, - ETO_CLIPPED | ETO_OPAQUE, - &RText, wc, wclen, NULL); -// &RText, wc, wclen, &Dx[0]); -#else - TextOutW(VTDC, *X+ts.FontDX, Y+ts.FontDY, wc, wclen); + // \x95\xB6\x8E\x9A\x82\xF0\x95`\x89\xE6 + eto_options = ETO_CLIPPED; + if(BGReverseText == TRUE && BGReverseTextAlpha < 255) { + eto_options |= ETO_OPAQUE; + } + ExtTextOutW(hdcBGBuffer,ts.FontDX,ts.FontDY,eto_options,&rect, StrW,Count,&Dx[0]); + // Window\x82ɓ\\x82\xE8\x95t\x82\xAF + BitBlt(VTDC,*X,Y,width,height,hdcBGBuffer,0,0,SRCCOPY); + + SelectObject(hdcBGBuffer,hPrevFont); + } #endif - *X = RText.right; - - if ((ts.Language==IdRussian) && - (ts.RussClient!=ts.RussFont)) - RussConvStr(ts.RussFont,ts.RussClient,Buff,Count); - - free(wc); + *X += dx3 *FontWidth; } #endif - void DispEraseCurToEnd(int YEnd) { RECT R; Modified: branches/unicode_buf/teraterm/teraterm/vtdisp.h =================================================================== --- branches/unicode_buf/teraterm/teraterm/vtdisp.h 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/vtdisp.h 2019-06-25 14:05:37 UTC (rev 7810) @@ -80,6 +80,7 @@ void DispReleaseDC(); void DispSetupDC(TCharAttr Attr, BOOL Reverse); void DispStr(PCHAR Buff, int Count, int Y, int* X); +void DispStrW(const wchar_t *StrW, const char *WidthInfo, int Count, int Y, int* X); void DispEraseCurToEnd(int YEnd); void DispEraseHomeToCur(int YHome); void DispEraseCharsInLine(int XStart, int Count); Modified: branches/unicode_buf/teraterm/teraterm/vtterm.c =================================================================== --- branches/unicode_buf/teraterm/teraterm/vtterm.c 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/vtterm.c 2019-06-25 14:05:37 UTC (rev 7810) @@ -64,6 +64,8 @@ #define _strdup(s) _strdup_dbg((s), _NORMAL_BLOCK, __FILE__, __LINE__) #endif +#include "unicode_test.h" + void ParseFirst(BYTE b); #define MAPSIZE(x) (sizeof(x)/sizeof((x)[0])) @@ -661,7 +663,11 @@ else CharAttrTmp.Attr |= CharAttr.Attr; +#if UNICODE_INTERNAL_BUFF + BuffPutUnicode(b, CharAttrTmp, InsertMode); +#else BuffPutChar(b, CharAttrTmp, InsertMode); +#endif if (CursorX == CursorRightM || CursorX >= NumOfColumns-1) { UpdateStr(); @@ -672,7 +678,7 @@ } } -void PutDecSp(BYTE b) +static void PutDecSp(BYTE b) { TCharAttr CharAttrTmp; @@ -717,7 +723,7 @@ } } -void PutKanji(BYTE b) +static void PutKanji(BYTE b) { int LineEnd; TCharAttr CharAttrTmp; @@ -848,7 +854,7 @@ } } -void PrnParseControl(BYTE b) // printer mode +static void PrnParseControl(BYTE b) // printer mode { switch (b) { case NUL: @@ -897,7 +903,7 @@ WriteToPrnFile(b, TRUE); } -void ParseControl(BYTE b) +static void ParseControl(BYTE b) { if (PrinterMode) { // printer mode PrnParseControl(b); @@ -5460,6 +5466,75 @@ 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 +// \x93\xE0\x95\x94\x83R\x81[\x83h unicode\x94\xC5 +static void UnicodeToCP932(unsigned int code) +{ + unsigned short cset; + char r; + + TCharAttr CharAttrTmp; + CharAttrTmp = CharAttr; + if (code <= US) { + // C0 + ParseControl(code); +#if 0 + } else if ((0x80<=code) && (code<=0x9F)) { + // C1 + ParseControl(code); + } else if (code < 0x20) { + PutChar(code); +#endif +#if 0 + } else if (code <= 0xff) { + PutChar(code); +#endif + } else { + // Unicode\x82\xA9\x82\xE7DEC\x93\xC1\x8Eꕶ\x8E\x9A\x82ւ̃}\x83b\x83s\x83\x93\x83O + if (ts.UnicodeDecSpMapping) { + cset = UTF32ToDecSp(code); + if (((cset >> 8) & ts.UnicodeDecSpMapping) != 0) { + code = cset & 0xff; + CharAttrTmp.Attr |= AttrSpecial; + } + } + + if ((CharAttrTmp.Attr & AttrSpecial) == 0) { + if (Special) { + UpdateStr(); + Special = FALSE; + } + } else { + if (!Special) { + UpdateStr(); + Special = TRUE; + } + } + + r = BuffPutUnicode(code, CharAttrTmp, InsertMode); + if (CursorX == CursorRightM || CursorX >= NumOfColumns - 1) { + UpdateStr(); + Wrap = AutoWrapMode; + } + else { + if (r == '0' || r == 'V') { + ; + } + else { + if (r == 'W') { + // \x91S\x8Ap + MoveRight(); + } + MoveRight(); + } + } + } +} + +#else + // unicode(UTF-32)\x82\xF0\x83o\x83b\x83t\x83@(t.CodePage)\x82֏\x91\x82\xAB\x8D\x9E\x82\xDE static void UnicodeToCP932(unsigned int code) { @@ -5505,6 +5580,24 @@ } } +#endif + +// UTF-8\x82Ŏ\xF3\x90M\x83f\x81[\x83^\x82\xF0\x8F\x88\x97\x9D\x82\xB7\x82\xE9(sub) +#if UNICODE_INTERNAL_BUFF +static BOOL ParseFirstUTF8Sub(BYTE b) +{ + if (b<=US) + ParseControl(b); + else if ((b>=0x20) && (b<=0x7E)) + PutChar(b); + else if ((b>=0x80) && (b<=0x9F)) + ParseControl(b); + else if (b>=0xA0) + PutChar(b); + return TRUE; +} +#endif + // UTF-8\x82Ŏ\xF3\x90M\x83f\x81[\x83^\x82\xF0\x8F\x88\x97\x9D\x82\xB7\x82\xE9 // returns TRUE if b is processed // (actually allways returns TRUE) @@ -5533,10 +5626,19 @@ } if (count == 1) { +//#if UNICODE_INTERNAL_BUFF +#if 0 + ParseFirstUTF8Sub(buf[0]); +#else ParseASCII(buf[0]); +#endif } +//#if UNICODE_INTERNAL_BUFF +#if 0 + ParseFirstUTF8Sub(b); +#else ParseASCII(b); - +#endif count = 0; // reset counter return TRUE; } @@ -5636,7 +5738,7 @@ return TRUE; } - if ((buf[0] & 0xf1) == 0xf0 && + if ((buf[0] & 0xf8) == 0xf0 && (buf[1] & 0xc0) == 0x80 && (buf[2] & 0xc0) == 0x80 && (buf[3] & 0xc0) == 0x80) Modified: branches/unicode_buf/teraterm/teraterm/vtwin.cpp =================================================================== --- branches/unicode_buf/teraterm/teraterm/vtwin.cpp 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/teraterm/vtwin.cpp 2019-06-25 14:05:37 UTC (rev 7810) @@ -85,6 +85,10 @@ #include "tekwin.h" #include <htmlhelp.h> #include "compat_win.h" +#include "unicode_test.h" +#if UNICODE_DEBUG +#include "tipwin.h" +#endif #include "initguid.h" //#include "Usbiodef.h" @@ -144,6 +148,10 @@ #define WM_IME_COMPOSITION 0x010F #endif +#if UNICODE_DEBUG +static TipWin *TipWinCodeDebug; +#endif + ///////////////////////////////////////////////////////////////////////////// // CVTWindow @@ -2266,6 +2274,12 @@ void CVTWindow::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { KeyUp(nChar); +#if UNICODE_DEBUG + if (TipWinCodeDebug != NULL) { + TipWinDestroy(TipWinCodeDebug); + TipWinCodeDebug = NULL; + } +#endif } void CVTWindow::OnKillFocus(HWND hNewWnd) @@ -2378,6 +2392,22 @@ int i; BOOL mousereport; +#if UNICODE_DEBUG + if (GetAsyncKeyState(VK_RCONTROL) != 0) { + wchar_t buf[128]; + BuffCheckMouse(point.x, point.y, buf, _countof(buf)); + POINT TipWinPos = { point.x, point.y }; + ClientToScreen(m_hWnd, &TipWinPos); + if (TipWinCodeDebug == NULL) { + TipWinCodeDebug = TipWinCreate(m_hWnd, TipWinPos.x, TipWinPos.y, "test"); + TipWinSetTextW(TipWinCodeDebug, buf); + } else { + TipWinSetPos(TipWinCodeDebug, TipWinPos.x, TipWinPos.y); + TipWinSetTextW(TipWinCodeDebug, buf); + } + } +#endif + if (!IgnoreRelease) mousereport = MouseReport(IdMouseEventMove, 0, point.x, point.y); @@ -6286,7 +6316,9 @@ OnRButtonUp((UINT)wp, MAKEPOINTS(lp)); break; case WM_SETFOCUS: +#if !UNICODE_DEBUG_CARET_OFF OnSetFocus((HWND)wp); +#endif DefWindowProc(msg, wp, lp); break; case WM_SIZE: Modified: branches/unicode_buf/teraterm/ttpcmn/ttcmn.c =================================================================== --- branches/unicode_buf/teraterm/ttpcmn/ttcmn.c 2019-06-25 13:58:11 UTC (rev 7809) +++ branches/unicode_buf/teraterm/ttpcmn/ttcmn.c 2019-06-25 14:05:37 UTC (rev 7810) @@ -40,6 +40,7 @@ #include <setupapi.h> #include <locale.h> #include <htmlhelp.h> +#include <assert.h> #define DllExport __declspec(dllexport) #include "language.h" @@ -1920,20 +1921,129 @@ return i; } -// TODO: UTF-16\x82\xA9\x82璼\x90ڕϊ\xB7\x82\xB5\x82ďo\x97͂\xB7\x82\xE9 +/** + * CommTextOut() \x82\xCC wchar_t \x94\xC5 + * \x8D\xA1\x82̏\x8AIME\x82\xA9\x82炵\x82\xA9\x8Eg\x82\xC1\x82Ă\xA2\x82Ȃ\xA2\x82\xBD\x82\xDF + * \x90\xA7\x8C\xE4\x83R\x81[\x83h\x8Cn\x82͖\xA2\x83e\x83X\x83g + */ int WINAPI CommTextOutW(PComVar cv, const wchar_t *B, int C) { - int CodePage = *cv->CodePage; - size_t mb_len; - int r; - char *mb_str = _WideCharToMultiByte(B, C, CodePage, &mb_len); - if (mb_str == NULL) { - r = 0; - } else { - r = CommTextOut(cv, mb_str, mb_len); - free(mb_str); +#if 1 + if (cv->KanjiCodeSend == IdUTF8 || cv->Language == IdUtf8) { + int i, TempLen; + char TempStr[12]; + wchar_t d; + BOOL Full; + + Full = FALSE; + i = 0; + while (! Full && (i < C)) { + TempLen = 0; + d = B[i]; + + if (d==CR) { + TempStr[TempLen++] = 0x0d; + if (cv->CRSend==IdCRLF) { + TempStr[TempLen++] = 0x0a; + } + else if ((cv->CRSend ==IdCR) && + cv->TelFlag && ! cv->TelBinSend) { + TempStr[TempLen++] = 0; + } + else if (cv->CRSend == IdLF) { + TempStr[TempLen-1] = 0x0a; + } + if (cv->TelLineMode) { + cv->Flush = TRUE; + } + } + else if (d== BS) { + if (cv->TelLineMode) { + if (cv->FlushLen < cv->LineModeBuffCount) { + cv->LineModeBuffCount--; + } + } + else { + TempStr[TempLen++] = BS; + } + } + else if (d==0x15) { // ctrl-u + if (cv->TelLineMode) { + cv->LineModeBuffCount = cv->FlushLen; + } + else { + TempStr[TempLen++] = 0x15; + } + } + else if (d>=0x80) { + unsigned int u32; + size_t u16_len = UTF16ToUTF32(&B[i], C - i, &u32); + if (u16_len == 0) { + // \x83f\x83R\x81[\x83h\x82ł\xAB\x82Ȃ\xA2\x95\xB6\x8E\x9A + TempStr[0] = '?'; + TempLen = 1; + i++; + } else { + size_t utf8_len = sizeof(TempStr); + utf8_len = UTF32ToUTF8(u32, TempStr, utf8_len); + TempLen += utf8_len; + i += u16_len; + } + } + + if (cv->TelLineMode) { + if (TempLen > 0) { + Full = OutBuffSize - cv->LineModeBuffCount - TempLen < 0; + if (!Full) { + memcpy(&(cv->LineModeBuff[cv->LineModeBuffCount]), TempStr, TempLen); + cv->LineModeBuffCount += TempLen; + if (cv->Flush) { + cv->FlushLen = cv->LineModeBuffCount; + } + } else { + // !? + assert(FALSE); + } + } + if (cv->FlushLen > 0) { + int OutLen = CommRawOut(cv, cv->LineModeBuff, cv->FlushLen); + cv->FlushLen -= OutLen; + cv->LineModeBuffCount -= OutLen; + memmove(cv->LineModeBuff, &(cv->LineModeBuff[OutLen]), cv->LineModeBuffCount); + } + cv->Flush = FALSE; + } + else { + if (TempLen > 0) { + Full = OutBuffSize -cv->OutBuffCount -TempLen < 0; + if (! Full) { + CommRawOut(cv,TempStr,TempLen); + } else { + // !? + assert(FALSE); + } + } + } + + } // end of "while {}" + + return i; } - return r; +#endif + + { + int CodePage = *cv->CodePage; + size_t mb_len; + int r; + char *mb_str = _WideCharToMultiByte(B, C, CodePage, &mb_len); + if (mb_str == NULL) { + r = 0; + } else { + r = CommTextOut(cv, mb_str, mb_len); + free(mb_str); + } + return r; + } } // TODO: UTF-16\x82\xA9\x82璼\x90ڕϊ\xB7\x82\xB5\x82ďo\x97͂\xB7\x82\xE9