#pragma once #include "system_headers.h" #include #include "base.h" #include "application.h" namespace cru { namespace graph { class GraphManager; //Represents a window render target. class WindowRenderTarget : public Object { public: WindowRenderTarget(GraphManager* graph_manager, HWND hwnd); WindowRenderTarget(const WindowRenderTarget& other) = delete; WindowRenderTarget(WindowRenderTarget&& other) = delete; WindowRenderTarget& operator=(const WindowRenderTarget& other) = delete; WindowRenderTarget& operator=(WindowRenderTarget&& other) = delete; ~WindowRenderTarget() override; public: //Get the graph manager that created the render target. GraphManager* GetGraphManager() const { return graph_manager_; } //Get the d2d device context. inline Microsoft::WRL::ComPtr GetD2DDeviceContext() const; //Get the target bitmap which can be set as the ID2D1DeviceContext's target. Microsoft::WRL::ComPtr GetTargetBitmap() const { return target_bitmap_; } //Resize the underlying buffer. void ResizeBuffer(int width, int height); //Set this render target as the d2d device context's target. void SetAsTarget(); //Present the data of the underlying buffer to the window. void Present(); private: void CreateTargetBitmap(); private: GraphManager* graph_manager_; Microsoft::WRL::ComPtr dxgi_swap_chain_; Microsoft::WRL::ComPtr target_bitmap_; }; struct Dpi { float x; float y; }; class GraphManager : public Object { public: static GraphManager* GetInstance(); public: GraphManager(); GraphManager(const GraphManager& other) = delete; GraphManager(GraphManager&& other) = delete; GraphManager& operator=(const GraphManager& other) = delete; GraphManager& operator=(GraphManager&& other) = delete; ~GraphManager() override; public: Microsoft::WRL::ComPtr GetD2D1Factory() const { return d2d1_factory_; } Microsoft::WRL::ComPtr GetD2D1DeviceContext() const { return d2d1_device_context_; } Microsoft::WRL::ComPtr GetD3D11Device() const { return d3d11_device_; } Microsoft::WRL::ComPtr GetDxgiFactory() const { return dxgi_factory_; } Microsoft::WRL::ComPtr GetDWriteFactory() const { return dwrite_factory_; } //Create a window render target with the HWND. std::shared_ptr CreateWindowRenderTarget(HWND hwnd); //Get the desktop dpi. Dpi GetDpi() const; //Reload system metrics including desktop dpi. void ReloadSystemMetrics(); Microsoft::WRL::ComPtr GetSystemFontCollection() const { return dwrite_system_font_collection_.Get(); } private: Microsoft::WRL::ComPtr d3d11_device_; Microsoft::WRL::ComPtr d3d11_device_context_; Microsoft::WRL::ComPtr d2d1_factory_; Microsoft::WRL::ComPtr d2d1_device_; Microsoft::WRL::ComPtr d2d1_device_context_; Microsoft::WRL::ComPtr dxgi_factory_; Microsoft::WRL::ComPtr dwrite_factory_; Microsoft::WRL::ComPtr dwrite_system_font_collection_; }; inline int DipToPixelInternal(const float dip, const float dpi) { return static_cast(dip * dpi / 96.0f); } inline int DipToPixelX(const float dip_x) { return DipToPixelInternal(dip_x, Application::GetInstance()->GetGraphManager()->GetDpi().x); } inline int DipToPixelY(const float dip_y) { return DipToPixelInternal(dip_y, Application::GetInstance()->GetGraphManager()->GetDpi().y); } inline float DipToPixelInternal(const int pixel, const float dpi) { return static_cast(pixel) * 96.0f / dpi; } inline float PixelToDipX(const int pixel_x) { return DipToPixelInternal(pixel_x, Application::GetInstance()->GetGraphManager()->GetDpi().x); } inline float PixelToDipY(const int pixel_y) { return DipToPixelInternal(pixel_y, Application::GetInstance()->GetGraphManager()->GetDpi().y); } Microsoft::WRL::ComPtr WindowRenderTarget::GetD2DDeviceContext() const { return graph_manager_->GetD2D1DeviceContext(); } } }