Skip to content

Commit

Permalink
textdisp: Split the CreateFont() detour to make use of detour promotion.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmlgc committed Jun 24, 2014
1 parent ee2741c commit 8d54854
Showing 1 changed file with 36 additions and 22 deletions.
58 changes: 36 additions & 22 deletions thcrap/src/textdisp.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@
/// Detour chains
/// -------------
DETOUR_CHAIN_DEF(CreateFontU);
// Type-safety is nice
static CreateFontIndirectExA_type chain_CreateFontIndirectExU = CreateFontIndirectExU;
/// -------------

// This detour is kept for backwards compatibility to patch configurations
// that replace multiple fonts via hardcoded string translation. Due to the
// fact that lower levels copy [pszFaceName] into the LOGFONT structure,
// it would be impossible to look up a replacement font name there.
HFONT WINAPI textdisp_CreateFontA(
__in int cHeight,
__in int cWidth,
Expand All @@ -32,51 +38,58 @@ HFONT WINAPI textdisp_CreateFontA(
__in_opt LPCSTR pszFaceName
)
{
int replaced = 0;
const char *string_font;

// Check hardcoded strings and the run configuration for a replacement
// font. Hardcoded strings take priority here.
string_font = strings_lookup(pszFaceName, NULL);
const char *string_font = strings_lookup(pszFaceName, NULL);
if(string_font != pszFaceName) {
pszFaceName = string_font;
replaced = 1;
} else {
json_t *run_font = json_object_get(run_cfg, "font");
if(json_is_string(run_font)) {
pszFaceName = json_string_value(run_font);
replaced = 1;
}
}
return (HFONT)chain_CreateFontU(
cHeight, cWidth, cEscapement, cOrientation, cWeight, bItalic,
bUnderline, bStrikeOut, iCharSet, iOutPrecision, iClipPrecision,
iQuality, iPitchAndFamily, pszFaceName
);
}

HFONT WINAPI textdisp_CreateFontIndirectExA(
__in ENUMLOGFONTEXDVA *lpelfe
)
{
LOGFONTA *lf = NULL;
if(!lpelfe) {
return NULL;
}
lf = &lpelfe->elfEnumLogfontEx.elfLogFont;
/**
* CreateFont() prioritizes [iCharSet] and ensures that the final font
* can display the given charset. If the font given in [pszFaceName]
* doesn't claim to cover the range of codepoints used in [iCharSet],
* Windows will just ignore [pszFaceName], select a different font
* CreateFont() prioritizes [lfCharSet] and ensures that the final font
* can display the given charset. If the font given in [lfFaceName]
* doesn't claim to cover the range of codepoints used in [lfCharSet],
* Windows will just ignore [lfFaceName], select a different font
* that does, and return that instead.
* To ensure that we actually get the named font, we instead specify
* DEFAULT_CHARSET, which refers to the charset of the current system
* locale. Yes, there's unfortunately no DONTCARE_CHARSET, but this
* should be fine for most use cases.
*
* However, we only do this if we *have* a face name, either from the
* original code or the run configuration. If [pszFaceName] is NULL or
* original code or the run configuration. If [lfFaceName] is NULL or
* empty, CreateFont() should simply use the default system font for
* [iCharSet], and DEFAULT_CHARSET might result in a different font.
* [lfCharSet], and DEFAULT_CHARSET might result in a different font.
*/
if(pszFaceName && pszFaceName[0]) {
iCharSet = DEFAULT_CHARSET;
if(lf->lfFaceName[0]) {
lf->lfCharSet = DEFAULT_CHARSET;
}
log_printf(
"CreateFontA: %s%s %d (Weight %d, CharSet %d, PitchAndFamily 0x%0x)\n",
pszFaceName, replaced ? " (repl.)" : "",
cHeight, cWeight, iCharSet, iPitchAndFamily
);
return (HFONT)chain_CreateFontU(
cHeight, cWidth, cEscapement, cOrientation, cWeight, bItalic,
bUnderline, bStrikeOut, iCharSet, iOutPrecision, iClipPrecision,
iQuality, iPitchAndFamily, pszFaceName
"CreateFont: %s %d (Weight %d, CharSet %d, PitchAndFamily 0x%0x)\n",
lf->lfFaceName, lf->lfHeight, lf->lfWeight,
lf->lfCharSet, lf->lfPitchAndFamily
);
return chain_CreateFontIndirectExU(lpelfe);
}

void patch_fonts_load(const json_t *patch_info)
Expand Down Expand Up @@ -106,6 +119,7 @@ void textdisp_mod_detour(void)
{
detour_chain("gdi32.dll", 1,
"CreateFontA", textdisp_CreateFontA, &chain_CreateFontU,
"CreateFontIndirectExA", textdisp_CreateFontIndirectExA, &chain_CreateFontIndirectExU,
NULL
);
}
Expand Down

0 comments on commit 8d54854

Please sign in to comment.