#include <cstdint>
#include <NsCore/Ptr.h>
#include <NsGui/IntegrationAPI.h>
#include <NsGui/TextureProvider.h>
#include <NsGui/Uri.h>
#include <NsRender/RenderDevice.h>
#include <NsRender/Texture.h>
#include "noesis_shim.h"
namespace {
class RustTextureProvider final : public Noesis::TextureProvider {
public:
RustTextureProvider(const noesis_texture_provider_vtable* vtable, void* userdata)
: mVtable(*vtable), mUserdata(userdata)
{}
Noesis::TextureInfo GetTextureInfo(const Noesis::Uri& uri) override {
Noesis::TextureInfo info;
if (!mVtable.get_info) return info;
const char* uriStr = uri.Str();
noesis_texture_info raw{};
bool ok = mVtable.get_info(mUserdata, uriStr ? uriStr : "", &raw);
if (!ok) return info;
info.width = raw.width;
info.height = raw.height;
info.x = raw.x;
info.y = raw.y;
info.dpiScale = raw.dpi_scale;
return info;
}
Noesis::Ptr<Noesis::Texture> LoadTexture(
const Noesis::Uri& uri, Noesis::RenderDevice* device) override
{
if (!mVtable.load_texture || !device) return nullptr;
const char* uriStr = uri.Str();
uint32_t width = 0;
uint32_t height = 0;
const uint8_t* data = nullptr;
uint32_t len = 0;
bool ok = mVtable.load_texture(
mUserdata,
uriStr ? uriStr : "",
&width, &height,
&data, &len);
if (!ok || data == nullptr || width == 0 || height == 0) {
return nullptr;
}
if (len != width * height * 4u) {
return nullptr;
}
const void* levels[] = { data };
return device->CreateTexture(
uriStr ? uriStr : "",
width, height, 1,
Noesis::TextureFormat::RGBA8,
levels);
}
private:
noesis_texture_provider_vtable mVtable;
void* mUserdata;
};
}
extern "C" void* noesis_texture_provider_create(
const noesis_texture_provider_vtable* vtable, void* userdata)
{
if (!vtable) return nullptr;
Noesis::Ptr<RustTextureProvider> p =
Noesis::MakePtr<RustTextureProvider>(vtable, userdata);
return p.GiveOwnership();
}
extern "C" void noesis_texture_provider_destroy(void* provider) {
if (!provider) return;
static_cast<Noesis::TextureProvider*>(provider)->Release();
}
extern "C" void noesis_set_texture_provider(void* provider) {
Noesis::GUI::SetTextureProvider(static_cast<Noesis::TextureProvider*>(provider));
}