Remove allocator API for the time being and add C-API for import-font extension

This commit is contained in:
KitsuneAlex 2024-05-11 17:32:14 +02:00
parent 3f68e015e5
commit a4b286e686
No known key found for this signature in database
GPG Key ID: 6B0CE864BB69B7D0
5 changed files with 135 additions and 83 deletions

View File

@ -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}")

View File

@ -39,47 +39,10 @@ namespace {
using MSDFBitmapRef = msdfgen::BitmapRef<float, 3>;
using MTSDFBitmap = msdfgen::Bitmap<float, 4>;
using MTSDFBitmapRef = msdfgen::BitmapRef<float, 4>;
msdf_allocator_t g_allocator = {malloc, realloc, free};
template<typename T>
[[nodiscard]] auto msdf_alloc(const size_t count = 1) noexcept -> T* {
return static_cast<T*>(g_allocator.alloc_callback(sizeof(T) * count));
}
auto msdf_free(void* memory) {
g_allocator.free_callback(memory);
}
template<typename T, typename... TArgs>
[[nodiscard]] auto msdf_new(TArgs&&... args) noexcept -> T* {
auto* memory = static_cast<T*>(g_allocator.alloc_callback(sizeof(T)));
new(memory) T(std::forward<TArgs>(args)...);
return memory;
}
template<typename T>
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<SDFBitmap>(width, height);
bitmap->handle = new SDFBitmap(width, height);
break;
case MSDF_BITMAP_TYPE_PSDF:
bitmap->handle = msdf_new<PSDFBitmap>(width, height);
bitmap->handle = new PSDFBitmap(width, height);
break;
case MSDF_BITMAP_TYPE_MSDF:
bitmap->handle = msdf_new<MSDFBitmap>(width, height);
bitmap->handle = new MSDFBitmap(width, height);
break;
case MSDF_BITMAP_TYPE_MTSDF:
bitmap->handle = msdf_new<MTSDFBitmap>(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<SDFBitmap*>(bitmap->handle));
delete static_cast<SDFBitmap*>(bitmap->handle);
break;
case MSDF_BITMAP_TYPE_PSDF:
msdf_delete(static_cast<PSDFBitmap*>(bitmap->handle));
delete static_cast<PSDFBitmap*>(bitmap->handle);
break;
case MSDF_BITMAP_TYPE_MSDF:
msdf_delete(static_cast<MSDFBitmap*>(bitmap->handle));
delete static_cast<MSDFBitmap*>(bitmap->handle);
break;
case MSDF_BITMAP_TYPE_MTSDF:
msdf_delete(static_cast<MTSDFBitmap*>(bitmap->handle));
delete static_cast<MTSDFBitmap*>(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_shape_handle>(msdf_new<msdfgen::Shape>());
*shape = reinterpret_cast<msdf_shape_handle>(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<msdfgen::Shape*>(shape));
delete reinterpret_cast<msdfgen::Shape*>(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_contour_handle>(msdf_new<msdfgen::Contour>());
*contour = reinterpret_cast<msdf_contour_handle>(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<const msdfgen::Contour*>(contour)->boundMiters(bounds->l, bounds->b, bounds->r, bounds->t, border, miter_limit, polarity);
reinterpret_cast<const msdfgen::Contour*>(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<msdfgen::Contour*>(contour));
delete reinterpret_cast<msdfgen::Contour*>(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_segment_handle>(msdf_new<msdfgen::LinearSegment>(msdfgen::Point2 {}, msdfgen::Point2 {}));
*segment = reinterpret_cast<msdf_segment_handle>(new msdfgen::LinearSegment(msdfgen::Point2 {}, msdfgen::Point2 {}));
break;
case MSDF_SEGMENT_TYPE_QUADRATIC:
*segment = reinterpret_cast<msdf_segment_handle>(
msdf_new<msdfgen::QuadraticSegment>(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_segment_handle>(
msdf_new<msdfgen::CubicSegment>(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<msdfgen::EdgeSegment*>(segment);
switch(p_segment->type()) {
case msdfgen::LinearSegment::EdgeType::EDGE_TYPE:
msdf_delete(dynamic_cast<msdfgen::LinearSegment*>(p_segment));
delete dynamic_cast<msdfgen::LinearSegment*>(p_segment);
break;
case msdfgen::QuadraticSegment::EdgeType::EDGE_TYPE:
msdf_delete(dynamic_cast<msdfgen::QuadraticSegment*>(p_segment));
delete dynamic_cast<msdfgen::QuadraticSegment*>(p_segment);
break;
case msdfgen::CubicSegment::EdgeType::EDGE_TYPE:
msdf_delete(dynamic_cast<msdfgen::CubicSegment*>(p_segment));
delete dynamic_cast<msdfgen::CubicSegment*>(p_segment);
break;
default:
return;

68
ext/msdfgen-ext-c.cpp Normal file
View File

@ -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<msdf_ft_handle>(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<msdf_ft_font_handle>(msdfgen::loadFont(reinterpret_cast<msdfgen::FreetypeHandle*>(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<msdf_ft_font_handle>(msdfgen::loadFontData(reinterpret_cast<msdfgen::FreetypeHandle*>(handle),
static_cast<const msdfgen::byte*>(data), static_cast<int>(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<msdfgen::FontHandle*>(font), cp);
*shape = reinterpret_cast<msdf_shape_handle>(actual_shape);
return MSDF_SUCCESS;
}
MSDF_API void msdf_ft_font_destroy(msdf_ft_handle handle) {
if(handle == nullptr) {
return;
}
msdfgen::destroyFont(reinterpret_cast<msdfgen::FontHandle*>(handle));
}
MSDF_API void msdf_ft_deinit(msdf_ft_handle handle) {
if(handle == nullptr) {
return;
}
msdfgen::deinitializeFreetype(reinterpret_cast<msdfgen::FreetypeHandle*>(handle));
}
}

View File

@ -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

39
msdfgen-ext-c.h Normal file
View File

@ -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