Add TextFormat && TextLayout
This commit is contained in:
parent
d34e14b799
commit
ed79c69e7a
25
appveyor.yml
25
appveyor.yml
|
|
@ -47,6 +47,14 @@ only_commits:
|
|||
- scripts/**/*.ps1
|
||||
- appveyor.yml
|
||||
|
||||
for:
|
||||
-
|
||||
branches:
|
||||
except:
|
||||
- master
|
||||
only_commits:
|
||||
message: /\[build\]/
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
|
|
@ -67,19 +75,8 @@ build:
|
|||
project: projects/Kiwano.sln
|
||||
verbosity: minimal
|
||||
|
||||
for:
|
||||
-
|
||||
branches:
|
||||
except:
|
||||
- master
|
||||
only_commits:
|
||||
message: /\[build\]/
|
||||
-
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
after_build:
|
||||
- ps: .\scripts\appveyor\wait_for_other_jobs.ps1
|
||||
after_build:
|
||||
- ps: .\scripts\appveyor\wait_for_other_jobs.ps1
|
||||
|
||||
artifacts:
|
||||
- path: projects/output/**/*.lib
|
||||
|
|
@ -119,6 +116,6 @@ notifications:
|
|||
- provider: Email
|
||||
to:
|
||||
- 569629550@qq.com
|
||||
on_build_success: false
|
||||
on_build_success: true
|
||||
on_build_failure: true
|
||||
on_build_status_changed: false
|
||||
|
|
@ -77,6 +77,7 @@
|
|||
<ClInclude Include="..\src\kiwano\renderer\Image.h" />
|
||||
<ClInclude Include="..\src\kiwano\renderer\ImageCache.h" />
|
||||
<ClInclude Include="..\src\kiwano\renderer\Renderer.h" />
|
||||
<ClInclude Include="..\src\kiwano\renderer\TextLayout.h" />
|
||||
<ClInclude Include="..\src\kiwano\renderer\TextRenderer.h" />
|
||||
<ClInclude Include="..\src\kiwano\third-party\StackWalker\StackWalker.h" />
|
||||
<ClInclude Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.h" />
|
||||
|
|
@ -130,6 +131,7 @@
|
|||
<ClCompile Include="..\src\kiwano\renderer\Image.cpp" />
|
||||
<ClCompile Include="..\src\kiwano\renderer\ImageCache.cpp" />
|
||||
<ClCompile Include="..\src\kiwano\renderer\Renderer.cpp" />
|
||||
<ClCompile Include="..\src\kiwano\renderer\TextLayout.cpp" />
|
||||
<ClCompile Include="..\src\kiwano\renderer\TextRenderer.cpp" />
|
||||
<ClCompile Include="..\src\kiwano\third-party\StackWalker\StackWalker.cpp" />
|
||||
<ClCompile Include="..\src\kiwano\third-party\tinyxml2\tinyxml2.cpp" />
|
||||
|
|
|
|||
|
|
@ -288,6 +288,9 @@
|
|||
<ClInclude Include="..\src\kiwano\renderer\Renderer.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\kiwano\renderer\TextLayout.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\kiwano\ui\Button.cpp">
|
||||
|
|
@ -443,5 +446,8 @@
|
|||
<ClCompile Include="..\src\kiwano\renderer\Renderer.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\kiwano\renderer\TextLayout.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -131,7 +131,7 @@ namespace kiwano
|
|||
auto renderer = Renderer::GetInstance();
|
||||
renderer->SetTransform(transform_matrix_);
|
||||
renderer->FillRectangle(bounds, Color(Color::Red, .4f));
|
||||
renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 4.f);
|
||||
renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 2.f);
|
||||
}
|
||||
|
||||
for (auto child = children_.first_item(); child; child = child->next_item())
|
||||
|
|
|
|||
|
|
@ -275,21 +275,18 @@ namespace kiwano
|
|||
ThrowIfFailed(
|
||||
Renderer::GetInstance()->GetD2DDeviceResources()->CreateTextFormat(
|
||||
text_format_,
|
||||
text_font_,
|
||||
text_style_
|
||||
text_font_
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
ComPtr<IDWriteTextLayout> text_layout;
|
||||
Size layout_size;
|
||||
ThrowIfFailed(
|
||||
Renderer::GetInstance()->GetD2DDeviceResources()->CreateTextLayout(
|
||||
text_layout,
|
||||
layout_size,
|
||||
text,
|
||||
text_format_,
|
||||
text_style_
|
||||
text_style_,
|
||||
text_format_
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ namespace kiwano
|
|||
debug_text_->SetFont(font);
|
||||
|
||||
TextStyle style;
|
||||
style.wrap = false;
|
||||
style.line_spacing = 20.f;
|
||||
debug_text_->SetStyle(style);
|
||||
|
||||
|
|
@ -98,7 +97,7 @@ namespace kiwano
|
|||
ss << "Memory: " << pmc.PrivateUsage / 1024 << "kb";
|
||||
|
||||
debug_text_->SetText(ss.str());
|
||||
SetSize(Size{ 20 + debug_text_->GetLayoutSize().x, 20 + debug_text_->GetLayoutSize().y });
|
||||
SetSize(Size{ 20 + debug_text_->GetSize().x, 20 + debug_text_->GetSize().y });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ namespace kiwano
|
|||
: font_(text_default_font)
|
||||
, style_(text_default_style)
|
||||
, layout_dirty_(false)
|
||||
, format_dirty_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -74,96 +75,6 @@ namespace kiwano
|
|||
{
|
||||
}
|
||||
|
||||
String const& Text::GetText() const
|
||||
{
|
||||
return text_;
|
||||
}
|
||||
|
||||
const Font& Text::GetFont() const
|
||||
{
|
||||
return font_;
|
||||
}
|
||||
|
||||
const TextStyle& Text::GetStyle() const
|
||||
{
|
||||
return style_;
|
||||
}
|
||||
|
||||
String const& Text::GetFontFamily() const
|
||||
{
|
||||
return font_.family;
|
||||
}
|
||||
|
||||
float Text::GetFontSize() const
|
||||
{
|
||||
return font_.size;
|
||||
}
|
||||
|
||||
unsigned int Text::GetFontWeight() const
|
||||
{
|
||||
return font_.weight;
|
||||
}
|
||||
|
||||
const Color& Text::GetColor() const
|
||||
{
|
||||
return style_.color;
|
||||
}
|
||||
|
||||
const Color& Text::GetOutlineColor() const
|
||||
{
|
||||
return style_.outline_color;
|
||||
}
|
||||
|
||||
float Text::GetOutlineWidth() const
|
||||
{
|
||||
return style_.outline_width;
|
||||
}
|
||||
|
||||
StrokeStyle Text::GetOutlineStroke() const
|
||||
{
|
||||
return style_.outline_stroke;
|
||||
}
|
||||
|
||||
int Text::GetLineCount()
|
||||
{
|
||||
UpdateLayout();
|
||||
if (text_layout_)
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
if (SUCCEEDED(text_layout_->GetMetrics(&metrics)))
|
||||
{
|
||||
return static_cast<int>(metrics.lineCount);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Size const& Text::GetLayoutSize() const
|
||||
{
|
||||
UpdateLayout();
|
||||
return layout_size_;
|
||||
}
|
||||
|
||||
bool Text::IsItalic() const
|
||||
{
|
||||
return font_.italic;
|
||||
}
|
||||
|
||||
bool Text::HasStrikethrough() const
|
||||
{
|
||||
return style_.strikethrough;
|
||||
}
|
||||
|
||||
bool Text::HasUnderline() const
|
||||
{
|
||||
return style_.underline;
|
||||
}
|
||||
|
||||
bool Text::HasOutline() const
|
||||
{
|
||||
return style_.outline;
|
||||
}
|
||||
|
||||
void Text::SetText(String const& text)
|
||||
{
|
||||
text_ = text;
|
||||
|
|
@ -179,7 +90,7 @@ namespace kiwano
|
|||
void Text::SetFont(const Font & font)
|
||||
{
|
||||
font_ = font;
|
||||
layout_dirty_ = true;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
|
||||
void Text::SetFontFamily(String const& family)
|
||||
|
|
@ -187,7 +98,7 @@ namespace kiwano
|
|||
if (font_.family != family)
|
||||
{
|
||||
font_.family = family;
|
||||
layout_dirty_ = true;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +107,7 @@ namespace kiwano
|
|||
if (font_.size != size)
|
||||
{
|
||||
font_.size = size;
|
||||
layout_dirty_ = true;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +116,7 @@ namespace kiwano
|
|||
if (font_.weight != weight)
|
||||
{
|
||||
font_.weight = weight;
|
||||
layout_dirty_ = true;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -219,16 +130,7 @@ namespace kiwano
|
|||
if (font_.italic != val)
|
||||
{
|
||||
font_.italic = val;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetWrapEnabled(bool wrap)
|
||||
{
|
||||
if (style_.wrap != wrap)
|
||||
{
|
||||
style_.wrap = wrap;
|
||||
layout_dirty_ = true;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,12 +138,12 @@ namespace kiwano
|
|||
{
|
||||
if (style_.wrap_width != wrap_width)
|
||||
{
|
||||
style_.wrap_width = std::max(wrap_width, 0.f);
|
||||
style_.wrap_width = wrap_width;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Text::SetLineacingPtr(float line_spacing)
|
||||
void Text::SetLineSpacing(float line_spacing)
|
||||
{
|
||||
if (style_.line_spacing != line_spacing)
|
||||
{
|
||||
|
|
@ -301,51 +203,26 @@ namespace kiwano
|
|||
{
|
||||
UpdateLayout();
|
||||
|
||||
if (text_layout_ && renderer->CheckVisibility(layout_size_, transform_matrix_))
|
||||
if (text_layout_ && renderer->CheckVisibility(size_, transform_matrix_))
|
||||
{
|
||||
PrepareRender(renderer);
|
||||
renderer->SetTextStyle(
|
||||
GetDisplayedOpacity(),
|
||||
style_.color,
|
||||
style_.outline,
|
||||
style_.outline_color,
|
||||
style_.outline_width,
|
||||
style_.outline_stroke
|
||||
);
|
||||
renderer->DrawTextLayout(text_layout_);
|
||||
}
|
||||
}
|
||||
|
||||
void Text::UpdateLayout() const
|
||||
void Text::UpdateLayout()
|
||||
{
|
||||
if (!layout_dirty_)
|
||||
return;
|
||||
if (format_dirty_)
|
||||
{
|
||||
format_dirty_ = false;
|
||||
text_layout_.Update(font_);
|
||||
}
|
||||
|
||||
layout_dirty_ = false;
|
||||
text_format_ = nullptr;
|
||||
text_layout_ = nullptr;
|
||||
|
||||
if (text_.empty())
|
||||
return;
|
||||
|
||||
auto renderer = Renderer::GetInstance();
|
||||
|
||||
ThrowIfFailed(
|
||||
renderer->GetD2DDeviceResources()->CreateTextFormat(
|
||||
text_format_,
|
||||
font_,
|
||||
style_
|
||||
)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
renderer->GetD2DDeviceResources()->CreateTextLayout(
|
||||
text_layout_,
|
||||
layout_size_,
|
||||
text_,
|
||||
text_format_,
|
||||
style_
|
||||
)
|
||||
);
|
||||
if (layout_dirty_)
|
||||
{
|
||||
layout_dirty_ = false;
|
||||
text_layout_.Update(text_, style_);
|
||||
SetSize(text_layout_.GetLayoutSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@
|
|||
|
||||
#pragma once
|
||||
#include "Actor.h"
|
||||
#include "Font.hpp"
|
||||
#include "TextStyle.hpp"
|
||||
#include <dwrite.h>
|
||||
#include "../renderer/TextLayout.h"
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
|
|
@ -56,52 +54,16 @@ namespace kiwano
|
|||
virtual ~Text();
|
||||
|
||||
// 获取文本
|
||||
String const& GetText() const;
|
||||
inline String const& GetText() const { return text_; }
|
||||
|
||||
// 获取字体
|
||||
const Font& GetFont() const;
|
||||
inline Font GetFont() const { return font_; }
|
||||
|
||||
// 获取文本样式
|
||||
const TextStyle& GetStyle() const;
|
||||
inline TextStyle GetStyle() const { return style_; }
|
||||
|
||||
// 获取字体族
|
||||
String const& GetFontFamily() const;
|
||||
|
||||
// 获取当前字号
|
||||
float GetFontSize() const;
|
||||
|
||||
// 获取当前字体粗细值
|
||||
unsigned int GetFontWeight() const;
|
||||
|
||||
// 获取文字颜色
|
||||
const Color& GetColor() const;
|
||||
|
||||
// 获取描边颜色
|
||||
const Color& GetOutlineColor() const;
|
||||
|
||||
// 获取描边线宽
|
||||
float GetOutlineWidth() const;
|
||||
|
||||
// 获取描边线相交样式
|
||||
StrokeStyle GetOutlineStroke() const;
|
||||
|
||||
// 获取文本显示行数
|
||||
int GetLineCount();
|
||||
|
||||
// 获取文字布局大小
|
||||
Size const& GetLayoutSize() const;
|
||||
|
||||
// 是否是斜体
|
||||
bool IsItalic() const;
|
||||
|
||||
// 是否显示删除线
|
||||
bool HasStrikethrough() const;
|
||||
|
||||
// 是否显示下划线
|
||||
bool HasUnderline() const;
|
||||
|
||||
// 是否显示描边
|
||||
bool HasOutline() const;
|
||||
// 获取文本布局
|
||||
inline TextLayout GetLayout() const { return text_layout_; }
|
||||
|
||||
// 设置文本
|
||||
void SetText(
|
||||
|
|
@ -143,18 +105,13 @@ namespace kiwano
|
|||
bool val
|
||||
);
|
||||
|
||||
// 打开或关闭文本自动换行(默认为关闭)
|
||||
void SetWrapEnabled(
|
||||
bool wrap
|
||||
);
|
||||
|
||||
// 设置文本自动换行的宽度(默认为 0)
|
||||
void SetWrapWidth(
|
||||
float wrap_width
|
||||
);
|
||||
|
||||
// 设置行间距(默认为 0)
|
||||
void SetLineacingPtr(
|
||||
void SetLineSpacing(
|
||||
float line_spacing
|
||||
);
|
||||
|
||||
|
|
@ -206,16 +163,14 @@ namespace kiwano
|
|||
void OnRender(Renderer* renderer) override;
|
||||
|
||||
protected:
|
||||
void UpdateLayout() const;
|
||||
void UpdateLayout();
|
||||
|
||||
protected:
|
||||
bool format_dirty_;
|
||||
bool layout_dirty_;
|
||||
TextLayout text_layout_;
|
||||
String text_;
|
||||
Font font_;
|
||||
TextStyle style_;
|
||||
|
||||
mutable bool layout_dirty_;
|
||||
mutable Size layout_size_;
|
||||
mutable ComPtr<IDWriteTextFormat> text_format_;
|
||||
mutable ComPtr<IDWriteTextLayout> text_layout_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ namespace kiwano
|
|||
public:
|
||||
Color color; // 颜色
|
||||
TextAlign alignment; // 对齐方式
|
||||
bool wrap; // 打开自动换行
|
||||
float wrap_width; // 自动换行宽度
|
||||
float line_spacing; // 行间距
|
||||
bool underline; // 下划线
|
||||
|
|
@ -51,7 +50,6 @@ namespace kiwano
|
|||
TextStyle()
|
||||
: color(Color::White)
|
||||
, alignment(TextAlign::Left)
|
||||
, wrap(false)
|
||||
, wrap_width(0.f)
|
||||
, line_spacing(0.f)
|
||||
, underline(false)
|
||||
|
|
@ -65,7 +63,6 @@ namespace kiwano
|
|||
TextStyle(
|
||||
Color color,
|
||||
TextAlign alignment = TextAlign::Left,
|
||||
bool wrap = false,
|
||||
float wrap_width = 0.f,
|
||||
float line_spacing = 0.f,
|
||||
bool underline = false,
|
||||
|
|
@ -77,7 +74,6 @@ namespace kiwano
|
|||
)
|
||||
: color(color)
|
||||
, alignment(alignment)
|
||||
, wrap(wrap)
|
||||
, wrap_width(wrap_width)
|
||||
, line_spacing(line_spacing)
|
||||
, underline(underline)
|
||||
|
|
@ -88,4 +84,4 @@ namespace kiwano
|
|||
, outline_stroke(outline_stroke)
|
||||
{}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,7 +146,9 @@ namespace kiwano
|
|||
if (render_border_enabled_)
|
||||
{
|
||||
if (curr_scene_)
|
||||
{
|
||||
curr_scene_->RenderBorder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,16 +51,14 @@ namespace kiwano
|
|||
|
||||
HRESULT CreateTextFormat(
|
||||
_Out_ ComPtr<IDWriteTextFormat>& text_format,
|
||||
_In_ Font const& font,
|
||||
_In_ TextStyle const& text_style
|
||||
_In_ Font const& font
|
||||
) const override;
|
||||
|
||||
HRESULT CreateTextLayout(
|
||||
_Out_ ComPtr<IDWriteTextLayout>& text_layout,
|
||||
_Out_ Size& layout_size,
|
||||
_In_ String const& text,
|
||||
_In_ ComPtr<IDWriteTextFormat> const& text_format,
|
||||
_In_ TextStyle const& text_style
|
||||
_In_ TextStyle const& text_style,
|
||||
_In_ ComPtr<IDWriteTextFormat> const& text_format
|
||||
) const override;
|
||||
|
||||
HRESULT SetD2DDevice(
|
||||
|
|
@ -460,13 +458,12 @@ namespace kiwano
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat> & text_format,
|
||||
_In_ Font const & font, _In_ TextStyle const & text_style) const
|
||||
HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat> & text_format, _In_ Font const & font) const
|
||||
{
|
||||
if (!dwrite_factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
ComPtr<IDWriteTextFormat> text_format_tmp;
|
||||
ComPtr<IDWriteTextFormat> output;
|
||||
HRESULT hr = dwrite_factory_->CreateTextFormat(
|
||||
font.family.c_str(),
|
||||
nullptr,
|
||||
|
|
@ -475,44 +472,27 @@ namespace kiwano
|
|||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
font.size,
|
||||
L"",
|
||||
&text_format_tmp
|
||||
&output
|
||||
);
|
||||
|
||||
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;
|
||||
text_format = output;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout> & text_layout,
|
||||
_Out_ Size& layout_size, _In_ String const & text, _In_ ComPtr<IDWriteTextFormat> const& text_format,
|
||||
_In_ TextStyle const & text_style) const
|
||||
HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout> & text_layout, _In_ String const & text,
|
||||
_In_ TextStyle const & text_style, _In_ ComPtr<IDWriteTextFormat> const& text_format) const
|
||||
{
|
||||
if (!dwrite_factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
text_layout = nullptr;
|
||||
|
||||
HRESULT hr;
|
||||
ComPtr<IDWriteTextLayout> text_layout_tmp;
|
||||
ComPtr<IDWriteTextLayout> output;
|
||||
UINT32 length = static_cast<UINT32>(text.length());
|
||||
|
||||
if (text_style.wrap)
|
||||
if (text_style.wrap_width > 0)
|
||||
{
|
||||
hr = dwrite_factory_->CreateTextLayout(
|
||||
text.c_str(),
|
||||
|
|
@ -520,7 +500,7 @@ namespace kiwano
|
|||
text_format.get(),
|
||||
text_style.wrap_width,
|
||||
0,
|
||||
&text_layout_tmp
|
||||
&output
|
||||
);
|
||||
}
|
||||
else
|
||||
|
|
@ -531,53 +511,70 @@ namespace kiwano
|
|||
text_format.get(),
|
||||
0,
|
||||
0,
|
||||
&text_layout_tmp
|
||||
&output
|
||||
);
|
||||
}
|
||||
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
if (SUCCEEDED(hr))
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (text_style.line_spacing == 0.f)
|
||||
{
|
||||
hr = text_layout_tmp->GetMetrics(&metrics);
|
||||
hr = output->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
else
|
||||
{
|
||||
text_layout_tmp = nullptr;
|
||||
hr = dwrite_factory_->CreateTextLayout(
|
||||
text.c_str(),
|
||||
length,
|
||||
text_format.get(),
|
||||
metrics.width,
|
||||
0,
|
||||
&text_layout_tmp
|
||||
hr = output->SetLineSpacing(
|
||||
DWRITE_LINE_SPACING_METHOD_UNIFORM,
|
||||
text_style.line_spacing,
|
||||
text_style.line_spacing * 0.8f
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
text_layout_tmp->GetMetrics(&metrics);
|
||||
hr = output->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(text_style.alignment));
|
||||
}
|
||||
|
||||
if (text_style.wrap)
|
||||
{
|
||||
layout_size = Size(metrics.layoutWidth, metrics.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
layout_size = Size(metrics.width, metrics.height);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = output->SetWordWrapping((text_style.wrap_width > 0) ? DWRITE_WORD_WRAPPING_WRAP : DWRITE_WORD_WRAPPING_NO_WRAP);
|
||||
}
|
||||
|
||||
DWRITE_TEXT_RANGE range = { 0, length };
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (text_style.underline)
|
||||
{
|
||||
text_layout_tmp->SetUnderline(true, range);
|
||||
hr = output->SetUnderline(true, { 0, length });
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (text_style.strikethrough)
|
||||
{
|
||||
text_layout_tmp->SetStrikethrough(true, range);
|
||||
output->SetStrikethrough(true, { 0, length });
|
||||
}
|
||||
text_layout = text_layout_tmp;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Fix the layout width when the text does not wrap
|
||||
if (!(text_style.wrap_width > 0))
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
hr = output->GetMetrics(&metrics);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = output->SetMaxWidth(metrics.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
text_layout = output;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,16 +48,14 @@ namespace kiwano
|
|||
|
||||
virtual HRESULT CreateTextFormat(
|
||||
_Out_ ComPtr<IDWriteTextFormat>& text_format,
|
||||
_In_ Font const& font,
|
||||
_In_ TextStyle const& text_style
|
||||
_In_ Font const& font
|
||||
) const = 0;
|
||||
|
||||
virtual HRESULT CreateTextLayout(
|
||||
_Out_ ComPtr<IDWriteTextLayout>& text_layout,
|
||||
_Out_ Size& layout_size,
|
||||
_In_ String const& text,
|
||||
_In_ ComPtr<IDWriteTextFormat> const& text_format,
|
||||
_In_ TextStyle const& text_style
|
||||
_In_ TextStyle const& text_style,
|
||||
_In_ ComPtr<IDWriteTextFormat> const& text_format
|
||||
) const = 0;
|
||||
|
||||
virtual ID2D1StrokeStyle* GetStrokeStyle(StrokeStyle stroke) const = 0;
|
||||
|
|
|
|||
|
|
@ -245,6 +245,55 @@ namespace kiwano
|
|||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Renderer::CreateTextFormat(TextFormat& format, Font const& font)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!d2d_res_)
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
}
|
||||
|
||||
ComPtr<IDWriteTextFormat> output;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d2d_res_->CreateTextFormat(output, font);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
format.SetTextFormat(output);
|
||||
}
|
||||
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Renderer::CreateTextLayout(TextLayout& layout, String const& text, TextStyle const& style, TextFormat const& format)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!d2d_res_)
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
}
|
||||
|
||||
ComPtr<IDWriteTextLayout> output;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d2d_res_->CreateTextLayout(
|
||||
output,
|
||||
text,
|
||||
style,
|
||||
format.GetTextFormat()
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
layout.SetTextLayout(output);
|
||||
}
|
||||
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Renderer::CreateLineGeometry(Geometry& geo, Point const& begin_pos, Point const& end_pos)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
|
@ -500,7 +549,7 @@ namespace kiwano
|
|||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Renderer::DrawTextLayout(ComPtr<IDWriteTextLayout> const& text_layout)
|
||||
void Renderer::DrawTextLayout(TextLayout const& layout)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!text_renderer_)
|
||||
|
|
@ -510,7 +559,19 @@ namespace kiwano
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = text_layout->Draw(nullptr, text_renderer_.get(), 0, 0);
|
||||
SetTextStyle(
|
||||
opacity_,
|
||||
layout.GetTextStyle().color,
|
||||
layout.GetTextStyle().outline,
|
||||
layout.GetTextStyle().outline_color,
|
||||
layout.GetTextStyle().outline_width,
|
||||
layout.GetTextStyle().outline_stroke
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = layout.GetTextLayout()->Draw(nullptr, text_renderer_.get(), 0, 0);
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
}
|
||||
|
|
@ -676,7 +737,7 @@ namespace kiwano
|
|||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!text_renderer_ || !d3d_res_)
|
||||
if (!text_renderer_)
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,10 @@
|
|||
#include "../base/Component.h"
|
||||
#include "../base/Resource.h"
|
||||
#include "../2d/include-forwards.h"
|
||||
#include "../2d/Font.hpp"
|
||||
#include "../2d/TextStyle.hpp"
|
||||
#include "helper.hpp"
|
||||
#include "Image.h"
|
||||
#include "Geometry.h"
|
||||
#include "TextLayout.h"
|
||||
#include "TextRenderer.h"
|
||||
|
||||
#if defined(KGE_USE_DIRECTX10)
|
||||
|
|
@ -51,11 +50,44 @@ namespace kiwano
|
|||
{
|
||||
KGE_DECLARE_SINGLETON(Renderer);
|
||||
|
||||
public:
|
||||
// 设置清屏颜色
|
||||
void SetClearColor(
|
||||
Color const& clear_color
|
||||
);
|
||||
|
||||
// 设置抗锯齿模式
|
||||
void SetAntialiasMode(
|
||||
bool enabled
|
||||
);
|
||||
|
||||
// 设置文字抗锯齿模式
|
||||
void SetTextAntialiasMode(
|
||||
TextAntialias mode
|
||||
);
|
||||
|
||||
// 开启或关闭垂直同步
|
||||
void SetVSyncEnabled(
|
||||
bool enabled
|
||||
);
|
||||
|
||||
public:
|
||||
void CreateLayer(
|
||||
ComPtr<ID2D1Layer>& layer
|
||||
);
|
||||
|
||||
void CreateTextFormat(
|
||||
TextFormat& format,
|
||||
Font const& font
|
||||
);
|
||||
|
||||
void CreateTextLayout(
|
||||
TextLayout& layout,
|
||||
String const& text,
|
||||
TextStyle const& style,
|
||||
TextFormat const& format
|
||||
);
|
||||
|
||||
void CreateLineGeometry(
|
||||
Geometry& geo,
|
||||
Point const& begin_pos,
|
||||
|
|
@ -114,30 +146,9 @@ namespace kiwano
|
|||
);
|
||||
|
||||
void DrawTextLayout(
|
||||
ComPtr<IDWriteTextLayout> const& text_layout
|
||||
TextLayout const& layout
|
||||
);
|
||||
|
||||
// 设置清屏颜色
|
||||
void SetClearColor(
|
||||
Color const& clear_color
|
||||
);
|
||||
|
||||
// 设置抗锯齿模式
|
||||
void SetAntialiasMode(
|
||||
bool enabled
|
||||
);
|
||||
|
||||
// 设置文字抗锯齿模式
|
||||
void SetTextAntialiasMode(
|
||||
TextAntialias mode
|
||||
);
|
||||
|
||||
// 开启或关闭垂直同步
|
||||
void SetVSyncEnabled(
|
||||
bool enabled
|
||||
);
|
||||
|
||||
// 设置画笔透明度
|
||||
void SetOpacity(
|
||||
float opacity
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright (c) 2016-2018 Kiwano - 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 "TextLayout.h"
|
||||
#include "Renderer.h"
|
||||
#include "../base/Logger.h"
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
//
|
||||
// TextFormat
|
||||
//
|
||||
|
||||
TextFormat::TextFormat()
|
||||
{
|
||||
}
|
||||
|
||||
TextFormat::TextFormat(Font const& font)
|
||||
{
|
||||
Update(font);
|
||||
}
|
||||
|
||||
void TextFormat::Update(Font const& font)
|
||||
{
|
||||
Renderer::GetInstance()->CreateTextFormat(*this, font);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TextLayout
|
||||
//
|
||||
|
||||
TextLayout::TextLayout()
|
||||
{
|
||||
}
|
||||
|
||||
TextLayout::TextLayout(String const& text, Font const& font, TextStyle const& style)
|
||||
{
|
||||
Update(font);
|
||||
Update(text, style);
|
||||
}
|
||||
|
||||
void TextLayout::Update(Font const& font)
|
||||
{
|
||||
text_format_.Update(font);
|
||||
}
|
||||
|
||||
void TextLayout::Update(String const& text, TextStyle const& style)
|
||||
{
|
||||
style_ = style;
|
||||
|
||||
if (text.empty())
|
||||
{
|
||||
text_format_.SetTextFormat(nullptr);
|
||||
SetTextLayout(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
Renderer::GetInstance()->CreateTextLayout(
|
||||
*this,
|
||||
text,
|
||||
style,
|
||||
text_format_
|
||||
);
|
||||
}
|
||||
|
||||
UINT32 TextLayout::GetLineCount()
|
||||
{
|
||||
if (text_layout_)
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
if (SUCCEEDED(text_layout_->GetMetrics(&metrics)))
|
||||
{
|
||||
return metrics.lineCount;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Size TextLayout::GetLayoutSize() const
|
||||
{
|
||||
if (text_layout_)
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
if (SUCCEEDED(text_layout_->GetMetrics(&metrics)))
|
||||
{
|
||||
return (metrics.layoutWidth > 0) ? Size(metrics.layoutWidth, metrics.height) : Size(metrics.width, metrics.height);
|
||||
}
|
||||
}
|
||||
return Size();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright (c) 2016-2018 Kiwano - 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 "D2DDeviceResources.h"
|
||||
#include "../2d/Font.hpp"
|
||||
#include "../2d/TextStyle.hpp"
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
// Îı¾¸ñʽ»¯
|
||||
class KGE_API TextFormat
|
||||
{
|
||||
public:
|
||||
TextFormat();
|
||||
|
||||
TextFormat(Font const& font);
|
||||
|
||||
void Update(Font const& font);
|
||||
|
||||
public:
|
||||
inline ComPtr<IDWriteTextFormat> GetTextFormat() const { return text_format_; }
|
||||
|
||||
inline void SetTextFormat(ComPtr<IDWriteTextFormat> format) { text_format_ = format; }
|
||||
|
||||
protected:
|
||||
ComPtr<IDWriteTextFormat> text_format_;
|
||||
};
|
||||
|
||||
|
||||
// Îı¾²¼¾Ö
|
||||
class KGE_API TextLayout
|
||||
{
|
||||
public:
|
||||
TextLayout();
|
||||
|
||||
TextLayout(String const& text, Font const& font, TextStyle const& style);
|
||||
|
||||
void Update(Font const& font);
|
||||
|
||||
void Update(String const& text, TextStyle const& style);
|
||||
|
||||
UINT32 GetLineCount();
|
||||
|
||||
Size GetLayoutSize() const;
|
||||
|
||||
inline TextStyle const& GetTextStyle() const { return style_; }
|
||||
|
||||
public:
|
||||
inline TextFormat GetTextFormat() const { return text_format_; }
|
||||
|
||||
inline ComPtr<IDWriteTextLayout> GetTextLayout() const { return text_layout_; }
|
||||
|
||||
inline void SetTextLayout(ComPtr<IDWriteTextLayout> layout) { text_layout_ = layout; }
|
||||
|
||||
inline operator bool() const { return static_cast<bool>(text_layout_); }
|
||||
|
||||
protected:
|
||||
TextStyle style_;
|
||||
TextFormat text_format_;
|
||||
ComPtr<IDWriteTextLayout> text_layout_;
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue