Add a new test program, QueryFont, and expand SetFont.

This commit is contained in:
Ryan Prichard 2015-10-09 17:42:18 -05:00
parent 44ee1cc7ea
commit 5beb4c1cbb
3 changed files with 224 additions and 6 deletions

75
misc/QueryFont.cc Normal file
View File

@ -0,0 +1,75 @@
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <wchar.h>
#include "TestUtil.cc"
#include "../shared/DebugClient.cc"
static void queryCurrentConsoleFont(HANDLE conout, BOOL max) {
CONSOLE_FONT_INFO info = {0};
if (!GetCurrentConsoleFont(conout, max, &info)) {
cprintf(L"GetCurrentConsoleFont call failed\n");
} else {
cprintf(L"info(max=%d): nFont=%u dwFontSize=(%d,%d)\n",
max, static_cast<unsigned>(info.nFont),
info.dwFontSize.X, info.dwFontSize.Y);
}
}
static void queryCurrentConsoleFontEx(HANDLE conout, BOOL max) {
CONSOLE_FONT_INFOEX infoex = {0};
infoex.cbSize = sizeof(infoex);
if (!GetCurrentConsoleFontEx(conout, max, &infoex)) {
cprintf(L"GetCurrentConsoleFontEx call failed\n");
} else {
wchar_t faceName[LF_FACESIZE + 1];
memcpy(faceName, infoex.FaceName, sizeof(faceName));
faceName[LF_FACESIZE] = L'\0';
cprintf(L"infoex(max=%d): nFont=%u dwFontSize=(%d,%d) "
L"FontFamily=0x%x FontWeight=%u "
L"FaceName=\"%ls\"",
max, static_cast<unsigned>(infoex.nFont),
infoex.dwFontSize.X, infoex.dwFontSize.Y,
infoex.FontFamily, infoex.FontWeight,
faceName);
cprintf(L" (");
for (int i = 0; i < LF_FACESIZE; ++i) {
if (i > 0) {
cprintf(L" ");
}
cprintf(L"%X", infoex.FaceName[i]);
if (infoex.FaceName[i] == L'\0') {
break;
}
}
cprintf(L")\n");
}
}
int main() {
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
queryCurrentConsoleFont(conout, FALSE);
queryCurrentConsoleFont(conout, TRUE);
queryCurrentConsoleFontEx(conout, FALSE);
queryCurrentConsoleFontEx(conout, TRUE);
const COORD largest = GetLargestConsoleWindowSize(conout);
cprintf(L"largestConsoleWindowSize=(%d,%d)\n", largest.X, largest.Y);
for (int i = 0;; ++i) {
const COORD size = GetConsoleFontSize(conout, i);
if (size.X == 0 && size.Y == 0) {
break;
}
cprintf(L"font %d: %dx%d\n", i, size.X, size.Y);
}
HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
FARPROC proc = GetProcAddress(kernel32, "GetNumberOfConsoleFonts");
if (proc == NULL) {
cprintf(L"Could not get address of GetNumberOfConsoleFonts\n");
} else {
cprintf(L"GetNumberOfConsoleFonts returned %d\n",
reinterpret_cast<int WINAPI(*)(HANDLE)>(proc)(conout));
}
cprintf(L"InputCP=%u OutputCP=%u", GetConsoleCP(), GetConsoleOutputCP());
return 0;
}

View File

