Codechange: [Win32] Pass a native GDI font description around when we have one, instead of repeatedly guessing the font.

This commit is contained in:
Michael Lutz 2018-11-25 02:02:20 +01:00 committed by Owen Rudge
parent 2675762ae9
commit d2ed426077
8 changed files with 46 additions and 13 deletions

View File

@ -737,6 +737,7 @@ public:
virtual GlyphID MapCharToGlyph(WChar key);
virtual const char *GetFontName() { return WIDE_TO_MB(this->logfont.lfFaceName); }
virtual bool IsBuiltInFont() { return false; }
virtual void *GetOSHandle() { return &this->logfont; }
};
@ -960,13 +961,16 @@ static void LoadWin32Font(FontSize fs)
LOGFONT logfont;
MemSetT(&logfont, 0);
if (settings->os_handle != nullptr) logfont = *(const LOGFONT *)settings->os_handle;
logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH;
logfont.lfCharSet = DEFAULT_CHARSET;
logfont.lfOutPrecision = OUT_OUTLINE_PRECIS;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName), false);
if (logfont.lfFaceName[0] == 0) {
logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH;
logfont.lfCharSet = DEFAULT_CHARSET;
logfont.lfOutPrecision = OUT_OUTLINE_PRECIS;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName), false);
}
HFONT font = CreateFontIndirect(&logfont);
if (font == nullptr) {

View File

@ -125,6 +125,15 @@ public:
*/
virtual const void *GetFontTable(uint32 tag, size_t &length) = 0;
/**
* Get the native OS font handle, if there is one.
* @return Opaque OS font handle.
*/
virtual void *GetOSHandle()
{
return nullptr;
}
/**
* Get the name of this font.
* @return The name of the font.
@ -209,6 +218,8 @@ struct FreeTypeSubSetting {
char font[MAX_PATH]; ///< The name of the font, or path to the font.
uint size; ///< The (requested) size of the font.
bool aa; ///< Whether to do anti aliasing or not.
const void *os_handle = nullptr; ///< Optional native OS font info.
};
/** Settings for the freetype fonts. */

View File

@ -346,7 +346,9 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT
const char *english_name = font_name;
#endif /* WITH_FREETYPE */
info->callback->SetFontNames(info->settings, font_name);
PLOGFONT os_data = MallocT<LOGFONT>(1);
*os_data = logfont->elfLogFont;
info->callback->SetFontNames(info->settings, font_name, os_data);
if (info->callback->FindMissingGlyphs(nullptr)) return 1;
DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name);
return 0; // stop enumerating

View File

@ -148,6 +148,8 @@ void UniscribeResetScriptCache(FontSize size)
/** Load the matching native Windows font. */
static HFONT HFontFromFont(Font *font)
{
if (font->fc->GetOSHandle() != nullptr) return CreateFontIndirect((PLOGFONT)font->fc->GetOSHandle());
LOGFONT logfont;
ZeroMemory(&logfont, sizeof(LOGFONT));
logfont.lfHeight = font->fc->GetHeight();

View File

@ -2068,13 +2068,18 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher {
return false;
}
void SetFontNames(FreeTypeSettings *settings, const char *font_name) override
void SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) override
{
#if defined(WITH_FREETYPE) || defined(_WIN32)
strecpy(settings->small.font, font_name, lastof(settings->small.font));
strecpy(settings->medium.font, font_name, lastof(settings->medium.font));
strecpy(settings->large.font, font_name, lastof(settings->large.font));
#endif /* WITH_FREETYPE */
free(settings->medium.os_handle); // Only free one, they are all the same pointer.
settings->small.os_handle = os_data;
settings->medium.os_handle = os_data;
settings->large.os_handle = os_data;
#endif
}
};
@ -2103,8 +2108,14 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
FreeTypeSettings backup;
memcpy(&backup, &_freetype, sizeof(backup));
_freetype.mono.os_handle = nullptr;
_freetype.medium.os_handle = nullptr;
bad_font = !SetFallbackFont(&_freetype, _langpack->isocode, _langpack->winlangid, searcher);
free(_freetype.mono.os_handle);
free(_freetype.medium.os_handle);
memcpy(&_freetype, &backup, sizeof(backup));
if (bad_font && base_font) {

View File

@ -275,8 +275,9 @@ public:
* Set the right font names.
* @param settings The settings to modify.
* @param font_name The new font name.
* @param os_data Opaque pointer to OS-specific data.
*/
virtual void SetFontNames(struct FreeTypeSettings *settings, const char *font_name) = 0;
virtual void SetFontNames(struct FreeTypeSettings *settings, const char *font_name, const void *os_data = nullptr) = 0;
bool FindMissingGlyphs(const char **str);
};

View File

@ -194,11 +194,13 @@ void TextfileWindow::SetupScrollbars()
return true;
}
/* virtual */ void TextfileWindow::SetFontNames(FreeTypeSettings *settings, const char *font_name)
/* virtual */ void TextfileWindow::SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data)
{
#if defined(WITH_FREETYPE) || defined(_WIN32)
strecpy(settings->mono.font, font_name, lastof(settings->mono.font));
#endif /* WITH_FREETYPE */
free(settings->mono.os_handle);
settings->mono.os_handle = os_data;
#endif
}
#if defined(WITH_ZLIB)

View File

@ -43,7 +43,7 @@ struct TextfileWindow : public Window, MissingGlyphSearcher {
FontSize DefaultSize() override;
const char *NextString() override;
bool Monospace() override;
void SetFontNames(FreeTypeSettings *settings, const char *font_name) override;
void SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) override;
virtual void LoadTextfile(const char *textfile, Subdirectory dir);