Skip to content

Commit

Permalink
feat: Render SVGs at native resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
csnover committed Jul 17, 2024
1 parent 66bce41 commit fdf2529
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 10 deletions.
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
39 changes: 35 additions & 4 deletions lib/libimhex/source/ui/imgui_imhex_extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ namespace ImGuiExt {

namespace {

void adjustSVGScale(const lunasvg::Document *document, int &width, int &height, int scale) {
if (document->width() == 0 || document->height() == 0)
return;

if (width == 0 && height == 0) {
width = document->width();
height = document->height();
} else if (width != 0 && height == 0) {
height = std::ceil(double(width) * document->height() / document->width());
} else if (height != 0 && width == 0) {
width = std::ceil(double(height) * document->width() / document->height());
}

width *= scale;
height *= scale;
}

bool isOpenGLExtensionSupported(const char *name) {
static std::set<std::string> extensions;

Expand Down Expand Up @@ -221,26 +238,37 @@ namespace ImGuiExt {
return result;
}

Texture Texture::fromSVG(const char *path, int width, int height, Filter filter) {
Texture Texture::fromSVG(const char *path, int width, int height, float scale, Filter filter) {
auto document = lunasvg::Document::loadFromFile(path);
if (!document)
return {};

adjustSVGScale(document.get(), width, height, scale);

auto bitmap = document->renderToBitmap(width, height);

auto texture = createMultisampleTextureFromRGBA8Array(bitmap.data(), bitmap.width(), bitmap.height(), filter);

Texture result;
result.m_width = bitmap.width();
result.m_height = bitmap.height();
result.m_scale = scale;
result.m_textureId = reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture));

return result;
}

Texture Texture::fromSVG(const std::fs::path &path, int width, int height, Filter filter) {
return Texture::fromSVG(wolv::util::toUTF8String(path).c_str(), width, height, filter);
Texture Texture::fromSVG(const std::fs::path &path, int width, int height, float scale, Filter filter) {
return Texture::fromSVG(wolv::util::toUTF8String(path).c_str(), width, height, scale, filter);
}

Texture Texture::fromSVG(std::span<const std::byte> buffer, int width, int height, Filter filter) {
Texture Texture::fromSVG(std::span<const std::byte> buffer, int width, int height, float scale, Filter filter) {
auto document = lunasvg::Document::loadFromData(reinterpret_cast<const char*>(buffer.data()), buffer.size());
if (!document)
return {};

adjustSVGScale(document.get(), width, height, scale);

auto bitmap = document->renderToBitmap(width, height);
bitmap.convertToRGBA();

Expand All @@ -249,6 +277,7 @@ namespace ImGuiExt {
Texture result;
result.m_width = bitmap.width();
result.m_height = bitmap.height();
result.m_scale = scale;
result.m_textureId = reinterpret_cast<ImTextureID>(static_cast<intptr_t>(texture));

return result;
Expand All @@ -261,6 +290,7 @@ namespace ImGuiExt {
m_textureId = other.m_textureId;
m_width = other.m_width;
m_height = other.m_height;
m_scale = other.m_scale;

other.m_textureId = nullptr;
}
Expand All @@ -272,6 +302,7 @@ namespace ImGuiExt {
m_textureId = other.m_textureId;
m_width = other.m_width;
m_height = other.m_height;
m_scale = other.m_scale;

other.m_textureId = nullptr;

Expand Down
3 changes: 2 additions & 1 deletion plugins/builtin/source/content/out_of_box_experience.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,8 @@ namespace hex::plugin::builtin {
ImHexApi::System::setWindowResizable(false);

const auto imageTheme = ThemeManager::getImageTheme();
s_imhexBanner = ImGuiExt::Texture::fromSVG(romfs::get(hex::format("assets/{}/banner.svg", imageTheme)).span<std::byte>());
const auto scale = ImHexApi::System::getContentScale();
s_imhexBanner = ImGuiExt::Texture::fromSVG(romfs::get(hex::format("assets/{}/banner.svg", imageTheme)).span<std::byte>(), 0, 0, scale);
s_compassTexture = ImGuiExt::Texture::fromImage(romfs::get("assets/common/compass.png").span<std::byte>());
s_globeTexture = ImGuiExt::Texture::fromImage(romfs::get("assets/common/globe.png").span<std::byte>());
s_screenshotDescriptions = nlohmann::json::parse(romfs::get("assets/screenshot_descriptions.json").string());
Expand Down
4 changes: 3 additions & 1 deletion plugins/builtin/source/content/welcome_screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,9 @@ namespace hex::plugin::builtin {
};

auto changeTextureSvg = [&](const std::string &path, float width) {
return ImGuiExt::Texture::fromSVG(romfs::get(path).span(), width, 0, ImGuiExt::Texture::Filter::Linear);
// UI scaling is already baked into the width
const auto scale = ImHexApi::System::getContentScale();
return ImGuiExt::Texture::fromSVG(romfs::get(path).span(), width, 0, scale, ImGuiExt::Texture::Filter::Linear);
};

ThemeManager::changeTheme(theme);
Expand Down

0 comments on commit fdf2529

Please sign in to comment.