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_blue = 0;
int gdrv::grtext_green = 0; int gdrv::grtext_green = 0;
int gdrv::grtext_red = -1; 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) int gdrv::init(HINSTANCE hInst, HWND hWnd)
{ {
@ -26,6 +29,9 @@ int gdrv::init(HINSTANCE hInst, HWND hWnd)
hwnd = hWnd; hwnd = hWnd;
if (!palette_handle) if (!palette_handle)
palette_handle = CreatePalette(&current_palette); palette_handle = CreatePalette(&current_palette);
choose_font();
return 0; return 0;
} }
@ -33,6 +39,10 @@ int gdrv::uninit()
{ {
if (palette_handle) if (palette_handle)
DeleteObject(palette_handle); DeleteObject(palette_handle);
if (!fontFilename.empty())
RemoveFontResourceExA(fontFilename.c_str(), FR_PRIVATE, 0);
return 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) 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; xOff = static_cast<int>(xOff * fullscrn::ScaleX) + fullscrn::OffsetX;
yOff = static_cast<int>(yOff * fullscrn::ScaleY) + fullscrn::OffsetY; yOff = static_cast<int>(yOff * fullscrn::ScaleY) + fullscrn::OffsetY;
width = static_cast<int>(width * fullscrn::ScaleX); 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); sscanf_s(fontColor, "%d %d %d", &grtext_red, &grtext_green, &grtext_blue);
} }
const char* font = "Arial"; auto fontSize = static_cast<int>(round(fontSizes[fullscrn::GetResolution()] * fullscrn::ScaleY));
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));
// Default font does not scale well // Default font does not scale well
auto hNewFont = CreateFont(fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, auto hNewFont = CreateFontA(fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, fontCharset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS, font); DEFAULT_PITCH | FF_SWISS, fontFamily.c_str());
HFONT hOldFont = static_cast<HFONT>(SelectObject(dc, hNewFont)); HFONT hOldFont = static_cast<HFONT>(SelectObject(dc, hNewFont));
int prevMode = SetBkMode(dc, TRANSPARENT); int prevMode = SetBkMode(dc, TRANSPARENT);
COLORREF color = SetTextColor(dc, grtext_red | grtext_green << 8 | grtext_blue << 16); 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 class gdrv
{ {
@ -65,6 +70,8 @@ public:
static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff, static void copy_bitmap_w_transparency(gdrv_bitmap8* dstBmp, int width, int height, int xOff, int yOff,
gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff); gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff);
static void ScrollBitmapHorizontal(gdrv_bitmap8* bmp, int xStart); 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); static void grtext_draw_ttext_in_box(LPCWSTR text, int xOff, int yOff, int width, int height, bool centered);
private: private:
/*COLORONCOLOR or HALFTONE*/ /*COLORONCOLOR or HALFTONE*/
@ -74,6 +81,10 @@ private:
static int grtext_blue; static int grtext_blue;
static int grtext_green; static int grtext_green;
static int grtext_red; 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, 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, 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 = get_int(nullptr, "Target UPS", 120);
Options.TargetUps = max(60, Options.TargetUps); Options.TargetUps = max(60, Options.TargetUps);
Options.TargetUps = min(Options.TargetUps, 360); 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 defaultLanguage = Languages::English;
auto language = static_cast<Languages>(get_int(nullptr, "Language", static_cast<int>(defaultLanguage))); 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, "Screen Resolution", Options.Resolution);
set_int(nullptr, "Uniform scaling", Options.UniformScaling); set_int(nullptr, "Uniform scaling", Options.UniformScaling);
set_int(nullptr, "Alternative Render", Options.AlternativeRender); 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, "Language", static_cast<int>(Options.Language));
set_int(nullptr, "Target UPS", Options.TargetUps); set_int(nullptr, "Target UPS", Options.TargetUps);
} }

View file

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

View file

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