@ -1,5 +1,10 @@
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "TestUtil.cc"
#include "../shared/DebugClient.cc"
#define COUNT_OF(array) (sizeof(array) / sizeof((array)[0]))
@ -12,16 +17,131 @@ static void setConsoleFont(const wchar_t *faceName, int pixelSize)
fontex.FontWeight = 400;
fontex.dwFontSize.Y = pixelSize;
wcsncpy(fontex.FaceName, faceName, COUNT_OF(fontex.FaceName));
SetCurrentConsoleFontEx(
fontex.nFont = 34;
BOOL ret = SetCurrentConsoleFontEx(
GetStdHandle(STD_OUTPUT_HANDLE),
FALSE,
&fontex);
printf("SetCurrentConsoleFontEx returned %d\n", ret);
}
int main(int argc, char *argv[]) {
wchar_t faceName[256];
mbstowcs(faceName, argv[1], COUNT_OF(faceName) - 1);
faceName[COUNT_OF(faceName) - 1] = L'\0';
setConsoleFont(faceName, atoi(argv[2]));
if (argc == 1) {
printf("Usage:\n");
printf(" SetFont <index>\n");
printf(" SetFont options\n");
printf("\n");
printf("Options for SetCurrentConsoleFontEx:\n");
printf(" -idx INDEX\n");
printf(" -w WIDTH\n");
printf(" -h HEIGHT\n");
printf(" -weight (normal|bold|NNN)\n");
printf(" -face FACENAME\n");
printf(" -tt\n");
printf(" -vec\n");
printf(" -vp\n");
printf(" -dev\n");
printf(" -roman\n");
printf(" -swiss\n");
printf(" -modern\n");
printf(" -script\n");
printf(" -decorative\n");
return 0;
}
if (isdigit(argv[1][0])) {
int index = atoi(argv[1]);
HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
FARPROC proc = GetProcAddress(kernel32, "SetConsoleFont");
if (proc == NULL) {
printf("Couldn't get address of SetConsoleFont\n");
} else {
const HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE);
BOOL ret = reinterpret_cast<BOOL WINAPI(*)(HANDLE, DWORD)>(proc)(
conout, index);
printf("SetFont returned %d\n", ret);
}
return 0;
}
CONSOLE_FONT_INFOEX fontex = {0};
fontex.cbSize = sizeof(fontex);
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (i + 1 < argc) {
std::string next = argv[i + 1];
if (arg == "-idx") {
fontex.nFont = atoi(next.c_str());
++i; continue;
} else if (arg == "-w") {
fontex.dwFontSize.X = atoi(next.c_str());
++i; continue;
} else if (arg == "-h") {
fontex.dwFontSize.Y = atoi(next.c_str());
++i; continue;
} else if (arg == "-weight") {
if (next == "normal") {
fontex.FontWeight = 400;
} else if (next == "bold") {
fontex.FontWeight = 700;
} else {
fontex.FontWeight = atoi(next.c_str());
}
++i; continue;
} else if (arg == "-face") {
memset(&fontex.FaceName, 0, sizeof(fontex.FaceName));
mbstowcs(fontex.FaceName, next.c_str(), COUNT_OF(fontex.FaceName) - 1);
fontex.FaceName[COUNT_OF(fontex.FaceName) - 1] = L'\0';
++i; continue;
}
}
if (arg == "-tt") {
fontex.FontFamily |= TMPF_TRUETYPE;
} else if (arg == "-vec") {
fontex.FontFamily |= TMPF_VECTOR;
} else if (arg == "-vp") {
// Setting the TMPF_FIXED_PITCH bit actually indicates variable
// pitch.
fontex.FontFamily |= TMPF_FIXED_PITCH;
} else if (arg == "-dev") {
fontex.FontFamily |= TMPF_DEVICE;
} else if (arg == "-roman") {
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_ROMAN;
} else if (arg == "-swiss") {
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_SWISS;
} else if (arg == "-modern") {
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_MODERN;
} else if (arg == "-script") {
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_SCRIPT;
} else if (arg == "-decorative") {
fontex.FontFamily = (fontex.FontFamily & ~0xF0) | FF_DECORATIVE;
} else if (arg == "-face-gothic") {
// ゴシック
const wchar_t gothicFace[] = {
0xFF2D, 0xFF33, 0x20, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0x0
};
memset(&fontex.FaceName, 0, sizeof(fontex.FaceName));
wcscpy(fontex.FaceName, gothicFace);
} else {
printf("Unrecognized argument: %s\n", arg.c_str());
exit(1);
}
}
cprintf(L"Setting to: nFont=%u dwFontSize=(%d,%d) "
L"FontFamily=0x%x FontWeight=%u "
L"FaceName=\"%ls\"\n",
static_cast<unsigned>(fontex.nFont),
fontex.dwFontSize.X, fontex.dwFontSize.Y,
fontex.FontFamily, fontex.FontWeight,
fontex.FaceName);
BOOL ret = SetCurrentConsoleFontEx(
GetStdHandle(STD_OUTPUT_HANDLE),
FALSE,
&fontex);
printf("SetCurrentConsoleFontEx returned %d\n", ret);
return 0;
}

View File

@ -96,4 +96,27 @@ static void repeatChar(int count, char ch) {
putchar(ch);
}
fflush(stdout);
}
}
// I don't know why, but wprintf fails to print this face name,
// " ゴシック" (aka MS Gothic). It helps to use wprintf instead of printf, and
// it helps to call `setlocale(LC_ALL, "")`, but the Japanese symbols are
// ultimately converted to `?` symbols, even though MS Gothic is able to
// display its own name, and the current code page is 932 (Shift-JIS).
static void cvprintf(const wchar_t *fmt, va_list ap) {
wchar_t buffer[256];
vswprintf(buffer, 256 - 1, fmt, ap);
buffer[255] = L'\0';
DWORD actual = 0;
if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
buffer, wcslen(buffer), &actual, NULL)) {
wprintf(L"WriteConsoleW call failed!\n");
}
}
static void cprintf(const wchar_t *fmt, ...) {
va_list ap;
va_start(ap, fmt);
cvprintf(fmt, ap);
va_end(ap);
}