Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support high-DPI rendering in a cross-platform way #1816

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/libimhex/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ set(LIBIMHEX_SOURCES
source/providers/memory_provider.cpp
source/providers/undo/stack.cpp

source/ui/glfw_di.cpp
source/ui/imgui_imhex_extensions.cpp
source/ui/view.cpp
source/ui/popup.cpp
Expand Down
2 changes: 1 addition & 1 deletion lib/libimhex/include/hex/api/event_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ namespace hex {
EVENT_DEF(EventAbnormalTermination, int);
EVENT_DEF(EventThemeChanged);
EVENT_DEF(EventOSThemeChanged);
EVENT_DEF(EventDPIChanged, float, float);
EVENT_DEF(EventScaleChanged);
EVENT_DEF(EventWindowFocused, bool);

/**
Expand Down
19 changes: 12 additions & 7 deletions lib/libimhex/include/hex/api/imhex_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ namespace hex {
void setMainDockSpaceId(ImGuiID id);
void setMainWindowHandle(GLFWwindow *window);

void setGlobalScale(float scale);
void setNativeScale(float scale);
void setContentScale(float scale);
void setUserScale(float scale);

void setBorderlessWindowMode(bool enabled);
void setMultiWindowMode(bool enabled);
Expand Down Expand Up @@ -481,17 +481,22 @@ namespace hex {


/**
* @brief Gets the current global scale
* @return The current global scale
* @brief Gets the combined window content and user scale
* @return The combined window content and user scale
*/
float getGlobalScale();

/**
* @brief Gets the current native scale
* @return The current native scale
* @brief Gets the window content scale
* @return The window content scale
*/
float getNativeScale();
float getContentScale();

/**
* @brief Gets the user requested scale
* @return The user requested scale
*/
float getUserScale();

/**
* @brief Gets the current main window position
Expand Down
1 change: 0 additions & 1 deletion lib/libimhex/include/hex/helpers/utils_macos.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
void openWebpageMacos(const char *url);
bool isMacosSystemDarkModeEnabled();
bool isMacosFullScreenModeEnabled(GLFWwindow *window);
float getBackingScaleFactor();

void setupMacosWindowStyle(GLFWwindow *window, bool borderlessWindowMode);

Expand Down
42 changes: 42 additions & 0 deletions lib/libimhex/include/hex/ui/glfw_di.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once

struct GLFWwindow;
struct GLFWmonitor;
typedef void (* GLFWcursorposfun)(GLFWwindow* window, double diX, double diY);
typedef void (* GLFWframebuffersizefun)(GLFWwindow* window, int width, int height);
typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, float yscale);
typedef void (* GLFWwindowposfun)(GLFWwindow* window, int diX, int diY);
typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int diWidth, int diHeight);

namespace hex {
/**
* These functions translate GLFW coordinates to/from a device-independent
* coordinate system so application code does not need to perform any
* platform-specific scaling transformations itself.
*
* This ought to be handled by GLFW, but GLFW <=3.4 leaks the platform’s
* coordinate system instead of abstracting it. Some platforms use a
* device-independent coordinate system (Wayland, macOS, Web) where others
* do not (X11, Win32), and this detail should not be leaking into
* application code.
*/
namespace glfw {
GLFWwindow *CreateWindow(int diWidth, int diHeight, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
void DestroyWindow(GLFWwindow *window);
void *GetWindowUserPointer(GLFWwindow *window);
void *SetWindowUserPointer(GLFWwindow *window, void *pointer);
void GetMonitorPos(GLFWmonitor *monitor, int *diX, int *diY);
bool GetMonitorSize(GLFWmonitor *monitor, int *diWidth, int *diHeight);
void SetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int diXpos, int diYpos, int diWidth, int diHeight, int refreshRate);
void GetWindowPos(GLFWwindow *window, int *diX, int *diY);
void SetWindowPos(GLFWwindow *window, int diX, int diY);
void GetWindowSize(GLFWwindow *window, int *diWidth, int *diHeight);
void SetWindowSize(GLFWwindow *window, int diWidth, int diHeight);
void SetWindowSizeLimits(GLFWwindow *window, int diMinWidth, int diMinHeight, int diMaxWidth, int diMaxHeight);
GLFWcursorposfun SetCursorPosCallback(GLFWwindow *window, GLFWcursorposfun callback);
GLFWwindowposfun SetFramebufferSizeCallback(GLFWwindow *window, GLFWframebuffersizefun callback);
GLFWwindowcontentscalefun SetWindowContentScaleCallback(GLFWwindow *window, GLFWwindowcontentscalefun callback);
GLFWwindowposfun SetWindowPosCallback(GLFWwindow *window, GLFWwindowposfun callback);
GLFWwindowsizefun SetWindowSizeCallback(GLFWwindow *window, GLFWwindowsizefun callback);
}
}
9 changes: 5 additions & 4 deletions lib/libimhex/include/hex/ui/imgui_imhex_extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ namespace ImGuiExt {
static Texture fromGLTexture(unsigned int texture, int width, int height);
static Texture fromBitmap(const ImU8 *buffer, int size, int width, int height, Filter filter = Filter::Nearest);
static Texture fromBitmap(std::span<const std::byte> buffer, int width, int height, Filter filter = Filter::Nearest);
static Texture fromSVG(const char *path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
static Texture fromSVG(const std::fs::path &path, int width = 0, int height = 0, Filter filter = Filter::Nearest);
static Texture fromSVG(std::span<const std::byte> buffer, int width = 0, int height = 0, Filter filter = Filter::Nearest);
static Texture fromSVG(const char *path, int width = 0, int height = 0, float scale = 1.0f, Filter filter = Filter::Nearest);
static Texture fromSVG(const std::fs::path &path, int width = 0, int height = 0, float scale = 1.0f, Filter filter = Filter::Nearest);
static Texture fromSVG(std::span<const std::byte> buffer, int width = 0, int height = 0, float scale = 1.0f, Filter filter = Filter::Nearest);


~Texture();
Expand All @@ -109,7 +109,7 @@ namespace ImGuiExt {
}

[[nodiscard]] auto getSize() const noexcept {
return ImVec2(m_width, m_height);
return ImVec2(float(m_width) / m_scale, float(m_height) / m_scale);
}

[[nodiscard]] constexpr auto getAspectRatio() const noexcept {
Expand All @@ -121,6 +121,7 @@ namespace ImGuiExt {
private:
ImTextureID m_textureId = nullptr;
int m_width = 0, m_height = 0;
float m_scale = 1.0f;
};

float GetTextWrapPos();
Expand Down
22 changes: 12 additions & 10 deletions lib/libimhex/source/api/imhex_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,17 +501,16 @@ namespace hex {
}


static float s_globalScale = 1.0;
void setGlobalScale(float scale) {
s_globalScale = scale;
static float s_contentScale = 1.0;
void setContentScale(float scale) {
s_contentScale = scale;
}

static float s_nativeScale = 1.0;
void setNativeScale(float scale) {
s_nativeScale = scale;
static float s_userScale = 1.0;
void setUserScale(float scale) {
s_userScale = scale;
}


static bool s_borderlessWindowMode;
void setBorderlessWindowMode(bool enabled) {
s_borderlessWindowMode = enabled;
Expand Down Expand Up @@ -598,13 +597,16 @@ namespace hex {
}

float getGlobalScale() {
return impl::s_globalScale;
return getUserScale() * getContentScale();
}

float getNativeScale() {
return impl::s_nativeScale;
float getContentScale() {
return impl::s_contentScale;
}

float getUserScale() {
return impl::s_userScale;
}

ImVec2 getMainWindowPosition() {
if ((ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) != ImGuiConfigFlags_None)
Expand Down
8 changes: 4 additions & 4 deletions lib/libimhex/source/helpers/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@
namespace hex {

float operator""_scaled(long double value) {
return value * ImHexApi::System::getGlobalScale();
return value * ImHexApi::System::getUserScale();
}

float operator""_scaled(unsigned long long value) {
return value * ImHexApi::System::getGlobalScale();
return value * ImHexApi::System::getUserScale();
}

ImVec2 scaled(const ImVec2 &vector) {
return vector * ImHexApi::System::getGlobalScale();
return vector * ImHexApi::System::getUserScale();
}

ImVec2 scaled(float x, float y) {
return ImVec2(x, y) * ImHexApi::System::getGlobalScale();
return ImVec2(x, y) * ImHexApi::System::getUserScale();
}

std::string to_string(u128 value) {
Expand Down
4 changes: 0 additions & 4 deletions lib/libimhex/source/helpers/utils_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ bool isMacosSystemDarkModeEnabled(void) {
}
}

float getBackingScaleFactor(void) {
return [[NSScreen mainScreen] backingScaleFactor];
}

void setupMacosWindowStyle(GLFWwindow *window, bool borderlessWindowMode) {
NSWindow* cocoaWindow = glfwGetCocoaWindow(window);

Expand Down
Loading
Loading