Add support for SYSTEM font (#119)

* Add support for SYSTEM font

* Add System Font Name registry option

Issue #87
This commit is contained in:
Gábor Dobra 2022-01-18 07:42:14 +01:00 committed by GitHub
parent b10fefd5af
commit 7a6ae6ac50
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 152 additions and 40 deletions

View file

@ -16,7 +16,10 @@ int gdrv::use_wing = 0;
int gdrv::grtext_blue = 0;
int gdrv::grtext_green = 0;
int gdrv::grtext_red = -1;
std::string gdrv::fontFamily;
std::string gdrv::fontFilename;
const int* gdrv::fontSizes = nullptr;
int gdrv::fontCharset = DEFAULT_CHARSET;
int gdrv::init(HINSTANCE hInst, HWND hWnd)
{
@ -26,6 +29,9 @@ int gdrv::init(HINSTANCE hInst, HWND hWnd)
hwnd = hWnd;
if (!palette_handle)
palette_handle = CreatePalette(&current_palette);
choose_font();
return 0;
}
@ -33,6 +39,10 @@ int gdrv::uninit()
{
if (palette_handle)
DeleteObject(palette_handle);
if (!fontFilename.empty())
RemoveFontResourceExA(fontFilename.c_str(), FR_PRIVATE, 0);
return 0;
}
@ -426,23 +436,128 @@ void gdrv::ScrollBitmapHorizontal(gdrv_bitmap8* bmp, int xStart)
}
}
int CALLBACK gdrv_find_font_func(
ENUMLOGFONTEXA *lpelfe,
NEWTEXTMETRICEXA *lpntme,
DWORD FontType,
LPARAM lParam
)
{
auto* params = reinterpret_cast<EnumFindFont*>(lParam);
if (strcmp(reinterpret_cast<const char*>(lpelfe->elfFullName), params->name) == 0)
params->found = true;
return 1; // continue enumeration
}
bool gdrv::find_font(const char* fontName)
{
EnumFindFont params;
params.name = fontName;
params.found = false;
LOGFONTA lf{};
strcpy_s(lf.lfFaceName, fontName);
HDC hDC = GetDC(NULL);
EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)&gdrv_find_font_func, reinterpret_cast<LPARAM>(&params), 0);
ReleaseDC(NULL, hDC);
return params.found;
}
void gdrv::choose_font()
{
// Original font was 16 points, used with lowest table resolution
static const int fontSizes_Arial[3] = { 16, 22, 28 };
static const int fontSizes_EastAsian[3] = { 22, 27, 32 };
static const int fontSizes_System[3] = { 17, 21, 29 };
static const int fontSizes_WinMenu[3] = { 17, 21, 27 };
const char* system_font_filename = nullptr;
// Only System font requires non-default charset,
// and custom charsets may break other fonts (like WinMenu).
int systemFontCharset = DEFAULT_CHARSET;
switch (options::Options.Language)
{
case Languages::TraditionalChinese:
fontFamily = "Microsoft JhengHei";
fontSizes = fontSizes_EastAsian;
break;
case Languages::SimplifiedChinese:
fontFamily = "Microsoft YaHei";
fontSizes = fontSizes_EastAsian;
break;
case Languages::Japanese:
fontFamily = "MS UI Gothic";
fontSizes = fontSizes_Arial; // we need feedback for this
break;
case Languages::Korean:
fontFamily = "Gulim";
fontSizes = fontSizes_EastAsian;
break;
case Languages::Greek:
system_font_filename = "vgasysg.fon";
systemFontCharset = GREEK_CHARSET;
break;
case Languages::Russian:
system_font_filename = "vgasysr.fon";
systemFontCharset = RUSSIAN_CHARSET;
break;
case Languages::Turkish:
system_font_filename = "vgasyst.fon";
systemFontCharset = TURKISH_CHARSET;
break;
case Languages::Danish:
case Languages::Dutch:
case Languages::Norwegian:
case Languages::Swedish:
system_font_filename = "vgasys.fon";
systemFontCharset = DEFAULT_CHARSET;
break;
case Languages::Czech:
case Languages::Hungarian:
case Languages::Polish:
system_font_filename = "vgasyse.fon";
systemFontCharset = EASTEUROPE_CHARSET;
break;
default:
system_font_filename = "vgasys.fon";
break;
}
if (fontFamily.empty()) // no font chosen yet
{
if (!options::Options.SystemFont)
{
fontFamily = "Arial";
fontSizes = fontSizes_Arial;
}
else if (options::Options.SystemFontName[0] != '\0' && find_font(options::Options.SystemFontName))
{
fontFamily = options::Options.SystemFontName;
fontSizes = fontSizes_WinMenu;
}
else
{
fontFamily = "System";
fontSizes = fontSizes_System;
fontCharset = systemFontCharset;
std::string windir(MAX_PATH, '\0');
DWORD result = GetEnvironmentVariableA("WINDIR", &windir[0], MAX_PATH);
if (result == 0 || result > MAX_PATH) // fails or doesn't fit
windir = "C:\\Windows";
else
windir.resize(result);
fontFilename = windir + "\\Fonts\\" + system_font_filename;
AddFontResourceExA(fontFilename.c_str(), FR_PRIVATE, 0);
}
}
}
void gdrv::grtext_draw_ttext_in_box(LPCWSTR text, int xOff, int yOff, int width, int height, bool centered)
{
// Original font was 16 points, used with lowest table resolution
static const int fontSizes[3] =
{
16,
22,
28
};
static const int fontSizes_EastAsian[3] =
{
22,
27,
32
};
xOff = static_cast<int>(xOff * fullscrn::ScaleX) + fullscrn::OffsetX;
yOff = static_cast<int>(yOff * fullscrn::ScaleY) + fullscrn::OffsetY;
width = static_cast<int>(width * fullscrn::ScaleX);
@ -464,33 +579,12 @@ void gdrv::grtext_draw_ttext_in_box(LPCWSTR text, int xOff, int yOff, int width,
sscanf_s(fontColor, "%d %d %d", &grtext_red, &grtext_green, &grtext_blue);
}
const char* font = "Arial";
const int* selectedFontSizes = fontSizes;
switch (options::Options.Language)
{
case Languages::TraditionalChinese:
font = "Microsoft JhengHei";
selectedFontSizes = fontSizes_EastAsian;
break;
case Languages::SimplifiedChinese:
font = "Microsoft YaHei";
selectedFontSizes = fontSizes_EastAsian;
break;
case Languages::Japanese:
font = "MS UI Gothic";
break;
case Languages::Korean:
font = "Malgun Gothic";
selectedFontSizes = fontSizes_EastAsian;
break;
}
auto fontSize = static_cast<int>(round(selectedFontSizes[fullscrn::GetResolution()] * fullscrn::ScaleY));
auto fontSize = static_cast<int>(round(fontSizes[fullscrn::GetResolution()] * fullscrn::ScaleY));
// Default font does not scale well
auto hNewFont = CreateFont(fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS, font);
auto hNewFont = CreateFontA(fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
fontCharset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS, fontFamily.c_str());
HFONT hOldFont = static_cast<HFONT>(SelectObject(dc, hNewFont));
int prevMode = SetBkMode(dc, TRANSPARENT);
COLORREF color = SetTextColor(dc, grtext_red | grtext_green << 8 | grtext_blue << 16);

View file

@ -33,6 +33,11 @@ struct LOGPALETTEx256 : LOGPALETTE
}
};
struct EnumFindFont
{
const char* name;
bool found;
};
class gdrv
{
@ -65,6 +70,8 @@ public:
static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff,
gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff);
static void ScrollBitmapHorizontal(gdrv_bitmap8* bmp, int xStart);
static bool find_font(const char* fontName);
static void choose_font();
static void grtext_draw_ttext_in_box(LPCWSTR text, int xOff, int yOff, int width, int height, bool centered);
private:
/*COLORONCOLOR or HALFTONE*/
@ -74,6 +81,10 @@ private:
static int grtext_blue;
static int grtext_green;
static int grtext_red;
static std::string fontFamily;
static std::string fontFilename;
static const int* fontSizes;
static int fontCharset;
static int StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc,
int SrcWidth, int SrcHeight, gdrv_bitmap8* bmp, UINT iUsage,

