refactor(new_editor/app): split native renderer draw responsibilities
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
#include "NativeRendererSupport.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace XCEngine::UI::Editor::Host {
|
||||
|
||||
using namespace NativeRendererSupport;
|
||||
|
||||
void NativeRenderer::RenderTextCommand(
|
||||
ID2D1RenderTarget& renderTarget,
|
||||
ID2D1SolidColorBrush& solidBrush,
|
||||
const ::XCEngine::UI::UIDrawCommand& command) {
|
||||
if (command.text.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float dpiScale = ClampDpiScale(m_dpiScale);
|
||||
const float fontSize = ResolveFontSize(command.fontSize);
|
||||
const float scaledFontSize = fontSize * dpiScale;
|
||||
IDWriteTextFormat* textFormat = GetTextFormat(scaledFontSize);
|
||||
if (textFormat == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::wstring text = Utf8ToWide(command.text);
|
||||
if (text.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const D2D1_SIZE_F targetSize = renderTarget.GetSize();
|
||||
const float originX = SnapToPixel(command.position.x, dpiScale);
|
||||
const float originY = SnapToPixel(command.position.y, dpiScale);
|
||||
const float lineHeight = std::ceil(scaledFontSize * 1.6f);
|
||||
const D2D1_RECT_F layoutRect = D2D1::RectF(
|
||||
originX,
|
||||
originY,
|
||||
targetSize.width,
|
||||
originY + lineHeight);
|
||||
renderTarget.DrawTextW(
|
||||
text.c_str(),
|
||||
static_cast<UINT32>(text.size()),
|
||||
textFormat,
|
||||
layoutRect,
|
||||
&solidBrush,
|
||||
D2D1_DRAW_TEXT_OPTIONS_CLIP,
|
||||
DWRITE_MEASURING_MODE_GDI_NATURAL);
|
||||
}
|
||||
|
||||
void NativeRenderer::RenderImageCommand(
|
||||
ID2D1RenderTarget& renderTarget,
|
||||
ID2D1SolidColorBrush& solidBrush,
|
||||
const ::XCEngine::UI::UIDrawCommand& command) {
|
||||
if (!command.texture.IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float dpiScale = ClampDpiScale(m_dpiScale);
|
||||
Microsoft::WRL::ComPtr<ID2D1Bitmap> bitmap;
|
||||
if (command.texture.kind == ::XCEngine::UI::UITextureHandleKind::ShaderResourceView) {
|
||||
if (!ResolveInteropBitmap(command.texture, bitmap) || !bitmap) {
|
||||
const D2D1_RECT_F rect = ToD2DRect(command.rect, dpiScale);
|
||||
renderTarget.DrawRectangle(rect, &solidBrush, 1.0f);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
auto* texture = reinterpret_cast<NativeTextureResource*>(command.texture.nativeHandle);
|
||||
if (texture == nullptr || m_liveTextures.find(texture) == m_liveTextures.end()) {
|
||||
const D2D1_RECT_F rect = ToD2DRect(command.rect, dpiScale);
|
||||
renderTarget.DrawRectangle(rect, &solidBrush, 1.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ResolveTextureBitmap(renderTarget, *texture, bitmap) || !bitmap) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const D2D1_RECT_F rect = ToD2DRect(command.rect, dpiScale);
|
||||
const float sourceWidth = static_cast<float>(command.texture.width);
|
||||
const float sourceHeight = static_cast<float>(command.texture.height);
|
||||
const float sourceLeft = sourceWidth * std::clamp(command.uvMin.x, 0.0f, 1.0f);
|
||||
const float sourceTop = sourceHeight * std::clamp(command.uvMin.y, 0.0f, 1.0f);
|
||||
const float sourceRight = sourceWidth * std::clamp(command.uvMax.x, 0.0f, 1.0f);
|
||||
const float sourceBottom = sourceHeight * std::clamp(command.uvMax.y, 0.0f, 1.0f);
|
||||
renderTarget.DrawBitmap(
|
||||
bitmap.Get(),
|
||||
rect,
|
||||
std::clamp(command.color.a, 0.0f, 1.0f),
|
||||
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
|
||||
D2D1::RectF(sourceLeft, sourceTop, sourceRight, sourceBottom));
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::Host
|
||||
Reference in New Issue
Block a user