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

View File

@ -125,6 +125,15 @@ public:
*/ */
virtual const void *GetFontTable(uint32 tag, size_t &length) = 0; 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. * Get the name of this font.
* @return The name of the 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. char font[MAX_PATH]; ///< The name of the font, or path to the font.
uint size; ///< The (requested) size of the font. uint size; ///< The (requested) size of the font.
bool aa; ///< Whether to do anti aliasing or not. bool aa; ///< Whether to do anti aliasing or not.
const void *os_handle = nullptr; ///< Optional native OS font info.
}; };
/** Settings for the freetype fonts. */ /** 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; const char *english_name = font_name;
#endif /* WITH_FREETYPE */ #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; if (info->callback->FindMissingGlyphs(nullptr)) return 1;
DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name); DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name);
return 0; // stop enumerating return 0; // stop enumerating

View File

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

View File

@ -2068,13 +2068,18 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher {
return false; 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) #if defined(WITH_FREETYPE) || defined(_WIN32)
strecpy(settings->small.font, font_name, lastof(settings->small.font)); strecpy(settings->small.font, font_name, lastof(settings->small.font));
strecpy(settings->medium.font, font_name, lastof(settings->medium.font)); strecpy(settings->medium.font, font_name, lastof(settings->medium.font));
strecpy(settings->large.font, font_name, lastof(settings->large.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; FreeTypeSettings backup;
memcpy(&backup, &_freetype, sizeof(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); bad_font = !SetFallbackFont(&_freetype, _langpack->isocode, _langpack->winlangid, searcher);
free(_freetype.mono.os_handle);
free(_freetype.medium.os_handle);
memcpy(&_freetype, &backup, sizeof(backup)); memcpy(&_freetype, &backup, sizeof(backup));
if (bad_font && base_font) { if (bad_font && base_font) {

View File

@ -275,8 +275,9 @@ public:
* Set the right font names. * Set the right font names.
* @param settings The settings to modify. * @param settings The settings to modify.
* @param font_name The new font name. * @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); bool FindMissingGlyphs(const char **str);
}; };

View File

@ -194,11 +194,13 @@ void TextfileWindow::SetupScrollbars()
return true; 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) #if defined(WITH_FREETYPE) || defined(_WIN32)
strecpy(settings->mono.font, font_name, lastof(settings->mono.font)); 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) #if defined(WITH_ZLIB)

View File

@ -43,7 +43,7 @@ struct TextfileWindow : public Window, MissingGlyphSearcher {
FontSize DefaultSize() override; FontSize DefaultSize() override;
const char *NextString() override; const char *NextString() override;
bool Monospace() 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); virtual void LoadTextfile(const char *textfile, Subdirectory dir);