diff --git a/CMakeModules/DuckStationDependencies.cmake b/CMakeModules/DuckStationDependencies.cmake
index 6fcaa1303..1cc70b383 100644
--- a/CMakeModules/DuckStationDependencies.cmake
+++ b/CMakeModules/DuckStationDependencies.cmake
@@ -16,6 +16,7 @@ find_package(ZLIB REQUIRED) # 1.3, but Mac currently doesn't use it.
find_package(PNG 1.6.40 REQUIRED)
find_package(JPEG 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)
find_package(cpuinfo REQUIRED)
find_package(DiscordRPC 3.4.0 REQUIRED)
find_package(SoundTouch 2.3.3 REQUIRED)
diff --git a/dep/imgui/CMakeLists.txt b/dep/imgui/CMakeLists.txt
index ce9e07cf0..f93e0ffda 100644
--- a/dep/imgui/CMakeLists.txt
+++ b/dep/imgui/CMakeLists.txt
@@ -19,4 +19,4 @@ set(SRCS
add_library(imgui ${SRCS})
target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/src")
target_include_directories(imgui INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
-target_link_libraries(imgui PUBLIC Freetype::Freetype)
+target_link_libraries(imgui PUBLIC Freetype::Freetype lunasvg::lunasvg)
diff --git a/dep/imgui/imgui.vcxproj b/dep/imgui/imgui.vcxproj
index 0045b50cf..e3a9cd928 100644
--- a/dep/imgui/imgui.vcxproj
+++ b/dep/imgui/imgui.vcxproj
@@ -29,7 +29,7 @@
TurnOffAllWarnings
- $(ProjectDir)include;$(ProjectDir)src;$(DepsIncludeDir)freetype2;%(AdditionalIncludeDirectories)
+ $(ProjectDir)include;$(ProjectDir)src;$(DepsIncludeDir)freetype2;$(DepsIncludeDir);%(AdditionalIncludeDirectories)
diff --git a/dep/imgui/include/imconfig.h b/dep/imgui/include/imconfig.h
index fb8690c0c..a0b132492 100644
--- a/dep/imgui/include/imconfig.h
+++ b/dep/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/dep/imgui/src/imgui_freetype.cpp b/dep/imgui/src/imgui_freetype.cpp
index 68e38ed95..aa778d5b0 100644
--- a/dep/imgui/src/imgui_freetype.cpp
+++ b/dep/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,47 +895,55 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
if (cache)
return state->err;
- state->svg = lunasvg::Document::loadFromData((const char*)document->svg_document, document->svg_document_length);
+ if (state->svg)
+ lunasvg_document_destroy(state->svg);
+ state->svg = lunasvg_document_load_from_data(document->svg_document, document->svg_document_length);
if (state->svg == nullptr)
{
state->err = FT_Err_Invalid_SVG_Document;
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/src/util/util.props b/src/util/util.props
index d6fdb23e8..22659e3c2 100644
--- a/src/util/util.props
+++ b/src/util/util.props
@@ -26,7 +26,7 @@
%(AdditionalIncludeDirectories);$(DepsIncludeDir)SDL2
- %(AdditionalDependencies);cpuinfo.lib;freetype.lib;jpeg.lib;libpng16.lib;libwebp.lib;SDL2.lib;soundtouch.lib;zlib.lib;zstd.lib
+ %(AdditionalDependencies);cpuinfo.lib;freetype.lib;jpeg.lib;libpng16.lib;libwebp.lib;lunasvg.lib;SDL2.lib;soundtouch.lib;zlib.lib;zstd.lib
@@ -38,6 +38,7 @@
+