indiaai-hackathon
/
datalab
/web
/node_modules
/node-pty
/deps
/winpty
/misc
/UnicodeDoubleWidthTest.cc
| // Demonstrates how U+30FC is sometimes handled as a single-width character | |
| // when it should be handled as a double-width character. | |
| // | |
| // It only runs on computers where 932 is a valid code page. Set the system | |
| // local to "Japanese (Japan)" to ensure this. | |
| // | |
| // The problem seems to happen when U+30FC is printed in a console using the | |
| // Lucida Console font, and only when that font is at certain sizes. | |
| // | |
| static void setFont(const wchar_t *faceName, int pxSize) { | |
| CONSOLE_FONT_INFOEX infoex = {0}; | |
| infoex.cbSize = sizeof(infoex); | |
| infoex.dwFontSize.Y = pxSize; | |
| wcsncpy(infoex.FaceName, faceName, COUNT_OF(infoex.FaceName)); | |
| BOOL ret = SetCurrentConsoleFontEx( | |
| GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &infoex); | |
| assert(ret); | |
| } | |
| static bool performTest(const wchar_t testChar) { | |
| const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE); | |
| SetConsoleTextAttribute(conout, 7); | |
| system("cls"); | |
| DWORD actual = 0; | |
| BOOL ret = WriteConsoleW(conout, &testChar, 1, &actual, NULL); | |
| assert(ret && actual == 1); | |
| CHAR_INFO verify[2]; | |
| COORD bufSize = {2, 1}; | |
| COORD bufCoord = {0, 0}; | |
| const SMALL_RECT readRegion = {0, 0, 1, 0}; | |
| SMALL_RECT actualRegion = readRegion; | |
| ret = ReadConsoleOutputW(conout, verify, bufSize, bufCoord, &actualRegion); | |
| assert(ret && !memcmp(&readRegion, &actualRegion, sizeof(readRegion))); | |
| assert(verify[0].Char.UnicodeChar == testChar); | |
| if (verify[1].Char.UnicodeChar == testChar) { | |
| // Typical double-width behavior with a TrueType font. Pass. | |
| assert(verify[0].Attributes == 0x107); | |
| assert(verify[1].Attributes == 0x207); | |
| return true; | |
| } else if (verify[1].Char.UnicodeChar == 0) { | |
| // Typical double-width behavior with a Raster Font. Pass. | |
| assert(verify[0].Attributes == 7); | |
| assert(verify[1].Attributes == 0); | |
| return true; | |
| } else if (verify[1].Char.UnicodeChar == L' ') { | |
| // Single-width behavior. Fail. | |
| assert(verify[0].Attributes == 7); | |
| assert(verify[1].Attributes == 7); | |
| return false; | |
| } else { | |
| // Unexpected output. | |
| assert(false); | |
| } | |
| } | |
| int main(int argc, char *argv[]) { | |
| setlocale(LC_ALL, ""); | |
| if (argc == 1) { | |
| startChildProcess(L"CHILD"); | |
| return 0; | |
| } | |
| assert(SetConsoleCP(932)); | |
| assert(SetConsoleOutputCP(932)); | |
| const wchar_t testChar = 0x30FC; | |
| const wchar_t *const faceNames[] = { | |
| L"Lucida Console", | |
| L"Consolas", | |
| L"MS ゴシック", | |
| }; | |
| trace("Test started"); | |
| for (auto faceName : faceNames) { | |
| for (int px = 1; px <= 50; ++px) { | |
| setFont(faceName, px); | |
| if (!performTest(testChar)) { | |
| trace("FAILURE: %s %dpx", narrowString(faceName).c_str(), px); | |
| } | |
| } | |
| } | |
| trace("Test complete"); | |
| return 0; | |
| } | |