Fixes
This commit is contained in:
111
src/runtime/text/FontAtlasImageLoader.cpp
Normal file
111
src/runtime/text/FontAtlasImageLoader.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user