From b9ac2c39344a03d320d34ef1ffca365150fc312e Mon Sep 17 00:00:00 2001 From: Haibo Date: Wed, 21 Nov 2018 17:18:59 +0800 Subject: [PATCH] add: Factory --- core/base/Canvas.cpp | 15 +- core/base/Factory.cpp | 518 ++++++++++++++++++++++ core/base/Factory.h | 127 ++++++ core/base/Game.cpp | 2 + core/base/Geometry.cpp | 15 +- core/base/Node.cpp | 5 +- core/base/Text.cpp | 7 +- core/base/render.cpp | 594 ++++---------------------- core/base/render.h | 71 +-- core/easy2d.h | 1 + project/vs2013/Easy2D.vcxproj | 2 + project/vs2013/Easy2D.vcxproj.filters | 6 + project/vs2015/Easy2D.vcxproj | 2 + project/vs2015/Easy2D.vcxproj.filters | 6 + project/vs2017/Easy2D.vcxproj | 2 + project/vs2017/Easy2D.vcxproj.filters | 6 + 16 files changed, 777 insertions(+), 602 deletions(-) create mode 100644 core/base/Factory.cpp create mode 100644 core/base/Factory.h diff --git a/core/base/Canvas.cpp b/core/base/Canvas.cpp index 78e7d4dd..72d6c1e1 100644 --- a/core/base/Canvas.cpp +++ b/core/base/Canvas.cpp @@ -23,6 +23,7 @@ #include "logs.h" #include "Image.h" #include "Geometry.h" +#include "Factory.h" namespace easy2d { @@ -57,7 +58,7 @@ namespace easy2d ); ThrowIfFailed( - devices::Graphics::Instance()->CreateTextRenderer( + Factory::Instance()->CreateTextRenderer( text_renderer_, render_target_, text_brush_ @@ -125,7 +126,7 @@ namespace easy2d void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join) { - outline_join_style_ = devices::Graphics::Instance()->GetStrokeStyle(outline_join); + outline_join_style_ = Factory::Instance()->GetStrokeStyle(outline_join); } void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style) @@ -138,7 +139,7 @@ namespace easy2d text_style_.outline, text_style_.outline_color, text_style_.outline_width, - devices::Graphics::Instance()->GetStrokeStyle(text_style_.outline_stroke).Get() + Factory::Instance()->GetStrokeStyle(text_style_.outline_stroke).Get() ); } @@ -266,11 +267,9 @@ namespace easy2d if (text.empty()) return; - auto graphics = devices::Graphics::Instance(); - cpTextFormat text_format; ThrowIfFailed( - graphics->CreateTextFormat( + Factory::Instance()->CreateTextFormat( text_format, text_font_, text_style_ @@ -280,7 +279,7 @@ namespace easy2d cpTextLayout text_layout; Size layout_size; ThrowIfFailed( - graphics->CreateTextLayout( + Factory::Instance()->CreateTextLayout( text_layout, layout_size, text, @@ -389,7 +388,7 @@ namespace easy2d current_geometry_ = nullptr; ThrowIfFailed( - devices::Graphics::Instance()->CreatePathGeometry(current_geometry_) + Factory::Instance()->CreatePathGeometry(current_geometry_) ); ThrowIfFailed( diff --git a/core/base/Factory.cpp b/core/base/Factory.cpp new file mode 100644 index 00000000..2f4dc35a --- /dev/null +++ b/core/base/Factory.cpp @@ -0,0 +1,518 @@ +// 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 "Factory.h" +#include "logs.h" +#include "modules.h" +#include "Transform.hpp" + +namespace easy2d +{ + FactoryImpl::FactoryImpl() + : initialized_(false) + { + } + + FactoryImpl::~FactoryImpl() + { + E2D_LOG("Destroying device independent resources"); + } + + void FactoryImpl::Init(bool debug) + { + if (initialized_) + return; + + E2D_LOG("Creating device independent resources"); + + D2D1_FACTORY_OPTIONS fact_options; + fact_options.debugLevel = debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE; + ThrowIfFailed( + modules::DirectX().D2D1CreateFactory( + D2D1_FACTORY_TYPE_SINGLE_THREADED, + __uuidof(ID2D1Factory), + &fact_options, + reinterpret_cast(&factory) + ) + ); + + ThrowIfFailed( + CoCreateInstance( + CLSID_WICImagingFactory, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory), + reinterpret_cast(&imaging_factory) + ) + ); + + ThrowIfFailed( + modules::DirectX().DWriteCreateFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(&write_factory) + ) + ); + + 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( + factory->CreateStrokeStyle( + stroke_style, + nullptr, + 0, + &miter_stroke_style + ) + ); + + stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL; + ThrowIfFailed( + factory->CreateStrokeStyle( + stroke_style, + nullptr, + 0, + &bevel_stroke_style + ) + ); + + stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND; + ThrowIfFailed( + factory->CreateStrokeStyle( + stroke_style, + nullptr, + 0, + &round_stroke_style + ) + ); + + initialized_ = true; + } + + HRESULT FactoryImpl::CreateHwndRenderTarget(cpHwndRenderTarget & hwnd_render_target, D2D1_RENDER_TARGET_PROPERTIES const & properties, D2D1_HWND_RENDER_TARGET_PROPERTIES const & hwnd_rt_properties) const + { + if (!factory) + return E_UNEXPECTED; + + cpHwndRenderTarget hwnd_render_target_tmp; + HRESULT hr = factory->CreateHwndRenderTarget( + properties, + hwnd_rt_properties, + &hwnd_render_target_tmp + ); + + if (SUCCEEDED(hr)) + hwnd_render_target = hwnd_render_target_tmp; + return hr; + } + + HRESULT FactoryImpl::CreateTextRenderer( + cpTextRenderer& text_renderer, + cpRenderTarget const& render_target, + cpSolidColorBrush const& brush + ) + { + if (!factory) + return E_UNEXPECTED; + + cpTextRenderer text_renderer_tmp; + HRESULT hr = ITextRenderer::Create( + &text_renderer_tmp, + factory.Get(), + render_target.Get(), + brush.Get() + ); + + if (SUCCEEDED(hr)) + text_renderer = text_renderer_tmp; + return hr; + } + + HRESULT FactoryImpl::CreateBitmapFromFile(cpBitmap & bitmap, cpRenderTarget const & rt, String const & file_path) + { + if (imaging_factory == nullptr) + { + return E_UNEXPECTED; + } + + using namespace intrusive; + + SmartPointer decoder; + SmartPointer source; + SmartPointer stream; + SmartPointer converter; + SmartPointer bitmap_tmp; + + HRESULT hr = imaging_factory->CreateDecoderFromFilename( + file_path.c_str(), + nullptr, + GENERIC_READ, + WICDecodeMetadataCacheOnLoad, + &decoder + ); + + if (SUCCEEDED(hr)) + { + hr = decoder->GetFrame(0, &source); + } + + if (SUCCEEDED(hr)) + { + hr = imaging_factory->CreateFormatConverter(&converter); + } + + if (SUCCEEDED(hr)) + { + // 图片格式转换成 32bppPBGRA + hr = converter->Initialize( + source.Get(), + GUID_WICPixelFormat32bppPBGRA, + WICBitmapDitherTypeNone, + nullptr, + 0.f, + WICBitmapPaletteTypeMedianCut + ); + } + + if (SUCCEEDED(hr)) + { + hr = rt->CreateBitmapFromWicBitmap( + converter.Get(), + nullptr, + &bitmap_tmp + ); + } + + if (SUCCEEDED(hr)) + bitmap = bitmap_tmp; + + return hr; + } + + HRESULT FactoryImpl::CreateBitmapFromResource(cpBitmap & bitmap, cpRenderTarget const & rt, Resource const & res) + { + if (imaging_factory == nullptr) + { + return E_UNEXPECTED; + } + + using namespace intrusive; + + SmartPointer decoder; + SmartPointer source; + SmartPointer stream; + SmartPointer converter; + SmartPointer bitmap_tmp; + + // 加载资源 + ResourceData buffer; + HRESULT hr = res.Load(&buffer) ? S_OK : E_FAIL; + + if (SUCCEEDED(hr)) + { + hr = imaging_factory->CreateStream(&stream); + } + + if (SUCCEEDED(hr)) + { + hr = stream->InitializeFromMemory( + static_cast(buffer.buffer), + buffer.buffer_size + ); + } + + if (SUCCEEDED(hr)) + { + hr = imaging_factory->CreateDecoderFromStream( + stream.Get(), + nullptr, + WICDecodeMetadataCacheOnLoad, + &decoder + ); + } + + if (SUCCEEDED(hr)) + { + hr = decoder->GetFrame(0, &source); + } + + if (SUCCEEDED(hr)) + { + hr = imaging_factory->CreateFormatConverter(&converter); + } + + if (SUCCEEDED(hr)) + { + // 图片格式转换成 32bppPBGRA + hr = converter->Initialize( + source.Get(), + GUID_WICPixelFormat32bppPBGRA, + WICBitmapDitherTypeNone, + nullptr, + 0.f, + WICBitmapPaletteTypeMedianCut + ); + } + + if (SUCCEEDED(hr)) + { + hr = rt->CreateBitmapFromWicBitmap( + converter.Get(), + nullptr, + &bitmap_tmp + ); + } + + if (SUCCEEDED(hr)) + { + bitmap = bitmap_tmp; + } + + return hr; + } + + HRESULT FactoryImpl::CreateRectangleGeometry(cpRectangleGeometry & geo, Rect const& rect) const + { + if (!factory) + return E_UNEXPECTED; + + cpRectangleGeometry rectangle; + HRESULT hr = factory->CreateRectangleGeometry( + rect, + &rectangle + ); + + if (SUCCEEDED(hr)) + geo = rectangle; + return hr; + } + + HRESULT FactoryImpl::CreateRoundedRectangleGeometry(cpRoundedRectangleGeometry & geo, Rect const & rect, float radius_x, float radius_y) const + { + if (!factory) + return E_UNEXPECTED; + + cpRoundedRectangleGeometry rounded_rect; + HRESULT hr = factory->CreateRoundedRectangleGeometry( + D2D1::RoundedRect( + rect, + radius_x, + radius_y + ), + &rounded_rect + ); + + if (SUCCEEDED(hr)) + geo = rounded_rect; + return hr; + } + + HRESULT FactoryImpl::CreateEllipseGeometry(cpEllipseGeometry & geo, Point const & center, float radius_x, float radius_y) const + { + if (!factory) + return E_UNEXPECTED; + + cpEllipseGeometry ellipse; + HRESULT hr = factory->CreateEllipseGeometry( + D2D1::Ellipse( + center, + radius_x, + radius_y + ), + &ellipse + ); + + if (SUCCEEDED(hr)) + geo = ellipse; + return hr; + } + + HRESULT FactoryImpl::CreateTransformedGeometry( + cpTransformedGeometry& transformed, + math::Matrix const& matrix, + cpGeometry const& geo + ) const + { + if (!factory) + return E_UNEXPECTED; + + cpTransformedGeometry transformed_tmp; + HRESULT hr = factory->CreateTransformedGeometry( + geo.Get(), + ConvertToD2DMatrix(matrix), + &transformed_tmp + ); + + if (SUCCEEDED(hr)) + { + transformed = transformed_tmp; + } + return hr; + } + + HRESULT FactoryImpl::CreatePathGeometry(cpPathGeometry & geometry) const + { + if (!factory) + return E_UNEXPECTED; + + return factory->CreatePathGeometry(&geometry); + } + + HRESULT FactoryImpl::CreateTextFormat(cpTextFormat & text_format, Font const & font, TextStyle const & text_style) const + { + if (!write_factory) + return E_UNEXPECTED; + + cpTextFormat text_format_tmp; + HRESULT hr = write_factory->CreateTextFormat( + 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"", + &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; + } + + HRESULT FactoryImpl::CreateTextLayout(cpTextLayout & text_layout, Size& layout_size, String const & text, cpTextFormat const& text_format, TextStyle const & text_style) const + { + if (!write_factory) + return E_UNEXPECTED; + + text_layout = nullptr; + + HRESULT hr; + cpTextLayout text_layout_tmp; + UINT32 length = static_cast(text.length()); + + if (text_style.wrap) + { + hr = write_factory->CreateTextLayout( + text.c_str(), + length, + text_format.Get(), + text_style.wrap_width, + 0, + &text_layout_tmp + ); + } + else + { + hr = 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 = 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; + } + + cpStrokeStyle const& FactoryImpl::GetStrokeStyle(StrokeStyle stroke) const + { + switch (stroke) + { + case StrokeStyle::Miter: + return miter_stroke_style; + break; + case StrokeStyle::Bevel: + return bevel_stroke_style; + break; + case StrokeStyle::Round: + return round_stroke_style; + break; + } + return miter_stroke_style; + } + +} diff --git a/core/base/Factory.h b/core/base/Factory.h new file mode 100644 index 00000000..32d47689 --- /dev/null +++ b/core/base/Factory.h @@ -0,0 +1,127 @@ +// 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. + +#pragma once +#include "base.hpp" +#include "Singleton.hpp" +#include "Font.hpp" +#include "Resource.h" +#include "TextRenderer.h" +#include "TextStyle.hpp" +#include "../math/Matrix.hpp" + +namespace easy2d +{ + class FactoryImpl + : protected Noncopyable + { + E2D_DECLARE_SINGLETON(FactoryImpl); + + public: + void Init(bool debug); + + HRESULT CreateHwndRenderTarget( + cpHwndRenderTarget& hwnd_render_target, + D2D1_RENDER_TARGET_PROPERTIES const& properties, + D2D1_HWND_RENDER_TARGET_PROPERTIES const& hwnd_rt_properties + ) const; + + HRESULT CreateTextRenderer( + cpTextRenderer& text_renderer, + cpRenderTarget const& render_target, + cpSolidColorBrush const& brush + ); + + HRESULT CreateBitmapFromFile( + cpBitmap& bitmap, + cpRenderTarget const& rt, + String const& file_path + ); + + HRESULT CreateBitmapFromResource( + cpBitmap& bitmap, + cpRenderTarget const& rt, + Resource const& res + ); + + HRESULT CreateRectangleGeometry( + cpRectangleGeometry& geo, + Rect const& rect + ) const; + + HRESULT CreateRoundedRectangleGeometry( + cpRoundedRectangleGeometry& geo, + Rect const& rect, + float radius_x, + float radius_y + ) const; + + HRESULT CreateEllipseGeometry( + cpEllipseGeometry& geo, + Point const& center, + float radius_x, + float radius_y + ) const; + + HRESULT CreateTransformedGeometry( + cpTransformedGeometry& transformed, + math::Matrix const& matrix, + cpGeometry const& geo + ) const; + + HRESULT CreatePathGeometry( + cpPathGeometry& geometry + ) const; + + HRESULT CreateTextFormat( + cpTextFormat& text_format, + Font const& font, + TextStyle const& text_style + ) const; + + HRESULT CreateTextLayout( + cpTextLayout& text_layout, + Size& layout_size, + String const& text, + cpTextFormat const& text_format, + TextStyle const& text_style + ) const; + + cpStrokeStyle const& GetStrokeStyle( + StrokeStyle stroke + ) const; + + protected: + FactoryImpl(); + + ~FactoryImpl(); + + protected: + bool initialized_; + cpFactory factory; + cpImagingFactory imaging_factory; + cpWriteFactory write_factory; + cpStrokeStyle miter_stroke_style; + cpStrokeStyle bevel_stroke_style; + cpStrokeStyle round_stroke_style; + }; + + E2D_DECLARE_SINGLETON_TYPE(FactoryImpl, Factory); +} diff --git a/core/base/Game.cpp b/core/base/Game.cpp index b9f46c4a..87b58dee 100644 --- a/core/base/Game.cpp +++ b/core/base/Game.cpp @@ -23,6 +23,7 @@ #include "input.h" #include "audio.h" #include "modules.h" +#include "Factory.h" #include "Scene.h" #include "Transition.h" #include "Debuger.h" @@ -77,6 +78,7 @@ namespace easy2d ::SetWindowLongW(hwnd_, GWLP_USERDATA, PtrToUlong(this)); + Factory::Instance()->Init(debug_enabled_); devices::Graphics::Instance()->Init(hwnd_, options.graphics_options, debug_enabled_); devices::Input::Instance()->Init(hwnd_, window->GetContentScaleX(), window->GetContentScaleY(), debug_enabled_); devices::Audio::Instance()->Init(debug_enabled_); diff --git a/core/base/Geometry.cpp b/core/base/Geometry.cpp index a0dc3102..117e3472 100644 --- a/core/base/Geometry.cpp +++ b/core/base/Geometry.cpp @@ -19,6 +19,7 @@ // THE SOFTWARE. #include "Geometry.h" +#include "Factory.h" #include "render.h" #include "logs.h" @@ -120,7 +121,7 @@ namespace easy2d return GeometryRelation::Unknown; cpTransformedGeometry transformed; - HRESULT hr = devices::Graphics::Instance()->CreateTransformedGeometry( + HRESULT hr = Factory::Instance()->CreateTransformedGeometry( transformed, GetTransformMatrix(), geo_.Get() @@ -162,7 +163,7 @@ namespace easy2d cpPathGeometry path_geo; cpGeometrySink path_sink; - HRESULT hr = devices::Graphics::Instance()->CreatePathGeometry(path_geo); + HRESULT hr = Factory::Instance()->CreatePathGeometry(path_geo); if (SUCCEEDED(hr)) { @@ -219,7 +220,7 @@ namespace easy2d void RectangleGeometry::SetRect(Rect const & rect) { cpRectangleGeometry geo; - if (SUCCEEDED(devices::Graphics::Instance()->CreateRectangleGeometry(geo, rect))) + if (SUCCEEDED(Factory::Instance()->CreateRectangleGeometry(geo, rect))) { geo_ = geo; rect_ = rect; @@ -258,7 +259,7 @@ namespace easy2d void CircleGeometry::SetCircle(Point const & center, float radius) { cpEllipseGeometry geo; - if (SUCCEEDED(devices::Graphics::Instance()->CreateEllipseGeometry(geo, center, radius, radius))) + if (SUCCEEDED(Factory::Instance()->CreateEllipseGeometry(geo, center, radius, radius))) { geo_ = geo; center_ = center; @@ -299,7 +300,7 @@ namespace easy2d void EllipseGeometry::SetEllipse(Point const & center, float radius_x, float radius_y) { cpEllipseGeometry geo; - if (SUCCEEDED(devices::Graphics::Instance()->CreateEllipseGeometry(geo, center, radius_x, radius_y))) + if (SUCCEEDED(Factory::Instance()->CreateEllipseGeometry(geo, center, radius_x, radius_y))) { geo_ = geo; radius_x_ = radius_x; @@ -325,7 +326,7 @@ namespace easy2d current_geometry_ = nullptr; ThrowIfFailed( - devices::Graphics::Instance()->CreatePathGeometry(current_geometry_) + Factory::Instance()->CreatePathGeometry(current_geometry_) ); ThrowIfFailed( @@ -448,7 +449,7 @@ namespace easy2d void RoundedRectGeometry::SetRoundedRect(Rect const & rect, float radius_x, float radius_y) { cpRoundedRectangleGeometry geo; - if (SUCCEEDED(devices::Graphics::Instance()->CreateRoundedRectangleGeometry(geo, rect, radius_x, radius_y))) + if (SUCCEEDED(Factory::Instance()->CreateRoundedRectangleGeometry(geo, rect, radius_x, radius_y))) { geo_ = geo; rect_ = rect; diff --git a/core/base/Node.cpp b/core/base/Node.cpp index 541d7660..3da4fc48 100644 --- a/core/base/Node.cpp +++ b/core/base/Node.cpp @@ -19,6 +19,7 @@ // THE SOFTWARE. #include "Node.h" +#include "Factory.h" #include "Scene.h" #include "Task.h" #include "Action.hpp" @@ -213,14 +214,14 @@ namespace easy2d cpTransformedGeometry transformed; ThrowIfFailed( - devices::Graphics::Instance()->CreateRectangleGeometry( + Factory::Instance()->CreateRectangleGeometry( rect, Rect(Point{}, size_) ) ); ThrowIfFailed( - devices::Graphics::Instance()->CreateTransformedGeometry( + Factory::Instance()->CreateTransformedGeometry( transformed, final_matrix_, rect diff --git a/core/base/Text.cpp b/core/base/Text.cpp index 4573522c..71e1dc73 100644 --- a/core/base/Text.cpp +++ b/core/base/Text.cpp @@ -19,6 +19,7 @@ // THE SOFTWARE. #include "Text.h" +#include "Factory.h" #include "render.h" #include "base.hpp" #include "logs.h" @@ -314,10 +315,8 @@ namespace easy2d if (text_.empty()) return; - auto graphics = devices::Graphics::Instance(); - ThrowIfFailed( - graphics->CreateTextFormat( + Factory::Instance()->CreateTextFormat( text_format_, font_, style_ @@ -326,7 +325,7 @@ namespace easy2d Size layout_size; ThrowIfFailed( - graphics->CreateTextLayout( + Factory::Instance()->CreateTextLayout( text_layout_, layout_size, text_, diff --git a/core/base/render.cpp b/core/base/render.cpp index 6d00aaf2..e0f93cd2 100644 --- a/core/base/render.cpp +++ b/core/base/render.cpp @@ -22,7 +22,7 @@ #include "time.h" #include "base.hpp" #include "logs.h" -#include "modules.h" +#include "Factory.h" #include "Image.h" #include "Transform.hpp" @@ -39,7 +39,6 @@ namespace easy2d , initialized_(false) , options_() { - ZeroMemory(&d2d, sizeof(D2DResources)); } GraphicsDevice::~GraphicsDevice() @@ -58,74 +57,6 @@ namespace easy2d options_ = options; - D2D1_FACTORY_OPTIONS fact_options; - fact_options.debugLevel = debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE; - ThrowIfFailed( - modules::DirectX().D2D1CreateFactory( - D2D1_FACTORY_TYPE_SINGLE_THREADED, - __uuidof(ID2D1Factory), - &fact_options, - reinterpret_cast(&d2d.factory) - ) - ); - - ThrowIfFailed( - CoCreateInstance( - CLSID_WICImagingFactory, - nullptr, - CLSCTX_INPROC_SERVER, - __uuidof(IWICImagingFactory), - reinterpret_cast(&d2d.imaging_factory) - ) - ); - - ThrowIfFailed( - modules::DirectX().DWriteCreateFactory( - DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast(&d2d.write_factory) - ) - ); - - 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( - d2d.factory->CreateStrokeStyle( - stroke_style, - nullptr, - 0, - &d2d.miter_stroke_style - ) - ); - - stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL; - ThrowIfFailed( - d2d.factory->CreateStrokeStyle( - stroke_style, - nullptr, - 0, - &d2d.bevel_stroke_style - ) - ); - - stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND; - ThrowIfFailed( - d2d.factory->CreateStrokeStyle( - stroke_style, - nullptr, - 0, - &d2d.round_stroke_style - ) - ); - CreateDeviceResources(hwnd); initialized_ = true; @@ -135,12 +66,12 @@ namespace easy2d { CreateDeviceResources(hwnd); - window_occluded_ = !!(d2d.render_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED); + window_occluded_ = !!(render_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED); if (!window_occluded_) { - d2d.render_target->BeginDraw(); - d2d.render_target->Clear(clear_color_); + render_target->BeginDraw(); + render_target->Clear(clear_color_); } } @@ -148,7 +79,7 @@ namespace easy2d { if (!window_occluded_) { - HRESULT hr = d2d.render_target->EndDraw(); + HRESULT hr = render_target->EndDraw(); if (hr == D2DERR_RECREATE_TARGET) { @@ -158,9 +89,9 @@ namespace easy2d fps_text_format_ = nullptr; fps_text_layout_ = nullptr; - d2d.text_renderer = nullptr; - d2d.solid_brush = nullptr; - d2d.render_target = nullptr; + text_renderer = nullptr; + solid_brush = nullptr; + render_target = nullptr; } ThrowIfFailed(hr); @@ -172,247 +103,22 @@ namespace easy2d bitmap_cache_.clear(); } - HRESULT GraphicsDevice::CreateRectangleGeometry(cpRectangleGeometry & geo, Rect const& rect) const - { - if (!d2d.factory) - return E_UNEXPECTED; - - cpRectangleGeometry rectangle; - HRESULT hr = d2d.factory->CreateRectangleGeometry( - rect, - &rectangle - ); - - if (SUCCEEDED(hr)) - geo = rectangle; - return hr; - } - - 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; - } - - 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 - ); - - if (SUCCEEDED(hr)) - 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 - ); - - if (SUCCEEDED(hr)) - { - transformed = transformed_tmp; - } - return hr; - } - - 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 - { - if (!d2d.write_factory) - return E_UNEXPECTED; - - cpTextFormat text_format_tmp; - HRESULT hr = d2d.write_factory->CreateTextFormat( - 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"", - &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; - } - - HRESULT GraphicsDevice::CreateTextLayout(cpTextLayout & text_layout, Size& layout_size, String const & text, cpTextFormat const& text_format, TextStyle const & text_style) const - { - if (!d2d.write_factory) - return E_UNEXPECTED; - - text_layout = nullptr; - - HRESULT hr; - cpTextLayout text_layout_tmp; - UINT32 length = static_cast(text.length()); - - 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() - ); - - if (SUCCEEDED(hr)) - text_renderer = text_renderer_tmp; - return hr; - } - HRESULT GraphicsDevice::CreateLayer(cpLayer& layer) { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; layer = nullptr; - return d2d.render_target->CreateLayer(&layer); + return render_target->CreateLayer(&layer); } HRESULT GraphicsDevice::CreateSolidColorBrush(cpSolidColorBrush & brush) const { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; brush = nullptr; - return d2d.render_target->CreateSolidColorBrush( + return render_target->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White), &brush ); @@ -425,43 +131,44 @@ namespace easy2d StrokeStyle stroke ) { - if (!d2d.solid_brush || - !d2d.render_target) + if (!solid_brush || + !render_target) return E_UNEXPECTED; if (window_occluded_) return S_OK; - d2d.solid_brush->SetColor(stroke_color); - d2d.render_target->DrawGeometry( + solid_brush->SetColor(stroke_color); + auto stroke_style = Factory::Instance()->GetStrokeStyle(stroke); + render_target->DrawGeometry( geometry.Get(), - d2d.solid_brush.Get(), + solid_brush.Get(), stroke_width, - GetStrokeStyle(stroke).Get() + stroke_style.Get() ); return S_OK; } HRESULT GraphicsDevice::FillGeometry(cpGeometry const & geometry, const Color & fill_color) { - if (!d2d.solid_brush || - !d2d.render_target) + if (!solid_brush || + !render_target) return E_UNEXPECTED; if (window_occluded_) return S_OK; - d2d.solid_brush->SetColor(fill_color); - d2d.render_target->FillGeometry( + solid_brush->SetColor(fill_color); + render_target->FillGeometry( geometry.Get(), - d2d.solid_brush.Get() + solid_brush.Get() ); return S_OK; } HRESULT GraphicsDevice::DrawImage(spImage const & image) { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; if (!image->GetBitmap()) @@ -470,7 +177,7 @@ namespace easy2d if (window_occluded_) return S_OK; - d2d.render_target->DrawBitmap( + render_target->DrawBitmap( image->GetBitmap().Get(), D2D1::RectF(0.f, 0.f, image->GetWidth(), image->GetHeight()), opacity_, @@ -480,28 +187,11 @@ namespace easy2d return S_OK; } - cpStrokeStyle const& GraphicsDevice::GetStrokeStyle(StrokeStyle stroke) const - { - switch (stroke) - { - case StrokeStyle::Miter: - return d2d.miter_stroke_style; - break; - case StrokeStyle::Bevel: - return d2d.bevel_stroke_style; - break; - case StrokeStyle::Round: - return d2d.round_stroke_style; - break; - } - return d2d.miter_stroke_style; - } - HRESULT GraphicsDevice::DrawBitmap( cpBitmap const& bitmap ) { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; if (window_occluded_) @@ -509,7 +199,7 @@ namespace easy2d // Do not crop bitmap auto rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height); - d2d.render_target->DrawBitmap( + render_target->DrawBitmap( bitmap.Get(), rect, opacity_, @@ -521,25 +211,25 @@ namespace easy2d HRESULT GraphicsDevice::DrawTextLayout(cpTextLayout const& text_layout) { - if (!d2d.text_renderer) + if (!text_renderer) return E_UNEXPECTED; if (window_occluded_) return S_OK; - return text_layout->Draw(nullptr, d2d.text_renderer.Get(), 0, 0); + return text_layout->Draw(nullptr, text_renderer.Get(), 0, 0); } HRESULT GraphicsDevice::PushClip(const math::Matrix & clip_matrix, const Size & clip_size) { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; if (window_occluded_) return S_OK; - d2d.render_target->SetTransform(ConvertToD2DMatrix(clip_matrix)); - d2d.render_target->PushAxisAlignedClip( + render_target->SetTransform(ConvertToD2DMatrix(clip_matrix)); + render_target->PushAxisAlignedClip( D2D1::RectF(0, 0, clip_size.width, clip_size.height), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE ); @@ -548,33 +238,33 @@ namespace easy2d HRESULT GraphicsDevice::PopClip() { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; if (window_occluded_) return S_OK; - d2d.render_target->PopAxisAlignedClip(); + render_target->PopAxisAlignedClip(); return S_OK; } HRESULT GraphicsDevice::PushLayer(cpLayer const& layer, LayerProperties const& properties) { - if (!d2d.render_target || - !d2d.solid_brush) + if (!render_target || + !solid_brush) return E_UNEXPECTED; if (window_occluded_) return S_OK; - d2d.render_target->PushLayer( + render_target->PushLayer( D2D1::LayerParameters( properties.area, nullptr, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, D2D1::Matrix3x2F::Identity(), properties.opacity, - d2d.solid_brush.Get(), + solid_brush.Get(), D2D1_LAYER_OPTIONS_NONE ), layer.Get() @@ -584,22 +274,22 @@ namespace easy2d HRESULT GraphicsDevice::PopLayer() { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; if (window_occluded_) return S_OK; - d2d.render_target->PopLayer(); + render_target->PopLayer(); return S_OK; } HRESULT GraphicsDevice::GetSize(Size & size) { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; - auto rtsize = d2d.render_target->GetSize(); + auto rtsize = render_target->GetSize(); size.width = rtsize.width; size.height = rtsize.height; return S_OK; @@ -607,8 +297,7 @@ namespace easy2d HRESULT GraphicsDevice::CreateBitmapFromFile(cpBitmap& bitmap, String const& file_path) { - if (d2d.imaging_factory == nullptr || - d2d.render_target == nullptr) + if (render_target == nullptr) { return E_UNEXPECTED; } @@ -620,73 +309,24 @@ namespace easy2d return S_OK; } - IWICBitmapDecoder* decoder = nullptr; - IWICBitmapFrameDecode* source = nullptr; - IWICStream* stream = nullptr; - IWICFormatConverter* converter = nullptr; - - // 创建解码器 - HRESULT hr = d2d.imaging_factory->CreateDecoderFromFilename( - file_path.c_str(), - nullptr, - GENERIC_READ, - WICDecodeMetadataCacheOnLoad, - &decoder + cpBitmap bitmap_tmp; + HRESULT hr = Factory::Instance()->CreateBitmapFromFile( + bitmap, + render_target, + file_path ); - if (SUCCEEDED(hr)) - { - // 创建初始化框架 - hr = decoder->GetFrame(0, &source); - } - - if (SUCCEEDED(hr)) - { - // 创建图片格式转换器 - hr = d2d.imaging_factory->CreateFormatConverter(&converter); - } - - if (SUCCEEDED(hr)) - { - // 图片格式转换成 32bppPBGRA - hr = converter->Initialize( - source, - GUID_WICPixelFormat32bppPBGRA, - WICBitmapDitherTypeNone, - nullptr, - 0.f, - WICBitmapPaletteTypeMedianCut - ); - } - - if (SUCCEEDED(hr)) - { - // 从 WIC 位图创建一个 Direct2D 位图 - bitmap = nullptr; - hr = d2d.render_target->CreateBitmapFromWicBitmap( - converter, - nullptr, - &bitmap - ); - } - if (SUCCEEDED(hr)) { bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); } - SafeRelease(decoder); - SafeRelease(source); - SafeRelease(stream); - SafeRelease(converter); - return hr; } HRESULT GraphicsDevice::CreateBitmapFromResource(cpBitmap& bitmap, Resource const& res) { - if (d2d.imaging_factory == nullptr || - d2d.render_target == nullptr) + if (render_target == nullptr) { return E_UNEXPECTED; } @@ -698,126 +338,54 @@ namespace easy2d return S_OK; } - HRESULT hr; - - HINSTANCE hinstance = GetModuleHandle(nullptr); - IWICBitmapDecoder* decoder = nullptr; - IWICBitmapFrameDecode* source = nullptr; - IWICStream* stream = nullptr; - IWICFormatConverter* converter = nullptr; - ResourceData buffer; - - // 加载资源 - hr = res.Load(&buffer) ? S_OK : E_FAIL; - - if (SUCCEEDED(hr)) - { - // 创建 WIC 流 - hr = d2d.imaging_factory->CreateStream(&stream); - } - - if (SUCCEEDED(hr)) - { - // 初始化流 - hr = stream->InitializeFromMemory( - static_cast(buffer.buffer), - buffer.buffer_size - ); - } - - if (SUCCEEDED(hr)) - { - // 创建流的解码器 - hr = d2d.imaging_factory->CreateDecoderFromStream( - stream, - nullptr, - WICDecodeMetadataCacheOnLoad, - &decoder - ); - } - - if (SUCCEEDED(hr)) - { - // 创建初始化框架 - hr = decoder->GetFrame(0, &source); - } - - if (SUCCEEDED(hr)) - { - // 创建图片格式转换器 - hr = d2d.imaging_factory->CreateFormatConverter(&converter); - } - - if (SUCCEEDED(hr)) - { - // 图片格式转换成 32bppPBGRA - hr = converter->Initialize( - source, - GUID_WICPixelFormat32bppPBGRA, - WICBitmapDitherTypeNone, - nullptr, - 0.f, - WICBitmapPaletteTypeMedianCut - ); - } - - if (SUCCEEDED(hr)) - { - // 从 WIC 位图创建一个 Direct2D 位图 - hr = d2d.render_target->CreateBitmapFromWicBitmap( - converter, - nullptr, - &bitmap - ); - } + HRESULT hr = Factory::Instance()->CreateBitmapFromResource( + bitmap, + render_target, + res + ); if (SUCCEEDED(hr)) { bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); } - SafeRelease(decoder); - SafeRelease(source); - SafeRelease(stream); - SafeRelease(converter); - return hr; } HRESULT GraphicsDevice::CreateBitmapRenderTarget(cpBitmapRenderTarget & brt) { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; brt = nullptr; - return d2d.render_target->CreateCompatibleRenderTarget(&brt); + return render_target->CreateCompatibleRenderTarget(&brt); } HRESULT GraphicsDevice::Resize(UINT32 width, UINT32 height) { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; - d2d.render_target->Resize(D2D1::SizeU(width, height)); + render_target->Resize(D2D1::SizeU(width, height)); return S_OK; } HRESULT GraphicsDevice::SetTransform(const math::Matrix & matrix) { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; - d2d.render_target->SetTransform(ConvertToD2DMatrix(matrix)); + render_target->SetTransform(ConvertToD2DMatrix(matrix)); return S_OK; } HRESULT GraphicsDevice::SetOpacity(float opacity) { - if (!d2d.render_target) + if (!render_target) return E_UNEXPECTED; opacity_ = opacity; - d2d.solid_brush->SetOpacity(opacity); + solid_brush->SetOpacity(opacity); return S_OK; } @@ -829,15 +397,16 @@ namespace easy2d StrokeStyle outline_stroke ) { - if (!d2d.text_renderer) + if (!text_renderer) return E_UNEXPECTED; - d2d.text_renderer->SetTextStyle( + auto stroke_style = Factory::Instance()->GetStrokeStyle(outline_stroke); + text_renderer->SetTextStyle( color, has_outline, outline_color, outline_width, - GetStrokeStyle(outline_stroke).Get() + stroke_style.Get() ); return S_OK; } @@ -849,7 +418,7 @@ namespace easy2d void GraphicsDevice::CreateDeviceResources(HWND hwnd) { - if (!d2d.render_target) + if (!render_target) { RECT rc; ::GetClientRect(hwnd, &rc); @@ -862,18 +431,18 @@ namespace easy2d // 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建 // 创建一个 Direct2D 渲染目标 ThrowIfFailed( - d2d.factory->CreateHwndRenderTarget( + Factory::Instance()->CreateHwndRenderTarget( + render_target, D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties( hwnd, size, options_.vsync ? D2D1_PRESENT_OPTIONS_NONE : D2D1_PRESENT_OPTIONS_IMMEDIATELY - ), - &d2d.render_target + ) ) ); - d2d.render_target->SetAntialiasMode( + render_target->SetAntialiasMode( options_.antialias ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED ); @@ -895,27 +464,26 @@ namespace easy2d default: break; } - d2d.render_target->SetTextAntialiasMode(mode); + render_target->SetTextAntialiasMode(mode); } - if (!d2d.solid_brush) + if (!solid_brush) { ThrowIfFailed( - d2d.render_target->CreateSolidColorBrush( + render_target->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White), - &d2d.solid_brush + &solid_brush ) ); } - if (!d2d.text_renderer) + if (!text_renderer) { ThrowIfFailed( - ITextRenderer::Create( - &d2d.text_renderer, - d2d.factory.Get(), - d2d.render_target.Get(), - d2d.solid_brush.Get() + Factory::Instance()->CreateTextRenderer( + text_renderer, + render_target, + solid_brush ) ); } diff --git a/core/base/render.h b/core/base/render.h index 3d218428..06422947 100644 --- a/core/base/render.h +++ b/core/base/render.h @@ -53,20 +53,6 @@ namespace easy2d namespace devices { - struct D2DResources - { - cpFactory factory; - cpImagingFactory imaging_factory; - cpWriteFactory write_factory; - cpTextRenderer text_renderer; - cpSolidColorBrush solid_brush; - cpHwndRenderTarget render_target; - cpStrokeStyle miter_stroke_style; - cpStrokeStyle bevel_stroke_style; - cpStrokeStyle round_stroke_style; - }; - - class GraphicsDevice : protected Noncopyable { @@ -88,55 +74,6 @@ namespace easy2d void CreateDeviceResources(HWND hwnd); - HRESULT CreateRectangleGeometry( - cpRectangleGeometry& geo, - Rect const& rect - ) const; - - HRESULT CreateRoundedRectangleGeometry( - cpRoundedRectangleGeometry& geo, - Rect const& rect, - float radius_x, - float radius_y - ) const; - - HRESULT CreateEllipseGeometry( - cpEllipseGeometry& geo, - Point const& center, - float radius_x, - float radius_y - ) const; - - HRESULT CreateTransformedGeometry( - cpTransformedGeometry& transformed, - math::Matrix const& matrix, - cpGeometry const& geo - ) const; - - HRESULT CreatePathGeometry( - cpPathGeometry& geometry - ) const; - - HRESULT CreateTextFormat( - cpTextFormat& text_format, - Font const& font, - TextStyle const& text_style - ) const; - - HRESULT CreateTextLayout( - cpTextLayout& text_layout, - Size& layout_size, - String const& text, - cpTextFormat const& text_format, - TextStyle const& text_style - ) const; - - HRESULT CreateTextRenderer( - cpTextRenderer& text_renderer, - cpRenderTarget const& render_target, - cpSolidColorBrush const& brush - ); - HRESULT CreateLayer( cpLayer& layer ); @@ -159,10 +96,6 @@ namespace easy2d cpBitmapRenderTarget& brt ); - cpStrokeStyle const& GetStrokeStyle( - StrokeStyle stroke - ) const; - HRESULT SetTransform( const math::Matrix& matrix ); @@ -238,7 +171,9 @@ namespace easy2d bool window_occluded_; float opacity_; GraphicsOptions options_; - D2DResources d2d; + cpTextRenderer text_renderer; + cpSolidColorBrush solid_brush; + cpHwndRenderTarget render_target; D2D1_COLOR_F clear_color_; cpTextFormat fps_text_format_; cpTextLayout fps_text_layout_; diff --git a/core/easy2d.h b/core/easy2d.h index 0264ed65..eab186a6 100644 --- a/core/easy2d.h +++ b/core/easy2d.h @@ -78,6 +78,7 @@ #include "base/KeyEvent.h" #include "base/MouseEvent.h" +#include "base/Factory.h" #include "base/Game.h" diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index 05ce657f..894b5170 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -32,6 +32,7 @@ + @@ -95,6 +96,7 @@ + diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 4642ce07..9bc3e1bf 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -194,6 +194,9 @@ math + + base + @@ -342,5 +345,8 @@ base + + base + \ No newline at end of file diff --git a/project/vs2015/Easy2D.vcxproj b/project/vs2015/Easy2D.vcxproj index 33e1dca5..4541122b 100644 --- a/project/vs2015/Easy2D.vcxproj +++ b/project/vs2015/Easy2D.vcxproj @@ -32,6 +32,7 @@ + @@ -95,6 +96,7 @@ + diff --git a/project/vs2015/Easy2D.vcxproj.filters b/project/vs2015/Easy2D.vcxproj.filters index 4642ce07..9bc3e1bf 100644 --- a/project/vs2015/Easy2D.vcxproj.filters +++ b/project/vs2015/Easy2D.vcxproj.filters @@ -194,6 +194,9 @@ math + + base + @@ -342,5 +345,8 @@ base + + base + \ No newline at end of file diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 6d3a59be..ae834806 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -32,6 +32,7 @@ + @@ -95,6 +96,7 @@ + diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 4642ce07..9bc3e1bf 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -194,6 +194,9 @@ math + + base + @@ -342,5 +345,8 @@ base + + base + \ No newline at end of file