View file

@ -139,6 +139,8 @@ void options::ReadOptions()
Options.TargetUps = get_int(nullptr, "Target UPS", 120);
Options.TargetUps = max(60, Options.TargetUps);
Options.TargetUps = min(Options.TargetUps, 360);
Options.SystemFont = get_int(nullptr, "System Font", false);
get_string(nullptr, "System Font Name", Options.SystemFontName, "", LF_FACESIZE);
auto defaultLanguage = Languages::English;
auto language = static_cast<Languages>(get_int(nullptr, "Language", static_cast<int>(defaultLanguage)));
@ -237,6 +239,8 @@ void options::uninit()
set_int(nullptr, "Screen Resolution", Options.Resolution);
set_int(nullptr, "Uniform scaling", Options.UniformScaling);
set_int(nullptr, "Alternative Render", Options.AlternativeRender);
set_int(nullptr, "System Font", Options.SystemFont);
set_string(nullptr, "System Font Name", Options.SystemFontName);
set_int(nullptr, "Language", static_cast<int>(Options.Language));
set_int(nullptr, "Target UPS", Options.TargetUps);
}

View file

@ -60,6 +60,8 @@ struct optionsStruct
bool UniformScaling;
bool AlternativeRender;
int TargetUps;
bool SystemFont;
char SystemFontName[LF_FACESIZE];
Languages Language;
};

View file

@ -19,6 +19,7 @@
#include <cstdint>
#include <type_traits> /*For control template*/
//#include <cstdlib>
#include <string>
/*Use (void) to silent unused warnings.*/
#define assertm(exp, msg) assert(((void)msg, exp))