Update TextLayout

This commit is contained in:
Nomango 2020-02-17 17:01:12 +08:00
parent f28d542551
commit 72e176a314
5 changed files with 77 additions and 70 deletions

View File

@ -106,21 +106,13 @@ void TextActor::SetTextLayout(TextLayoutPtr layout)
void TextActor::SetText(String const& text)
{
if (text_ != text)
{
text_ = text;
layout_->Reset(text_, style_);
}
layout_->Reset(text, style_);
}
void TextActor::SetStyle(const TextStyle& style)
{
style_ = style;
if (!text_.empty())
{
layout_->Reset(text_, style);
}
layout_->Reset(style);
}
void TextActor::SetFont(FontPtr font)
@ -128,10 +120,7 @@ void TextActor::SetFont(FontPtr font)
if (style_.font != font)
{
style_.font = font;
if (!text_.empty())
{
layout_->SetFont(font, { 0, text_.length() });
}
layout_->SetFont(font, { 0, layout_->GetContentLength() });
}
}
@ -140,10 +129,7 @@ void TextActor::SetFontFamily(String const& family)
if (style_.font_family != family)
{
style_.font_family = family;
if (!text_.empty())
{
layout_->SetFontFamily(family, { 0, text_.length() });
}
layout_->SetFontFamily(family, { 0, layout_->GetContentLength() });
}
}
@ -152,10 +138,7 @@ void TextActor::SetFontSize(float size)
if (style_.font_size != size)
{
style_.font_size = size;
if (!text_.empty())
{
layout_->SetFontSize(size, { 0, text_.length() });
}
layout_->SetFontSize(size, { 0, layout_->GetContentLength() });
}
}
@ -164,10 +147,7 @@ void TextActor::SetFontWeight(uint32_t weight)
if (style_.font_weight != weight)
{
style_.font_weight = weight;
if (!text_.empty())
{
layout_->SetFontWeight(weight, { 0, text_.length() });
}
layout_->SetFontWeight(weight, { 0, layout_->GetContentLength() });
}
}
@ -176,10 +156,7 @@ void TextActor::SetItalic(bool italic)
if (style_.italic != italic)
{
style_.italic = italic;
if (!text_.empty())
{
layout_->SetItalic(italic, { 0, text_.length() });
}
layout_->SetItalic(italic, { 0, layout_->GetContentLength() });
}
}
@ -188,10 +165,7 @@ void TextActor::SetUnderline(bool enable)
if (style_.show_underline != enable)
{
style_.show_underline = enable;
if (!text_.empty())
{
layout_->SetUnderline(enable, { 0, text_.length() });
}
layout_->SetUnderline(enable, { 0, layout_->GetContentLength() });
}
}
@ -200,10 +174,7 @@ void TextActor::SetStrikethrough(bool enable)
if (style_.show_strikethrough != enable)
{
style_.show_strikethrough = enable;
if (!text_.empty())
{
layout_->SetStrikethrough(enable, { 0, text_.length() });
}
layout_->SetStrikethrough(enable, { 0, layout_->GetContentLength() });
}
}
@ -212,11 +183,8 @@ void TextActor::SetWrapWidth(float wrap_width)
if (style_.wrap_width != wrap_width)
{
style_.wrap_width = wrap_width;
if (!text_.empty())
{
layout_->SetWrapWidth(wrap_width);
}
}
}
void TextActor::SetLineSpacing(float line_spacing)
@ -224,11 +192,8 @@ void TextActor::SetLineSpacing(float line_spacing)
if (style_.line_spacing != line_spacing)
{
style_.line_spacing = line_spacing;
if (!text_.empty())
{
layout_->SetLineSpacing(line_spacing);
}
}
}
void TextActor::SetAlignment(TextAlign align)
@ -236,11 +201,8 @@ void TextActor::SetAlignment(TextAlign align)
if (style_.alignment != align)
{
style_.alignment = align;
if (!text_.empty())
{
layout_->SetAlignment(align);
}
}
}
void TextActor::SetFillBrush(BrushPtr brush)
@ -295,14 +257,7 @@ void TextActor::ForceUpdateLayout()
KGE_ASSERT(layout_);
layout_->UpdateWhenDirty();
if (text_.empty())
{
SetSize(Size());
}
else
{
SetSize(layout_->GetSize());
}
}
} // namespace kiwano

View File

@ -176,7 +176,6 @@ protected:
bool CheckVisibility(RenderContext& ctx) const override;
private:
String text_;
TextStyle style_;
TextLayoutPtr layout_;
};
@ -185,7 +184,8 @@ private:
inline const String& TextActor::GetText() const
{
return text_;
KGE_ASSERT(layout_);
return layout_->GetContent();
}
inline FontPtr TextActor::GetFont() const

View File

