in src/agent/ConsoleFont.cc [508:600]
static Font selectSmallFont(int codePage, int columns, bool isNewW10) {
// Iterate over a set of font sizes according to the code page, and select
// one.
const wchar_t *faceName = nullptr;
unsigned int fontFamily = 0;
const FontSize *table = nullptr;
size_t tableSize = 0;
switch (codePage) {
case 932: // Japanese
faceName = kMSGothic;
fontFamily = 0x36;
if (isNewW10) {
table = k932GothicWin10;
tableSize = COUNT_OF(k932GothicWin10);
} else if (isAtLeastWindows8()) {
table = k932GothicWin8;
tableSize = COUNT_OF(k932GothicWin8);
} else {
table = k932GothicVista;
tableSize = COUNT_OF(k932GothicVista);
}
break;
case 936: // Chinese Simplified
faceName = kNSimSun;
fontFamily = 0x36;
table = k936SimSun;
tableSize = COUNT_OF(k936SimSun);
break;
case 949: // Korean
faceName = kGulimChe;
fontFamily = 0x36;
table = k949GulimChe;
tableSize = COUNT_OF(k949GulimChe);
break;
case 950: // Chinese Traditional
faceName = kMingLight;
fontFamily = 0x36;
table = k950MingLight;
tableSize = COUNT_OF(k950MingLight);
break;
default:
faceName = kLucidaConsole;
fontFamily = 0x36;
table = kLucidaFontSizes;
tableSize = COUNT_OF(kLucidaFontSizes);
break;
}
size_t bestIndex = static_cast<size_t>(-1);
std::tuple<int, int> bestScore = std::make_tuple(-1, -1);
// We might want to pick the smallest possible font, because we don't know
// how large the monitor is (and the monitor size can change). We might
// want to pick a larger font to accommodate console programs that resize
// the console on their own, like DOS edit.com, which tends to resize the
// console to 80 columns.
for (size_t i = 0; i < tableSize; ++i) {
const int width = table[i].width * columns;
// In general, we'd like to pick a font size where cutting the number
// of columns in half doesn't immediately violate the minimum width
// constraint. (e.g. To run DOS edit.com, a user might resize their
// terminal to ~100 columns so it's big enough to show the 80 columns
// post-resize.) To achieve this, give priority to fonts that allow
// this halving. We don't want to encourage *very* large fonts,
// though, so disable the effect as the number of columns scales from
// 80 to 40.
const int halfColumns = std::min(columns, std::max(40, columns / 2));
const int halfWidth = table[i].width * halfColumns;
std::tuple<int, int> thisScore = std::make_tuple(-1, -1);
if (width >= 160 && halfWidth >= 160) {
// Both sizes are good. Prefer the smaller fonts.
thisScore = std::make_tuple(2, -width);
} else if (width >= 160) {
// Prefer the smaller fonts.
thisScore = std::make_tuple(1, -width);
} else {
// Otherwise, prefer the largest font in our table.
thisScore = std::make_tuple(0, width);
}
if (thisScore > bestScore) {
bestIndex = i;
bestScore = thisScore;
}
}
ASSERT(bestIndex != static_cast<size_t>(-1));
return Font { faceName, fontFamily, table[bestIndex].size };
}