Skip to content

Commit

Permalink
Codechange: [Win32] Pass a native GDI font description around when we…
Browse files Browse the repository at this point in the history
… have one, instead of repeatedly guessing the font.
  • Loading branch information
michicc authored and orudge committed May 14, 2019
1 parent 2675762 commit d2ed426
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 14 deletions.
18 changes: 11 additions & 7 deletions src/fontcache.cpp
Expand Up @@ -737,6 +737,7 @@ class Win32FontCache : public TrueTypeFontCache {
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; }
};


Expand Down Expand Up @@ -960,13 +961,16 @@ static void LoadWin32Font(FontSize fs)

LOGFONT logfont;
MemSetT(&logfont, 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);
if (settings->os_handle != nullptr) logfont = *(const LOGFONT *)settings->os_handle;

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) {
Expand Down
11 changes: 11 additions & 0 deletions src/fontcache.h
Expand Up @@ -125,6 +125,15 @@ class FontCache {
*/
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.
Expand Down Expand Up @@ -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. */
Expand Down
4 changes: 3 additions & 1 deletion src/fontdetection.cpp
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/os/windows/string_uniscribe.cpp
Expand Up @@ -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();
Expand Down
15 changes: 13 additions & 2 deletions src/strings.cpp
Expand Up @@ -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
}
};

Expand Down Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion src/strings_func.h
Expand Up @@ -275,8 +275,9 @@ class MissingGlyphSearcher {
* 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);
};
Expand Down
6 changes: 4 additions & 2 deletions src/textfile_gui.cpp
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/textfile_gui.h
Expand Up @@ -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);

Expand Down

0 comments on commit d2ed426

Please sign in to comment.