89 lines
2.8 KiB
C
89 lines
2.8 KiB
C
|
|
#pragma once
|
||
|
|
|
||
|
|
#include "NativeRenderer.h"
|
||
|
|
|
||
|
|
#include <algorithm>
|
||
|
|
#include <cmath>
|
||
|
|
#include <cstdio>
|
||
|
|
|
||
|
|
namespace XCEngine::UI::Editor::Host::NativeRendererSupport {
|
||
|
|
|
||
|
|
inline constexpr float kBaseDpi = 96.0f;
|
||
|
|
inline constexpr float kDefaultFontSize = 16.0f;
|
||
|
|
|
||
|
|
inline std::string HrToString(const char* operation, HRESULT hr) {
|
||
|
|
char buffer[128] = {};
|
||
|
|
sprintf_s(buffer, "%s failed with hr=0x%08X.", operation, static_cast<unsigned int>(hr));
|
||
|
|
return buffer;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline float ClampDpiScale(float dpiScale) {
|
||
|
|
return dpiScale > 0.0f ? dpiScale : 1.0f;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline float ResolveFontSize(float fontSize) {
|
||
|
|
return fontSize > 0.0f ? fontSize : kDefaultFontSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline float SnapToPixel(float value, float dpiScale) {
|
||
|
|
const float scale = ClampDpiScale(dpiScale);
|
||
|
|
return std::round(value * scale);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline D2D1_RECT_F ToD2DRect(const ::XCEngine::UI::UIRect& rect, float dpiScale) {
|
||
|
|
const float left = SnapToPixel(rect.x, dpiScale);
|
||
|
|
const float top = SnapToPixel(rect.y, dpiScale);
|
||
|
|
const float right = SnapToPixel(rect.x + rect.width, dpiScale);
|
||
|
|
const float bottom = SnapToPixel(rect.y + rect.height, dpiScale);
|
||
|
|
return D2D1::RectF(left, top, right, bottom);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline D2D1_POINT_2F ToD2DPoint(
|
||
|
|
const ::XCEngine::UI::UIPoint& point,
|
||
|
|
float dpiScale,
|
||
|
|
float pixelOffset = 0.0f) {
|
||
|
|
return D2D1::Point2F(
|
||
|
|
SnapToPixel(point.x, dpiScale) + pixelOffset,
|
||
|
|
SnapToPixel(point.y, dpiScale) + pixelOffset);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline float ResolveStrokePixelOffset(float thickness) {
|
||
|
|
const float roundedThickness = std::round(thickness);
|
||
|
|
return std::fmod(roundedThickness, 2.0f) == 1.0f ? 0.5f : 0.0f;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline D2D1_BITMAP_PROPERTIES1 BuildD2DBitmapProperties(
|
||
|
|
DXGI_FORMAT format,
|
||
|
|
D2D1_BITMAP_OPTIONS options,
|
||
|
|
D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_IGNORE) {
|
||
|
|
return D2D1::BitmapProperties1(
|
||
|
|
options,
|
||
|
|
D2D1::PixelFormat(format, alphaMode),
|
||
|
|
kBaseDpi,
|
||
|
|
kBaseDpi);
|
||
|
|
}
|
||
|
|
|
||
|
|
inline bool IsInteropTextureHandle(const ::XCEngine::UI::UITextureHandle& texture) {
|
||
|
|
return texture.kind == ::XCEngine::UI::UITextureHandleKind::ShaderResourceView &&
|
||
|
|
texture.resourceHandle != 0u;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline void CollectInteropTextureHandles(
|
||
|
|
const ::XCEngine::UI::UIDrawData& drawData,
|
||
|
|
std::vector<::XCEngine::UI::UITextureHandle>& outTextures) {
|
||
|
|
outTextures.clear();
|
||
|
|
std::unordered_set<std::uintptr_t> seenKeys = {};
|
||
|
|
for (const ::XCEngine::UI::UIDrawList& drawList : drawData.GetDrawLists()) {
|
||
|
|
for (const ::XCEngine::UI::UIDrawCommand& command : drawList.GetCommands()) {
|
||
|
|
if (!IsInteropTextureHandle(command.texture) ||
|
||
|
|
!seenKeys.insert(command.texture.resourceHandle).second) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
outTextures.push_back(command.texture);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace XCEngine::UI::Editor::Host::NativeRendererSupport
|