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

View File

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