From 6ea9d6ef858ba1cf32e792d8c344f5b5a39f0c1b Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Thu, 24 May 2018 17:19:54 +0800 Subject: [PATCH] =?UTF-8?q?Renderer=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=B8=89=E7=A7=8D=E7=B1=BB=E5=9E=8BID2D1StrokeStyle=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Base/Renderer.cpp | 98 ++++++++++++++++++++++- core/Common/String.cpp | 11 +-- core/Custom/TextRenderer.cpp | 150 +++++++++++++++-------------------- core/e2dbase.h | 9 +++ core/e2dcustom.h | 11 ++- 5 files changed, 175 insertions(+), 104 deletions(-) diff --git a/core/Base/Renderer.cpp b/core/Base/Renderer.cpp index 0821737d..7d8a26c8 100644 --- a/core/Base/Renderer.cpp +++ b/core/Base/Renderer.cpp @@ -12,6 +12,9 @@ static ID2D1SolidColorBrush * s_pSolidBrush = nullptr; static IWICImagingFactory * s_pIWICFactory = nullptr; static IDWriteFactory * s_pDWriteFactory = nullptr; static e2d::TextRenderer * s_pTextRenderer = nullptr; +static ID2D1StrokeStyle * s_pMiterStrokeStyle = nullptr; +static ID2D1StrokeStyle * s_pBevelStrokeStyle = nullptr; +static ID2D1StrokeStyle * s_pRoundStrokeStyle = nullptr; static D2D1_COLOR_F s_nClearColor = D2D1::ColorF(D2D1::ColorF::Black); @@ -23,11 +26,80 @@ bool e2d::Renderer::__createDeviceIndependentResources() &s_pDirect2dFactory ); + // 工厂将返回当前的系统 DPI,这个值也将用来创建窗口 + if (SUCCEEDED(hr)) + { + s_pDirect2dFactory->GetDesktopDpi(&s_fDpiScaleX, &s_fDpiScaleY); + } + if (FAILED(hr)) { throw SystemException(L"Create ID2D1Factory failed"); } else + { + hr = s_pDirect2dFactory->CreateStrokeStyle( + 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), + nullptr, + 0, + &s_pMiterStrokeStyle + ); + } + + if (FAILED(hr)) + { + throw SystemException(L"Create ID2D1StrokeStyle failed"); + } + else + { + hr = s_pDirect2dFactory->CreateStrokeStyle( + D2D1::StrokeStyleProperties( + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_LINE_JOIN_BEVEL, + 2.0f, + D2D1_DASH_STYLE_SOLID, + 0.0f), + nullptr, + 0, + &s_pBevelStrokeStyle + ); + } + + if (FAILED(hr)) + { + throw SystemException(L"Create ID2D1StrokeStyle failed"); + } + else + { + hr = s_pDirect2dFactory->CreateStrokeStyle( + D2D1::StrokeStyleProperties( + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_LINE_JOIN_ROUND, + 2.0f, + D2D1_DASH_STYLE_SOLID, + 0.0f), + nullptr, + 0, + &s_pRoundStrokeStyle + ); + } + + if (FAILED(hr)) + { + throw SystemException(L"Create ID2D1StrokeStyle failed"); + } + else { // 创建 WIC 绘图工厂,用于统一处理各种格式的图片 hr = CoCreateInstance( @@ -59,9 +131,6 @@ bool e2d::Renderer::__createDeviceIndependentResources() } else { - // 工厂将返回当前的系统 DPI,这个值也将用来创建窗口 - Renderer::getID2D1Factory()->GetDesktopDpi(&s_fDpiScaleX, &s_fDpiScaleY); - // 创建文本格式化对象 hr = s_pDWriteFactory->CreateTextFormat( L"", @@ -130,7 +199,7 @@ bool e2d::Renderer::__createDeviceResources() else { // 创建自定义的文字渲染器 - s_pTextRenderer = new (std::nothrow) TextRenderer( + s_pTextRenderer = TextRenderer::Create( s_pDirect2dFactory, s_pRenderTarget, s_pSolidBrush @@ -146,6 +215,9 @@ void e2d::Renderer::__discardDeviceResources() SafeRelease(s_pRenderTarget); SafeRelease(s_pSolidBrush); SafeRelease(s_pTextRenderer); + SafeRelease(s_pMiterStrokeStyle); + SafeRelease(s_pBevelStrokeStyle); + SafeRelease(s_pRoundStrokeStyle); } void e2d::Renderer::__discardResources() @@ -155,6 +227,9 @@ void e2d::Renderer::__discardResources() SafeRelease(s_pRenderTarget); SafeRelease(s_pSolidBrush); SafeRelease(s_pTextRenderer); + SafeRelease(s_pMiterStrokeStyle); + SafeRelease(s_pBevelStrokeStyle); + SafeRelease(s_pRoundStrokeStyle); SafeRelease(s_pIWICFactory); SafeRelease(s_pDWriteFactory); } @@ -292,3 +367,18 @@ e2d::TextRenderer * e2d::Renderer::getTextRenderer() { return s_pTextRenderer; } + +ID2D1StrokeStyle * e2d::Renderer::getMiterID2D1StrokeStyle() +{ + return s_pMiterStrokeStyle; +} + +ID2D1StrokeStyle * e2d::Renderer::getBevelID2D1StrokeStyle() +{ + return s_pBevelStrokeStyle; +} + +ID2D1StrokeStyle * e2d::Renderer::getRoundID2D1StrokeStyle() +{ + return s_pRoundStrokeStyle; +} diff --git a/core/Common/String.cpp b/core/Common/String.cpp index c36d2634..4fcd1df5 100644 --- a/core/Common/String.cpp +++ b/core/Common/String.cpp @@ -1,5 +1,6 @@ #include "..\e2dcommon.h" #include +#include #include #pragma comment(lib, "comsuppw.lib") @@ -377,20 +378,14 @@ int e2d::String::compare(const String & str) const e2d::String e2d::String::toUpper() const { String str(*this); - - for (size_t i = 0, length = _str.size(); i < length; ++i) - str[i] = towupper(str[i]); - + std::transform(str._str.begin(), str._str.end(), str._str.begin(), std::towupper); return std::move(str); } e2d::String e2d::String::toLower() const { e2d::String str(*this); - - for (size_t i = 0, length = _str.size(); i < length; ++i) - str[i] = towlower(str[i]); - + std::transform(str._str.begin(), str._str.end(), str._str.begin(), std::towlower); return std::move(str); } diff --git a/core/Custom/TextRenderer.cpp b/core/Custom/TextRenderer.cpp index 830a2761..376ccfb3 100644 --- a/core/Custom/TextRenderer.cpp +++ b/core/Custom/TextRenderer.cpp @@ -3,24 +3,17 @@ using namespace e2d; -TextRenderer::TextRenderer( - ID2D1Factory* pD2DFactory, - ID2D1HwndRenderTarget* pRT, - ID2D1SolidColorBrush* pBrush -) +TextRenderer::TextRenderer() : cRefCount_(0) - , pD2DFactory_(pD2DFactory) - , pRT_(pRT) - , pBrush_(pBrush) + , pD2DFactory_(nullptr) + , pRT_(nullptr) + , pBrush_(nullptr) , sFillColor_() , sOutlineColor_() , fOutlineWidth(1) , bShowOutline_(TRUE) - , nOutlineJoin_(D2D1_LINE_JOIN_MITER) + , pCurrStrokeStyle_(nullptr) { - pD2DFactory_->AddRef(); - pRT_->AddRef(); - pBrush_->AddRef(); } TextRenderer::~TextRenderer() @@ -30,6 +23,26 @@ TextRenderer::~TextRenderer() SafeRelease(pBrush_); } +TextRenderer * TextRenderer::Create( + ID2D1Factory* pD2DFactory, + ID2D1HwndRenderTarget* pRT, + ID2D1SolidColorBrush* pBrush +) +{ + TextRenderer * pTextRenderer = new (std::nothrow) TextRenderer(); + if (pTextRenderer) + { + pD2DFactory->AddRef(); + pRT->AddRef(); + pBrush->AddRef(); + + pTextRenderer->pD2DFactory_ = pD2DFactory; + pTextRenderer->pRT_ = pRT; + pTextRenderer->pBrush_ = pBrush; + } + return pTextRenderer; +} + STDMETHODIMP_(void) TextRenderer::SetTextStyle( CONST D2D1_COLOR_F &fillColor, BOOL hasOutline, @@ -42,7 +55,22 @@ STDMETHODIMP_(void) TextRenderer::SetTextStyle( bShowOutline_ = hasOutline; sOutlineColor_ = outlineColor; fOutlineWidth = 2 * outlineWidth; - nOutlineJoin_ = outlineJoin; + + switch (outlineJoin) + { + case D2D1_LINE_JOIN_MITER: + pCurrStrokeStyle_ = Renderer::getMiterID2D1StrokeStyle(); + break; + case D2D1_LINE_JOIN_BEVEL: + pCurrStrokeStyle_ = Renderer::getBevelID2D1StrokeStyle(); + break; + case D2D1_LINE_JOIN_ROUND: + pCurrStrokeStyle_ = Renderer::getRoundID2D1StrokeStyle(); + break; + default: + pCurrStrokeStyle_ = nullptr; + break; + } } STDMETHODIMP TextRenderer::DrawGlyphRun( @@ -107,32 +135,14 @@ STDMETHODIMP TextRenderer::DrawGlyphRun( if (SUCCEEDED(hr) && bShowOutline_) { - ID2D1StrokeStyle * pStrokeStyle = nullptr; - hr = Renderer::getID2D1Factory()->CreateStrokeStyle( - D2D1::StrokeStyleProperties( - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - nOutlineJoin_, - 2.0f, - D2D1_DASH_STYLE_SOLID, - 0.0f), - nullptr, - 0, - &pStrokeStyle + pBrush_->SetColor(sOutlineColor_); + + pRT_->DrawGeometry( + pTransformedGeometry, + pBrush_, + fOutlineWidth, + pCurrStrokeStyle_ ); - - if (SUCCEEDED(hr)) - { - pBrush_->SetColor(sOutlineColor_); - - pRT_->DrawGeometry( - pTransformedGeometry, - pBrush_, - fOutlineWidth, - pStrokeStyle - ); - } } if (SUCCEEDED(hr)) @@ -193,32 +203,14 @@ STDMETHODIMP TextRenderer::DrawUnderline( if (SUCCEEDED(hr) && bShowOutline_) { - ID2D1StrokeStyle * pStrokeStyle = nullptr; - hr = Renderer::getID2D1Factory()->CreateStrokeStyle( - D2D1::StrokeStyleProperties( - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - nOutlineJoin_, - 2.0f, - D2D1_DASH_STYLE_SOLID, - 0.0f), - nullptr, - 0, - &pStrokeStyle + pBrush_->SetColor(sOutlineColor_); + + pRT_->DrawGeometry( + pTransformedGeometry, + pBrush_, + fOutlineWidth, + pCurrStrokeStyle_ ); - - if (SUCCEEDED(hr)) - { - pBrush_->SetColor(sOutlineColor_); - - pRT_->DrawGeometry( - pTransformedGeometry, - pBrush_, - fOutlineWidth, - pStrokeStyle - ); - } } if (SUCCEEDED(hr)) @@ -278,32 +270,14 @@ STDMETHODIMP TextRenderer::DrawStrikethrough( if (SUCCEEDED(hr) && bShowOutline_) { - ID2D1StrokeStyle * pStrokeStyle = nullptr; - hr = Renderer::getID2D1Factory()->CreateStrokeStyle( - D2D1::StrokeStyleProperties( - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - nOutlineJoin_, - 2.0f, - D2D1_DASH_STYLE_SOLID, - 0.0f), - nullptr, - 0, - &pStrokeStyle + pBrush_->SetColor(sOutlineColor_); + + pRT_->DrawGeometry( + pTransformedGeometry, + pBrush_, + fOutlineWidth, + pCurrStrokeStyle_ ); - - if (SUCCEEDED(hr)) - { - pBrush_->SetColor(sOutlineColor_); - - pRT_->DrawGeometry( - pTransformedGeometry, - pBrush_, - fOutlineWidth, - pStrokeStyle - ); - } } if (SUCCEEDED(hr)) diff --git a/core/e2dbase.h b/core/e2dbase.h index 3a841692..14222a34 100644 --- a/core/e2dbase.h +++ b/core/e2dbase.h @@ -416,6 +416,15 @@ public: // 获取文字渲染器 static TextRenderer * getTextRenderer(); + // 获取 Miter 样式的 ID2D1StrokeStyle + static ID2D1StrokeStyle * getMiterID2D1StrokeStyle(); + + // 获取 Bevel 样式的 ID2D1StrokeStyle + static ID2D1StrokeStyle * getBevelID2D1StrokeStyle(); + + // 获取 Round 样式的 ID2D1StrokeStyle + static ID2D1StrokeStyle * getRoundID2D1StrokeStyle(); + private: // 渲染游戏画面 static void __render(); diff --git a/core/e2dcustom.h b/core/e2dcustom.h index 65353d8e..7727500a 100644 --- a/core/e2dcustom.h +++ b/core/e2dcustom.h @@ -71,15 +71,18 @@ protected: class TextRenderer : public IDWriteTextRenderer { +private: + TextRenderer(); + + ~TextRenderer(); + public: - TextRenderer( + static TextRenderer * Create( ID2D1Factory* pD2DFactory, ID2D1HwndRenderTarget* pRT, ID2D1SolidColorBrush* pBrush ); - ~TextRenderer(); - STDMETHOD_(void, SetTextStyle)( CONST D2D1_COLOR_F &fillColor, BOOL hasOutline, @@ -153,10 +156,10 @@ private: D2D1_COLOR_F sOutlineColor_; FLOAT fOutlineWidth; BOOL bShowOutline_; - D2D1_LINE_JOIN nOutlineJoin_; ID2D1Factory* pD2DFactory_; ID2D1HwndRenderTarget* pRT_; ID2D1SolidColorBrush* pBrush_; + ID2D1StrokeStyle * pCurrStrokeStyle_; };