From a4b286e6865bb80e2c7d30ad756fab8e253cdc04 Mon Sep 17 00:00:00 2001 From: KitsuneAlex Date: Sat, 11 May 2024 17:32:14 +0200 Subject: [PATCH] Remove allocator API for the time being and add C-API for import-font extension --- CMakeLists.txt | 5 ++- core/msdfgen-c.cpp | 76 ++++++++++++------------------------------- ext/msdfgen-ext-c.cpp | 68 ++++++++++++++++++++++++++++++++++++++ msdfgen-c.h | 30 +++-------------- msdfgen-ext-c.h | 39 ++++++++++++++++++++++ 5 files changed, 135 insertions(+), 83 deletions(-) create mode 100644 ext/msdfgen-ext-c.cpp create mode 100644 msdfgen-ext-c.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d9f25fc..5747627 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,7 +144,10 @@ if(NOT MSDFGEN_CORE_ONLY) find_package(PNG REQUIRED) endif() - add_library(msdfgen-ext "${CMAKE_CURRENT_SOURCE_DIR}/msdfgen-ext.h" ${MSDFGEN_EXT_HEADERS} ${MSDFGEN_EXT_SOURCES}) + add_library(msdfgen-ext "${CMAKE_CURRENT_SOURCE_DIR}/msdfgen-ext.h" + "${CMAKE_CURRENT_SOURCE_DIR}/msdfgen-ext-c.h" + ${MSDFGEN_EXT_HEADERS} + ${MSDFGEN_EXT_SOURCES}) add_library(msdfgen::msdfgen-ext ALIAS msdfgen-ext) set_target_properties(msdfgen-ext PROPERTIES PUBLIC_HEADER "${MSDFGEN_EXT_HEADERS}") set_property(TARGET msdfgen-ext PROPERTY MSVC_RUNTIME_LIBRARY "${MSDFGEN_MSVC_RUNTIME}") diff --git a/core/msdfgen-c.cpp b/core/msdfgen-c.cpp index 37bf65a..812a418 100644 --- a/core/msdfgen-c.cpp +++ b/core/msdfgen-c.cpp @@ -39,47 +39,10 @@ namespace { using MSDFBitmapRef = msdfgen::BitmapRef; using MTSDFBitmap = msdfgen::Bitmap; using MTSDFBitmapRef = msdfgen::BitmapRef; - - msdf_allocator_t g_allocator = {malloc, realloc, free}; - - template - [[nodiscard]] auto msdf_alloc(const size_t count = 1) noexcept -> T* { - return static_cast(g_allocator.alloc_callback(sizeof(T) * count)); - } - - auto msdf_free(void* memory) { - g_allocator.free_callback(memory); - } - - template - [[nodiscard]] auto msdf_new(TArgs&&... args) noexcept -> T* { - auto* memory = static_cast(g_allocator.alloc_callback(sizeof(T))); - new(memory) T(std::forward(args)...); - return memory; - } - - template - auto msdf_delete(T* memory) noexcept -> void { - if(memory == nullptr) { - return; - } - memory->~T(); - g_allocator.free_callback(memory); - } }// namespace extern "C" { -// msdf_allocator - -MSDF_API void msdf_allocator_set(const msdf_allocator_t* allocator) { - g_allocator = *allocator; -} - -MSDF_API const msdf_allocator_t* msdf_allocator_get() { - return &g_allocator; -} - // msdf_bitmap MSDF_API int msdf_bitmap_alloc(const int type, const int width, const int height, msdf_bitmap_t* bitmap) { @@ -94,16 +57,16 @@ MSDF_API int msdf_bitmap_alloc(const int type, const int width, const int height bitmap->height = height; switch(type) { case MSDF_BITMAP_TYPE_SDF: - bitmap->handle = msdf_new(width, height); + bitmap->handle = new SDFBitmap(width, height); break; case MSDF_BITMAP_TYPE_PSDF: - bitmap->handle = msdf_new(width, height); + bitmap->handle = new PSDFBitmap(width, height); break; case MSDF_BITMAP_TYPE_MSDF: - bitmap->handle = msdf_new(width, height); + bitmap->handle = new MSDFBitmap(width, height); break; case MSDF_BITMAP_TYPE_MTSDF: - bitmap->handle = msdf_new(width, height); + bitmap->handle = new MTSDFBitmap(width, height); break; default: return MSDF_ERR_INVALID_ARG; @@ -171,16 +134,16 @@ MSDF_API void msdf_bitmap_free(msdf_bitmap_t* bitmap) { } switch(bitmap->type) { case MSDF_BITMAP_TYPE_SDF: - msdf_delete(static_cast(bitmap->handle)); + delete static_cast(bitmap->handle); break; case MSDF_BITMAP_TYPE_PSDF: - msdf_delete(static_cast(bitmap->handle)); + delete static_cast(bitmap->handle); break; case MSDF_BITMAP_TYPE_MSDF: - msdf_delete(static_cast(bitmap->handle)); + delete static_cast(bitmap->handle); break; case MSDF_BITMAP_TYPE_MTSDF: - msdf_delete(static_cast(bitmap->handle)); + delete static_cast(bitmap->handle); break; default: return; @@ -193,7 +156,7 @@ MSDF_API int msdf_shape_alloc(msdf_shape_handle* shape) { if(shape == nullptr) { return MSDF_ERR_INVALID_ARG; } - *shape = reinterpret_cast(msdf_new()); + *shape = reinterpret_cast(new msdfgen::Shape()); return MSDF_SUCCESS; } @@ -290,7 +253,7 @@ MSDF_API int msdf_shape_orient_contours(msdf_shape_handle shape) { } MSDF_API void msdf_shape_free(msdf_shape_handle shape) { - msdf_delete(reinterpret_cast(shape)); + delete reinterpret_cast(shape); } // msdf_contour @@ -299,7 +262,7 @@ MSDF_API int msdf_contour_alloc(msdf_contour_handle* contour) { if(contour == nullptr) { return MSDF_ERR_INVALID_ARG; } - *contour = reinterpret_cast(msdf_new()); + *contour = reinterpret_cast(new msdfgen::Contour()); return MSDF_SUCCESS; } @@ -344,7 +307,8 @@ MSDF_API int msdf_contour_bound_miters(msdf_contour_const_handle contour, if(contour == nullptr || bounds == nullptr) { return MSDF_ERR_INVALID_ARG; } - reinterpret_cast(contour)->boundMiters(bounds->l, bounds->b, bounds->r, bounds->t, border, miter_limit, polarity); + reinterpret_cast(contour)->boundMiters(bounds->l, bounds->b, bounds->r, bounds->t, border, miter_limit, + polarity); return MSDF_SUCCESS; } @@ -365,7 +329,7 @@ MSDF_API int msdf_contour_reverse(msdf_contour_handle contour) { } MSDF_API void msdf_contour_free(msdf_contour_handle contour) { - msdf_delete(reinterpret_cast(contour)); + delete reinterpret_cast(contour); } // msdf_segment @@ -379,15 +343,15 @@ MSDF_API int msdf_segment_alloc(const int type, msdf_segment_handle* segment) { } switch(type) { case MSDF_SEGMENT_TYPE_LINEAR: - *segment = reinterpret_cast(msdf_new(msdfgen::Point2 {}, msdfgen::Point2 {})); + *segment = reinterpret_cast(new msdfgen::LinearSegment(msdfgen::Point2 {}, msdfgen::Point2 {})); break; case MSDF_SEGMENT_TYPE_QUADRATIC: *segment = reinterpret_cast( - msdf_new(msdfgen::Point2 {}, msdfgen::Point2 {}, msdfgen::Point2 {})); + new msdfgen::QuadraticSegment(msdfgen::Point2 {}, msdfgen::Point2 {}, msdfgen::Point2 {})); break; case MSDF_SEGMENT_TYPE_CUBIC: *segment = reinterpret_cast( - msdf_new(msdfgen::Point2 {}, msdfgen::Point2 {}, msdfgen::Point2 {}, msdfgen::Point2 {})); + new msdfgen::CubicSegment(msdfgen::Point2 {}, msdfgen::Point2 {}, msdfgen::Point2 {}, msdfgen::Point2 {})); break; default: return MSDF_ERR_INVALID_ARG; @@ -563,13 +527,13 @@ MSDF_API void msdf_segment_free(msdf_segment_handle segment) { auto* p_segment = reinterpret_cast(segment); switch(p_segment->type()) { case msdfgen::LinearSegment::EdgeType::EDGE_TYPE: - msdf_delete(dynamic_cast(p_segment)); + delete dynamic_cast(p_segment); break; case msdfgen::QuadraticSegment::EdgeType::EDGE_TYPE: - msdf_delete(dynamic_cast(p_segment)); + delete dynamic_cast(p_segment); break; case msdfgen::CubicSegment::EdgeType::EDGE_TYPE: - msdf_delete(dynamic_cast(p_segment)); + delete dynamic_cast(p_segment); break; default: return; diff --git a/ext/msdfgen-ext-c.cpp b/ext/msdfgen-ext-c.cpp new file mode 100644 index 0000000..0bb35ad --- /dev/null +++ b/ext/msdfgen-ext-c.cpp @@ -0,0 +1,68 @@ +/* +* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR + * --------------------------------------------- + * A utility by Viktor Chlumsky, (c) 2014 - 2024 + * + * The technique used to generate multi-channel distance fields in this code + * has been developed by Viktor Chlumsky in 2014 for his master's thesis, + * "Shape Decomposition for Multi-Channel Distance Fields". It provides improved + * quality of sharp corners in glyphs and other 2D shapes compared to monochrome + * distance fields. To reconstruct an image of the shape, apply the median of + * three operation on the triplet of sampled signed distance values. + * + */ + +#include "../msdfgen-ext-c.h" +#include "../msdfgen-ext.h" + +extern "C" { + +MSDF_API int msdf_ft_init(msdf_ft_handle* handle) { + if(handle == nullptr) { + return MSDF_ERR_INVALID_ARG; + } + *handle = reinterpret_cast(msdfgen::initializeFreetype()); + return MSDF_SUCCESS; +} + +MSDF_API int msdf_ft_font_load(msdf_ft_handle handle, const char* filename, msdf_ft_font_handle* font) { + if(handle == nullptr || filename == nullptr || font == nullptr) { + return MSDF_ERR_INVALID_ARG; + } + *font = reinterpret_cast(msdfgen::loadFont(reinterpret_cast(handle), filename)); + return MSDF_SUCCESS; +} + +MSDF_API int msdf_ft_font_load_data(msdf_ft_handle handle, const void* data, const size_t size, msdf_ft_font_handle* font) { + if(handle == nullptr || data == nullptr || font == nullptr) { + return MSDF_ERR_INVALID_ARG; + } + *font = reinterpret_cast(msdfgen::loadFontData(reinterpret_cast(handle), + static_cast(data), static_cast(size))); + return MSDF_SUCCESS; +} + +MSDF_API int msdf_ft_font_load_glyph(msdf_ft_font_handle font, const unsigned cp, msdf_shape_handle* shape) { + if(font == nullptr || shape == nullptr) { + return MSDF_ERR_INVALID_ARG; + } + auto* actual_shape = new msdfgen::Shape(); + msdfgen::loadGlyph(*actual_shape, reinterpret_cast(font), cp); + *shape = reinterpret_cast(actual_shape); + return MSDF_SUCCESS; +} + +MSDF_API void msdf_ft_font_destroy(msdf_ft_handle handle) { + if(handle == nullptr) { + return; + } + msdfgen::destroyFont(reinterpret_cast(handle)); +} + +MSDF_API void msdf_ft_deinit(msdf_ft_handle handle) { + if(handle == nullptr) { + return; + } + msdfgen::deinitializeFreetype(reinterpret_cast(handle)); +} +} \ No newline at end of file diff --git a/msdfgen-c.h b/msdfgen-c.h index f5b9291..bc8c9dc 100644 --- a/msdfgen-c.h +++ b/msdfgen-c.h @@ -78,16 +78,6 @@ extern "C" { // -------------------- Type definitions -typedef void* (*msdf_allocator_alloc_callback_t)(size_t size); -typedef void* (*msdf_allocator_realloc_callback_t)(void* memory, size_t size); -typedef void (*msdf_allocator_free_callback_t)(void* memory); - -typedef struct msdf_allocator { - msdf_allocator_alloc_callback_t alloc_callback; - msdf_allocator_realloc_callback_t realloc_callback; - msdf_allocator_free_callback_t free_callback; -} msdf_allocator_t; - typedef struct msdf_vector2 { double x; double y; @@ -137,22 +127,6 @@ MSDF_DEFINE_HANDLE_TYPE(msdf_contour); MSDF_DEFINE_HANDLE_TYPE(msdf_segment); // -------------------- Exported API functions -// msdf_allocator - -/** - * Sets the allocation callbacks to use for allocating API objects. - * @param allocator The address of an msdf_allocator_t structure - * to copy the callback pointers from. - */ -MSDF_API void msdf_allocator_set(const msdf_allocator_t* allocator); - -/** - * Retrieves the address of the allocator used by the C API - * to allocate underlying objects. - * @returns The address of the allocator used by the C API - * to allocate underlying objects. - */ -MSDF_API const msdf_allocator_t* msdf_allocator_get(); // msdf_bitmap @@ -599,6 +573,10 @@ MSDF_API int msdf_generate_mtsdf_with_config(msdf_bitmap_t* output, const msdf_transform_t* transform, const msdf_multichannel_config_t* config); +#ifdef MSDFGEN_EXTENSIONS + +#endif + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/msdfgen-ext-c.h b/msdfgen-ext-c.h new file mode 100644 index 0000000..9d68472 --- /dev/null +++ b/msdfgen-ext-c.h @@ -0,0 +1,39 @@ +#pragma once + +/* + * MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR + * --------------------------------------------- + * A utility by Viktor Chlumsky, (c) 2014 - 2024 + * + * The technique used to generate multi-channel distance fields in this code + * has been developed by Viktor Chlumsky in 2014 for his master's thesis, + * "Shape Decomposition for Multi-Channel Distance Fields". It provides improved + * quality of sharp corners in glyphs and other 2D shapes compared to monochrome + * distance fields. To reconstruct an image of the shape, apply the median of three + * operation on the triplet of sampled signed distance values. + */ + +#include "msdfgen-c.h" + +MSDF_DEFINE_HANDLE_TYPE(msdf_ft); +MSDF_DEFINE_HANDLE_TYPE(msdf_ft_font); + +#ifdef __cplusplus +extern "C" { +#endif + +MSDF_API int msdf_ft_init(msdf_ft_handle* handle); + +MSDF_API int msdf_ft_font_load(msdf_ft_handle handle, const char* filename, msdf_ft_font_handle* font); + +MSDF_API int msdf_ft_font_load_data(msdf_ft_handle handle, const void* data, size_t size, msdf_ft_font_handle* font); + +MSDF_API int msdf_ft_font_load_glyph(msdf_ft_font_handle font, unsigned cp, msdf_shape_handle* shape); + +MSDF_API void msdf_ft_font_destroy(msdf_ft_handle handle); + +MSDF_API void msdf_ft_deinit(msdf_ft_handle handle); + +#ifdef __cplusplus +} +#endif \ No newline at end of file