| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | // Copyright (c) 2016-2018 Easy2D - Nomango
 | 
					
						
							|  |  |  |  | // 
 | 
					
						
							|  |  |  |  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					
						
							|  |  |  |  | // of this software and associated documentation files (the "Software"), to deal
 | 
					
						
							|  |  |  |  | // in the Software without restriction, including without limitation the rights
 | 
					
						
							|  |  |  |  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					
						
							|  |  |  |  | // copies of the Software, and to permit persons to whom the Software is
 | 
					
						
							|  |  |  |  | // furnished to do so, subject to the following conditions:
 | 
					
						
							|  |  |  |  | // 
 | 
					
						
							|  |  |  |  | // The above copyright notice and this permission notice shall be included in
 | 
					
						
							|  |  |  |  | // all copies or substantial portions of the Software.
 | 
					
						
							|  |  |  |  | // 
 | 
					
						
							|  |  |  |  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
					
						
							|  |  |  |  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
					
						
							|  |  |  |  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
					
						
							|  |  |  |  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					
						
							|  |  |  |  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
					
						
							|  |  |  |  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					
						
							|  |  |  |  | // THE SOFTWARE.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #include "render.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-15 17:59:18 +08:00
										 |  |  |  | #include "logs.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | #include "render.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | #include "Image.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | #include "Transform.hpp"
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | namespace easy2d | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	Renderer::Renderer() | 
					
						
							|  |  |  |  | 		: antialias_(true) | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 		, vsync_(true) | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		, text_antialias_(TextAntialias::ClearType) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		, clear_color_(D2D1::ColorF(D2D1::ColorF::Black)) | 
					
						
							|  |  |  |  | 		, opacity_(1.f) | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 		, collecting_status_(false) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		status_.primitives = 0; | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	Renderer::~Renderer() | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::Init(HWND hwnd) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		HRESULT hr = S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		E2D_LOG(L"Creating device resources"); | 
					
						
							|  |  |  |  | 		 | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			device_resources_ = nullptr; | 
					
						
							|  |  |  |  | 			hr = DeviceResources::Create( | 
					
						
							|  |  |  |  | 				&device_resources_, | 
					
						
							|  |  |  |  | 				hwnd | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			factory_ = device_resources_->GetD2DFactory(); | 
					
						
							|  |  |  |  | 			device_context_ = device_resources_->GetD2DDeviceContext(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-15 17:59:18 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			drawing_state_block_ = nullptr; | 
					
						
							|  |  |  |  | 			hr = factory_->CreateDrawingStateBlock( | 
					
						
							|  |  |  |  | 				&drawing_state_block_ | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-12 22:36:50 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			hr = CreateDeviceResources(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		return hr; | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	void Renderer::Destroy() | 
					
						
							| 
									
										
										
										
											2019-02-09 00:03:24 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		E2D_LOG(L"Destroying device resources"); | 
					
						
							| 
									
										
										
										
											2019-02-09 00:03:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_resources_.Reset(); | 
					
						
							|  |  |  |  | 		factory_.Reset(); | 
					
						
							|  |  |  |  | 		device_context_.Reset(); | 
					
						
							|  |  |  |  | 		drawing_state_block_.Reset(); | 
					
						
							| 
									
										
										
										
											2019-02-09 00:03:24 +08:00
										 |  |  |  | 		text_renderer_.Reset(); | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		solid_color_brush_.Reset(); | 
					
						
							| 
									
										
										
										
											2019-02-09 00:03:24 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::CreateDeviceResources() | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		HRESULT hr = S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		hr = device_context_->CreateSolidColorBrush( | 
					
						
							|  |  |  |  | 			D2D1::ColorF(D2D1::ColorF::White), | 
					
						
							|  |  |  |  | 			&solid_color_brush_ | 
					
						
							|  |  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			hr = ITextRenderer::Create( | 
					
						
							|  |  |  |  | 				&text_renderer_, | 
					
						
							|  |  |  |  | 				device_context_.Get() | 
					
						
							|  |  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			SetAntialiasMode(antialias_); | 
					
						
							|  |  |  |  | 			SetTextAntialiasMode(text_antialias_); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return hr; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::HandleDeviceLost() | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		HRESULT hr = device_resources_->HandleDeviceLost(); | 
					
						
							| 
									
										
										
										
											2018-11-25 19:29:32 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							| 
									
										
										
										
											2018-11-25 19:29:32 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			hr = CreateDeviceResources(); | 
					
						
							| 
									
										
										
										
											2018-11-25 19:29:32 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return hr; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::BeginDraw() | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							|  |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 		if (collecting_status_) | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			status_.start = time::Now(); | 
					
						
							|  |  |  |  | 			status_.primitives = 0; | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->SaveDrawingState(drawing_state_block_.Get()); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		device_context_->BeginDraw(); | 
					
						
							|  |  |  |  | 		return S_OK; | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::EndDraw() | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		HRESULT hr = device_context_->EndDraw(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		device_context_->RestoreDrawingState(drawing_state_block_.Get()); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			// The first argument instructs DXGI to block until VSync.
 | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 			hr = device_resources_->GetDXGISwapChain()->Present(vsync_ ? 1 : 0, 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			auto main_rt_view = device_resources_->GetD3DRenderTargetView(); | 
					
						
							|  |  |  |  | 			device_resources_->GetD3DDeviceContext()->OMSetRenderTargets( | 
					
						
							|  |  |  |  | 				1,  | 
					
						
							|  |  |  |  | 				&main_rt_view, | 
					
						
							|  |  |  |  | 				device_resources_->GetD3DDepthStencilView() | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			device_resources_->GetD3DDeviceContext()->ClearRenderTargetView( | 
					
						
							|  |  |  |  | 				main_rt_view, | 
					
						
							|  |  |  |  | 				reinterpret_cast<float*>(&clear_color_) | 
					
						
							|  |  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			// <20><><EFBFBD><EFBFBD> Direct3D <20>豸<EFBFBD><E8B1B8>ִ<EFBFBD>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
 | 
					
						
							|  |  |  |  | 			hr = HandleDeviceLost(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 		if (collecting_status_) | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			status_.duration = time::Now() - status_.start; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 		return hr; | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::CreateLayer(ComPtr<ID2D1Layer>& layer) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		layer = nullptr; | 
					
						
							|  |  |  |  | 		return device_context_->CreateLayer(&layer); | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::DrawGeometry( | 
					
						
							|  |  |  |  | 		ComPtr<ID2D1Geometry> const& geometry, | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		Color const& stroke_color, | 
					
						
							|  |  |  |  | 		float stroke_width, | 
					
						
							|  |  |  |  | 		StrokeStyle stroke | 
					
						
							|  |  |  |  | 	) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!solid_color_brush_ || !device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->DrawGeometry( | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			geometry.Get(), | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			solid_color_brush_.Get(), | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			stroke_width, | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			device_resources_->GetStrokeStyle(stroke) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 		if (collecting_status_) | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 			++status_.primitives; | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::FillGeometry(ComPtr<ID2D1Geometry> const & geometry, Color const& fill_color) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!solid_color_brush_ || !device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); | 
					
						
							|  |  |  |  | 		device_context_->FillGeometry( | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			geometry.Get(), | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			solid_color_brush_.Get() | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::DrawImage(ImagePtr const & image, Rect const& dest_rect) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		if (!image->GetBitmap()) | 
					
						
							|  |  |  |  | 			return S_OK; | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->DrawBitmap( | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			image->GetBitmap().Get(), | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			DX::ConvertToRectF(dest_rect), | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			opacity_, | 
					
						
							|  |  |  |  | 			D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			DX::ConvertToRectF(image->GetCropRect()) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 		if (collecting_status_) | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 			++status_.primitives; | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::DrawBitmap(ComPtr<ID2D1Bitmap> const & bitmap) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!bitmap) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			return S_OK; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		// Do not crop bitmap 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		D2D_RECT_F rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height); | 
					
						
							|  |  |  |  | 		device_context_->DrawBitmap( | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			bitmap.Get(), | 
					
						
							|  |  |  |  | 			rect, | 
					
						
							|  |  |  |  | 			opacity_, | 
					
						
							|  |  |  |  | 			D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, | 
					
						
							|  |  |  |  | 			rect | 
					
						
							|  |  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 		if (collecting_status_) | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		++status_.primitives; | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::DrawTextLayout(ComPtr<IDWriteTextLayout> const& text_layout) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (!text_renderer_) | 
					
						
							|  |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 		if (collecting_status_) | 
					
						
							| 
									
										
										
										
											2018-11-23 14:55:03 +08:00
										 |  |  |  | 			++status_.primitives; | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return text_layout->Draw(nullptr, text_renderer_.Get(), 0, 0); | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 	void Renderer::SetVSyncEnabled(bool enabled) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		vsync_ = enabled; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::PushClip(const Matrix & clip_matrix, const Size & clip_size) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->SetTransform(DX::ConvertToMatrix3x2F(clip_matrix)); | 
					
						
							|  |  |  |  | 		device_context_->PushAxisAlignedClip( | 
					
						
							| 
									
										
										
										
											2018-11-25 15:00:15 +08:00
										 |  |  |  | 			D2D1::RectF(0, 0, clip_size.x, clip_size.y), | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			D2D1_ANTIALIAS_MODE_PER_PRIMITIVE | 
					
						
							|  |  |  |  | 		); | 
					
						
							|  |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::PopClip() | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->PopAxisAlignedClip(); | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::PushLayer(ComPtr<ID2D1Layer> const& layer, LayerProperties const& properties) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_ || !solid_color_brush_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->PushLayer( | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			D2D1::LayerParameters( | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 				DX::ConvertToRectF(properties.area), | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 				nullptr, | 
					
						
							|  |  |  |  | 				D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, | 
					
						
							|  |  |  |  | 				D2D1::Matrix3x2F::Identity(), | 
					
						
							|  |  |  |  | 				properties.opacity, | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 				solid_color_brush_.Get(), | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 				D2D1_LAYER_OPTIONS_NONE | 
					
						
							|  |  |  |  | 			), | 
					
						
							|  |  |  |  | 			layer.Get() | 
					
						
							|  |  |  |  | 		); | 
					
						
							|  |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::PopLayer() | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->PopLayer(); | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-11 11:11:39 +08:00
										 |  |  |  | 	void Renderer::StartCollectStatus() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		collecting_status_ = true; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 	void Renderer::StopCollectStatus() | 
					
						
							|  |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		collecting_status_ = false; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	void Renderer::SetClearColor(const Color & color) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		clear_color_ = DX::ConvertToColorF(color); | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::SetTransform(const Matrix & matrix) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->SetTransform(DX::ConvertToMatrix3x2F(matrix)); | 
					
						
							|  |  |  |  | 		return S_OK; | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	void Renderer::SetOpacity(float opacity) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (opacity_ != opacity) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			opacity_ = opacity; | 
					
						
							|  |  |  |  | 			solid_color_brush_->SetOpacity(opacity); | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::SetTextStyle( | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		Color const& color, | 
					
						
							|  |  |  |  | 		bool has_outline, | 
					
						
							|  |  |  |  | 		Color const& outline_color, | 
					
						
							|  |  |  |  | 		float outline_width, | 
					
						
							|  |  |  |  | 		StrokeStyle outline_stroke | 
					
						
							|  |  |  |  | 	) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!text_renderer_ || !device_resources_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		text_renderer_->SetTextStyle( | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			DX::ConvertToColorF(color), | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			has_outline, | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			DX::ConvertToColorF(outline_color), | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			outline_width, | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 			device_resources_->GetStrokeStyle(outline_stroke) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		); | 
					
						
							|  |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::SetAntialiasMode(bool enabled) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->SetAntialiasMode( | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED | 
					
						
							|  |  |  |  | 		); | 
					
						
							|  |  |  |  | 		antialias_ = enabled; | 
					
						
							|  |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 	HRESULT Renderer::SetTextAntialiasMode(TextAntialias mode) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		if (!device_context_) | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 			return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		text_antialias_ = mode; | 
					
						
							|  |  |  |  | 		D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; | 
					
						
							|  |  |  |  | 		switch (text_antialias_) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		case TextAntialias::Default: | 
					
						
							|  |  |  |  | 			antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; | 
					
						
							|  |  |  |  | 			break; | 
					
						
							|  |  |  |  | 		case TextAntialias::ClearType: | 
					
						
							|  |  |  |  | 			antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; | 
					
						
							|  |  |  |  | 			break; | 
					
						
							|  |  |  |  | 		case TextAntialias::GrayScale: | 
					
						
							|  |  |  |  | 			antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE; | 
					
						
							|  |  |  |  | 			break; | 
					
						
							|  |  |  |  | 		case TextAntialias::None: | 
					
						
							|  |  |  |  | 			antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED; | 
					
						
							|  |  |  |  | 			break; | 
					
						
							|  |  |  |  | 		default: | 
					
						
							|  |  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-03-10 13:44:02 +08:00
										 |  |  |  | 		device_context_->SetTextAntialiasMode(antialias_mode); | 
					
						
							| 
									
										
										
										
											2018-11-22 19:31:44 +08:00
										 |  |  |  | 		return S_OK; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | } |