[deploy] pref: support text actor pre render mode

This commit is contained in:
Nomango 2023-09-13 22:52:00 +08:00
parent 76b3b4fbed
commit 6f880db21e
2 changed files with 100 additions and 15 deletions

View File

@ -25,7 +25,13 @@
namespace kiwano
{
TextActor::TextActor() {}
// Ô¤Áô³öÃè±ßµÄ¿Õ¼ä
const Point cached_texture_offset = Point{ 5, 5 };
TextActor::TextActor()
: is_cache_dirty_(false)
{
}
TextActor::TextActor(const String& text)
: TextActor(text, TextStyle())
@ -33,6 +39,7 @@ TextActor::TextActor(const String& text)
}
TextActor::TextActor(const String& text, const TextStyle& style)
: TextActor()
{
SetStyle(style);
SetText(text);
@ -43,12 +50,22 @@ TextActor::~TextActor() {}
void TextActor::OnRender(RenderContext& ctx)
{
if (layout_)
{
if (texture_cached_)
{
Rect dest_rect = GetBounds();
dest_rect.left_top -= cached_texture_offset;
dest_rect.right_bottom -= cached_texture_offset;
ctx.DrawTexture(*texture_cached_, nullptr, &dest_rect);
}
else
{
ctx.SetCurrentBrush(fill_brush_);
ctx.SetCurrentStrokeStyle(outline_stroke_);
ctx.DrawTextLayout(*layout_, Point{}, outline_brush_);
}
}
}
Size TextActor::GetSize() const
{
@ -67,6 +84,7 @@ void TextActor::SetText(const String& text)
{
layout_->Reset(text, style_);
content_ = text;
is_cache_dirty_ = true;
}
catch (SystemError& e)
{
@ -76,6 +94,7 @@ void TextActor::SetText(const String& text)
void TextActor::SetStyle(const TextStyle& style)
{
is_cache_dirty_ = true;
style_ = style;
if (layout_)
layout_->Reset(content_, style);
@ -85,6 +104,7 @@ void TextActor::SetFont(FontPtr font)
{
if (style_.font != font)
{
is_cache_dirty_ = true;
style_.font = font;
if (layout_)
layout_->SetFont(font);
@ -95,6 +115,7 @@ void TextActor::SetUnderline(bool enable)
{
if (style_.show_underline != enable)
{
is_cache_dirty_ = true;
style_.show_underline = enable;
if (layout_)
layout_->SetUnderline(enable);
@ -105,6 +126,7 @@ void TextActor::SetStrikethrough(bool enable)
{
if (style_.show_strikethrough != enable)
{
is_cache_dirty_ = true;
style_.show_strikethrough = enable;
if (layout_)
layout_->SetStrikethrough(enable);
@ -115,6 +137,7 @@ void TextActor::SetWrapWidth(float wrap_width)
{
if (style_.wrap_width != wrap_width)
{
is_cache_dirty_ = true;
style_.wrap_width = wrap_width;
if (layout_)
layout_->SetWrapWidth(wrap_width);
@ -125,6 +148,7 @@ void TextActor::SetLineSpacing(float line_spacing)
{
if (style_.line_spacing != line_spacing)
{
is_cache_dirty_ = true;
style_.line_spacing = line_spacing;
if (layout_)
layout_->SetLineSpacing(line_spacing);
@ -135,6 +159,7 @@ void TextActor::SetAlignment(TextAlign align)
{
if (style_.alignment != align)
{
is_cache_dirty_ = true;
style_.alignment = align;
if (layout_)
layout_->SetAlignment(align);
@ -144,22 +169,26 @@ void TextActor::SetAlignment(TextAlign align)
void TextActor::SetFillBrush(BrushPtr brush)
{
fill_brush_ = brush;
is_cache_dirty_ = true;
}
void TextActor::SetOutlineBrush(BrushPtr brush)
{
outline_brush_ = brush;
is_cache_dirty_ = true;
}
void TextActor::SetOutlineStrokeStyle(StrokeStylePtr stroke)
{
outline_stroke_ = stroke;
is_cache_dirty_ = true;
}
void TextActor::SetFillColor(const Color& color)
{
if (fill_brush_)
{
is_cache_dirty_ = true;
fill_brush_->SetColor(color);
}
else
@ -172,6 +201,7 @@ void TextActor::SetOutlineColor(const Color& outline_color)
{
if (outline_brush_)
{
is_cache_dirty_ = true;
outline_brush_->SetColor(outline_color);
}
else
@ -184,11 +214,26 @@ void TextActor::SetTextLayout(TextLayoutPtr layout)
{
if (layout_ != layout)
{
is_cache_dirty_ = true;
layout_ = layout;
ForceUpdateLayout();
}
}
void TextActor::SetPreRenderEnabled(bool enable)
{
if (enable)
{
texture_cached_ = MakePtr<Texture>();
}
else
{
texture_cached_ = nullptr;
}
render_ctx_ = nullptr;
is_cache_dirty_ = true;
}
void TextActor::Update(Duration dt)
{
this->UpdateDirtyLayout();
@ -206,6 +251,10 @@ void TextActor::UpdateDirtyLayout()
{
ForceUpdateLayout();
}
else if (is_cache_dirty_)
{
UpdateCachedTexture();
}
}
void TextActor::ForceUpdateLayout()
@ -214,6 +263,7 @@ void TextActor::ForceUpdateLayout()
{
layout_->UpdateIfDirty();
SetSize(layout_->GetSize());
UpdateCachedTexture();
}
else
{
@ -221,4 +271,30 @@ void TextActor::ForceUpdateLayout()
}
}
void TextActor::UpdateCachedTexture()
{
if (!texture_cached_)
{
return;
}
const auto expectedSize = layout_->GetSize() + cached_texture_offset * 2;
if (!render_ctx_)
{
render_ctx_ = RenderContext::Create(*texture_cached_, expectedSize);
}
else if (render_ctx_->GetSize() != expectedSize)
{
render_ctx_->Resize(expectedSize);
}
render_ctx_->BeginDraw();
render_ctx_->Clear();
render_ctx_->SetCurrentBrush(fill_brush_);
render_ctx_->SetCurrentStrokeStyle(outline_stroke_);
render_ctx_->DrawTextLayout(*layout_, cached_texture_offset, outline_brush_);
render_ctx_->EndDraw();
is_cache_dirty_ = false;
}
} // namespace kiwano

View File

@ -142,6 +142,10 @@ public:
/// @brief 设置文本布局
void SetTextLayout(TextLayoutPtr layout);
/// \~chinese
/// @brief 设置预渲染模式,在描边等情况下会有更好的性能
void SetPreRenderEnabled(bool enable);
/// \~chinese
/// @brief 更新脏文字布局
/// @details 仅当文字布局脏时更新
@ -159,13 +163,18 @@ protected:
bool CheckVisibility(RenderContext& ctx) const override;
void UpdateCachedTexture();
private:
bool is_cache_dirty_;
String content_;
TextStyle style_;
TextLayoutPtr layout_;
BrushPtr fill_brush_;
BrushPtr outline_brush_;
StrokeStylePtr outline_stroke_;
TexturePtr texture_cached_;
RenderContextPtr render_ctx_;
};
/** @} */