From 9f5aea7f06faa6e3b3d7b8685c029ea5be28ce4a Mon Sep 17 00:00:00 2001 From: KamFretoZ <14798312+kamfretoz@users.noreply.github.com> Date: Mon, 2 Sep 2024 23:01:10 +0700 Subject: [PATCH] ImGui: Enable lunasvg Backport from: https://github.com/stenzek/duckstation/commit/11787a59698b00a73f644cc871f7a0083c4fe705 --- 3rdparty/imgui/CMakeLists.txt | 2 +- 3rdparty/imgui/imgui.vcxproj | 2 +- 3rdparty/imgui/include/imconfig.h | 2 +- 3rdparty/imgui/src/imgui_freetype.cpp | 76 ++++++++++++++++++--------- cmake/SearchForStuff.cmake | 1 + common/vsprops/LinkPCSX2Deps.props | 5 +- 6 files changed, 58 insertions(+), 30 deletions(-) diff --git a/3rdparty/imgui/CMakeLists.txt b/3rdparty/imgui/CMakeLists.txt index 06495fd334b14a..74f9953cc447bd 100644 --- a/3rdparty/imgui/CMakeLists.txt +++ b/3rdparty/imgui/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(imgui target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src") -target_link_libraries(imgui PUBLIC Freetype::Freetype) +target_link_libraries(imgui PUBLIC Freetype::Freetype lunasvg::lunasvg) # Needed for macOS compile. set_property(TARGET imgui PROPERTY CXX_STANDARD 17) diff --git a/3rdparty/imgui/imgui.vcxproj b/3rdparty/imgui/imgui.vcxproj index e9bf80b6d02a6a..c683a976808545 100644 --- a/3rdparty/imgui/imgui.vcxproj +++ b/3rdparty/imgui/imgui.vcxproj @@ -33,7 +33,7 @@ %(PreprocessorDefinitions) TurnOffAllWarnings - $(ProjectDir)include;$(ProjectDir)src;$(SolutionDir)deps\include\freetype2;%(AdditionalIncludeDirectories) + $(ProjectDir)include;$(ProjectDir)src;$(DepsIncludeDir)freetype2;$(DepsIncludeDir);%(AdditionalIncludeDirectories) diff --git a/3rdparty/imgui/include/imconfig.h b/3rdparty/imgui/include/imconfig.h index 67a75bf04948ec..440554f8889c49 100644 --- a/3rdparty/imgui/include/imconfig.h +++ b/3rdparty/imgui/include/imconfig.h @@ -87,7 +87,7 @@ // Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided). // Only works in combination with IMGUI_ENABLE_FREETYPE. // (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement) -//#define IMGUI_ENABLE_FREETYPE_LUNASVG +#define IMGUI_ENABLE_FREETYPE_LUNASVG //---- Use stb_truetype to build and rasterize the font atlas (default) // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. diff --git a/3rdparty/imgui/src/imgui_freetype.cpp b/3rdparty/imgui/src/imgui_freetype.cpp index 68e38ed95b8884..36c27c6cc48e28 100644 --- a/3rdparty/imgui/src/imgui_freetype.cpp +++ b/3rdparty/imgui/src/imgui_freetype.cpp @@ -48,7 +48,8 @@ #ifdef IMGUI_ENABLE_FREETYPE_LUNASVG #include FT_OTSVG_H // #include FT_BBOX_H // -#include +#include +#include #if !((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12)) #error IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12 #endif @@ -835,11 +836,26 @@ void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* u // The original code from the demo is licensed under CeCILL-C Free Software License Agreement (https://gitlab.freedesktop.org/freetype/freetype/-/blob/master/LICENSE.TXT) struct LunasvgPortState { - FT_Error err = FT_Err_Ok; - lunasvg::Matrix matrix; - std::unique_ptr svg = nullptr; + LunasvgPortState(); + ~LunasvgPortState(); + + FT_Error err = FT_Err_Ok; + lunasvg_matrix* matrix = nullptr; + lunasvg_document* svg = nullptr; }; +LunasvgPortState::LunasvgPortState() +{ + matrix = lunasvg_matrix_create(); +} + +LunasvgPortState::~LunasvgPortState() +{ + lunasvg_matrix_destroy(matrix); + if (svg) + lunasvg_document_destroy(svg); +} + static FT_Error ImGuiLunasvgPortInit(FT_Pointer* _state) { *_state = IM_NEW(LunasvgPortState)(); @@ -860,9 +876,10 @@ static FT_Error ImGuiLunasvgPortRender(FT_GlyphSlot slot, FT_Pointer* _state) return state->err; // rows is height, pitch (or stride) equals to width * sizeof(int32) - lunasvg::Bitmap bitmap((uint8_t*)slot->bitmap.buffer, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.pitch); - state->svg->setMatrix(state->svg->matrix().identity()); // Reset the svg matrix to the default value - state->svg->render(bitmap, state->matrix); // state->matrix is already scaled and translated + lunasvg_bitmap* bitmap = lunasvg_bitmap_create_with_data((uint8_t*)slot->bitmap.buffer, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.pitch); + lunasvg_document_set_identity_matrix(state->svg); // Reset the svg matrix to the default value + lunasvg_document_render(state->svg, bitmap, state->matrix); // state->matrix is already scaled and translated + lunasvg_bitmap_destroy(bitmap); state->err = FT_Err_Ok; return state->err; } @@ -878,6 +895,10 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_ if (cache) return state->err; + if (state->svg) + lunasvg_document_destroy(state->svg); + state->svg = lunasvg_document_load_from_data(document->svg_document, document->svg_document_length); + state->svg = lunasvg::Document::loadFromData((const char*)document->svg_document, document->svg_document_length); if (state->svg == nullptr) { @@ -885,40 +906,45 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_ return state->err; } - lunasvg::Box box = state->svg->box(); - double scale = std::min(metrics.x_ppem / box.w, metrics.y_ppem / box.h); + lunasvg_box* box = lunasvg_box_create(); + double box_x, box_y, box_w, box_h; + lunasvg_document_get_box(state->svg, box); + lunasvg_box_get_values(box, &box_x, &box_y, &box_w, &box_h); + double scale = std::min(metrics.x_ppem / box_w, metrics.y_ppem / box_h); double xx = (double)document->transform.xx / (1 << 16); double xy = -(double)document->transform.xy / (1 << 16); double yx = -(double)document->transform.yx / (1 << 16); double yy = (double)document->transform.yy / (1 << 16); - double x0 = (double)document->delta.x / 64 * box.w / metrics.x_ppem; - double y0 = -(double)document->delta.y / 64 * box.h / metrics.y_ppem; + double x0 = (double)document->delta.x / 64 * box_w / metrics.x_ppem; + double y0 = -(double)document->delta.y / 64 * box_h / metrics.y_ppem; // Scale and transform, we don't translate the svg yet - state->matrix.identity(); - state->matrix.scale(scale, scale); - state->matrix.transform(xx, xy, yx, yy, x0, y0); - state->svg->setMatrix(state->matrix); + lunasvg_matrix_identity(state->matrix); + lunasvg_matrix_scale(state->matrix, scale, scale); + lunasvg_matrix_transform(state->matrix, xx, xy, yx, yy, x0, y0); + lunasvg_document_set_matrix(state->svg, state->matrix); // Pre-translate the matrix for the rendering step - state->matrix.translate(-box.x, -box.y); + lunasvg_matrix_translate(state->matrix, -box_x, -box_y); // Get the box again after the transformation - box = state->svg->box(); + lunasvg_document_get_box(state->svg, box); + lunasvg_box_get_values(box, &box_x, &box_y, &box_w, &box_h); + lunasvg_box_destroy(box); // Calculate the bitmap size - slot->bitmap_left = FT_Int(box.x); - slot->bitmap_top = FT_Int(-box.y); - slot->bitmap.rows = (unsigned int)(ImCeil((float)box.h)); - slot->bitmap.width = (unsigned int)(ImCeil((float)box.w)); + slot->bitmap_left = FT_Int(box_x); + slot->bitmap_top = FT_Int(-box_y); + slot->bitmap.rows = (unsigned int)(ImCeil((float)box_h)); + slot->bitmap.width = (unsigned int)(ImCeil((float)box_w)); slot->bitmap.pitch = slot->bitmap.width * 4; slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA; // Compute all the bearings and set them correctly. The outline is scaled already, we just need to use the bounding box. - double metrics_width = box.w; - double metrics_height = box.h; - double horiBearingX = box.x; - double horiBearingY = -box.y; + double metrics_width = box_w; + double metrics_height = box_h; + double horiBearingX = box_x; + double horiBearingY = -box_y; double vertBearingX = slot->metrics.horiBearingX / 64.0 - slot->metrics.horiAdvance / 64.0 / 2.0; double vertBearingY = (slot->metrics.vertAdvance / 64.0 - slot->metrics.height / 64.0) / 2.0; slot->metrics.width = FT_Pos(IM_ROUND(metrics_width * 64.0)); // Using IM_ROUND() assume width and height are positive diff --git a/cmake/SearchForStuff.cmake b/cmake/SearchForStuff.cmake index 566801a1e966a9..efd7b0391aa27f 100644 --- a/cmake/SearchForStuff.cmake +++ b/cmake/SearchForStuff.cmake @@ -19,6 +19,7 @@ find_package(LZ4 REQUIRED) find_package(WebP REQUIRED) # v1.3.2, spews an error on Linux because no pkg-config. find_package(SDL2 2.30.4 REQUIRED) find_package(Freetype 2.13.2 REQUIRED) # 2.13.3, but flatpak is still on 2.13.2. +find_package(lunasvg 2.4.1 REQUIRED) if(USE_VULKAN) find_package(Shaderc REQUIRED) diff --git a/common/vsprops/LinkPCSX2Deps.props b/common/vsprops/LinkPCSX2Deps.props index 581422b35cbdb4..09c4eeff7a8a14 100644 --- a/common/vsprops/LinkPCSX2Deps.props +++ b/common/vsprops/LinkPCSX2Deps.props @@ -4,8 +4,8 @@ $(DepsLibDir);%(AdditionalLibraryDirectories) - %(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;lz4.lib;SDL2.lib;zlib.lib;zstd.lib - + %(AdditionalDependencies);freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;lunasvg.lib;lz4.lib;SDL2.lib;zlib.lib;zstd.lib + @@ -14,6 +14,7 @@ +