Skip to content

Commit

Permalink
fix: Crash when changing DPI
Browse files Browse the repository at this point in the history
  • Loading branch information
WerWolv committed Jan 19, 2025
1 parent 16eae89 commit c117d9b
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 80 deletions.
7 changes: 7 additions & 0 deletions main/gui/source/window/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,11 @@ namespace hex {
if (!isMainWindow(window)) return;

ImHexApi::System::impl::setMainWindowPosition(x, y);

int width = 0, height = 0;
glfwGetWindowSize(window, &width, &height);
ImHexApi::System::impl::setMainWindowPosition(x, y);
ImHexApi::System::impl::setMainWindowSize(width, height);
});

// Register window resize callback
Expand Down Expand Up @@ -1091,6 +1096,8 @@ namespace hex {
io.ConfigWindowsMoveFromTitleBarOnly = true;
io.FontGlobalScale = 1.0F;

ImGui::GetCurrentContext()->FontAtlasOwnedByContext = false;

if (glfwGetPrimaryMonitor() != nullptr) {
if (ImHexApi::System::isMutliWindowModeEnabled())
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
Expand Down
69 changes: 23 additions & 46 deletions plugins/fonts/include/font_atlas.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ namespace hex::fonts {
enableUnicodeCharacters(false);

// Set the default configuration for the font atlas
m_config.OversampleH = m_config.OversampleV = 1;
m_config.PixelSnapH = true;
m_config.MergeMode = false;
m_defaultConfig.OversampleH = m_defaultConfig.OversampleV = 1;
m_defaultConfig.PixelSnapH = true;
m_defaultConfig.MergeMode = false;

// Make sure the font atlas doesn't get too large, otherwise weaker GPUs might reject it
m_fontAtlas->Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;
Expand All @@ -52,57 +52,38 @@ namespace hex::fonts {
FontAtlas(const FontAtlas &) = delete;
FontAtlas &operator=(const FontAtlas &) = delete;

FontAtlas(FontAtlas &&other) noexcept {
this->m_fontAtlas = other.m_fontAtlas;
other.m_fontAtlas = nullptr;

this->m_fontSizes = std::move(other.m_fontSizes);
this->m_config = other.m_config;
this->m_glyphRange = std::move(other.m_glyphRange);
this->m_fontData = std::move(other.m_fontData);
}

FontAtlas &operator=(FontAtlas &&other) noexcept {
this->m_fontAtlas = other.m_fontAtlas;
other.m_fontAtlas = nullptr;

this->m_fontSizes = std::move(other.m_fontSizes);
this->m_config = other.m_config;
this->m_glyphRange = std::move(other.m_glyphRange);
this->m_fontData = std::move(other.m_fontData);

return *this;
}

~FontAtlas() {
if (m_fontAtlas != nullptr)
if (m_fontAtlas != nullptr) {
m_fontAtlas->Locked = false;
IM_DELETE(m_fontAtlas);
m_fontAtlas = nullptr;
}
}

Font addDefaultFont() {
ImFontConfig config = m_config;
auto &config = m_fontConfigs.emplace_back(m_defaultConfig);
config.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting;
config.SizePixels = std::floor(getAdjustedFontSize(ImHexApi::System::getGlobalScale() * 13.0F));

auto font = m_fontAtlas->AddFontDefault(&config);
m_fontSizes.emplace_back(false, config.SizePixels);

m_config.MergeMode = true;
m_defaultConfig.MergeMode = true;

return Font(font);
}

Font addFontFromMemory(const std::vector<u8> &fontData, float fontSize, bool scalable, ImVec2 offset, const ImVector<ImWchar> &glyphRange = {}) {
auto &storedFontData = m_fontData.emplace_back(fontData);

ImFontConfig config = m_config;
auto &config = m_fontConfigs.emplace_back(m_defaultConfig);
config.FontDataOwnedByAtlas = false;

config.GlyphOffset = { offset.x, offset.y };
auto font = m_fontAtlas->AddFontFromMemoryTTF(storedFontData.data(), int(storedFontData.size()), getAdjustedFontSize(fontSize), &config, !glyphRange.empty() ? glyphRange.Data : m_glyphRange.Data);
m_fontSizes.emplace_back(scalable, fontSize);

m_config.MergeMode = true;
m_defaultConfig.MergeMode = true;

return Font(font);
}
Expand All @@ -121,23 +102,23 @@ namespace hex::fonts {

void setBold(bool enabled) {
if (enabled)
m_config.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Bold;
m_defaultConfig.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Bold;
else
m_config.FontBuilderFlags &= ~ImGuiFreeTypeBuilderFlags_Bold;
m_defaultConfig.FontBuilderFlags &= ~ImGuiFreeTypeBuilderFlags_Bold;
}

void setItalic(bool enabled) {
if (enabled)
m_config.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Oblique;
m_defaultConfig.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Oblique;
else
m_config.FontBuilderFlags &= ~ImGuiFreeTypeBuilderFlags_Oblique;
m_defaultConfig.FontBuilderFlags &= ~ImGuiFreeTypeBuilderFlags_Oblique;
}

void setAntiAliasing(bool enabled) {
if (enabled)
m_config.FontBuilderFlags &= ~ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting;
m_defaultConfig.FontBuilderFlags &= ~ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting;
else
m_config.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting;
m_defaultConfig.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Monochrome | ImGuiFreeTypeBuilderFlags_MonoHinting;
}

void enableUnicodeCharacters(bool enabled) {
Expand Down Expand Up @@ -177,14 +158,12 @@ namespace hex::fonts {
}

[[nodiscard]] ImFontAtlas* getAtlas() {
auto result = m_fontAtlas;

return result;
return m_fontAtlas;
}

float calculateFontDescend(const ImHexApi::Fonts::Font &font, float fontSize) const {
auto atlas = std::make_unique<ImFontAtlas>();
auto cfg = m_config;
auto cfg = m_defaultConfig;

// Calculate the expected font size
auto size = fontSize;
Expand Down Expand Up @@ -214,11 +193,8 @@ namespace hex::fonts {
}

void reset() {
/*IM_DELETE(m_fontAtlas);
m_fontAtlas = IM_NEW(ImFontAtlas);*/

m_fontData.clear();
m_config.MergeMode = false;
m_defaultConfig.MergeMode = false;
}

void updateFontScaling(float newScaling) {
Expand All @@ -242,9 +218,10 @@ namespace hex::fonts {
}

private:
ImFontAtlas* m_fontAtlas;
ImFontAtlas* m_fontAtlas = nullptr;
std::vector<std::pair<bool, float>> m_fontSizes;
ImFontConfig m_config;
ImFontConfig m_defaultConfig;
std::list<ImFontConfig> m_fontConfigs;
ImVector<ImWchar> m_glyphRange;

std::list<std::vector<u8>> m_fontData;
Expand Down
2 changes: 1 addition & 1 deletion plugins/fonts/include/font_settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace hex::fonts {

private:
std::string m_selectedFontName;
bool m_pixelPerfectFont = false;
bool m_pixelPerfectFont = true;
};

class SliderPoints : public ContentRegistry::Settings::Widgets::SliderFloat {
Expand Down
46 changes: 13 additions & 33 deletions plugins/fonts/source/library_fonts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ namespace hex::fonts {

bool buildFontAtlas(FontAtlas *fontAtlas, std::fs::path fontPath, bool pixelPerfectFont, float fontSize, bool loadUnicodeCharacters, bool bold, bool italic, bool antialias);

static AutoReset<std::map<ImFont*, FontAtlas>> s_fontAtlases;
static AutoReset<std::map<ImFont*, std::unique_ptr<FontAtlas>>> s_fontAtlases;

void loadFont(const ContentRegistry::Settings::Widgets::Widget &widget, const UnlocalizedString &name, ImFont **font) {
void loadFont(const ContentRegistry::Settings::Widgets::Widget &widget, const UnlocalizedString &name, ImFont **font, float scale) {
const auto &settings = static_cast<const FontSelector&>(widget);

FontAtlas atlas;
auto atlas = std::make_unique<FontAtlas>();

const bool atlasBuilt = buildFontAtlas(
&atlas,
atlas.get(),
settings.getFontPath(),
settings.isPixelPerfectFont(),
settings.getFontSize(),
settings.getFontSize() * scale,
true,
settings.isBold(),
settings.isItalic(),
Expand All @@ -35,10 +35,10 @@ namespace hex::fonts {

if (!atlasBuilt) {
buildFontAtlas(
&atlas,
atlas.get(),
"",
false,
settings.getFontSize(),
settings.getFontSize() * scale,
false,
settings.isBold(),
settings.isItalic(),
Expand All @@ -48,32 +48,9 @@ namespace hex::fonts {
log::error("Failed to load font {}! Reverting back to default font!", name.get());
}

if (*font != nullptr) {
EventDPIChanged::unsubscribe(*font);
}

*font = atlas.getAtlas()->Fonts[0];
*font = atlas->getAtlas()->Fonts[0];

s_fontAtlases->insert_or_assign(*font, std::move(atlas));
(*s_fontAtlases)[*font] = std::move(atlas);

EventDPIChanged::subscribe(*font, [&atlas, font](float, float newScaling) {
atlas.updateFontScaling(newScaling);

if (atlas.build()) {
auto &io = ImGui::GetIO();
auto prevFont = io.Fonts;

{
io.Fonts = atlas.getAtlas();
ImGui_ImplOpenGL3_DestroyFontsTexture();
ImGui_ImplOpenGL3_CreateFontsTexture();
io.Fonts = prevFont;
}

*font = atlas.getAtlas()->Fonts[0];
}
});
}

bool setupFonts() {
Expand All @@ -87,10 +64,13 @@ namespace hex::fonts {
return;
}

loadFont(widget, name, &font);
loadFont(widget, name, &font, ImHexApi::System::getGlobalScale());
});

loadFont(widget.getWidget(), name, &font);
loadFont(widget.getWidget(), name, &font, ImHexApi::System::getGlobalScale());
EventDPIChanged::subscribe(font, [&widget, name, &font](float, float newScaling) {
loadFont(widget.getWidget(), name, &font, newScaling);
});
}

return true;
Expand Down

0 comments on commit c117d9b

Please sign in to comment.