Full Unicode patch with RTL Support & BiDi logic.

This commit is well documented, so no need to tell you my life story.

Full Unicode patch with RTL Support & BiDi logic.

Removed the legacy codePage, normalised to UTF8 (65001).

It also comes with:

CTRL + A : select text (highlighted)
CTRL + C : copy
CTRL + V : paste
CTRL + X : cut
CTRL + Y : redo
CTRL + Z : undo
This commit is contained in:
rtw1x1
2025-12-26 12:32:43 +00:00
parent d37607baa1
commit a955c50744
86 changed files with 4076 additions and 3839 deletions

View File

@@ -133,252 +133,3 @@ D3DXCOLOR TokenToColor(CTokenVector & rVector)
atof(rVector[2].c_str()),
atof(rVector[3].c_str()));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
static std::string gs_fontFace="";
static DWORD gs_codePage=0;
int CALLBACK EnumFontFamExProc(CONST LOGFONT* plogFont, CONST TEXTMETRIC* /*textMetric*/, DWORD /*dwWord*/, LPARAM lParam)
{
return stricmp((const char*)lParam, plogFont->lfFaceName);
}
int GetCharsetFromCodePage(WORD codePage)
{
switch( codePage )
{
case CP_932:
return SHIFTJIS_CHARSET;
case CP_949:
return HANGUL_CHARSET;
case CP_936:
return GB2312_CHARSET;
case CP_950:
return CHINESEBIG5_CHARSET;
case CP_1253:
return GREEK_CHARSET;
case CP_1254:
return TURKISH_CHARSET;
case CP_1255:
return HEBREW_CHARSET;
case CP_1256:
return ARABIC_CHARSET;
case CP_1257:
return BALTIC_CHARSET;
case CP_1258:
return VIETNAMESE_CHARSET;
case CP_874:
return THAI_CHARSET;
case CP_1250:
return EASTEUROPE_CHARSET;
case CP_1251:
return RUSSIAN_CHARSET;
default:
return DEFAULT_CHARSET;
}
}
const char* GetFontFaceFromCodePageNT(WORD codePage)
{
switch( codePage )
{
case CP_932:
return "MS PGothic";
case CP_949:
return "GulimChe";
case CP_936:
return "SimSun";
case CP_950:
return "MingLiU";
case CP_874:
return "Tahoma";
case CP_1252:
return "Arial";
case CP_1256:
return "Tahoma";
case CP_1258:
return "Tahoma";
case CP_65001:
return "Arial";
default:
return "Arial";
}
}
const char* GetFontFaceFromCodePage9x(WORD codePage)
{
switch( codePage )
{
case CP_932:
return "굃굍 굊긕긘긞긏";
case CP_949:
return "굴림체";
case CP_936:
return "芥竟";
case CP_950:
return "꾄ⁿ톱";
case CP_874:
return "Tahoma";
case CP_1252:
return "Arial";
case CP_1256:
return "Tahoma";
case CP_1258:
return "Tahoma";
case CP_65001:
return "Arial";
default:
return "Arial";
}
}
DWORD GetDefaultCodePage()
{
return gs_codePage;
}
const char * GetDefaultFontFace()
{
return gs_fontFace.c_str();
}
const char* GetFontFaceFromCodePage(WORD codePage)
{
LOGFONTA logFont = {};
logFont.lfCharSet = GetCharsetFromCodePage(codePage);
const char* fontFace = GetFontFaceFromCodePage9x(codePage);
HDC hDC = GetDC(NULL);
if(EnumFontFamiliesEx(hDC, &logFont, EnumFontFamExProc, (LPARAM)fontFace, 0) == 0)
{
ReleaseDC(NULL, hDC);
return fontFace;
}
fontFace = GetFontFaceFromCodePageNT(codePage);
if(EnumFontFamiliesEx(hDC, &logFont, EnumFontFamExProc, (LPARAM)fontFace, 0) == 0)
{
ReleaseDC(NULL, hDC);
return fontFace;
}
ReleaseDC(NULL, hDC);
return GetDefaultFontFace();
}
void SetDefaultFontFace(const char* fontFace)
{
gs_fontFace=fontFace;
}
bool SetDefaultCodePage(DWORD codePage)
{
gs_codePage=codePage;
std::string fontFace=GetFontFaceFromCodePage(codePage);
if (fontFace.empty())
return false;
SetDefaultFontFace(fontFace.c_str());
return true;
}
int __base64_get( const int c )
{
if( 'A' <= c && c <= 'Z' )
return c-'A';
if( 'a' <= c && c <= 'z' )
return c - 'a' + 26;
if( '0' <= c && c <= '9' )
return c - '0' + 52;
if( c == '+' )
return 62;
if( c == '/' )
return 63;
if( c == '=' ) // end of line
return -1;
return -2; // non value;
}
void __strcat1(char * str,int i)
{
char result[2];
result[0] = i;
result[1] = NULL;
strcat(str,result);
}
void base64_decode(const char * str,char * resultStr)
{
int nCount=0, i=0, r, result;
int length = strlen(str);
char szDest[5]="";
strcpy(resultStr,"");
while(nCount < length)
{
i=0;
strcpy(szDest, "");
while(nCount<length && i<4) // 4개의 바이트를 얻는다.
{
r = str[nCount++];
result = __base64_get(r);
if(result!=-2)
{
if(result!=-1)
szDest[i++] = result;
else szDest[i++] = '@'; // It's end (64번은 디코딩시 사용되지 않기 때문)
}
}
if(i==4) // 4개의 소스를 모두 얻어냈다. 디코드 시작
{
if( nCount+3 >= length ) // 데이터의 끝에 도달했다.
{
if( szDest[1] == '@' )
{
__strcat1(resultStr,(szDest[0]<<2));
break;
}// exit while loop
else
__strcat1(resultStr,(szDest[0]<<2 | szDest[1]>>4)); // 1 Byte
if( szDest[2] == '@' )
{
__strcat1(resultStr,(szDest[1]<<4));
break;
}
else
__strcat1(resultStr,(szDest[1]<<4 | szDest[2]>>2)); // 2 Byte
if( szDest[3] == '@' )
{
__strcat1(resultStr,(szDest[2]<<6));
break;
}
else
__strcat1(resultStr,(szDest[2]<<6 | szDest[3])); // 3 Byte
}
else
{
__strcat1(resultStr,(szDest[0]<<2 | szDest[1]>>4)); // 1 Byte
__strcat1(resultStr,(szDest[1]<<4 | szDest[2]>>2)); // 2 Byte
__strcat1(resultStr,(szDest[2]<<6 | szDest[3])); // 3 Byte
}
}
}// end of while
for (i = 0; i < strlen(resultStr); i++)
{
char c = resultStr[i];
int xx = i + 5;
resultStr[i] = char(c ^ xx);
}
// E
}