11 #define COUNT_OF(array) (sizeof(array) / sizeof((array)[0]))
13 // See https://en.wikipedia.org/wiki/List_of_CJK_fonts
14 const wchar_t kMSGothic[] = { 0xff2d, 0xff33, 0x0020, 0x30b4, 0x30b7, 0x30c3, 0x30af, 0 }; // Japanese
15 const wchar_t kNSimSun[] = { 0x65b0, 0x5b8b, 0x4f53, 0 }; // Simplified Chinese
16 const wchar_t kMingLight[] = { 0x7d30, 0x660e, 0x9ad4, 0 }; // Traditional Chinese
17 const wchar_t kGulimChe[] = { 0xad74, 0xb9bc, 0xccb4, 0 }; // Korean
19 std::vector<bool> condense(const std::vector<CHAR_INFO> &buf) {
20 std::vector<bool> ret;
22 while (i < buf.size()) {
23 if (buf[i].Char.UnicodeChar == L' ' &&
24 ((buf[i].Attributes & 0x300) == 0)) {
27 } else if (i + 1 < buf.size() &&
28 ((buf[i].Attributes & 0x300) == 0x100) &&
29 ((buf[i + 1].Attributes & 0x300) == 0x200) &&
30 buf[i].Char.UnicodeChar != L' ' &&
31 buf[i].Char.UnicodeChar == buf[i + 1].Char.UnicodeChar) {
35 } else if ((buf[i].Attributes & 0x300) == 0) {
40 ASSERT(false && "unexpected output");
46 int main(int argc, char *argv[]) {
48 printf("Usage: %s \"arguments for SetFont.exe\"\n", argv[0]);
52 const char *setFontArgs = argv[1];
54 const wchar_t testLine[] = { 0xA2, 0xA3, 0x2014, 0x3044, 0x30FC, 0x4000, 0 };
55 const HANDLE conout = openConout();
57 char setFontCmd[1024];
58 for (int h = 1; h <= 100; ++h) {
59 sprintf(setFontCmd, ".\\SetFont.exe %s -h %d && cls", setFontArgs, h);
62 CONSOLE_FONT_INFOEX infoex = {};
63 infoex.cbSize = sizeof(infoex);
64 BOOL success = GetCurrentConsoleFontEx(conout, FALSE, &infoex);
65 ASSERT(success && "GetCurrentConsoleFontEx failed");
68 success = WriteConsoleW(conout, testLine, wcslen(testLine), &actual, nullptr);
69 ASSERT(success && actual == wcslen(testLine));
71 std::vector<CHAR_INFO> readBuf(14);
72 const SMALL_RECT readRegion = {0, 0, static_cast<short>(readBuf.size() - 1), 0};
73 SMALL_RECT readRegion2 = readRegion;
74 success = ReadConsoleOutputW(
75 conout, readBuf.data(),
76 {static_cast<short>(readBuf.size()), 1},
79 ASSERT(success && !memcmp(&readRegion, &readRegion2, sizeof(readRegion)));
81 const auto widths = condense(readBuf);
82 std::string widthsStr;
83 for (bool width : widths) {
84 widthsStr.append(width ? "F" : "H");
87 sprintf(size, "%d,%d", infoex.dwFontSize.X, infoex.dwFontSize.Y);
88 const char *status = "";
89 if (widthsStr == "HHFFFF") {
91 } else if (widthsStr == "HHHFFF") {
96 trace("Size %3d: %-7s %-4s (%s)", h, size, status, widthsStr.c_str());
98 sprintf(setFontCmd, ".\\SetFont.exe %s -h 14", setFontArgs);