// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. #pragma once #include "../../renderer/inc/RenderEngineBase.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include "CustomTextRenderer.h" #include "../../types/inc/Viewport.hpp" namespace Microsoft::Console::Render { class DxEngine final : public RenderEngineBase { public: DxEngine(); ~DxEngine(); DxEngine(const DxEngine&) = default; DxEngine(DxEngine&&) = default; DxEngine& operator=(const DxEngine&) = default; DxEngine& operator=(DxEngine&&) = default; // Used to release device resources so that another instance of // conhost can render to the screen (i.e. only one DirectX // application may control the screen at a time.) [[nodiscard]] HRESULT Enable() noexcept; [[nodiscard]] HRESULT Disable() noexcept; [[nodiscard]] HRESULT SetHwnd(const HWND hwnd) noexcept; [[nodiscard]] HRESULT SetWindowSize(const SIZE pixels) noexcept; void SetCallback(std::function pfn); ::Microsoft::WRL::ComPtr GetSwapChain(); // IRenderEngine Members [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override; [[nodiscard]] HRESULT InvalidateCursor(const COORD* const pcoordCursor) noexcept override; [[nodiscard]] HRESULT InvalidateSystem(const RECT* const prcDirtyClient) noexcept override; [[nodiscard]] HRESULT InvalidateSelection(const std::vector& rectangles) noexcept override; [[nodiscard]] HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept override; [[nodiscard]] HRESULT InvalidateAll() noexcept override; [[nodiscard]] HRESULT InvalidateCircling(_Out_ bool* const pForcePaint) noexcept override; [[nodiscard]] HRESULT PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept override; [[nodiscard]] HRESULT StartPaint() noexcept override; [[nodiscard]] HRESULT EndPaint() noexcept override; [[nodiscard]] HRESULT Present() noexcept override; [[nodiscard]] HRESULT ScrollFrame() noexcept override; [[nodiscard]] HRESULT PaintBackground() noexcept override; [[nodiscard]] HRESULT PaintBufferLine(std::basic_string_view const clusters, COORD const coord, bool const fTrimLeft) noexcept override; [[nodiscard]] HRESULT PaintBufferGridLines(GridLines const lines, COLORREF const color, size_t const cchLine, COORD const coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(const SMALL_RECT rect) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; [[nodiscard]] HRESULT UpdateDrawingBrushes(COLORREF const colorForeground, COLORREF const colorBackground, const WORD legacyColorAttribute, const ExtendedAttributes extendedAttrs, bool const isSettingDefaultBrushes) noexcept override; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo) noexcept override; [[nodiscard]] HRESULT UpdateDpi(int const iDpi) noexcept override; [[nodiscard]] HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept override; [[nodiscard]] HRESULT GetProposedFont(const FontInfoDesired& fiFontInfoDesired, FontInfo& fiFontInfo, int const iDpi) noexcept override; [[nodiscard]] SMALL_RECT GetDirtyRectInChars() noexcept override; [[nodiscard]] HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept override; [[nodiscard]] HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept override; [[nodiscard]] ::Microsoft::Console::Types::Viewport GetViewportInCharacters(const ::Microsoft::Console::Types::Viewport& viewInPixels) noexcept; float GetScaling() const noexcept; protected: [[nodiscard]] HRESULT _DoUpdateTitle(_In_ const std::wstring& newTitle) noexcept override; private: enum class SwapChainMode { ForHwnd, ForComposition }; SwapChainMode _chainMode; HWND _hwndTarget; SIZE _sizeTarget; int _dpi; float _scale; std::function _pfn; bool _isEnabled; bool _isPainting; SIZE _displaySizePixels; SIZE _glyphCell; D2D1_COLOR_F _defaultForegroundColor; D2D1_COLOR_F _defaultBackgroundColor; D2D1_COLOR_F _foregroundColor; D2D1_COLOR_F _backgroundColor; [[nodiscard]] RECT _GetDisplayRect() const noexcept; bool _isInvalidUsed; RECT _invalidRect; SIZE _invalidScroll; void _InvalidOr(SMALL_RECT sr) noexcept; void _InvalidOr(RECT rc) noexcept; void _InvalidOffset(POINT pt); bool _presentReady; RECT _presentDirty; RECT _presentScroll; POINT _presentOffset; DXGI_PRESENT_PARAMETERS _presentParams; static const ULONG s_ulMinCursorHeightPercent = 25; static const ULONG s_ulMaxCursorHeightPercent = 100; // Device-Independent Resources ::Microsoft::WRL::ComPtr _d2dFactory; ::Microsoft::WRL::ComPtr _dwriteFactory; ::Microsoft::WRL::ComPtr _dwriteTextFormat; ::Microsoft::WRL::ComPtr _dwriteFontFace; ::Microsoft::WRL::ComPtr _dwriteTextAnalyzer; ::Microsoft::WRL::ComPtr _customRenderer; ::Microsoft::WRL::ComPtr _strokeStyle; // Device-Dependent Resources bool _haveDeviceResources; ::Microsoft::WRL::ComPtr _d3dDevice; ::Microsoft::WRL::ComPtr _d3dDeviceContext; ::Microsoft::WRL::ComPtr _dxgiFactory2; ::Microsoft::WRL::ComPtr _dxgiSurface; ::Microsoft::WRL::ComPtr _d2dRenderTarget; ::Microsoft::WRL::ComPtr _d2dBrushForeground; ::Microsoft::WRL::ComPtr _d2dBrushBackground; ::Microsoft::WRL::ComPtr _dxgiSwapChain; [[nodiscard]] HRESULT _CreateDeviceResources(const bool createSwapChain) noexcept; [[nodiscard]] HRESULT _PrepareRenderTarget() noexcept; void _ReleaseDeviceResources() noexcept; [[nodiscard]] HRESULT _CreateTextLayout( _In_reads_(StringLength) PCWCHAR String, _In_ size_t StringLength, _Out_ IDWriteTextLayout** ppTextLayout) noexcept; [[nodiscard]] HRESULT _CopyFrontToBack() noexcept; [[nodiscard]] HRESULT _EnableDisplayAccess(const bool outputEnabled) noexcept; [[nodiscard]] ::Microsoft::WRL::ComPtr _ResolveFontFaceWithFallback(std::wstring& familyName, DWRITE_FONT_WEIGHT& weight, DWRITE_FONT_STRETCH& stretch, DWRITE_FONT_STYLE& style, std::wstring& localeName) const; [[nodiscard]] ::Microsoft::WRL::ComPtr _FindFontFace(std::wstring& familyName, DWRITE_FONT_WEIGHT& weight, DWRITE_FONT_STRETCH& stretch, DWRITE_FONT_STYLE& style, std::wstring& localeName) const; [[nodiscard]] std::wstring _GetLocaleName() const; [[nodiscard]] std::wstring _GetFontFamilyName(gsl::not_null const fontFamily, std::wstring& localeName) const; [[nodiscard]] HRESULT _GetProposedFont(const FontInfoDesired& desired, FontInfo& actual, const int dpi, ::Microsoft::WRL::ComPtr& textFormat, ::Microsoft::WRL::ComPtr& textAnalyzer, ::Microsoft::WRL::ComPtr& fontFace) const noexcept; [[nodiscard]] COORD _GetFontSize() const noexcept; [[nodiscard]] SIZE _GetClientSize() const noexcept; [[nodiscard]] D2D1_COLOR_F _ColorFFromColorRef(const COLORREF color) noexcept; // Routine Description: // - Helps convert a Direct2D ColorF into a DXGI RGBA // Arguments: // - color - Direct2D Color F // Return Value: // - DXGI RGBA [[nodiscard]] constexpr DXGI_RGBA s_RgbaFromColorF(const D2D1_COLOR_F color) noexcept { return { color.r, color.g, color.b, color.a }; } }; }