添加CustomTextRenderer类,用于实现文字描边功能
This commit is contained in:
parent
6d7550608c
commit
f215632e60
|
|
@ -3,12 +3,15 @@
|
||||||
#include "..\e2dnode.h"
|
#include "..\e2dnode.h"
|
||||||
|
|
||||||
static bool s_bShowFps = false;
|
static bool s_bShowFps = false;
|
||||||
|
static float s_fDpiScaleX = 0;
|
||||||
|
static float s_fDpiScaleY = 0;
|
||||||
static IDWriteTextFormat * s_pTextFormat = nullptr;
|
static IDWriteTextFormat * s_pTextFormat = nullptr;
|
||||||
static ID2D1Factory * s_pDirect2dFactory = nullptr;
|
static ID2D1Factory * s_pDirect2dFactory = nullptr;
|
||||||
static ID2D1HwndRenderTarget * s_pRenderTarget = nullptr;
|
static ID2D1HwndRenderTarget * s_pRenderTarget = nullptr;
|
||||||
static ID2D1SolidColorBrush * s_pSolidBrush = nullptr;
|
static ID2D1SolidColorBrush * s_pSolidBrush = nullptr;
|
||||||
static IWICImagingFactory * s_pIWICFactory = nullptr;
|
static IWICImagingFactory * s_pIWICFactory = nullptr;
|
||||||
static IDWriteFactory * s_pDWriteFactory = nullptr;
|
static IDWriteFactory * s_pDWriteFactory = nullptr;
|
||||||
|
static e2d::CustomTextRenderer * s_pTextRenderer = nullptr;
|
||||||
static D2D1_COLOR_F s_nClearColor = D2D1::ColorF(D2D1::ColorF::Black);
|
static D2D1_COLOR_F s_nClearColor = D2D1::ColorF(D2D1::ColorF::Black);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -16,7 +19,7 @@ bool e2d::Renderer::__createDeviceIndependentResources()
|
||||||
{
|
{
|
||||||
// 创建设备无关资源,它们的生命周期和程序的时长相同
|
// 创建设备无关资源,它们的生命周期和程序的时长相同
|
||||||
HRESULT hr = D2D1CreateFactory(
|
HRESULT hr = D2D1CreateFactory(
|
||||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||||
&s_pDirect2dFactory
|
&s_pDirect2dFactory
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -46,21 +49,27 @@ bool e2d::Renderer::__createDeviceIndependentResources()
|
||||||
ASSERT(SUCCEEDED(hr), "Create IDWriteFactory Failed!");
|
ASSERT(SUCCEEDED(hr), "Create IDWriteFactory Failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
// 工厂将返回当前的系统 DPI,这个值也将用来创建窗口
|
||||||
|
Renderer::getID2D1Factory()->GetDesktopDpi(&s_fDpiScaleX, &s_fDpiScaleY);
|
||||||
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// 创建文本格式化对象
|
// 创建文本格式化对象
|
||||||
hr = s_pDWriteFactory->CreateTextFormat(
|
hr = s_pDWriteFactory->CreateTextFormat(
|
||||||
L"",
|
L"",
|
||||||
NULL,
|
NULL,
|
||||||
DWRITE_FONT_WEIGHT_NORMAL,
|
DWRITE_FONT_WEIGHT_BOLD,
|
||||||
DWRITE_FONT_STYLE_NORMAL,
|
DWRITE_FONT_STYLE_NORMAL,
|
||||||
DWRITE_FONT_STRETCH_NORMAL,
|
DWRITE_FONT_STRETCH_NORMAL,
|
||||||
18,
|
22,
|
||||||
L"",
|
L"",
|
||||||
&s_pTextFormat
|
&s_pTextFormat
|
||||||
);
|
);
|
||||||
|
|
||||||
if (s_pTextFormat)
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
s_pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
|
s_pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +81,7 @@ bool e2d::Renderer::__createDeviceIndependentResources()
|
||||||
bool e2d::Renderer::__createDeviceResources()
|
bool e2d::Renderer::__createDeviceResources()
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
if (!s_pRenderTarget)
|
if (!s_pRenderTarget)
|
||||||
{
|
{
|
||||||
HWND hWnd = Window::getHWnd();
|
HWND hWnd = Window::getHWnd();
|
||||||
|
|
@ -107,8 +116,18 @@ bool e2d::Renderer::__createDeviceResources()
|
||||||
);
|
);
|
||||||
ASSERT(SUCCEEDED(hr), "Create ID2D1SolidColorBrush Failed!");
|
ASSERT(SUCCEEDED(hr), "Create ID2D1SolidColorBrush Failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
// 创建自定义的文字渲染器
|
||||||
|
s_pTextRenderer = new (std::nothrow) CustomTextRenderer(
|
||||||
|
s_pDirect2dFactory,
|
||||||
|
s_pRenderTarget,
|
||||||
|
s_pSolidBrush
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
return SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,6 +135,7 @@ void e2d::Renderer::__discardDeviceResources()
|
||||||
{
|
{
|
||||||
SafeReleaseInterface(&s_pRenderTarget);
|
SafeReleaseInterface(&s_pRenderTarget);
|
||||||
SafeReleaseInterface(&s_pSolidBrush);
|
SafeReleaseInterface(&s_pSolidBrush);
|
||||||
|
SafeReleaseInterface(&s_pTextRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Renderer::__discardResources()
|
void e2d::Renderer::__discardResources()
|
||||||
|
|
@ -124,6 +144,7 @@ void e2d::Renderer::__discardResources()
|
||||||
SafeReleaseInterface(&s_pDirect2dFactory);
|
SafeReleaseInterface(&s_pDirect2dFactory);
|
||||||
SafeReleaseInterface(&s_pRenderTarget);
|
SafeReleaseInterface(&s_pRenderTarget);
|
||||||
SafeReleaseInterface(&s_pSolidBrush);
|
SafeReleaseInterface(&s_pSolidBrush);
|
||||||
|
SafeReleaseInterface(&s_pTextRenderer);
|
||||||
SafeReleaseInterface(&s_pIWICFactory);
|
SafeReleaseInterface(&s_pIWICFactory);
|
||||||
SafeReleaseInterface(&s_pDWriteFactory);
|
SafeReleaseInterface(&s_pDWriteFactory);
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +169,7 @@ void e2d::Renderer::__render()
|
||||||
{
|
{
|
||||||
static int s_nRenderTimes = 0;
|
static int s_nRenderTimes = 0;
|
||||||
static double s_fLastRenderTime = 0;
|
static double s_fLastRenderTime = 0;
|
||||||
static e2d::String s_sFpsText = L"";
|
static String s_sFpsText;
|
||||||
|
|
||||||
s_nRenderTimes++;
|
s_nRenderTimes++;
|
||||||
|
|
||||||
|
|
@ -160,9 +181,31 @@ void e2d::Renderer::__render()
|
||||||
s_nRenderTimes = 0;
|
s_nRenderTimes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_pSolidBrush->SetColor(D2D1::ColorF(D2D1::ColorF::White));
|
IDWriteTextLayout * pTextLayout = nullptr;
|
||||||
s_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
|
|
||||||
s_pRenderTarget->DrawTextW(s_sFpsText, (UINT32)s_sFpsText.getLength(), s_pTextFormat, D2D1::RectF(), s_pSolidBrush);
|
hr = s_pDWriteFactory->CreateTextLayout(
|
||||||
|
s_sFpsText,
|
||||||
|
(UINT32)s_sFpsText.getLength(),
|
||||||
|
s_pTextFormat,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&pTextLayout
|
||||||
|
);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
s_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||||
|
s_pTextRenderer->SetTextStyle(
|
||||||
|
D2D1::ColorF(D2D1::ColorF::White),
|
||||||
|
D2D1::ColorF(D2D1::ColorF::Black),
|
||||||
|
2.0f,
|
||||||
|
1.0f
|
||||||
|
);
|
||||||
|
|
||||||
|
pTextLayout->Draw(NULL, s_pTextRenderer, 10, 0);
|
||||||
|
|
||||||
|
SafeReleaseInterface(&pTextLayout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 终止渲染
|
// 终止渲染
|
||||||
|
|
@ -195,6 +238,16 @@ void e2d::Renderer::showFps(bool show)
|
||||||
s_bShowFps = show;
|
s_bShowFps = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float e2d::Renderer::getDpiScaleX()
|
||||||
|
{
|
||||||
|
return s_fDpiScaleX;
|
||||||
|
}
|
||||||
|
|
||||||
|
float e2d::Renderer::getDpiScaleY()
|
||||||
|
{
|
||||||
|
return s_fDpiScaleY;
|
||||||
|
}
|
||||||
|
|
||||||
ID2D1Factory * e2d::Renderer::getID2D1Factory()
|
ID2D1Factory * e2d::Renderer::getID2D1Factory()
|
||||||
{
|
{
|
||||||
return s_pDirect2dFactory;
|
return s_pDirect2dFactory;
|
||||||
|
|
@ -219,3 +272,8 @@ IDWriteFactory * e2d::Renderer::getIDWriteFactory()
|
||||||
{
|
{
|
||||||
return s_pDWriteFactory;
|
return s_pDWriteFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e2d::CustomTextRenderer * e2d::Renderer::getCustomTextRenderer()
|
||||||
|
{
|
||||||
|
return s_pTextRenderer;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,8 @@ bool e2d::Window::__init()
|
||||||
|
|
||||||
// 因为 CreateWindow 函数使用的是像素大小,获取系统的 DPI 以使它
|
// 因为 CreateWindow 函数使用的是像素大小,获取系统的 DPI 以使它
|
||||||
// 适应窗口缩放
|
// 适应窗口缩放
|
||||||
float dpiX, dpiY;
|
float dpiX = Renderer::getDpiScaleX();
|
||||||
|
float dpiY = Renderer::getDpiScaleY();
|
||||||
// 工厂将返回当前的系统 DPI,这个值也将用来创建窗口
|
|
||||||
Renderer::getID2D1Factory()->GetDesktopDpi(&dpiX, &dpiY);
|
|
||||||
|
|
||||||
UINT nWidth = static_cast<UINT>(ceil(640 * dpiX / 96.f));
|
UINT nWidth = static_cast<UINT>(ceil(640 * dpiX / 96.f));
|
||||||
UINT nHeight = static_cast<UINT>(ceil(480 * dpiY / 96.f));
|
UINT nHeight = static_cast<UINT>(ceil(480 * dpiY / 96.f));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,346 @@
|
||||||
|
#include "..\e2dcustom.h"
|
||||||
|
|
||||||
|
using namespace e2d;
|
||||||
|
|
||||||
|
CustomTextRenderer::CustomTextRenderer(
|
||||||
|
ID2D1Factory* pD2DFactory,
|
||||||
|
ID2D1HwndRenderTarget* pRT,
|
||||||
|
ID2D1SolidColorBrush* pBrush
|
||||||
|
)
|
||||||
|
: cRefCount_(0)
|
||||||
|
, pD2DFactory_(pD2DFactory)
|
||||||
|
, pRT_(pRT)
|
||||||
|
, pBrush_(pBrush)
|
||||||
|
, sFillColor_()
|
||||||
|
, sOutlineColor_()
|
||||||
|
, fStrokeWidth_(1)
|
||||||
|
, fOpacity_(1)
|
||||||
|
{
|
||||||
|
pD2DFactory_->AddRef();
|
||||||
|
pRT_->AddRef();
|
||||||
|
pBrush_->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomTextRenderer::~CustomTextRenderer()
|
||||||
|
{
|
||||||
|
SafeReleaseInterface(&pD2DFactory_);
|
||||||
|
SafeReleaseInterface(&pRT_);
|
||||||
|
SafeReleaseInterface(&pBrush_);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP_(void) CustomTextRenderer::SetTextStyle(
|
||||||
|
CONST D2D1_COLOR_F &fillColor,
|
||||||
|
CONST D2D1_COLOR_F &outlineColor,
|
||||||
|
FLOAT strokeWidth,
|
||||||
|
FLOAT opacity
|
||||||
|
)
|
||||||
|
{
|
||||||
|
sFillColor_ = fillColor;
|
||||||
|
sOutlineColor_ = outlineColor;
|
||||||
|
fStrokeWidth_ = strokeWidth;
|
||||||
|
fOpacity_ = opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CustomTextRenderer::DrawGlyphRun(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
FLOAT baselineOriginX,
|
||||||
|
FLOAT baselineOriginY,
|
||||||
|
DWRITE_MEASURING_MODE measuringMode,
|
||||||
|
__in DWRITE_GLYPH_RUN const* glyphRun,
|
||||||
|
__in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
|
||||||
|
IUnknown* clientDrawingEffect
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
ID2D1PathGeometry* pPathGeometry = NULL;
|
||||||
|
hr = pD2DFactory_->CreatePathGeometry(
|
||||||
|
&pPathGeometry
|
||||||
|
);
|
||||||
|
|
||||||
|
ID2D1GeometrySink* pSink = NULL;
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = pPathGeometry->Open(
|
||||||
|
&pSink
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = glyphRun->fontFace->GetGlyphRunOutline(
|
||||||
|
glyphRun->fontEmSize,
|
||||||
|
glyphRun->glyphIndices,
|
||||||
|
glyphRun->glyphAdvances,
|
||||||
|
glyphRun->glyphOffsets,
|
||||||
|
glyphRun->glyphCount,
|
||||||
|
glyphRun->isSideways,
|
||||||
|
glyphRun->bidiLevel % 2,
|
||||||
|
pSink
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = pSink->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F(
|
||||||
|
1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f,
|
||||||
|
baselineOriginX, baselineOriginY
|
||||||
|
);
|
||||||
|
|
||||||
|
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = pD2DFactory_->CreateTransformedGeometry(
|
||||||
|
pPathGeometry,
|
||||||
|
&matrix,
|
||||||
|
&pTransformedGeometry
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
pBrush_->SetOpacity(fOpacity_);
|
||||||
|
pBrush_->SetColor(sOutlineColor_);
|
||||||
|
|
||||||
|
pRT_->DrawGeometry(
|
||||||
|
pTransformedGeometry,
|
||||||
|
pBrush_,
|
||||||
|
fStrokeWidth_
|
||||||
|
);
|
||||||
|
|
||||||
|
pBrush_->SetColor(sFillColor_);
|
||||||
|
|
||||||
|
pRT_->FillGeometry(
|
||||||
|
pTransformedGeometry,
|
||||||
|
pBrush_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeReleaseInterface(&pPathGeometry);
|
||||||
|
SafeReleaseInterface(&pSink);
|
||||||
|
SafeReleaseInterface(&pTransformedGeometry);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CustomTextRenderer::DrawUnderline(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
FLOAT baselineOriginX,
|
||||||
|
FLOAT baselineOriginY,
|
||||||
|
__in DWRITE_UNDERLINE const* underline,
|
||||||
|
IUnknown* clientDrawingEffect
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
D2D1_RECT_F rect = D2D1::RectF(
|
||||||
|
0,
|
||||||
|
underline->offset,
|
||||||
|
underline->width,
|
||||||
|
underline->offset + underline->thickness
|
||||||
|
);
|
||||||
|
|
||||||
|
ID2D1RectangleGeometry* pRectangleGeometry = NULL;
|
||||||
|
hr = pD2DFactory_->CreateRectangleGeometry(
|
||||||
|
&rect,
|
||||||
|
&pRectangleGeometry
|
||||||
|
);
|
||||||
|
|
||||||
|
D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F(
|
||||||
|
1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f,
|
||||||
|
baselineOriginX, baselineOriginY
|
||||||
|
);
|
||||||
|
|
||||||
|
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = pD2DFactory_->CreateTransformedGeometry(
|
||||||
|
pRectangleGeometry,
|
||||||
|
&matrix,
|
||||||
|
&pTransformedGeometry
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
pBrush_->SetOpacity(fOpacity_);
|
||||||
|
pBrush_->SetColor(sOutlineColor_);
|
||||||
|
|
||||||
|
pRT_->DrawGeometry(
|
||||||
|
pTransformedGeometry,
|
||||||
|
pBrush_,
|
||||||
|
fStrokeWidth_
|
||||||
|
);
|
||||||
|
|
||||||
|
pBrush_->SetColor(sFillColor_);
|
||||||
|
|
||||||
|
pRT_->FillGeometry(
|
||||||
|
pTransformedGeometry,
|
||||||
|
pBrush_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeReleaseInterface(&pRectangleGeometry);
|
||||||
|
SafeReleaseInterface(&pTransformedGeometry);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CustomTextRenderer::DrawStrikethrough(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
FLOAT baselineOriginX,
|
||||||
|
FLOAT baselineOriginY,
|
||||||
|
__in DWRITE_STRIKETHROUGH const* strikethrough,
|
||||||
|
IUnknown* clientDrawingEffect
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
D2D1_RECT_F rect = D2D1::RectF(
|
||||||
|
0,
|
||||||
|
strikethrough->offset,
|
||||||
|
strikethrough->width,
|
||||||
|
strikethrough->offset + strikethrough->thickness
|
||||||
|
);
|
||||||
|
|
||||||
|
ID2D1RectangleGeometry* pRectangleGeometry = NULL;
|
||||||
|
hr = pD2DFactory_->CreateRectangleGeometry(
|
||||||
|
&rect,
|
||||||
|
&pRectangleGeometry
|
||||||
|
);
|
||||||
|
|
||||||
|
D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F(
|
||||||
|
1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f,
|
||||||
|
baselineOriginX, baselineOriginY
|
||||||
|
);
|
||||||
|
|
||||||
|
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = pD2DFactory_->CreateTransformedGeometry(
|
||||||
|
pRectangleGeometry,
|
||||||
|
&matrix,
|
||||||
|
&pTransformedGeometry
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
pBrush_->SetOpacity(fOpacity_);
|
||||||
|
pBrush_->SetColor(sOutlineColor_);
|
||||||
|
|
||||||
|
pRT_->DrawGeometry(
|
||||||
|
pTransformedGeometry,
|
||||||
|
pBrush_,
|
||||||
|
fStrokeWidth_
|
||||||
|
);
|
||||||
|
|
||||||
|
pBrush_->SetColor(sFillColor_);
|
||||||
|
|
||||||
|
pRT_->FillGeometry(
|
||||||
|
pTransformedGeometry,
|
||||||
|
pBrush_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeReleaseInterface(&pRectangleGeometry);
|
||||||
|
SafeReleaseInterface(&pTransformedGeometry);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CustomTextRenderer::DrawInlineObject(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
FLOAT originX,
|
||||||
|
FLOAT originY,
|
||||||
|
IDWriteInlineObject* inlineObject,
|
||||||
|
BOOL isSideways,
|
||||||
|
BOOL isRightToLeft,
|
||||||
|
IUnknown* clientDrawingEffect
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP_(unsigned long) CustomTextRenderer::AddRef()
|
||||||
|
{
|
||||||
|
return InterlockedIncrement(&cRefCount_);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP_(unsigned long) CustomTextRenderer::Release()
|
||||||
|
{
|
||||||
|
unsigned long newCount = InterlockedDecrement(&cRefCount_);
|
||||||
|
|
||||||
|
if (newCount == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CustomTextRenderer::IsPixelSnappingDisabled(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
__out BOOL* isDisabled
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*isDisabled = FALSE;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CustomTextRenderer::GetCurrentTransform(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
__out DWRITE_MATRIX* transform
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pRT_->GetTransform(reinterpret_cast<D2D1_MATRIX_3X2_F*>(transform));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CustomTextRenderer::GetPixelsPerDip(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
__out FLOAT* pixelsPerDip
|
||||||
|
)
|
||||||
|
{
|
||||||
|
float x, yUnused;
|
||||||
|
|
||||||
|
pRT_->GetDpi(&x, &yUnused);
|
||||||
|
*pixelsPerDip = x / 96;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CustomTextRenderer::QueryInterface(
|
||||||
|
IID const& riid,
|
||||||
|
void** ppvObject
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (__uuidof(IDWriteTextRenderer) == riid)
|
||||||
|
{
|
||||||
|
*ppvObject = this;
|
||||||
|
}
|
||||||
|
else if (__uuidof(IDWritePixelSnapping) == riid)
|
||||||
|
{
|
||||||
|
*ppvObject = this;
|
||||||
|
}
|
||||||
|
else if (__uuidof(IUnknown) == riid)
|
||||||
|
{
|
||||||
|
*ppvObject = this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ppvObject = NULL;
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddRef();
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
@ -241,6 +241,12 @@ public:
|
||||||
bool show = true
|
bool show = true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 获取系统 DPI 缩放
|
||||||
|
static float getDpiScaleX();
|
||||||
|
|
||||||
|
// 获取系统 DPI 缩放
|
||||||
|
static float getDpiScaleY();
|
||||||
|
|
||||||
// 获取 ID2D1Factory 对象
|
// 获取 ID2D1Factory 对象
|
||||||
static ID2D1Factory * getID2D1Factory();
|
static ID2D1Factory * getID2D1Factory();
|
||||||
|
|
||||||
|
|
@ -256,6 +262,9 @@ public:
|
||||||
// 获取 IDWriteFactory 对象
|
// 获取 IDWriteFactory 对象
|
||||||
static IDWriteFactory * getIDWriteFactory();
|
static IDWriteFactory * getIDWriteFactory();
|
||||||
|
|
||||||
|
// 获取自定义的文字渲染器
|
||||||
|
static CustomTextRenderer * getCustomTextRenderer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 渲染游戏画面
|
// 渲染游戏画面
|
||||||
static void __render();
|
static void __render();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "e2dmacros.h"
|
#include "e2dmacros.h"
|
||||||
|
#include "e2dcustom.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -677,13 +678,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } }
|
|
||||||
|
|
||||||
template<typename Object>
|
template<typename Object>
|
||||||
inline void SafeRelease(Object** p) { if (*p) { (*p)->release(); *p = nullptr; } }
|
inline void SafeRelease(Object** p) { if (*p) { (*p)->release(); *p = nullptr; } }
|
||||||
|
|
||||||
template<class Interface>
|
|
||||||
inline void SafeReleaseInterface(Interface **pp) { if (*pp != nullptr) { (*pp)->Release(); (*pp) = nullptr; } }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
#pragma once
|
||||||
|
#include "e2dmacros.h"
|
||||||
|
|
||||||
|
namespace e2d
|
||||||
|
{
|
||||||
|
template<class Interface>
|
||||||
|
inline void SafeReleaseInterface(Interface **pp)
|
||||||
|
{
|
||||||
|
if (*pp != nullptr)
|
||||||
|
{
|
||||||
|
(*pp)->Release();
|
||||||
|
(*pp) = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ×Ô¶¨ÒåµÄÎÄ×ÖäÖȾÆ÷
|
||||||
|
class CustomTextRenderer
|
||||||
|
: public IDWriteTextRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CustomTextRenderer(
|
||||||
|
ID2D1Factory* pD2DFactory,
|
||||||
|
ID2D1HwndRenderTarget* pRT,
|
||||||
|
ID2D1SolidColorBrush* pBrush
|
||||||
|
);
|
||||||
|
|
||||||
|
~CustomTextRenderer();
|
||||||
|
|
||||||
|
STDMETHOD_(void, SetTextStyle)(
|
||||||
|
CONST D2D1_COLOR_F &fillColor,
|
||||||
|
CONST D2D1_COLOR_F &outlineColor,
|
||||||
|
FLOAT strokeWidth,
|
||||||
|
FLOAT opacity
|
||||||
|
);
|
||||||
|
|
||||||
|
STDMETHOD(DrawGlyphRun)(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
FLOAT baselineOriginX,
|
||||||
|
FLOAT baselineOriginY,
|
||||||
|
DWRITE_MEASURING_MODE measuringMode,
|
||||||
|
__in DWRITE_GLYPH_RUN const* glyphRun,
|
||||||
|
__in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
|
||||||
|
IUnknown* clientDrawingEffect
|
||||||
|
);
|
||||||
|
|
||||||
|
STDMETHOD(DrawUnderline)(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
FLOAT baselineOriginX,
|
||||||
|
FLOAT baselineOriginY,
|
||||||
|
__in DWRITE_UNDERLINE const* underline,
|
||||||
|
IUnknown* clientDrawingEffect
|
||||||
|
);
|
||||||
|
|
||||||
|
STDMETHOD(DrawStrikethrough)(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
FLOAT baselineOriginX,
|
||||||
|
FLOAT baselineOriginY,
|
||||||
|
__in DWRITE_STRIKETHROUGH const* strikethrough,
|
||||||
|
IUnknown* clientDrawingEffect
|
||||||
|
);
|
||||||
|
|
||||||
|
STDMETHOD(DrawInlineObject)(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
FLOAT originX,
|
||||||
|
FLOAT originY,
|
||||||
|
IDWriteInlineObject* inlineObject,
|
||||||
|
BOOL isSideways,
|
||||||
|
BOOL isRightToLeft,
|
||||||
|
IUnknown* clientDrawingEffect
|
||||||
|
);
|
||||||
|
|
||||||
|
STDMETHOD(IsPixelSnappingDisabled)(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
__out BOOL* isDisabled
|
||||||
|
);
|
||||||
|
|
||||||
|
STDMETHOD(GetCurrentTransform)(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
__out DWRITE_MATRIX* transform
|
||||||
|
);
|
||||||
|
|
||||||
|
STDMETHOD(GetPixelsPerDip)(
|
||||||
|
__maybenull void* clientDrawingContext,
|
||||||
|
__out FLOAT* pixelsPerDip
|
||||||
|
);
|
||||||
|
|
||||||
|
public:
|
||||||
|
unsigned long STDMETHODCALLTYPE AddRef();
|
||||||
|
unsigned long STDMETHODCALLTYPE Release();
|
||||||
|
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||||
|
IID const& riid,
|
||||||
|
void** ppvObject
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned long cRefCount_;
|
||||||
|
D2D1_COLOR_F sFillColor_;
|
||||||
|
D2D1_COLOR_F sOutlineColor_;
|
||||||
|
FLOAT fStrokeWidth_;
|
||||||
|
FLOAT fOpacity_;
|
||||||
|
ID2D1Factory* pD2DFactory_;
|
||||||
|
ID2D1HwndRenderTarget* pRT_;
|
||||||
|
ID2D1SolidColorBrush* pBrush_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -222,6 +222,7 @@
|
||||||
<ClCompile Include="..\..\core\Common\Size.cpp" />
|
<ClCompile Include="..\..\core\Common\Size.cpp" />
|
||||||
<ClCompile Include="..\..\core\Common\String.cpp" />
|
<ClCompile Include="..\..\core\Common\String.cpp" />
|
||||||
<ClCompile Include="..\..\core\Common\Image.cpp" />
|
<ClCompile Include="..\..\core\Common\Image.cpp" />
|
||||||
|
<ClCompile Include="..\..\core\Custom\CustomTextRenderer.cpp" />
|
||||||
<ClCompile Include="..\..\core\Manager\ActionManager.cpp" />
|
<ClCompile Include="..\..\core\Manager\ActionManager.cpp" />
|
||||||
<ClCompile Include="..\..\core\Manager\InputManager.cpp" />
|
<ClCompile Include="..\..\core\Manager\InputManager.cpp" />
|
||||||
<ClCompile Include="..\..\core\Manager\MusicManager.cpp" />
|
<ClCompile Include="..\..\core\Manager\MusicManager.cpp" />
|
||||||
|
|
@ -255,6 +256,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\core\e2daction.h" />
|
<ClInclude Include="..\..\core\e2daction.h" />
|
||||||
|
<ClInclude Include="..\..\core\e2dcustom.h" />
|
||||||
<ClInclude Include="..\..\core\easy2d.h" />
|
<ClInclude Include="..\..\core\easy2d.h" />
|
||||||
<ClInclude Include="..\..\core\e2dbase.h" />
|
<ClInclude Include="..\..\core\e2dbase.h" />
|
||||||
<ClInclude Include="..\..\core\e2dcommon.h" />
|
<ClInclude Include="..\..\core\e2dcommon.h" />
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@
|
||||||
<Filter Include="Tool\Listener">
|
<Filter Include="Tool\Listener">
|
||||||
<UniqueIdentifier>{d3968182-2399-40d4-8e39-accb4711018c}</UniqueIdentifier>
|
<UniqueIdentifier>{d3968182-2399-40d4-8e39-accb4711018c}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Custom">
|
||||||
|
<UniqueIdentifier>{3475b59d-d50c-43b1-8334-bcb9e1703ed2}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\core\Base\Input.cpp">
|
<ClCompile Include="..\..\core\Base\Input.cpp">
|
||||||
|
|
@ -219,6 +222,9 @@
|
||||||
<ClCompile Include="..\..\core\Tool\Listener\Listener.cpp">
|
<ClCompile Include="..\..\core\Tool\Listener\Listener.cpp">
|
||||||
<Filter>Tool\Listener</Filter>
|
<Filter>Tool\Listener</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\core\Custom\CustomTextRenderer.cpp">
|
||||||
|
<Filter>Custom</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\core\easy2d.h" />
|
<ClInclude Include="..\..\core\easy2d.h" />
|
||||||
|
|
@ -232,5 +238,6 @@
|
||||||
<ClInclude Include="..\..\core\e2dshape.h" />
|
<ClInclude Include="..\..\core\e2dshape.h" />
|
||||||
<ClInclude Include="..\..\core\e2dtool.h" />
|
<ClInclude Include="..\..\core\e2dtool.h" />
|
||||||
<ClInclude Include="..\..\core\e2dtransition.h" />
|
<ClInclude Include="..\..\core\e2dtransition.h" />
|
||||||
|
<ClInclude Include="..\..\core\e2dcustom.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Loading…
Reference in New Issue