#include <cstdint>
#include <NsCore/Ptr.h>
#include <NsCore/String.h>
#include <NsGui/CachedFontProvider.h>
#include <NsGui/IntegrationAPI.h>
#include <NsGui/MemoryStream.h>
#include <NsGui/Stream.h>
#include <NsGui/Uri.h>
#include "noesis_shim.h"
namespace {
class RustFontProvider final : public Noesis::CachedFontProvider {
public:
RustFontProvider(const noesis_font_provider_vtable* vtable, void* userdata)
: mVtable(*vtable), mUserdata(userdata)
{}
void RegisterFontFromRust(const Noesis::Uri& folder, const char* filename) {
RegisterFont(folder, filename);
}
protected:
void ScanFolder(const Noesis::Uri& folder) override {
if (!mVtable.scan_folder) return;
const char* folderUri = folder.Str();
struct Ctx {
RustFontProvider* self;
const Noesis::Uri* folder;
};
Ctx ctx{this, &folder};
mVtable.scan_folder(
mUserdata,
folderUri,
[](void* raw, const char* filename) {
if (!raw || !filename) return;
auto* c = static_cast<Ctx*>(raw);
c->self->RegisterFontFromRust(*c->folder, filename);
},
&ctx);
}
Noesis::Ptr<Noesis::Stream> OpenFont(
const Noesis::Uri& folder, const char* filename) const override
{
if (!mVtable.open_font) return nullptr;
const char* folderUri = folder.Str();
const uint8_t* data = nullptr;
uint32_t len = 0;
bool ok = mVtable.open_font(
mUserdata,
folderUri ? folderUri : "",
filename ? filename : "",
&data, &len);
if (!ok || data == nullptr) {
return nullptr;
}
return Noesis::MakePtr<Noesis::MemoryStream>(data, len);
}
private:
noesis_font_provider_vtable mVtable;
void* mUserdata;
};
}
extern "C" void* noesis_font_provider_create(
const noesis_font_provider_vtable* vtable, void* userdata)
{
if (!vtable) return nullptr;
Noesis::Ptr<RustFontProvider> p =
Noesis::MakePtr<RustFontProvider>(vtable, userdata);
return p.GiveOwnership();
}
extern "C" void noesis_font_provider_destroy(void* provider) {
if (!provider) return;
static_cast<Noesis::FontProvider*>(provider)->Release();
}
extern "C" void noesis_set_font_provider(void* provider) {
Noesis::GUI::SetFontProvider(static_cast<Noesis::FontProvider*>(provider));
}
extern "C" void noesis_font_provider_register_font(
void* provider, const char* folder_uri, const char* filename)
{
if (!provider || !filename) return;
auto* p = static_cast<RustFontProvider*>(provider);
Noesis::Uri folder{folder_uri ? folder_uri : ""};
p->RegisterFontFromRust(folder, filename);
}
extern "C" void noesis_set_font_fallbacks(const char* const* families, uint32_t count) {
if (!families || count == 0) {
Noesis::GUI::SetFontFallbacks(nullptr, 0);
return;
}
Noesis::GUI::SetFontFallbacks(const_cast<const char**>(families), count);
}
extern "C" void noesis_set_font_default_properties(
float size, int32_t weight, int32_t stretch, int32_t style)
{
Noesis::GUI::SetFontDefaultProperties(
size,
static_cast<Noesis::FontWeight>(weight),
static_cast<Noesis::FontStretch>(stretch),
static_cast<Noesis::FontStyle>(style));
}