Files
video-shader-toys/src/runtime/text/FontAtlasImageLoader.cpp
Aiden 0b6a2300ea
Some checks failed
CI / React UI Build (push) Successful in 38s
CI / Native Windows Build And Tests (push) Failing after 3m0s
CI / Windows Release Package (push) Has been skipped
Fixes
2026-05-22 14:43:03 +10:00

112 lines
2.6 KiB
C++

#include "FontAtlasBuilder.h"
#include <wincodec.h>
#include <wrl/client.h>
#include <windows.h>
namespace RenderCadenceCompositor
{
namespace
{
struct ComThreadGuard
{
~ComThreadGuard()
{
if (initialized)
CoUninitialize();
}
bool Initialize()
{
const HRESULT result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
initialized = SUCCEEDED(result);
return SUCCEEDED(result) || result == RPC_E_CHANGED_MODE;
}
bool initialized = false;
};
}
bool FontAtlasBuilder::LoadAtlasImage(FontAtlasBuildOutput& output, std::string& error) const
{
ComThreadGuard comGuard;
if (!comGuard.Initialize())
{
error = "Could not initialize COM for font atlas PNG loading.";
return false;
}
Microsoft::WRL::ComPtr<IWICImagingFactory> factory;
HRESULT result = CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(factory.GetAddressOf()));
if (FAILED(result))
{
error = "Could not create WIC imaging factory for font atlas PNG loading.";
return false;
}
Microsoft::WRL::ComPtr<IWICBitmapDecoder> decoder;
result = factory->CreateDecoderFromFilename(
output.imagePath.wstring().c_str(),
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
decoder.GetAddressOf());
if (FAILED(result))
{
error = "Could not decode font atlas PNG: " + output.imagePath.string();
return false;
}
Microsoft::WRL::ComPtr<IWICBitmapFrameDecode> frame;
result = decoder->GetFrame(0, frame.GetAddressOf());
if (FAILED(result))
{
error = "Could not read font atlas PNG frame: " + output.imagePath.string();
return false;
}
Microsoft::WRL::ComPtr<IWICFormatConverter> converter;
result = factory->CreateFormatConverter(converter.GetAddressOf());
if (FAILED(result))
{
error = "Could not create WIC format converter for font atlas PNG.";
return false;
}
result = converter->Initialize(
frame.Get(),
GUID_WICPixelFormat32bppRGBA,
WICBitmapDitherTypeNone,
nullptr,
0.0,
WICBitmapPaletteTypeCustom);
if (FAILED(result))
{
error = "Could not convert font atlas PNG to RGBA.";
return false;
}
UINT width = 0;
UINT height = 0;
converter->GetSize(&width, &height);
output.width = static_cast<unsigned>(width);
output.height = static_cast<unsigned>(height);
output.rgbaPixels.assign(static_cast<std::size_t>(output.width) * output.height * 4u, 0);
const UINT stride = width * 4u;
result = converter->CopyPixels(nullptr, stride, static_cast<UINT>(output.rgbaPixels.size()), output.rgbaPixels.data());
if (FAILED(result))
{
error = "Could not copy font atlas PNG pixels.";
return false;
}
error.clear();
return true;
}
}