#include "FontAtlasBuilder.h" #include #include #include 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 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 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 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 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(width); output.height = static_cast(height); output.rgbaPixels.assign(static_cast(output.width) * output.height * 4u, 0); const UINT stride = width * 4u; result = converter->CopyPixels(nullptr, stride, static_cast(output.rgbaPixels.size()), output.rgbaPixels.data()); if (FAILED(result)) { error = "Could not copy font atlas PNG pixels."; return false; } error.clear(); return true; } }