Implement Bitmap/BitmapRef interface

This commit is contained in:
KitsuneAlex 2024-05-02 03:35:33 +02:00
parent 6b32308b8a
commit cebe5fdab8
No known key found for this signature in database
GPG Key ID: 6B0CE864BB69B7D0
2 changed files with 153 additions and 42 deletions

View File

@ -18,16 +18,39 @@
#include <utility>
namespace {
using SDFBitmap = msdfgen::Bitmap<float>;
using SDFBitmapRef = msdfgen::BitmapRef<float>;
using PSDFBitmap = msdfgen::Bitmap<float>;
using PSDFBitmapRef = msdfgen::BitmapRef<float>;
using MSDFBitmap = msdfgen::Bitmap<float, 3>;
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 _new(TArgs&&... args) noexcept -> T* {
[[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;
}
auto _delete(void* memory) noexcept -> void {
template<typename T>
auto msdf_delete(T* memory) noexcept -> void {
if(memory == nullptr) {
return;
}
memory->~T();
g_allocator.free_callback(memory);
}
}// namespace
@ -46,31 +69,112 @@ MSDF_API const msdf_allocator_t* msdf_allocator_get() {
// msdf_bitmap
MSDF_API int msdf_bitmap_alloc(int type, int num_channels, int width, int height, msdf_bitmap_handle* bitmap) {
MSDF_API int msdf_bitmap_alloc(const int type, const int width, const int height, msdf_bitmap_t** bitmap) {
if(width < 0 || height < 0) {
return MSDF_ERR_INVALID_SIZE;
}
if(bitmap == nullptr) {
return MSDF_ERR_INVALID_ARG;
}
auto* wrapper = msdf_alloc<msdf_bitmap_t>();
wrapper->type = type;
wrapper->width = width;
wrapper->height = height;
switch(type) {
case MSDF_BITMAP_TYPE_SDF:
wrapper->handle = msdf_new<SDFBitmap>(width, height);
break;
case MSDF_BITMAP_TYPE_PSDF:
wrapper->handle = msdf_new<PSDFBitmap>(width, height);
break;
case MSDF_BITMAP_TYPE_MSDF:
wrapper->handle = msdf_new<MSDFBitmap>(width, height);
break;
case MSDF_BITMAP_TYPE_MTSDF:
wrapper->handle = msdf_new<MTSDFBitmap>(width, height);
break;
default:
return MSDF_ERR_INVALID_ARG;
}
*bitmap = wrapper;
return MSDF_SUCCESS;
}
MSDF_API int msdf_bitmap_get_type(msdf_bitmap_handle bitmap, int* type) {
MSDF_API int msdf_bitmap_get_channel_count(const msdf_bitmap_t* bitmap, int* channel_count) {
if(bitmap == nullptr || channel_count == nullptr) {
return MSDF_ERR_INVALID_ARG;
}
switch(bitmap->type) {
case MSDF_BITMAP_TYPE_MSDF:
*channel_count = 3;
break;
case MSDF_BITMAP_TYPE_MTSDF:
*channel_count = 4;
break;
default:
*channel_count = 1;
break;
}
return MSDF_SUCCESS;
}
MSDF_API int msdf_bitmap_get_channel_count(msdf_bitmap_handle bitmap, int* channel_count) {
MSDF_API int msdf_bitmap_get_size(const msdf_bitmap_t* bitmap, size_t* size) {
if(bitmap == nullptr || size == nullptr) {
return MSDF_ERR_INVALID_ARG;
}
int channel_count;
if(msdf_bitmap_get_channel_count(bitmap, &channel_count) != MSDF_SUCCESS) {
return MSDF_ERR_FAILED;
}
// << 2 because we only support floats right now, sizeof(float) is always 4
*size = static_cast<size_t>(bitmap->width) * static_cast<size_t>(bitmap->height) * static_cast<size_t>(channel_count) << 2;
return MSDF_SUCCESS;
}
MSDF_API int msdf_bitmap_get_width(msdf_bitmap_handle bitmap, int* width) {
MSDF_API int msdf_bitmap_get_pixels(const msdf_bitmap_t* bitmap, void** pixels) {
if(bitmap == nullptr || pixels == nullptr) {
return MSDF_ERR_INVALID_ARG;
}
switch(bitmap->type) {
case MSDF_BITMAP_TYPE_SDF:
*pixels = static_cast<SDFBitmapRef>(*static_cast<SDFBitmap*>(bitmap->handle)).pixels;
break;
case MSDF_BITMAP_TYPE_PSDF:
*pixels = static_cast<PSDFBitmapRef>(*static_cast<PSDFBitmap*>(bitmap->handle)).pixels;
break;
case MSDF_BITMAP_TYPE_MSDF:
*pixels = static_cast<MSDFBitmapRef>(*static_cast<MSDFBitmap*>(bitmap->handle)).pixels;
break;
case MSDF_BITMAP_TYPE_MTSDF:
*pixels = static_cast<MTSDFBitmapRef>(*static_cast<MTSDFBitmap*>(bitmap->handle)).pixels;
break;
default:
return MSDF_ERR_INVALID_TYPE;
}
return MSDF_SUCCESS;
}
MSDF_API int msdf_bitmap_get_height(msdf_bitmap_handle bitmap, int* height) {
return MSDF_SUCCESS;
MSDF_API void msdf_bitmap_free(msdf_bitmap_t* bitmap) {
if(bitmap == nullptr) {
return;
}
MSDF_API int msdf_bitmap_get_pixels(msdf_bitmap_handle bitmap, void** pixels) {
return MSDF_SUCCESS;
switch(bitmap->type) {
case MSDF_BITMAP_TYPE_SDF:
msdf_delete(static_cast<SDFBitmap*>(bitmap->handle));
break;
case MSDF_BITMAP_TYPE_PSDF:
msdf_delete(static_cast<PSDFBitmap*>(bitmap->handle));
break;
case MSDF_BITMAP_TYPE_MSDF:
msdf_delete(static_cast<MSDFBitmap*>(bitmap->handle));
break;
case MSDF_BITMAP_TYPE_MTSDF:
msdf_delete(static_cast<MTSDFBitmap*>(bitmap->handle));
break;
default:
return;
}
MSDF_API void msdf_bitmap_free(msdf_bitmap_handle bitmap) {
msdf_free(bitmap);
}
// msdf_shape

View File

@ -30,17 +30,21 @@
#define MSDF_TRUE 1
#define MSDF_SUCCESS 0
#define MSDF_ERR_INVALID_ARG 1
#define MSDF_ERR_INVALID_FORMAT 2
#define MSDF_ERR_FAILED 1
#define MSDF_ERR_INVALID_ARG 2
#define MSDF_ERR_INVALID_TYPE 3
#define MSDF_ERR_INVALID_SIZE 4
#define MSDF_BITMAP_TYPE_FLOAT 0
#define MSDF_BITMAP_TYPE_DOUBLE 1
#define MSDF_BITMAP_TYPE_INT 2
#define MSDF_BITMAP_TYPE_SHORT 3
#define MSDF_BITMAP_TYPE_SDF 0
#define MSDF_BITMAP_TYPE_PSDF 1
#define MSDF_BITMAP_TYPE_MSDF 2
#define MSDF_BITMAP_TYPE_MTSDF 3
#define MSDF_BITMAP_TYPE_MAX MSDF_BITMAP_TYPE_MTSDF
#define MSDF_SEGMENT_TYPE_LINEAR 0
#define MSDF_SEGMENT_TYPE_QUADRATIC 1
#define MSDF_SEGMENT_TYPE_CUBIC 2
#define MSDF_SEGMENT_TYPE_MAX MSDF_SEGMENT_TYPE_CUBIC
#define MSDF_EDGE_COLOR_BLACK 0
#define MSDF_EDGE_COLOR_RED 1
@ -54,10 +58,10 @@
#define MSDF_DEFINE_HANDLE_TYPE(n) typedef struct n* n##_handle // NOLINT
// Macros for allocating default MSDF bitmap types
#define MSDF_ALLOC_SDF_BITMAP(w, h) msdf_bitmap_alloc(MSDF_BITMAP_TYPE_FLOAT, 1, w, h)
#define MSDF_ALLOC_PSDF_BITMAP(w, h) msdf_bitmap_alloc(MSDF_BITMAP_TYPE_FLOAT, 1, w, h)
#define MSDF_ALLOC_MSDF_BITMAP(w, h) msdf_bitmap_alloc(MSDF_BITMAP_TYPE_FLOAT, 3, w, h)
#define MSDF_ALLOC_MTSDF_BITMAP(w, h) msdf_bitmap_alloc(MSDF_BITMAP_TYPE_FLOAT, 4, w, h)
#define MSDF_ALLOC_SDF_BITMAP(w, h) msdf_bitmap_alloc(MSDF_BITMAP_TYPE_SDF, w, h)
#define MSDF_ALLOC_PSDF_BITMAP(w, h) msdf_bitmap_alloc(MSDF_BITMAP_TYPE_PSDF, w, h)
#define MSDF_ALLOC_MSDF_BITMAP(w, h) msdf_bitmap_alloc(MSDF_BITMAP_TYPE_MSDF, w, h)
#define MSDF_ALLOC_MTSDF_BITMAP(w, h) msdf_bitmap_alloc(MSDF_BITMAP_TYPE_MTSDF, w, h)
#ifdef __cplusplus
extern "C" {
@ -112,11 +116,16 @@ typedef struct msdf_multichannel_config {
int distance_check_mode;
double min_deviation_ratio;
double min_improve_ratio;
char* buffer;
} msdf_multichannel_config_t;
typedef struct msdf_bitmap {
int type;
int width;
int height;
void* handle;
} msdf_bitmap_t;
// Opaque handle types
MSDF_DEFINE_HANDLE_TYPE(msdf_bitmap);
MSDF_DEFINE_HANDLE_TYPE(msdf_shape);
MSDF_DEFINE_HANDLE_TYPE(msdf_contour);
MSDF_DEFINE_HANDLE_TYPE(msdf_edge_holder);
@ -126,13 +135,11 @@ MSDF_DEFINE_HANDLE_TYPE(msdf_segment);
MSDF_API void msdf_allocator_set(const msdf_allocator_t* allocator);
MSDF_API const msdf_allocator_t* msdf_allocator_get();
MSDF_API int msdf_bitmap_alloc(int type, int num_channels, int width, int height, msdf_bitmap_handle* bitmap);
MSDF_API int msdf_bitmap_get_type(msdf_bitmap_handle bitmap, int* type);
MSDF_API int msdf_bitmap_get_channel_count(msdf_bitmap_handle bitmap, int* channel_count);
MSDF_API int msdf_bitmap_get_width(msdf_bitmap_handle bitmap, int* width);
MSDF_API int msdf_bitmap_get_height(msdf_bitmap_handle bitmap, int* height);
MSDF_API int msdf_bitmap_get_pixels(msdf_bitmap_handle bitmap, void** pixels);
MSDF_API void msdf_bitmap_free(msdf_bitmap_handle bitmap);
MSDF_API int msdf_bitmap_alloc(int type, int width, int height, msdf_bitmap_t** bitmap);
MSDF_API int msdf_bitmap_get_channel_count(const msdf_bitmap_t* bitmap, int* channel_count);
MSDF_API int msdf_bitmap_get_pixels(const msdf_bitmap_t* bitmap, void** pixels);
MSDF_API int msdf_bitmap_get_size(const msdf_bitmap_t* bitmap, size_t* size);
MSDF_API void msdf_bitmap_free(msdf_bitmap_t* bitmap);
MSDF_API int msdf_shape_alloc(msdf_shape_handle* shape);
MSDF_API int msdf_shape_get_bounds(msdf_shape_handle shape, msdf_bounds_t* bounds);
@ -181,24 +188,24 @@ MSDF_API int msdf_segment_move_start_point(msdf_segment_handle segment, const ms
MSDF_API int msdf_segment_move_end_point(msdf_segment_handle segment, const msdf_vector2_t* point);
MSDF_API void msdf_segment_free(msdf_segment_handle segment);
MSDF_API int msdf_generate_sdf(msdf_bitmap_handle output, msdf_shape_handle shape, const msdf_transform_t* transform);
MSDF_API int msdf_generate_psdf(msdf_bitmap_handle output, msdf_shape_handle shape, const msdf_transform_t* transform);
MSDF_API int msdf_generate_msdf(msdf_bitmap_handle output, msdf_shape_handle shape, const msdf_transform_t* transform);
MSDF_API int msdf_generate_mtsdf(msdf_bitmap_handle output, msdf_shape_handle shape, const msdf_transform_t* transform);
MSDF_API int msdf_generate_sdf(msdf_bitmap_t* output, msdf_shape_handle shape, const msdf_transform_t* transform);
MSDF_API int msdf_generate_psdf(msdf_bitmap_t* output, msdf_shape_handle shape, const msdf_transform_t* transform);
MSDF_API int msdf_generate_msdf(msdf_bitmap_t* output, msdf_shape_handle shape, const msdf_transform_t* transform);
MSDF_API int msdf_generate_mtsdf(msdf_bitmap_t* output, msdf_shape_handle shape, const msdf_transform_t* transform);
MSDF_API int msdf_generate_sdf_with_config(msdf_bitmap_handle output,
MSDF_API int msdf_generate_sdf_with_config(msdf_bitmap_t* output,
msdf_shape_handle shape,
const msdf_transform_t* transform,
const msdf_config_t* config);
MSDF_API int msdf_generate_psdf_with_config(msdf_bitmap_handle output,
MSDF_API int msdf_generate_psdf_with_config(msdf_bitmap_t* output,
msdf_shape_handle shape,
const msdf_transform_t* transform,
const msdf_config_t* config);
MSDF_API int msdf_generate_msdf_with_config(msdf_bitmap_handle output,
MSDF_API int msdf_generate_msdf_with_config(msdf_bitmap_t* output,
msdf_shape_handle shape,
const msdf_transform_t* transform,
const msdf_multichannel_config_t* config);
MSDF_API int msdf_generate_mtsdf_with_config(msdf_bitmap_handle output,
MSDF_API int msdf_generate_mtsdf_with_config(msdf_bitmap_t* output,
msdf_shape_handle shape,
const msdf_transform_t* transform,
const msdf_multichannel_config_t* config);