Magic_Game/core/Node/Text.cpp

431 lines
8.2 KiB
C++
Raw Normal View History

2018-04-21 21:24:46 +08:00
#include "..\e2dnode.h"
e2d::Text::Text()
: m_TextStyle()
, m_pDWriteTextLayout(nullptr)
, m_pDWriteTextFormat(nullptr)
{
}
e2d::Text::Text(String text)
: m_TextStyle()
, m_pDWriteTextLayout(nullptr)
, m_pDWriteTextFormat(nullptr)
, m_sText(text)
{
_reset();
}
e2d::Text::Text(TextStyle textStyle)
: m_TextStyle(textStyle)
, m_pDWriteTextLayout(nullptr)
, m_pDWriteTextFormat(nullptr)
{
_reset();
}
e2d::Text::Text(String text, TextStyle textStyle)
: m_TextStyle(textStyle)
, m_pDWriteTextLayout(nullptr)
, m_pDWriteTextFormat(nullptr)
, m_sText(text)
{
_reset();
}
e2d::Text::Text(
String text,
String fontFamily,
double fontSize,
UINT32 color,
UINT32 fontWeight,
bool italic,
TextAlign alignment,
bool wrapping,
double wrappingWidth,
double lineSpacing,
bool hasUnderline,
bool hasStrikethrough,
2018-04-22 14:08:29 +08:00
bool hasOutline,
UINT32 outlineColor,
UINT32 outlineWidth
)
: m_TextStyle(
fontFamily,
fontSize,
color,
fontWeight,
italic,
alignment,
wrapping,
wrappingWidth,
lineSpacing,
hasUnderline,
hasStrikethrough,
2018-04-22 14:08:29 +08:00
hasOutline,
outlineColor,
outlineWidth
)
, m_pDWriteTextLayout(nullptr)
, m_pDWriteTextFormat(nullptr)
, m_sText(text)
{
_reset();
}
e2d::Text::~Text()
{
SafeReleaseInterface(&m_pDWriteTextFormat);
SafeReleaseInterface(&m_pDWriteTextLayout);
}
e2d::String e2d::Text::getText() const
{
return m_sText;
}
e2d::TextStyle e2d::Text::getTextStyle() const
{
return m_TextStyle;
}
e2d::String e2d::Text::getFontFamily() const
{
return m_TextStyle.fontFamily;
}
double e2d::Text::getFontSize() const
{
return m_TextStyle.fontSize;
}
UINT32 e2d::Text::getFontWeight() const
{
return m_TextStyle.fontWeight;
}
e2d::Color e2d::Text::getColor() const
{
return m_TextStyle.color;
}
e2d::Color e2d::Text::getOutlineColor() const
{
return m_TextStyle.outlineColor;
}
double e2d::Text::getOutlineWidth() const
{
return m_TextStyle.outlineWidth;
}
e2d::LineJoin e2d::Text::getOutlineJoin() const
{
return m_TextStyle.outlineJoin;
}
int e2d::Text::getLineCount() const
{
2018-04-09 18:41:56 +08:00
if (m_pDWriteTextLayout)
{
DWRITE_TEXT_METRICS metrics;
m_pDWriteTextLayout->GetMetrics(&metrics);
return static_cast<int>(metrics.lineCount);
}
else
{
return 0;
}
}
bool e2d::Text::isItalic() const
{
return m_TextStyle.italic;
}
2018-04-22 14:08:29 +08:00
bool e2d::Text::hasStrikethrough() const
{
2018-04-22 14:08:29 +08:00
return m_TextStyle.hasStrikethrough;
}
bool e2d::Text::hasUnderline() const
{
return m_TextStyle.hasUnderline;
}
bool e2d::Text::hasOutline() const
{
return m_TextStyle.hasOutline;
}
void e2d::Text::setText(String text)
{
m_sText = text;
_reset();
}
void e2d::Text::setTextStyle(TextStyle textStyle)
{
m_TextStyle = textStyle;
_reset();
}
void e2d::Text::setFontFamily(String fontFamily)
{
m_TextStyle.fontFamily = fontFamily;
_reset();
}
void e2d::Text::setFontSize(double fontSize)
{
m_TextStyle.fontSize = fontSize;
_reset();
}
void e2d::Text::setFontWeight(UINT32 fontWeight)
{
m_TextStyle.fontWeight = fontWeight;
_reset();
}
void e2d::Text::setColor(Color color)
{
m_TextStyle.color = color;
}
void e2d::Text::setItalic(bool value)
{
m_TextStyle.italic = value;
_reset();
}
void e2d::Text::setWrapping(bool wrapping)
{
if (m_TextStyle.wrapping != wrapping)
{
m_TextStyle.wrapping = wrapping;
_reset();
}
}
void e2d::Text::setWrappingWidth(double fWrappingWidth)
{
if (m_TextStyle.wrappingWidth != fWrappingWidth)
{
m_TextStyle.wrappingWidth = max(fWrappingWidth, 0);
if (m_TextStyle.wrapping)
{
_reset();
}
}
}
void e2d::Text::setLineSpacing(double fLineSpacing)
{
if (m_TextStyle.lineSpacing != fLineSpacing)
{
m_TextStyle.lineSpacing = fLineSpacing;
_reset();
}
}
void e2d::Text::setAlignment(TextAlign align)
{
if (m_TextStyle.alignment != align)
{
m_TextStyle.alignment = align;
_reset();
}
}
void e2d::Text::setUnderline(bool hasUnderline)
{
2018-04-22 14:08:29 +08:00
if (m_TextStyle.hasUnderline != hasUnderline)
{
2018-04-22 14:08:29 +08:00
m_TextStyle.hasUnderline = hasUnderline;
if (!m_pDWriteTextFormat)
_createFormat();
_createLayout();
}
}
void e2d::Text::setStrikethrough(bool hasStrikethrough)
{
2018-04-22 14:08:29 +08:00
if (m_TextStyle.hasStrikethrough != hasStrikethrough)
{
2018-04-22 14:08:29 +08:00
m_TextStyle.hasStrikethrough = hasStrikethrough;
if (!m_pDWriteTextFormat)
_createFormat();
_createLayout();
}
}
2018-04-22 14:08:29 +08:00
void e2d::Text::setOutline(bool hasOutline)
{
2018-04-22 14:08:29 +08:00
m_TextStyle.hasOutline = hasOutline;
}
void e2d::Text::setOutlineColor(Color outlineColor)
{
m_TextStyle.outlineColor = outlineColor;
}
void e2d::Text::setOutlineWidth(double outlineWidth)
{
m_TextStyle.outlineWidth = outlineWidth;
}
void e2d::Text::setOutlineJoin(LineJoin outlineJoin)
{
m_TextStyle.outlineJoin = outlineJoin;
}
void e2d::Text::onRender()
{
if (m_pDWriteTextLayout)
{
// <20><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>
D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, m_fWidth, m_fHeight);
// <20><><EFBFBD>û<EFBFBD>ˢ<EFBFBD><CBA2>ɫ<EFBFBD><C9AB>͸<EFBFBD><CDB8><EFBFBD><EFBFBD>
Renderer::getSolidColorBrush()->SetOpacity(m_fDisplayOpacity);
// <20><>ȡ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>Ⱦ<EFBFBD><C8BE>
auto pTextRenderer = Renderer::getCustomTextRenderer();
pTextRenderer->SetTextStyle(
m_TextStyle.color.toColorF(),
2018-04-22 14:08:29 +08:00
m_TextStyle.hasOutline,
m_TextStyle.outlineColor.toColorF(),
static_cast<FLOAT>(m_TextStyle.outlineWidth),
D2D1_LINE_JOIN(m_TextStyle.outlineJoin)
);
m_pDWriteTextLayout->Draw(NULL, pTextRenderer, 0, 0);
}
}
void e2d::Text::_reset()
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>ʽ<EFBFBD><CABD>
_createFormat();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD>
_createLayout();
}
void e2d::Text::_createFormat()
{
SafeReleaseInterface(&m_pDWriteTextFormat);
HRESULT hr = Renderer::getIDWriteFactory()->CreateTextFormat(
m_TextStyle.fontFamily,
NULL,
DWRITE_FONT_WEIGHT(m_TextStyle.fontWeight),
m_TextStyle.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
static_cast<float>(m_TextStyle.fontSize),
2018-04-17 11:41:33 +08:00
L"",
&m_pDWriteTextFormat
);
ASSERT(SUCCEEDED(hr), "Create IDWriteTextFormat Failed!");
if (m_pDWriteTextFormat)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6>ʽ
m_pDWriteTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(m_TextStyle.alignment));
// <20><><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD>
if (m_TextStyle.lineSpacing == 0.0)
{
m_pDWriteTextFormat->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0);
}
else
{
m_pDWriteTextFormat->SetLineSpacing(
DWRITE_LINE_SPACING_METHOD_UNIFORM,
static_cast<FLOAT>(m_TextStyle.lineSpacing),
static_cast<FLOAT>(m_TextStyle.lineSpacing) * 0.8f
);
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (m_TextStyle.wrapping)
{
m_pDWriteTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_WRAP);
}
else
{
m_pDWriteTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
}
}
}
void e2d::Text::_createLayout()
{
SafeReleaseInterface(&m_pDWriteTextLayout);
// <20>ı<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (m_sText.isEmpty())
{
this->setSize(0, 0);
return;
}
if (m_pDWriteTextFormat == nullptr)
{
WARN_IF(true, "Text::_createLayout failed! m_pDWriteTextFormat NULL pointer exception.");
return;
}
UINT32 length = static_cast<UINT32>(m_sText.getLength());
// <20><><EFBFBD><EFBFBD> TextLayout
HRESULT hr;
// <20><><EFBFBD>ı<EFBFBD><C4B1>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD>д<EFBFBD><D0B4><EFBFBD>
if (m_TextStyle.wrapping)
{
hr = Renderer::getIDWriteFactory()->CreateTextLayout(
m_sText,
length,
m_pDWriteTextFormat,
static_cast<FLOAT>(m_TextStyle.wrappingWidth),
0,
&m_pDWriteTextLayout
);
if (m_pDWriteTextLayout)
{
// <20><>ȡ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>ֵĿ<D6B5><C4BF>Ⱥ͸߶<CDB8>
DWRITE_TEXT_METRICS metrics;
m_pDWriteTextLayout->GetMetrics(&metrics);
// <20><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>
this->setSize(metrics.layoutWidth, metrics.height);
}
}
else
{
hr = Renderer::getIDWriteFactory()->CreateTextLayout(m_sText, length, m_pDWriteTextFormat, 0, 0, &m_pDWriteTextLayout);
// Ϊ<><CEAA>ֹ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E2A3AC><EFBFBD>ݸղŴ<D5B2><C5B4><EFBFBD><EFBFBD><EFBFBD> layout <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD>
if (m_pDWriteTextLayout)
{
// <20><>ȡ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>ֵĿ<D6B5><C4BF>Ⱥ͸߶<CDB8>
DWRITE_TEXT_METRICS metrics;
m_pDWriteTextLayout->GetMetrics(&metrics);
// <20><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>
this->setSize(metrics.width, metrics.height);
// <20><><EFBFBD>´<EFBFBD><C2B4><EFBFBD> layout
SafeReleaseInterface(&m_pDWriteTextLayout);
hr = Renderer::getIDWriteFactory()->CreateTextLayout(m_sText, length, m_pDWriteTextFormat, m_fWidth, 0, &m_pDWriteTextLayout);
}
}
ASSERT(SUCCEEDED(hr), "Create IDWriteTextFormat Failed!");
// <20><><EFBFBD><EFBFBD><EFBFBD>»<EFBFBD><C2BB>ߺ<EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD>
2018-04-01 13:28:32 +08:00
DWRITE_TEXT_RANGE range = { 0, length };
2018-04-22 14:08:29 +08:00
if (m_TextStyle.hasUnderline)
{
2018-04-01 13:28:32 +08:00
m_pDWriteTextLayout->SetUnderline(true, range);
}
2018-04-22 14:08:29 +08:00
if (m_TextStyle.hasStrikethrough)
{
2018-04-01 13:28:32 +08:00
m_pDWriteTextLayout->SetStrikethrough(true, range);
}
}