@ -203,8 +203,7 @@ STDMETHODIMP TextRenderer::DrawGlyphRun(__maybenull void* clientDrawingContext,
if (SUCCEEDED(hr))
{
pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(),
fDefaultOutlineWidth_ * 2, // twice width for widening
pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_,
pDefaultStrokeStyle_.Get());
++cPrimitivesCount_;
@ -276,7 +275,7 @@ STDMETHODIMP TextRenderer::DrawUnderline(__maybenull void* clientDrawingContext,
if (SUCCEEDED(hr) && pDefaultOutlineBrush_)
{
pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_ * 2,
pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_,
pDefaultStrokeStyle_.Get());
++cPrimitivesCount_;
@ -332,7 +331,7 @@ STDMETHODIMP TextRenderer::DrawStrikethrough(__maybenull void* clientDrawingCont
if (SUCCEEDED(hr) && pDefaultOutlineBrush_)
{
pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_ * 2,
pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_,
pDefaultStrokeStyle_.Get());
++cPrimitivesCount_;

View File

@ -27,6 +27,7 @@
namespace kiwano
{
TextLayoutPtr TextLayout::Create()
{
TextLayoutPtr ptr = new (std::nothrow) TextLayout;
@ -51,9 +52,10 @@ TextLayout::TextLayout()
void TextLayout::Reset(const String& content, const TextStyle& style)
{
if (!content.empty())
content_ = content;
if (!content_.empty())
{
Renderer::GetInstance().CreateTextLayout(*this, content, style);
Renderer::GetInstance().CreateTextLayout(*this, content_, style);
SetAlignment(style.alignment);
SetWrapWidth(style.wrap_width);
@ -64,17 +66,16 @@ void TextLayout::Reset(const String& content, const TextStyle& style)
SetDefaultOutlineStrokeStyle(style.outline_stroke);
if (style.show_underline)
SetUnderline(style.show_underline, { 0, content.length() });
SetUnderline(style.show_underline, { 0, content_.length() });
if (style.show_strikethrough)
SetStrikethrough(style.show_strikethrough, { 0, content.length() });
SetStrikethrough(style.show_strikethrough, { 0, content_.length() });
}
else
{
Clear();
}
content_ = content;
SetDirtyFlag(DirtyFlag::Dirty);
}
@ -93,6 +94,8 @@ uint32_t TextLayout::GetLineCount() const
void TextLayout::SetFont(FontPtr font, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this);
@ -115,6 +118,8 @@ void TextLayout::SetFont(FontPtr font, TextRange range)
void TextLayout::SetFontFamily(String const& family, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this);
@ -137,6 +142,8 @@ void TextLayout::SetFontFamily(String const& family, TextRange range)
void TextLayout::SetFontSize(float size, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this);
@ -157,6 +164,8 @@ void TextLayout::SetFontSize(float size, TextRange range)
void TextLayout::SetFontWeight(uint32_t weight, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this);
@ -179,6 +188,8 @@ void TextLayout::SetFontWeight(uint32_t weight, TextRange range)
void TextLayout::SetItalic(bool italic, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this);
@ -201,6 +212,8 @@ void TextLayout::SetItalic(bool italic, TextRange range)
void TextLayout::SetUnderline(bool enable, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this);
@ -221,6 +234,8 @@ void TextLayout::SetUnderline(bool enable, TextRange range)
void TextLayout::SetStrikethrough(bool enable, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this);
@ -241,6 +256,8 @@ void TextLayout::SetStrikethrough(bool enable, TextRange range)
void TextLayout::SetFillBrush(BrushPtr brush, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this);
@ -262,6 +279,8 @@ void TextLayout::SetFillBrush(BrushPtr brush, TextRange range)
void TextLayout::SetOutlineBrush(BrushPtr brush, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
// TODO
@ -275,6 +294,8 @@ void TextLayout::SetOutlineBrush(BrushPtr brush, TextRange range)
void TextLayout::SetOutlineStrokeStyle(StrokeStylePtr stroke, TextRange range)
{
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
// TODO
@ -385,8 +406,12 @@ bool TextLayout::UpdateWhenDirty()
{
SetDirtyFlag(DirtyFlag::Clean);
line_count_ = 0;
size_ = Size();
auto native = NativePtr::Get<IDWriteTextLayout>(this);
KGE_ASSERT(native);
if (content_.empty() || !native)
return true;
HRESULT hr = S_OK;

View File

@ -60,12 +60,25 @@ public:
/// @brief 清空文本布局
void Clear();
/// \~chinese
/// @brief 重设文本布局
/// @param style 文本样式
void Reset(const TextStyle& style);
/// \~chinese
/// @brief 重设文本布局
/// @param content 文字内容
/// @param style 文本样式
void Reset(const String& content, const TextStyle& style);
/// \~chinese
/// @brief 获取文字内容
String GetContent() const;
/// \~chinese
/// @brief 获取文字内容的长度
uint32_t GetContentLength() const;
/// \~chinese
/// @brief 获取文本布局大小
Size GetSize() const;
@ -225,6 +238,21 @@ inline void TextLayout::Clear()
ResetNativePointer();
}
inline void TextLayout::Reset(const TextStyle& style)
{
this->Reset(content_, style);
}
inline String TextLayout::GetContent() const
{
return content_;
}
inline uint32_t TextLayout::GetContentLength() const
{
return uint32_t(content_.size());
}
inline TextLayout::DirtyFlag TextLayout::GetDirtyFlag() const
{
return dirty_flag_;