From c30eda289b5815b6b62799ef986eaf3c462fd72d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 31 Mar 2025 01:18:03 +0100 Subject: Add SvgIcon class Based on Icon class, but constructor replaced with calls to lunasvg. --- config/types.h | 1 + res/ui/icon/rails.svg | 36 ++++++++++++++++++++++++++++++++++++ test/Jamfile.jam | 1 + test/test-ui.cpp | 20 ++++++++++++++++++++ ui/svgIcon.cpp | 34 ++++++++++++++++++++++++++++++++++ ui/svgIcon.h | 18 ++++++++++++++++++ 6 files changed, 110 insertions(+) create mode 100644 res/ui/icon/rails.svg create mode 100644 test/test-ui.cpp create mode 100644 ui/svgIcon.cpp create mode 100644 ui/svgIcon.h diff --git a/config/types.h b/config/types.h index c501f41..06825b5 100644 --- a/config/types.h +++ b/config/types.h @@ -42,6 +42,7 @@ using Normal3D = Normal<3>; using Rotation2D = Rotation<2>; using Rotation3D = Rotation<3>; using TextureRelCoord = glm::vec<2, float>; +using ImageDimensions = glm::vec<2, GLsizei>; using TextureDimensions = glm::vec<3, GLsizei>; using TextureRelRegion = glm::vec<4, float>; using TextureAbsCoord = glm::vec<2, GLsizei>; diff --git a/res/ui/icon/rails.svg b/res/ui/icon/rails.svg new file mode 100644 index 0000000..81e9b94 --- /dev/null +++ b/res/ui/icon/rails.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Jamfile.jam b/test/Jamfile.jam index bedc2ad..c922187 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -65,6 +65,7 @@ run perf-instancing.cpp : \< : test-instancing : benchmark tes run test-glContainer.cpp : : : test ; run test-pack.cpp : : : test ; run test-environment.cpp : : : test ; +run test-ui.cpp : : : test ; compile test-static-enumDetails.cpp ; compile test-static-stream_support.cpp ; explicit perf-assetFactory ; diff --git a/test/test-ui.cpp b/test/test-ui.cpp new file mode 100644 index 0000000..2810cda --- /dev/null +++ b/test/test-ui.cpp @@ -0,0 +1,20 @@ +#define BOOST_TEST_MODULE UI +#include +#include + +#include "testMainWindow.h" +#include +#include +#include + +constexpr GLsizei RENDER_SIZE = 64; + +BOOST_GLOBAL_FIXTURE(TestMainWindowAppBase); + +BOOST_AUTO_TEST_CASE(LoadFromFile) +{ + SvgIcon svg(ImageDimensions {RENDER_SIZE}, Resource::mapPath("ui/icon/rails.svg")); + const auto size = Texture::getSize(svg.texture); + BOOST_CHECK_EQUAL(size, TextureDimensions(RENDER_SIZE, RENDER_SIZE, 1)); + Texture::save(svg.texture, "/tmp/rails.tga"); +} diff --git a/ui/svgIcon.cpp b/ui/svgIcon.cpp new file mode 100644 index 0000000..499d9cc --- /dev/null +++ b/ui/svgIcon.cpp @@ -0,0 +1,34 @@ +#include "svgIcon.h" +#include "gl_traits.h" +#include + +SvgIcon::SvgIcon(ImageDimensions dim, const std::filesystem::path & path) +{ + const auto svgDoc = lunasvg::Document::loadFromFile(Resource::mapPath(path).native()); + if (!svgDoc) { + throw std::runtime_error("Failed to load SVG from " + path.string()); + } + + auto bitmap = svgDoc->renderToBitmap(dim.x, dim.y); + if (bitmap.isNull()) { + throw std::runtime_error("Failed to render SVG " + path.string()); + } + bitmap.convertToRGBA(); + + glBindTexture(GL_TEXTURE_2D, texture); + + glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + + glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dim.x, dim.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap.data()); +} + +ImTextureID +SvgIcon::operator*() const +{ + static_assert(sizeof(glTexture) <= sizeof(ImTextureID)); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,performance-no-int-to-ptr) This is how ImGui works + return reinterpret_cast(*texture); +} diff --git a/ui/svgIcon.h b/ui/svgIcon.h new file mode 100644 index 0000000..106f97c --- /dev/null +++ b/ui/svgIcon.h @@ -0,0 +1,18 @@ +#pragma once + +#include "glArrays.h" +#include "imgui_wrap.h" +#include +#include +#include + +class SvgIcon { +public: + SvgIcon(ImageDimensions, const std::filesystem::path &); + + ImTextureID operator*() const; + +private: + friend class LoadFromFile; // Test case verifying size/content + glTexture texture; +}; -- cgit v1.2.3