Add a FontSurvey program for automatically testing 100 font sizes
This commit is contained in:
parent
f7545a8499
commit
111d0c67b1
95
misc/FontSurvey.cc
Executable file
95
misc/FontSurvey.cc
Executable file
@ -0,0 +1,95 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "TestUtil.cc"
|
||||||
|
|
||||||
|
#define COUNT_OF(array) (sizeof(array) / sizeof((array)[0]))
|
||||||
|
|
||||||
|
// See https://en.wikipedia.org/wiki/List_of_CJK_fonts
|
||||||
|
const wchar_t kMSGothic[] = { 0xff2d, 0xff33, 0x0020, 0x30b4, 0x30b7, 0x30c3, 0x30af, 0 }; // Japanese
|
||||||
|
const wchar_t kNSimSun[] = { 0x65b0, 0x5b8b, 0x4f53, 0 }; // Simplified Chinese
|
||||||
|
const wchar_t kMingLight[] = { 0x7d30, 0x660e, 0x9ad4, 0 }; // Traditional Chinese
|
||||||
|
const wchar_t kGulimChe[] = { 0xad74, 0xb9bc, 0xccb4, 0 }; // Korean
|
||||||
|
|
||||||
|
std::vector<bool> condense(const std::vector<CHAR_INFO> &buf) {
|
||||||
|
std::vector<bool> ret;
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < buf.size()) {
|
||||||
|
if (buf[i].Char.UnicodeChar == L' ' &&
|
||||||
|
((buf[i].Attributes & 0x300) == 0)) {
|
||||||
|
// end of line
|
||||||
|
break;
|
||||||
|
} else if (i + 1 < buf.size() &&
|
||||||
|
((buf[i].Attributes & 0x300) == 0x100) &&
|
||||||
|
((buf[i + 1].Attributes & 0x300) == 0x200) &&
|
||||||
|
buf[i].Char.UnicodeChar != L' ' &&
|
||||||
|
buf[i].Char.UnicodeChar == buf[i + 1].Char.UnicodeChar) {
|
||||||
|
// double-width
|
||||||
|
ret.push_back(true);
|
||||||
|
i += 2;
|
||||||
|
} else if ((buf[i].Attributes & 0x300) == 0) {
|
||||||
|
// single-width
|
||||||
|
ret.push_back(false);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
ASSERT(false && "unexpected output");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 3) {
|
||||||
|
printf("Usage: %s \"arguments for SetFont.exe\" EXPECTED_WIDTHS\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *setFontArgs = argv[1];
|
||||||
|
std::string expectedWidths = argv[2];
|
||||||
|
|
||||||
|
const wchar_t testLine[] = { 0xA2, 0xA3, 0x2014, 0x3044, 0x30FC, 0x4000, 0 };
|
||||||
|
const HANDLE conout = openConout();
|
||||||
|
|
||||||
|
char setFontCmd[1024];
|
||||||
|
for (int h = 1; h <= 100; ++h) {
|
||||||
|
sprintf(setFontCmd, ".\\SetFont.exe %s -h %d && cls", setFontArgs, h);
|
||||||
|
system(setFontCmd);
|
||||||
|
|
||||||
|
CONSOLE_FONT_INFOEX infoex = {};
|
||||||
|
infoex.cbSize = sizeof(infoex);
|
||||||
|
BOOL success = GetCurrentConsoleFontEx(conout, FALSE, &infoex);
|
||||||
|
ASSERT(success && "GetCurrentConsoleFontEx failed");
|
||||||
|
|
||||||
|
DWORD actual = 0;
|
||||||
|
success = WriteConsoleW(conout, testLine, wcslen(testLine), &actual, nullptr);
|
||||||
|
ASSERT(success && actual == wcslen(testLine));
|
||||||
|
|
||||||
|
std::vector<CHAR_INFO> readBuf(14);
|
||||||
|
const SMALL_RECT readRegion = {0, 0, static_cast<short>(readBuf.size() - 1), 0};
|
||||||
|
SMALL_RECT readRegion2 = readRegion;
|
||||||
|
success = ReadConsoleOutputW(
|
||||||
|
conout, readBuf.data(),
|
||||||
|
{static_cast<short>(readBuf.size()), 1},
|
||||||
|
{0, 0},
|
||||||
|
&readRegion2);
|
||||||
|
ASSERT(success && !memcmp(&readRegion, &readRegion2, sizeof(readRegion)));
|
||||||
|
|
||||||
|
const auto widths = condense(readBuf);
|
||||||
|
std::string widthsStr;
|
||||||
|
for (bool width : widths) {
|
||||||
|
widthsStr.append(width ? "F" : "H");
|
||||||
|
}
|
||||||
|
char size[16];
|
||||||
|
sprintf(size, "%d,%d", infoex.dwFontSize.X, infoex.dwFontSize.Y);
|
||||||
|
trace("Size %3d: %-7s %-4s (%s)", h, size,
|
||||||
|
(widthsStr == expectedWidths ? "GOOD" : "BAD"),
|
||||||
|
widthsStr.c_str());
|
||||||
|
}
|
||||||
|
sprintf(setFontCmd, ".\\SetFont.exe -face-simsun -h 14 -family 0x36");
|
||||||
|
system(setFontCmd);
|
||||||
|
}
|
@ -14,28 +14,12 @@ const wchar_t kNSimSun[] = { 0x65b0, 0x5b8b, 0x4f53, 0 }; // Simplified Chinese
|
|||||||
const wchar_t kMingLight[] = { 0x7d30, 0x660e, 0x9ad4, 0 }; // Traditional Chinese
|
const wchar_t kMingLight[] = { 0x7d30, 0x660e, 0x9ad4, 0 }; // Traditional Chinese
|
||||||
const wchar_t kGulimChe[] = { 0xad74, 0xb9bc, 0xccb4, 0 }; // Korean
|
const wchar_t kGulimChe[] = { 0xad74, 0xb9bc, 0xccb4, 0 }; // Korean
|
||||||
|
|
||||||
// Attempt to set the console font to the given facename and pixel size.
|
|
||||||
// These APIs should exist on Vista and up.
|
|
||||||
static void setConsoleFont(const wchar_t *faceName, int pixelSize)
|
|
||||||
{
|
|
||||||
CONSOLE_FONT_INFOEX fontex = {0};
|
|
||||||
fontex.cbSize = sizeof(fontex);
|
|
||||||
fontex.FontWeight = 400;
|
|
||||||
fontex.dwFontSize.Y = pixelSize;
|
|
||||||
wcsncpy(fontex.FaceName, faceName, COUNT_OF(fontex.FaceName));
|
|
||||||
fontex.nFont = 34;
|
|
||||||
BOOL ret = SetCurrentConsoleFontEx(
|
|
||||||
GetStdHandle(STD_OUTPUT_HANDLE),
|
|
||||||
FALSE,
|
|
||||||
&fontex);
|
|
||||||
cprintf(L"SetCurrentConsoleFontEx returned %d\n", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
wchar_t *cmdline = GetCommandLineW();
|
wchar_t *cmdline = GetCommandLineW();
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
wchar_t **argv = CommandLineToArgvW(cmdline, &argc);
|
wchar_t **argv = CommandLineToArgvW(cmdline, &argc);
|
||||||
|
const HANDLE conout = openConout();
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
cprintf(L"Usage:\n");
|
cprintf(L"Usage:\n");
|
||||||
@ -69,7 +53,6 @@ int main() {
|
|||||||
if (proc == NULL) {
|
if (proc == NULL) {
|
||||||
cprintf(L"Couldn't get address of SetConsoleFont\n");
|
cprintf(L"Couldn't get address of SetConsoleFont\n");
|
||||||
} else {
|
} else {
|
||||||
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
BOOL ret = reinterpret_cast<BOOL WINAPI(*)(HANDLE, DWORD)>(proc)(
|
BOOL ret = reinterpret_cast<BOOL WINAPI(*)(HANDLE, DWORD)>(proc)(
|
||||||
conout, index);
|
conout, index);
|
||||||
cprintf(L"SetFont returned %d\n", ret);
|
cprintf(L"SetFont returned %d\n", ret);
|
||||||
@ -153,7 +136,7 @@ int main() {
|
|||||||
fontex.FaceName);
|
fontex.FaceName);
|
||||||
|
|
||||||
BOOL ret = SetCurrentConsoleFontEx(
|
BOOL ret = SetCurrentConsoleFontEx(
|
||||||
GetStdHandle(STD_OUTPUT_HANDLE),
|
conout,
|
||||||
FALSE,
|
FALSE,
|
||||||
&fontex);
|
&fontex);
|
||||||
cprintf(L"SetCurrentConsoleFontEx returned %d\n", ret);
|
cprintf(L"SetCurrentConsoleFontEx returned %d\n", ret);
|
||||||
|
Loading…
Reference in New Issue
Block a user