| 
									
										
										
										
											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"
 | 
					
						
							|  |  |  |  | #include "time.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-16 15:53:39 +08:00
										 |  |  |  | #include "base.hpp"
 | 
					
						
							| 
									
										
										
										
											2018-11-15 17:59:18 +08:00
										 |  |  |  | #include "logs.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | #include "modules.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 | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 	namespace devices | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		GraphicsDevice::GraphicsDevice() | 
					
						
							|  |  |  |  | 			: fps_text_format_(nullptr) | 
					
						
							|  |  |  |  | 			, fps_text_layout_(nullptr) | 
					
						
							|  |  |  |  | 			, clear_color_(D2D1::ColorF(D2D1::ColorF::Black)) | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 			, opacity_(1.f) | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			, window_occluded(false) | 
					
						
							| 
									
										
										
										
											2018-11-12 22:36:50 +08:00
										 |  |  |  | 			, initialized(false) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			ZeroMemory(&d2d, sizeof(D2DResources)); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		GraphicsDevice::~GraphicsDevice() | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-15 17:59:18 +08:00
										 |  |  |  | 			E2D_LOG("Destroying graphics device"); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			ClearImageCache(); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-14 01:34:41 +08:00
										 |  |  |  | 		void GraphicsDevice::Init(HWND hwnd, bool debug) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 22:36:50 +08:00
										 |  |  |  | 			if (initialized) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-15 17:59:18 +08:00
										 |  |  |  | 			E2D_LOG("Initing graphics device"); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 22:36:50 +08:00
										 |  |  |  | 			D2D1_FACTORY_OPTIONS options{ debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE }; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			ThrowIfFailed( | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				modules::DirectX().D2D1CreateFactory( | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 					D2D1_FACTORY_TYPE_SINGLE_THREADED, | 
					
						
							| 
									
										
										
										
											2018-11-12 22:36:50 +08:00
										 |  |  |  | 					__uuidof(ID2D1Factory), | 
					
						
							|  |  |  |  | 					&options, | 
					
						
							|  |  |  |  | 					reinterpret_cast<void**>(&d2d.factory) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				) | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			ThrowIfFailed( | 
					
						
							|  |  |  |  | 				CoCreateInstance( | 
					
						
							|  |  |  |  | 					CLSID_WICImagingFactory, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							|  |  |  |  | 					CLSCTX_INPROC_SERVER, | 
					
						
							| 
									
										
										
										
											2018-11-12 22:36:50 +08:00
										 |  |  |  | 					__uuidof(IWICImagingFactory), | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 					reinterpret_cast<void**>(&d2d.imaging_factory) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				) | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			ThrowIfFailed( | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				modules::DirectX().DWriteCreateFactory( | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 					DWRITE_FACTORY_TYPE_SHARED, | 
					
						
							|  |  |  |  | 					__uuidof(IDWriteFactory), | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 					reinterpret_cast<IUnknown**>(&d2d.write_factory) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				) | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			auto stroke_style = D2D1::StrokeStyleProperties( | 
					
						
							|  |  |  |  | 				D2D1_CAP_STYLE_FLAT, | 
					
						
							|  |  |  |  | 				D2D1_CAP_STYLE_FLAT, | 
					
						
							|  |  |  |  | 				D2D1_CAP_STYLE_FLAT, | 
					
						
							|  |  |  |  | 				D2D1_LINE_JOIN_MITER, | 
					
						
							|  |  |  |  | 				2.0f, | 
					
						
							|  |  |  |  | 				D2D1_DASH_STYLE_SOLID, | 
					
						
							|  |  |  |  | 				0.0f | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			ThrowIfFailed( | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				d2d.factory->CreateStrokeStyle( | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 					stroke_style, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							|  |  |  |  | 					0, | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 					&d2d.miter_stroke_style | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				) | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL; | 
					
						
							|  |  |  |  | 			ThrowIfFailed( | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				d2d.factory->CreateStrokeStyle( | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 					stroke_style, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							|  |  |  |  | 					0, | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 					&d2d.bevel_stroke_style | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				) | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND; | 
					
						
							|  |  |  |  | 			ThrowIfFailed( | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				d2d.factory->CreateStrokeStyle( | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 					stroke_style, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							|  |  |  |  | 					0, | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 					&d2d.round_stroke_style | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 				) | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			CreateDeviceResources(hwnd); | 
					
						
							| 
									
										
										
										
											2018-11-12 22:36:50 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 			initialized = true; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		void GraphicsDevice::BeginDraw(HWND hwnd) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			CreateDeviceResources(hwnd); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			window_occluded = !!(d2d.render_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (!window_occluded) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				d2d.render_target->BeginDraw(); | 
					
						
							|  |  |  |  | 				d2d.render_target->Clear(clear_color_); | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		void GraphicsDevice::EndDraw() | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			if (!window_occluded) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 				HRESULT hr = d2d.render_target->EndDraw(); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 				if (hr == D2DERR_RECREATE_TARGET) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					// <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>Դ
 | 
					
						
							|  |  |  |  | 					// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ε<EFBFBD><CEB5><EFBFBD>ʱ<EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>Դ
 | 
					
						
							|  |  |  |  | 					hr = S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 					fps_text_format_ = nullptr; | 
					
						
							|  |  |  |  | 					fps_text_layout_ = nullptr; | 
					
						
							|  |  |  |  | 					d2d.text_renderer = nullptr; | 
					
						
							|  |  |  |  | 					d2d.solid_brush = nullptr; | 
					
						
							|  |  |  |  | 					d2d.render_target = nullptr; | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 				ThrowIfFailed(hr); | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 		void GraphicsDevice::ClearImageCache() | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			bitmap_cache_.clear(); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::CreateRectangleGeometry(cpRectangleGeometry & geo, Rect const& rect) const | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.factory) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 			cpRectangleGeometry rectangle; | 
					
						
							|  |  |  |  | 			HRESULT hr = d2d.factory->CreateRectangleGeometry( | 
					
						
							|  |  |  |  | 				rect, | 
					
						
							|  |  |  |  | 				&rectangle | 
					
						
							|  |  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 				geo = rectangle; | 
					
						
							|  |  |  |  | 			return hr; | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 14:30:39 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::CreateRoundedRectangleGeometry(cpRoundedRectangleGeometry & geo, Rect const & rect, float radius_x, float radius_y) const | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.factory) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			cpRoundedRectangleGeometry rounded_rect; | 
					
						
							|  |  |  |  | 			HRESULT hr = d2d.factory->CreateRoundedRectangleGeometry( | 
					
						
							|  |  |  |  | 				D2D1::RoundedRect( | 
					
						
							|  |  |  |  | 					rect, | 
					
						
							|  |  |  |  | 					radius_x, | 
					
						
							|  |  |  |  | 					radius_y | 
					
						
							|  |  |  |  | 				), | 
					
						
							|  |  |  |  | 				&rounded_rect | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 				geo = rounded_rect; | 
					
						
							|  |  |  |  | 			return hr; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::CreateEllipseGeometry(cpEllipseGeometry & geo, Point const & center, float radius_x, float radius_y) const | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.factory) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			cpEllipseGeometry ellipse; | 
					
						
							|  |  |  |  | 			HRESULT hr = d2d.factory->CreateEllipseGeometry( | 
					
						
							|  |  |  |  | 				D2D1::Ellipse( | 
					
						
							|  |  |  |  | 					center, | 
					
						
							|  |  |  |  | 					radius_x, | 
					
						
							|  |  |  |  | 					radius_y | 
					
						
							|  |  |  |  | 				), | 
					
						
							|  |  |  |  | 				&ellipse | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 				geo = ellipse; | 
					
						
							|  |  |  |  | 			return hr; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		HRESULT GraphicsDevice::CreateTransformedGeometry( | 
					
						
							|  |  |  |  | 			cpTransformedGeometry& transformed, | 
					
						
							|  |  |  |  | 			math::Matrix const& matrix, | 
					
						
							|  |  |  |  | 			cpGeometry const& geo | 
					
						
							|  |  |  |  | 		) const | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.factory) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			cpTransformedGeometry transformed_tmp; | 
					
						
							|  |  |  |  | 			HRESULT hr = d2d.factory->CreateTransformedGeometry( | 
					
						
							|  |  |  |  | 				geo.Get(), | 
					
						
							|  |  |  |  | 				ConvertToD2DMatrix(matrix), | 
					
						
							|  |  |  |  | 				&transformed_tmp | 
					
						
							|  |  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 				transformed = transformed_tmp; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			return hr; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::CreatePathGeometry(cpPathGeometry & geometry) const | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.factory) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			return d2d.factory->CreatePathGeometry(&geometry); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		HRESULT GraphicsDevice::CreateTextFormat(cpTextFormat & text_format, Font const & font, TextStyle const & text_style) const | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.write_factory) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 			cpTextFormat text_format_tmp; | 
					
						
							|  |  |  |  | 			HRESULT hr = d2d.write_factory->CreateTextFormat( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				font.family.c_str(), | 
					
						
							|  |  |  |  | 				nullptr, | 
					
						
							|  |  |  |  | 				DWRITE_FONT_WEIGHT(font.weight), | 
					
						
							|  |  |  |  | 				font.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, | 
					
						
							|  |  |  |  | 				DWRITE_FONT_STRETCH_NORMAL, | 
					
						
							|  |  |  |  | 				font.size, | 
					
						
							|  |  |  |  | 				L"", | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 				&text_format_tmp | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				if (text_style.line_spacing == 0.f) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					text_format_tmp->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 				else | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					text_format_tmp->SetLineSpacing( | 
					
						
							|  |  |  |  | 						DWRITE_LINE_SPACING_METHOD_UNIFORM, | 
					
						
							|  |  |  |  | 						text_style.line_spacing, | 
					
						
							|  |  |  |  | 						text_style.line_spacing * 0.8f | 
					
						
							|  |  |  |  | 					); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 				text_format_tmp->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(text_style.alignment)); | 
					
						
							|  |  |  |  | 				text_format_tmp->SetWordWrapping(text_style.wrap ? DWRITE_WORD_WRAPPING_WRAP : DWRITE_WORD_WRAPPING_NO_WRAP); | 
					
						
							|  |  |  |  | 				text_format = text_format_tmp; | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			return hr; | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::CreateTextLayout(cpTextLayout & text_layout, Size& layout_size, String const & text, cpTextFormat const& text_format, TextStyle const & text_style) const | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.write_factory) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 			text_layout = nullptr; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 			HRESULT hr; | 
					
						
							|  |  |  |  | 			cpTextLayout text_layout_tmp; | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			UINT32 length = static_cast<UINT32>(text.length()); | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (text_style.wrap) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				hr = d2d.write_factory->CreateTextLayout( | 
					
						
							|  |  |  |  | 					text.c_str(), | 
					
						
							|  |  |  |  | 					length, | 
					
						
							|  |  |  |  | 					text_format.Get(), | 
					
						
							|  |  |  |  | 					text_style.wrap_width, | 
					
						
							|  |  |  |  | 					0, | 
					
						
							|  |  |  |  | 					&text_layout_tmp | 
					
						
							|  |  |  |  | 				); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			else | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				hr = d2d.write_factory->CreateTextLayout( | 
					
						
							|  |  |  |  | 					text.c_str(), | 
					
						
							|  |  |  |  | 					length, | 
					
						
							|  |  |  |  | 					text_format.Get(), | 
					
						
							|  |  |  |  | 					0, | 
					
						
							|  |  |  |  | 					0, | 
					
						
							|  |  |  |  | 					&text_layout_tmp | 
					
						
							|  |  |  |  | 				); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 				DWRITE_TEXT_METRICS metrics; | 
					
						
							|  |  |  |  | 				text_layout_tmp->GetMetrics(&metrics); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 				if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					text_layout_tmp = nullptr; | 
					
						
							|  |  |  |  | 					hr = d2d.write_factory->CreateTextLayout( | 
					
						
							|  |  |  |  | 						text.c_str(), | 
					
						
							|  |  |  |  | 						length, | 
					
						
							|  |  |  |  | 						text_format.Get(), | 
					
						
							|  |  |  |  | 						metrics.width, | 
					
						
							|  |  |  |  | 						0, | 
					
						
							|  |  |  |  | 						&text_layout_tmp | 
					
						
							|  |  |  |  | 					); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				DWRITE_TEXT_METRICS metrics; | 
					
						
							|  |  |  |  | 				text_layout_tmp->GetMetrics(&metrics); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 				if (text_style.wrap) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					layout_size = Size(metrics.layoutWidth, metrics.height); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 				else | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					layout_size = Size(metrics.width, metrics.height); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 				DWRITE_TEXT_RANGE range = { 0, length }; | 
					
						
							|  |  |  |  | 				if (text_style.underline) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					text_layout_tmp->SetUnderline(true, range); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 				if (text_style.strikethrough) | 
					
						
							|  |  |  |  | 				{ | 
					
						
							|  |  |  |  | 					text_layout_tmp->SetStrikethrough(true, range); | 
					
						
							|  |  |  |  | 				} | 
					
						
							|  |  |  |  | 				text_layout = text_layout_tmp; | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 			return hr; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		HRESULT GraphicsDevice::CreateTextRenderer( | 
					
						
							|  |  |  |  | 			cpTextRenderer& text_renderer, | 
					
						
							|  |  |  |  | 			cpRenderTarget const& render_target, | 
					
						
							|  |  |  |  | 			cpSolidColorBrush const& brush | 
					
						
							|  |  |  |  | 		) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.factory) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			cpTextRenderer text_renderer_tmp; | 
					
						
							|  |  |  |  | 			HRESULT hr = ITextRenderer::Create( | 
					
						
							|  |  |  |  | 				&text_renderer_tmp, | 
					
						
							|  |  |  |  | 				d2d.factory.Get(), | 
					
						
							|  |  |  |  | 				render_target.Get(), | 
					
						
							|  |  |  |  | 				brush.Get() | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 				text_renderer = text_renderer_tmp; | 
					
						
							|  |  |  |  | 			return hr; | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::CreateLayer(cpLayer& layer) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 			layer = nullptr; | 
					
						
							|  |  |  |  | 			return d2d.render_target->CreateLayer(&layer); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		HRESULT GraphicsDevice::CreateSolidColorBrush(cpSolidColorBrush & brush) const | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.render_target) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			brush = nullptr; | 
					
						
							|  |  |  |  | 			return d2d.render_target->CreateSolidColorBrush( | 
					
						
							|  |  |  |  | 				D2D1::ColorF(D2D1::ColorF::White), | 
					
						
							|  |  |  |  | 				&brush | 
					
						
							|  |  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		HRESULT GraphicsDevice::DrawGeometry( | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 			cpGeometry const& geometry, | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 			Color const& stroke_color, | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			float stroke_width, | 
					
						
							|  |  |  |  | 			StrokeStyle stroke | 
					
						
							|  |  |  |  | 		) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.solid_brush || | 
					
						
							|  |  |  |  | 				!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			if (window_occluded) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 			d2d.solid_brush->SetColor(stroke_color); | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			d2d.render_target->DrawGeometry( | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				geometry.Get(), | 
					
						
							|  |  |  |  | 				d2d.solid_brush.Get(), | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				stroke_width, | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				GetStrokeStyle(stroke).Get() | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			); | 
					
						
							|  |  |  |  | 			return S_OK; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::FillGeometry(cpGeometry const & geometry, const Color & fill_color) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.solid_brush || | 
					
						
							|  |  |  |  | 				!d2d.render_target) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (window_occluded) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			d2d.solid_brush->SetColor(fill_color); | 
					
						
							|  |  |  |  | 			d2d.render_target->FillGeometry( | 
					
						
							|  |  |  |  | 				geometry.Get(), | 
					
						
							|  |  |  |  | 				d2d.solid_brush.Get() | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 			return S_OK; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::DrawImage(spImage const & image) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.render_target) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (!image->GetBitmap()) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			if (window_occluded) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 			d2d.render_target->DrawBitmap( | 
					
						
							|  |  |  |  | 				image->GetBitmap().Get(), | 
					
						
							|  |  |  |  | 				D2D1::RectF(0.f, 0.f, image->GetWidth(), image->GetHeight()), | 
					
						
							|  |  |  |  | 				opacity_, | 
					
						
							|  |  |  |  | 				D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, | 
					
						
							|  |  |  |  | 				image->GetCropRect() | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 			return S_OK; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 		cpStrokeStyle const& GraphicsDevice::GetStrokeStyle(StrokeStyle stroke) const | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			switch (stroke) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			case StrokeStyle::Miter: | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				return d2d.miter_stroke_style; | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				break; | 
					
						
							|  |  |  |  | 			case StrokeStyle::Bevel: | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				return d2d.bevel_stroke_style; | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				break; | 
					
						
							|  |  |  |  | 			case StrokeStyle::Round: | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				return d2d.round_stroke_style; | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 			return d2d.miter_stroke_style; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::DrawBitmap( | 
					
						
							|  |  |  |  | 			cpBitmap const& bitmap | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			if (window_occluded) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 			// Do not crop bitmap 
 | 
					
						
							|  |  |  |  | 			auto rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height); | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			d2d.render_target->DrawBitmap( | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 				bitmap.Get(), | 
					
						
							|  |  |  |  | 				rect, | 
					
						
							|  |  |  |  | 				opacity_, | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 				rect | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			); | 
					
						
							|  |  |  |  | 			return S_OK; | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::DrawTextLayout(cpTextLayout const& text_layout) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.text_renderer) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			if (window_occluded) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 			return text_layout->Draw(nullptr, d2d.text_renderer.Get(), 0, 0); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::PushClip(const math::Matrix & clip_matrix, const Size & clip_size) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			if (window_occluded) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-16 17:19:03 +08:00
										 |  |  |  | 			d2d.render_target->SetTransform(ConvertToD2DMatrix(clip_matrix)); | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			d2d.render_target->PushAxisAlignedClip( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				D2D1::RectF(0, 0, clip_size.width, clip_size.height), | 
					
						
							|  |  |  |  | 				D2D1_ANTIALIAS_MODE_PER_PRIMITIVE | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 			return S_OK; | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::PopClip() | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			if (window_occluded) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			d2d.render_target->PopAxisAlignedClip(); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			return S_OK; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::PushLayer(cpLayer const& layer, LayerProperties const& properties) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target || | 
					
						
							|  |  |  |  | 				!d2d.solid_brush) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			if (window_occluded) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			d2d.render_target->PushLayer( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				D2D1::LayerParameters( | 
					
						
							|  |  |  |  | 					properties.area, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							|  |  |  |  | 					D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, | 
					
						
							|  |  |  |  | 					D2D1::Matrix3x2F::Identity(), | 
					
						
							|  |  |  |  | 					properties.opacity, | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 					d2d.solid_brush.Get(), | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 					D2D1_LAYER_OPTIONS_NONE | 
					
						
							|  |  |  |  | 				), | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				layer.Get() | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			); | 
					
						
							|  |  |  |  | 			return S_OK; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::PopLayer() | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 17:56:17 +08:00
										 |  |  |  | 			if (window_occluded) | 
					
						
							|  |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			d2d.render_target->PopLayer(); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			return S_OK; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::GetSize(Size & size) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.render_target) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			auto rtsize = d2d.render_target->GetSize(); | 
					
						
							|  |  |  |  | 			size.width = rtsize.width; | 
					
						
							|  |  |  |  | 			size.height = rtsize.height; | 
					
						
							|  |  |  |  | 			return S_OK; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::CreateBitmapFromFile(cpBitmap& bitmap, String const& file_path) | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (d2d.imaging_factory == nullptr || | 
					
						
							|  |  |  |  | 				d2d.render_target == nullptr) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			size_t hash_code = std::hash<String>{}(file_path); | 
					
						
							|  |  |  |  | 			if (bitmap_cache_.find(hash_code) != bitmap_cache_.end()) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				bitmap = bitmap_cache_[hash_code]; | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			IWICBitmapDecoder*		decoder = nullptr; | 
					
						
							|  |  |  |  | 			IWICBitmapFrameDecode*	source = nullptr; | 
					
						
							|  |  |  |  | 			IWICStream*				stream = nullptr; | 
					
						
							|  |  |  |  | 			IWICFormatConverter*	converter = nullptr; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			HRESULT hr = d2d.imaging_factory->CreateDecoderFromFilename( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				file_path.c_str(), | 
					
						
							|  |  |  |  | 				nullptr, | 
					
						
							|  |  |  |  | 				GENERIC_READ, | 
					
						
							|  |  |  |  | 				WICDecodeMetadataCacheOnLoad, | 
					
						
							|  |  |  |  | 				&decoder | 
					
						
							|  |  |  |  | 			); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 				hr = decoder->GetFrame(0, &source); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD>ͼƬ<CDBC><C6AC>ʽת<CABD><D7AA><EFBFBD><EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				hr = d2d.imaging_factory->CreateFormatConverter(&converter); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// ͼƬ<CDBC><C6AC>ʽת<CABD><D7AA><EFBFBD><EFBFBD> 32bppPBGRA
 | 
					
						
							|  |  |  |  | 				hr = converter->Initialize( | 
					
						
							|  |  |  |  | 					source, | 
					
						
							|  |  |  |  | 					GUID_WICPixelFormat32bppPBGRA, | 
					
						
							|  |  |  |  | 					WICBitmapDitherTypeNone, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							|  |  |  |  | 					0.f, | 
					
						
							|  |  |  |  | 					WICBitmapPaletteTypeMedianCut | 
					
						
							|  |  |  |  | 				); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// <20><> WIC λͼ<CEBB><CDBC><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> Direct2D λͼ
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				bitmap = nullptr; | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				hr = d2d.render_target->CreateBitmapFromWicBitmap( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 					converter, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 					&bitmap | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			SafeRelease(decoder); | 
					
						
							|  |  |  |  | 			SafeRelease(source); | 
					
						
							|  |  |  |  | 			SafeRelease(stream); | 
					
						
							|  |  |  |  | 			SafeRelease(converter); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			return hr; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::CreateBitmapFromResource(cpBitmap& bitmap, Resource const& res) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (d2d.imaging_factory == nullptr || | 
					
						
							|  |  |  |  | 				d2d.render_target == nullptr) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			size_t hash_code = res.GetHashCode(); | 
					
						
							|  |  |  |  | 			if (bitmap_cache_.find(hash_code) != bitmap_cache_.end()) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				bitmap = bitmap_cache_[hash_code]; | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				return S_OK; | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			HRESULT hr; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			HINSTANCE				hinstance = GetModuleHandle(nullptr); | 
					
						
							|  |  |  |  | 			IWICBitmapDecoder*		decoder = nullptr; | 
					
						
							|  |  |  |  | 			IWICBitmapFrameDecode*	source = nullptr; | 
					
						
							|  |  |  |  | 			IWICStream*				stream = nullptr; | 
					
						
							|  |  |  |  | 			IWICFormatConverter*	converter = nullptr; | 
					
						
							| 
									
										
										
										
											2018-11-12 23:32:50 +08:00
										 |  |  |  | 			ResourceData			buffer; | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
 | 
					
						
							| 
									
										
										
										
											2018-11-12 23:32:50 +08:00
										 |  |  |  | 			hr = res.Load(&buffer) ? S_OK : E_FAIL; | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD> WIC <20><>
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				hr = d2d.imaging_factory->CreateStream(&stream); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 				hr = stream->InitializeFromMemory( | 
					
						
							| 
									
										
										
										
											2018-11-12 23:32:50 +08:00
										 |  |  |  | 					static_cast<WICInProcPointer>(buffer.buffer), | 
					
						
							|  |  |  |  | 					buffer.buffer_size | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				hr = d2d.imaging_factory->CreateDecoderFromStream( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 					stream, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							|  |  |  |  | 					WICDecodeMetadataCacheOnLoad, | 
					
						
							|  |  |  |  | 					&decoder | 
					
						
							|  |  |  |  | 				); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 				hr = decoder->GetFrame(0, &source); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD>ͼƬ<CDBC><C6AC>ʽת<CABD><D7AA><EFBFBD><EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				hr = d2d.imaging_factory->CreateFormatConverter(&converter); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// ͼƬ<CDBC><C6AC>ʽת<CABD><D7AA><EFBFBD><EFBFBD> 32bppPBGRA
 | 
					
						
							|  |  |  |  | 				hr = converter->Initialize( | 
					
						
							|  |  |  |  | 					source, | 
					
						
							|  |  |  |  | 					GUID_WICPixelFormat32bppPBGRA, | 
					
						
							|  |  |  |  | 					WICBitmapDitherTypeNone, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							|  |  |  |  | 					0.f, | 
					
						
							|  |  |  |  | 					WICBitmapPaletteTypeMedianCut | 
					
						
							|  |  |  |  | 				); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				// <20><> WIC λͼ<CEBB><CDBC><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> Direct2D λͼ
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 				hr = d2d.render_target->CreateBitmapFromWicBitmap( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 					converter, | 
					
						
							|  |  |  |  | 					nullptr, | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 					&bitmap | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (SUCCEEDED(hr)) | 
					
						
							|  |  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			SafeRelease(decoder); | 
					
						
							|  |  |  |  | 			SafeRelease(source); | 
					
						
							|  |  |  |  | 			SafeRelease(stream); | 
					
						
							|  |  |  |  | 			SafeRelease(converter); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			return hr; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::CreateBitmapRenderTarget(cpBitmapRenderTarget & brt) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			if (!d2d.render_target) | 
					
						
							|  |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 			brt = nullptr; | 
					
						
							|  |  |  |  | 			return d2d.render_target->CreateCompatibleRenderTarget(&brt); | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::Resize(UINT32 width, UINT32 height) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			d2d.render_target->Resize(D2D1::SizeU(width, height)); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			return S_OK; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		HRESULT GraphicsDevice::SetTransform(const math::Matrix & matrix) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-16 17:19:03 +08:00
										 |  |  |  | 			d2d.render_target->SetTransform(ConvertToD2DMatrix(matrix)); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			return S_OK; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 		HRESULT GraphicsDevice::SetOpacity(float opacity) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 20:26:41 +08:00
										 |  |  |  | 			opacity_ = opacity; | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			d2d.solid_brush->SetOpacity(opacity); | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			return S_OK; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		HRESULT GraphicsDevice::SetTextStyle( | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 			Color const& color, | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			bool has_outline, | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 			Color const& outline_color, | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			float outline_width, | 
					
						
							|  |  |  |  | 			StrokeStyle outline_stroke | 
					
						
							|  |  |  |  | 		) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.text_renderer) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				return E_UNEXPECTED; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			d2d.text_renderer->SetTextStyle( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 				color, | 
					
						
							|  |  |  |  | 				has_outline, | 
					
						
							|  |  |  |  | 				outline_color, | 
					
						
							|  |  |  |  | 				outline_width, | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 				GetStrokeStyle(outline_stroke).Get() | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			); | 
					
						
							|  |  |  |  | 			return S_OK; | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 		void GraphicsDevice::SetBackgroundColor(const Color& color) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			clear_color_ = color; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 		void GraphicsDevice::CreateDeviceResources(HWND hwnd) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.render_target) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				RECT rc; | 
					
						
							|  |  |  |  | 				::GetClientRect(hwnd, &rc); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 				D2D1_SIZE_U size = D2D1::SizeU( | 
					
						
							|  |  |  |  | 					rc.right - rc.left, | 
					
						
							|  |  |  |  | 					rc.bottom - rc.top | 
					
						
							|  |  |  |  | 				); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>Щ<EFBFBD><D0A9>ԴӦ<D4B4><D3A6> Direct2D <20>豸<EFBFBD><E8B1B8>ʧʱ<CAA7>ؽ<EFBFBD>
 | 
					
						
							|  |  |  |  | 				// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> Direct2D <20><>ȾĿ<C8BE><C4BF>
 | 
					
						
							|  |  |  |  | 				ThrowIfFailed( | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 					d2d.factory->CreateHwndRenderTarget( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 						D2D1::RenderTargetProperties(), | 
					
						
							|  |  |  |  | 						D2D1::HwndRenderTargetProperties( | 
					
						
							|  |  |  |  | 							hwnd, | 
					
						
							|  |  |  |  | 							size, | 
					
						
							|  |  |  |  | 							D2D1_PRESENT_OPTIONS_NONE), | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 						&d2d.render_target | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 					) | 
					
						
							|  |  |  |  | 				); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.solid_brush) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				ThrowIfFailed( | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 					d2d.render_target->CreateSolidColorBrush( | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 						D2D1::ColorF(D2D1::ColorF::White), | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 						&d2d.solid_brush | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 					) | 
					
						
							|  |  |  |  | 				); | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 			if (!d2d.text_renderer) | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 			{ | 
					
						
							|  |  |  |  | 				ThrowIfFailed( | 
					
						
							|  |  |  |  | 					ITextRenderer::Create( | 
					
						
							| 
									
										
										
										
											2018-11-12 20:46:54 +08:00
										 |  |  |  | 						&d2d.text_renderer, | 
					
						
							| 
									
										
										
										
											2018-11-17 17:15:32 +08:00
										 |  |  |  | 						d2d.factory.Get(), | 
					
						
							|  |  |  |  | 						d2d.render_target.Get(), | 
					
						
							|  |  |  |  | 						d2d.solid_brush.Get() | 
					
						
							| 
									
										
										
										
											2018-11-12 02:10:35 +08:00
										 |  |  |  | 					) | 
					
						
							|  |  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-11-20 01:20:06 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 21:39:26 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } |