update Font

This commit is contained in:
Nomango 2020-08-04 16:31:20 +08:00
parent 0e5f0a5be9
commit 4eb5dd007d
11 changed files with 223 additions and 432 deletions

View File

@ -60,9 +60,7 @@ DebugActor::DebugActor()
BrushPtr fill_brush = MakePtr<Brush>(); BrushPtr fill_brush = MakePtr<Brush>();
fill_brush->SetColor(Color::White); fill_brush->SetColor(Color::White);
debug_text_style_.font = new Font("Arial"); debug_text_style_.font = new Font("Arial", 16.0f, FontWeight::Normal);
debug_text_style_.font_size = 16.f;
debug_text_style_.font_weight = FontWeight::Normal;
debug_text_style_.line_spacing = 20.f; debug_text_style_.line_spacing = 20.f;
debug_text_style_.fill_brush = fill_brush; debug_text_style_.fill_brush = fill_brush;

View File

@ -64,6 +64,7 @@ void TextActor::SetText(const String& text)
try try
{ {
layout_->Reset(text, style_); layout_->Reset(text, style_);
content_ = text;
} }
catch (SystemError& e) catch (SystemError& e)
{ {
@ -75,7 +76,7 @@ void TextActor::SetStyle(const TextStyle& style)
{ {
style_ = style; style_ = style;
if (layout_) if (layout_)
layout_->Reset(style); layout_->Reset(content_, style);
} }
void TextActor::SetFont(FontPtr font) void TextActor::SetFont(FontPtr font)
@ -84,37 +85,7 @@ void TextActor::SetFont(FontPtr font)
{ {
style_.font = font; style_.font = font;
if (layout_) if (layout_)
layout_->SetFont(font, { 0, layout_->GetContentLength() }); layout_->SetFont(font);
}
}
void TextActor::SetFontSize(float size)
{
if (style_.font_size != size)
{
style_.font_size = size;
if (layout_)
layout_->SetFontSize(size, { 0, layout_->GetContentLength() });
}
}
void TextActor::SetFontWeight(uint32_t weight)
{
if (style_.font_weight != weight)
{
style_.font_weight = weight;
if (layout_)
layout_->SetFontWeight(weight, { 0, layout_->GetContentLength() });
}
}
void TextActor::SetItalic(bool italic)
{
if (style_.italic != italic)
{
style_.italic = italic;
if (layout_)
layout_->SetItalic(italic, { 0, layout_->GetContentLength() });
} }
} }
@ -124,7 +95,7 @@ void TextActor::SetUnderline(bool enable)
{ {
style_.show_underline = enable; style_.show_underline = enable;
if (layout_) if (layout_)
layout_->SetUnderline(enable, { 0, layout_->GetContentLength() }); layout_->SetUnderline(enable);
} }
} }
@ -134,7 +105,7 @@ void TextActor::SetStrikethrough(bool enable)
{ {
style_.show_strikethrough = enable; style_.show_strikethrough = enable;
if (layout_) if (layout_)
layout_->SetStrikethrough(enable, { 0, layout_->GetContentLength() }); layout_->SetStrikethrough(enable);
} }
} }
@ -174,7 +145,7 @@ void TextActor::SetFillBrush(BrushPtr brush)
{ {
style_.fill_brush = brush; style_.fill_brush = brush;
if (layout_) if (layout_)
layout_->SetDefaultFillBrush(brush); layout_->SetFillBrush(brush);
} }
} }
@ -184,7 +155,7 @@ void TextActor::SetOutlineBrush(BrushPtr brush)
{ {
style_.outline_brush = brush; style_.outline_brush = brush;
if (layout_) if (layout_)
layout_->SetDefaultOutlineBrush(brush); layout_->SetOutlineBrush(brush);
} }
} }
@ -194,7 +165,7 @@ void TextActor::SetOutlineStrokeStyle(StrokeStylePtr stroke)
{ {
style_.outline_stroke = stroke; style_.outline_stroke = stroke;
if (layout_) if (layout_)
layout_->SetDefaultOutlineStrokeStyle(stroke); layout_->SetOutlineStrokeStyle(stroke);
} }
} }
@ -244,7 +215,7 @@ bool TextActor::CheckVisibility(RenderContext& ctx) const
void TextActor::UpdateDirtyLayout() void TextActor::UpdateDirtyLayout()
{ {
if (layout_ && layout_->UpdateWhenDirty()) if (layout_ && layout_->UpdateIfDirty())
{ {
ForceUpdateLayout(); ForceUpdateLayout();
} }
@ -254,7 +225,7 @@ void TextActor::ForceUpdateLayout()
{ {
if (layout_) if (layout_)
{ {
layout_->UpdateWhenDirty(); layout_->UpdateIfDirty();
SetSize(layout_->GetSize()); SetSize(layout_->GetSize());
} }
else else

View File

@ -98,14 +98,6 @@ public:
/// @brief 设置字体 /// @brief 设置字体
void SetFont(FontPtr font); void SetFont(FontPtr font);
/// \~chinese
/// @brief 设置字号(默认值为 18
void SetFontSize(float size);
/// \~chinese
/// @brief 设置字体粗细值(默认值为 FontWeight::Normal
void SetFontWeight(uint32_t weight);
/// \~chinese /// \~chinese
/// @brief 设置文字填充画刷 /// @brief 设置文字填充画刷
void SetFillBrush(BrushPtr brush); void SetFillBrush(BrushPtr brush);
@ -114,10 +106,6 @@ public:
/// @brief 设置文字填充颜色(默认值为 Color::White /// @brief 设置文字填充颜色(默认值为 Color::White
void SetFillColor(const Color& color); void SetFillColor(const Color& color);
/// \~chinese
/// @brief 设置文字斜体(默认值为 false
void SetItalic(bool italic);
/// \~chinese /// \~chinese
/// @brief 设置文本自动换行的宽度(默认为 0 /// @brief 设置文本自动换行的宽度(默认为 0
void SetWrapWidth(float wrap_width); void SetWrapWidth(float wrap_width);
@ -172,6 +160,7 @@ protected:
bool CheckVisibility(RenderContext& ctx) const override; bool CheckVisibility(RenderContext& ctx) const override;
private: private:
String content_;
TextStyle style_; TextStyle style_;
TextLayoutPtr layout_; TextLayoutPtr layout_;
}; };
@ -180,11 +169,7 @@ private:
inline String TextActor::GetText() const inline String TextActor::GetText() const
{ {
if (layout_) return content_;
{
return layout_->GetContent();
}
return String();
} }
inline FontPtr TextActor::GetFont() const inline FontPtr TextActor::GetFont() const

View File

@ -126,9 +126,9 @@ void RenderContextImpl::DrawTextLayout(const TextLayout& layout, const Point& of
if (layout.IsValid()) if (layout.IsValid())
{ {
auto native = NativePtr::Get<IDWriteTextLayout>(layout); auto native = NativePtr::Get<IDWriteTextLayout>(layout);
auto fill_brush = NativePtr::Get<ID2D1Brush>(layout.GetDefaultFillBrush()); auto fill_brush = NativePtr::Get<ID2D1Brush>(layout.GetFillBrush());
auto outline_brush = NativePtr::Get<ID2D1Brush>(layout.GetDefaultOutlineBrush()); auto outline_brush = NativePtr::Get<ID2D1Brush>(layout.GetOutlineBrush());
auto outline_stroke = NativePtr::Get<ID2D1StrokeStyle>(layout.GetDefaultOutlineStrokeStyle()); auto outline_stroke = NativePtr::Get<ID2D1StrokeStyle>(layout.GetOutlineStrokeStyle());
float outline_width = 1.0f; float outline_width = 1.0f;
if (fill_brush) if (fill_brush)
@ -141,9 +141,9 @@ void RenderContextImpl::DrawTextLayout(const TextLayout& layout, const Point& of
outline_brush->SetOpacity(brush_opacity_); outline_brush->SetOpacity(brush_opacity_);
} }
if (layout.GetDefaultOutlineStrokeStyle()) if (layout.GetOutlineStrokeStyle())
{ {
outline_width = layout.GetDefaultOutlineStrokeStyle()->GetStrokeWidth(); outline_width = layout.GetOutlineStrokeStyle()->GetStrokeWidth();
} }
HRESULT hr = text_renderer_->DrawTextLayout(native.Get(), offset.x, offset.y, fill_brush.Get(), HRESULT hr = text_renderer_->DrawTextLayout(native.Get(), offset.x, offset.y, fill_brush.Get(),

View File

@ -599,23 +599,29 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
auto font_weight = DWRITE_FONT_WEIGHT(style.font_weight); FontPtr font = style.font;
auto font_style = style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; if (!font)
auto collection = NativePtr::Get<IDWriteFontCollection>(style.font); {
font = new Font;
}
float font_size = font->GetSize();
auto font_weight = DWRITE_FONT_WEIGHT(font->GetWeight());
bool is_italic = (font->GetPosture() == FontPosture::Italic);
auto font_style = is_italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
auto collection = NativePtr::Get<IDWriteFontCollection>(font);
WideString font_family; WideString font_family;
if (style.font)
{ String name = font->GetFamilyName();
String name = style.font->GetFamilyName();
if (!name.empty()) if (!name.empty())
{ {
font_family = strings::NarrowToWide(name); font_family = strings::NarrowToWide(name);
} }
}
ComPtr<IDWriteTextFormat> format; ComPtr<IDWriteTextFormat> format;
hr = d2d_res_->CreateTextFormat(format, font_family.c_str(), collection, font_weight, font_style, hr = d2d_res_->CreateTextFormat(format, font_family.c_str(), collection, font_weight, font_style,
DWRITE_FONT_STRETCH_NORMAL, style.font_size); DWRITE_FONT_STRETCH_NORMAL, font_size);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {

View File

@ -84,26 +84,31 @@ FontPtr Font::Preload(const Resource& resource)
return ptr; return ptr;
} }
Font::Font() {} Font::Font()
: size_(18.0f)
Font::Font(const String& family_name) , weight_(FontWeight::Normal)
, posture_(FontPosture::Regular)
{ {
Load(family_name);
} }
bool Font::Load(const String& family_name) Font::Font(const String& family_name, float size, uint32_t weight, FontPosture posture)
: size_(size)
, weight_(weight)
, posture_(posture)
{ {
if (family_name.empty()) if (family_name.empty())
return true; return;
if (FontPtr font = FontCache::GetInstance().GetFontByFamily(family_name)) FontPtr found = FontCache::GetInstance().GetFontByFamily(family_name);
if (found)
{ {
ResetNativePointer(font->GetNativePointer()); this->ResetNativePointer(found->GetNativePointer());
SetFamilyName(family_name); this->SetFamilyName(family_name);
return true; }
else
{
this->Fail(strings::Format("Font::Load failed: cannot find family name \"%s\"", family_name.c_str()));
} }
Fail(strings::Format("Font::Load failed: cannot find family name \"%s\"", family_name.c_str()));
return false;
} }
FontCache::FontCache() {} FontCache::FontCache() {}

View File

@ -33,6 +33,36 @@ class Renderer;
* @{ * @{
*/ */
/**
* \~chinese
* @brief
*/
struct FontWeight
{
enum Value : uint32_t
{
Thin = 100U,
ExtraLight = 200U,
Light = 300U,
Normal = 400U, ///< 正常
Medium = 500U,
Bold = 700U,
ExtraBold = 800U,
Black = 900U,
ExtraBlack = 950U
};
};
/**
* \~chinese
* @brief
*/
enum class FontPosture
{
Regular, ///< 正常
Italic, ///< 斜体
};
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -50,28 +80,44 @@ public:
/// @param resource 字体资源 /// @param resource 字体资源
static FontPtr Preload(const Resource& resource); static FontPtr Preload(const Resource& resource);
/// \~chinese
/// @brief 创建系统默认字体
Font(); Font();
/// \~chinese /// \~chinese
/// @brief 通过字体族创建字体 /// @brief 通过字体族创建字体
/// @param family_name 字体族 /// @param family_name 字体族
Font(const String& family_name); /// @param size 字号
/// @param weight 字体粗细
/// \~chinese /// @param posture 字体形态
/// @brief ¼ÓÔØ×ÖÌå×å Font(const String& family_name, float size, uint32_t weight = FontWeight::Normal,
/// @param family_name ×ÖÌå×å FontPosture posture = FontPosture::Regular);
bool Load(const String& family_name);
/// \~chinese /// \~chinese
/// @brief 获取字体族 /// @brief 获取字体族
String GetFamilyName() const; String GetFamilyName() const;
/// \~chinese
/// @brief 获取字号
float GetSize() const;
/// \~chinese
/// @brief 获取字体粗细值
uint32_t GetWeight() const;
/// \~chinese
/// @brief 获取字体形态
FontPosture GetPosture() const;
protected: protected:
/// \~chinese /// \~chinese
/// @brief 获取字体族 /// @brief 获取字体族
void SetFamilyName(const String& name); void SetFamilyName(const String& name);
protected: protected:
float size_;
uint32_t weight_;
FontPosture posture_;
String family_name_; String family_name_;
}; };
@ -134,6 +180,21 @@ inline String Font::GetFamilyName() const
return family_name_; return family_name_;
} }
inline float Font::GetSize() const
{
return size_;
}
inline uint32_t Font::GetWeight() const
{
return weight_;
}
inline FontPosture Font::GetPosture() const
{
return posture_;
}
inline void Font::SetFamilyName(const String& name) inline void Font::SetFamilyName(const String& name)
{ {
family_name_ = name; family_name_ = name;

View File

@ -31,6 +31,7 @@ namespace kiwano
TextLayout::TextLayout() TextLayout::TextLayout()
: dirty_flag_(DirtyFlag::Clean) : dirty_flag_(DirtyFlag::Clean)
, line_count_(0) , line_count_(0)
, content_length_(0)
{ {
} }
@ -42,24 +43,24 @@ TextLayout::TextLayout(const String& content, const TextStyle& style)
void TextLayout::Reset(const String& content, const TextStyle& style) void TextLayout::Reset(const String& content, const TextStyle& style)
{ {
content_ = content; content_length_ = (uint32_t)content.length();
if (!content_.empty()) if (content_length_)
{ {
Renderer::GetInstance().CreateTextLayout(*this, content_, style); Renderer::GetInstance().CreateTextLayout(*this, content, style);
SetAlignment(style.alignment); SetAlignment(style.alignment);
SetWrapWidth(style.wrap_width); SetWrapWidth(style.wrap_width);
SetLineSpacing(style.line_spacing); SetLineSpacing(style.line_spacing);
SetDefaultFillBrush(style.fill_brush); SetFillBrush(style.fill_brush);
SetDefaultOutlineBrush(style.outline_brush); SetOutlineBrush(style.outline_brush);
SetDefaultOutlineStrokeStyle(style.outline_stroke); SetOutlineStrokeStyle(style.outline_stroke);
if (style.show_underline) if (style.show_underline)
SetUnderline(style.show_underline, { 0, content_.length() }); SetUnderline(style.show_underline);
if (style.show_strikethrough) if (style.show_strikethrough)
SetStrikethrough(style.show_strikethrough, { 0, content_.length() }); SetStrikethrough(style.show_strikethrough);
} }
else else
{ {
@ -71,20 +72,19 @@ void TextLayout::Reset(const String& content, const TextStyle& style)
Size TextLayout::GetSize() const Size TextLayout::GetSize() const
{ {
const_cast<TextLayout*>(this)->UpdateWhenDirty(); const_cast<TextLayout*>(this)->UpdateIfDirty();
return size_; return size_;
} }
uint32_t TextLayout::GetLineCount() const uint32_t TextLayout::GetLineCount() const
{ {
const_cast<TextLayout*>(this)->UpdateWhenDirty(); const_cast<TextLayout*>(this)->UpdateIfDirty();
return line_count_; return line_count_;
} }
void TextLayout::SetFont(FontPtr font, TextRange range) void TextLayout::SetFont(FontPtr font)
{ {
KGE_ASSERT(content_.size() >= (range.start + range.length)); if (!font)
if (range.length == 0)
return; return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
@ -92,81 +92,48 @@ void TextLayout::SetFont(FontPtr font, TextRange range)
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)
{
HRESULT hr = S_OK;
// reset font collection
{ {
auto collection = NativePtr::Get<IDWriteFontCollection>(font); auto collection = NativePtr::Get<IDWriteFontCollection>(font);
HRESULT hr = native->SetFontCollection(collection.Get(), { range.start, range.length }); hr = native->SetFontCollection(collection.Get(), { 0, content_length_ });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontCollection failed"); KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontCollection failed");
} }
#else
// not supported
#endif
SetDirtyFlag(DirtyFlag::Dirty); // reset font family
}
void TextLayout::SetFontFamily(const String& 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);
KGE_ASSERT(native);
if (native)
{ {
String family = font->GetFamilyName();
WideString font_family = family.empty() ? L"" : strings::NarrowToWide(family); WideString font_family = family.empty() ? L"" : strings::NarrowToWide(family);
HRESULT hr = native->SetFontFamilyName(font_family.c_str(), { range.start, range.length }); hr = native->SetFontFamilyName(font_family.c_str(), { 0, content_length_ });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontFamilyName failed"); KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontFamilyName failed");
} }
#else
// not supported
#endif
SetDirtyFlag(DirtyFlag::Dirty); // reset font size
}
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);
KGE_ASSERT(native);
if (native)
{ {
HRESULT hr = native->SetFontSize(size, { range.start, range.length }); hr = native->SetFontSize(font->GetSize(), { 0, content_length_ });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontSize failed"); KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontSize failed");
} }
#else
// not supported
#endif
SetDirtyFlag(DirtyFlag::Dirty); // reset font weight
}
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);
KGE_ASSERT(native);
if (native)
{ {
DWRITE_FONT_WEIGHT font_weight = DWRITE_FONT_WEIGHT(weight); auto font_weight = DWRITE_FONT_WEIGHT(font->GetWeight());
HRESULT hr = native->SetFontWeight(font_weight, { range.start, range.length }); hr = native->SetFontWeight(font_weight, { 0, content_length_ });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontWeight failed"); KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontSize failed");
}
// reset font style
{
bool is_italic = (font->GetPosture() == FontPosture::Italic);
auto font_style = is_italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
hr = native->SetFontStyle(font_style, { 0, content_length_ });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontSize failed");
}
} }
#else #else
// not supported // not supported
@ -175,43 +142,15 @@ void TextLayout::SetFontWeight(uint32_t weight, TextRange range)
SetDirtyFlag(DirtyFlag::Dirty); SetDirtyFlag(DirtyFlag::Dirty);
} }
void TextLayout::SetItalic(bool italic, TextRange range) void TextLayout::SetUnderline(bool enable)
{ {
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativePtr::Get<IDWriteTextLayout>(this);
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)
{ {
DWRITE_FONT_STYLE font_style = italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; HRESULT hr = native->SetUnderline(enable, { 0, content_length_ });
HRESULT hr = native->SetFontStyle(font_style, { range.start, range.length });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontStyle failed");
}
#else
// not supported
#endif
SetDirtyFlag(DirtyFlag::Dirty);
}
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);
KGE_ASSERT(native);
if (native)
{
HRESULT hr = native->SetUnderline(enable, { range.start, range.length });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetUnderline failed"); KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetUnderline failed");
} }
#else #else
@ -221,19 +160,15 @@ void TextLayout::SetUnderline(bool enable, TextRange range)
SetDirtyFlag(DirtyFlag::Dirty); SetDirtyFlag(DirtyFlag::Dirty);
} }
void TextLayout::SetStrikethrough(bool enable, TextRange range) void TextLayout::SetStrikethrough(bool enable)
{ {
KGE_ASSERT(content_.size() >= (range.start + range.length));
if (range.length == 0)
return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativePtr::Get<IDWriteTextLayout>(this);
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)
{ {
HRESULT hr = native->SetStrikethrough(enable, { range.start, range.length }); HRESULT hr = native->SetStrikethrough(enable, { 0, content_length_ });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetStrikethrough failed"); KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetStrikethrough failed");
} }
#else #else
@ -243,59 +178,6 @@ void TextLayout::SetStrikethrough(bool enable, TextRange range)
SetDirtyFlag(DirtyFlag::Dirty); SetDirtyFlag(DirtyFlag::Dirty);
} }
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);
KGE_ASSERT(native);
if (native)
{
HRESULT hr =
native->SetDrawingEffect(NativePtr::Get<ID2D1Brush>(brush).Get(), { range.start, range.length });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetDrawingEffect failed");
}
#else
// not supported
#endif
SetDirtyFlag(DirtyFlag::Dirty);
}
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
KGE_NOT_USED(range);
SetDefaultOutlineBrush(brush);
#else
return; // not supported
#endif
}
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
KGE_NOT_USED(range);
SetDefaultOutlineStrokeStyle(stroke);
#else
return; // not supported
#endif
}
void TextLayout::SetAlignment(TextAlign align) void TextLayout::SetAlignment(TextAlign align)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
@ -389,7 +271,7 @@ void TextLayout::SetLineSpacing(float line_spacing)
SetDirtyFlag(DirtyFlag::Dirty); SetDirtyFlag(DirtyFlag::Dirty);
} }
bool TextLayout::UpdateWhenDirty() bool TextLayout::UpdateIfDirty()
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (dirty_flag_ == DirtyFlag::Dirty) if (dirty_flag_ == DirtyFlag::Dirty)
@ -400,7 +282,7 @@ bool TextLayout::UpdateWhenDirty()
size_ = Size(); size_ = Size();
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativePtr::Get<IDWriteTextLayout>(this);
if (content_.empty() || !native) if (content_length_ == 0 || !native)
return true; return true;
HRESULT hr = S_OK; HRESULT hr = S_OK;

View File

@ -54,25 +54,12 @@ public:
/// @brief 清空文本布局 /// @brief 清空文本布局
void Clear(); void Clear();
/// \~chinese
/// @brief 重设文本布局
/// @param style 文本样式
void Reset(const TextStyle& style);
/// \~chinese /// \~chinese
/// @brief 重设文本布局 /// @brief 重设文本布局
/// @param content 文字内容 /// @param content 文字内容
/// @param style 文本样式 /// @param style 文本样式
void Reset(const String& content, const TextStyle& style); void Reset(const String& content, const TextStyle& style);
/// \~chinese
/// @brief 获取文字内容
String GetContent() const;
/// \~chinese
/// @brief 获取文字内容的长度
uint32_t GetContentLength() const;
/// \~chinese /// \~chinese
/// @brief 获取文本布局大小 /// @brief 获取文本布局大小
Size GetSize() const; Size GetSize() const;
@ -83,83 +70,45 @@ public:
/// \~chinese /// \~chinese
/// @brief 获取默认填充画刷 /// @brief 获取默认填充画刷
BrushPtr GetDefaultFillBrush() const; BrushPtr GetFillBrush() const;
/// \~chinese /// \~chinese
/// @brief 获取默认描边画刷 /// @brief 获取默认描边画刷
BrushPtr GetDefaultOutlineBrush() const; BrushPtr GetOutlineBrush() const;
/// \~chinese /// \~chinese
/// @brief 获取默认描边线条样式 /// @brief 获取默认描边线条样式
StrokeStylePtr GetDefaultOutlineStrokeStyle() const; StrokeStylePtr GetOutlineStrokeStyle() const;
/// \~chinese
/// @brief 文字范围
struct TextRange
{
uint32_t start; ///< 起始位置
uint32_t length; ///< 长度
};
/// \~chinese /// \~chinese
/// @brief 设置字体 /// @brief 设置字体
/// @param font 字体 /// @param font 字体
/// @param range 文字范围 void SetFont(FontPtr font);
void SetFont(FontPtr font, TextRange range);
/// \~chinese
/// @brief 设置字体族
/// @param family 字体族
/// @param range 文字范围
void SetFontFamily(const String& family, TextRange range);
/// \~chinese
/// @brief 设置字号(默认值为 18
/// @param size 字号
/// @param range 文字范围
void SetFontSize(float size, TextRange range);
/// \~chinese
/// @brief 设置字体粗细值(默认值为 FontWeight::Normal
/// @param weight 粗细值
/// @param range 文字范围
void SetFontWeight(uint32_t weight, TextRange range);
/// \~chinese
/// @brief 设置文字斜体(默认值为 false
/// @param italic 是否是斜体
/// @param range 文字范围
void SetItalic(bool italic, TextRange range);
/// \~chinese /// \~chinese
/// @brief 设置下划线 /// @brief 设置下划线
/// @param enable 是否显示下划线 /// @param enable 是否显示下划线
/// @param range 文字范围 void SetUnderline(bool enable);
void SetUnderline(bool enable, TextRange range);
/// \~chinese /// \~chinese
/// @brief 设置删除线 /// @brief 设置删除线
/// @param enable 是否显示删除线 /// @param enable 是否显示删除线
/// @param range 文字范围 void SetStrikethrough(bool enable);
void SetStrikethrough(bool enable, TextRange range);
/// \~chinese /// \~chinese
/// @brief 设置文字填充画刷,描边画刷和描边线宽 /// @brief 设置文字填充画刷,描边画刷和描边线宽
/// @param brush 画刷 /// @param brush 画刷
/// @param range 文字范围 void SetFillBrush(BrushPtr brush);
void SetFillBrush(BrushPtr brush, TextRange range);
/// \~chinese /// \~chinese
/// @brief 设置文字描边画刷 /// @brief 设置文字描边画刷
/// @param brush 画刷 /// @param brush 画刷
/// @param range 文字范围 void SetOutlineBrush(BrushPtr brush);
void SetOutlineBrush(BrushPtr brush, TextRange range);
/// \~chinese /// \~chinese
/// @brief 设置描边线条样式 /// @brief 设置描边线条样式
/// @param stroke 线条样式 /// @param stroke 线条样式
/// @param range 文字范围 void SetOutlineStrokeStyle(StrokeStylePtr stroke);
void SetOutlineStrokeStyle(StrokeStylePtr stroke, TextRange range);
/// \~chinese /// \~chinese
/// @brief 设置对齐方式 /// @brief 设置对齐方式
@ -174,21 +123,6 @@ public:
/// @brief 设置行间距(默认为 0 /// @brief 设置行间距(默认为 0
void SetLineSpacing(float line_spacing); void SetLineSpacing(float line_spacing);
/// \~chinese
/// @brief 设置默认文字填充画刷
/// @param brush 画刷
void SetDefaultFillBrush(BrushPtr brush);
/// \~chinese
/// @brief 设置默认文字描边画刷
/// @param brush 画刷
void SetDefaultOutlineBrush(BrushPtr brush);
/// \~chinese
/// @brief 设置默认描边线条样式
/// @param stroke 线条样式
void SetDefaultOutlineStrokeStyle(StrokeStylePtr stroke);
/// \~chinese /// \~chinese
/// @brief 脏布局标志 /// @brief 脏布局标志
enum class DirtyFlag : uint8_t enum class DirtyFlag : uint8_t
@ -208,16 +142,16 @@ public:
/// \~chinese /// \~chinese
/// @brief 更新脏布局 /// @brief 更新脏布局
/// @return 是否需要更新 /// @return 是否需要更新
bool UpdateWhenDirty(); bool UpdateIfDirty();
private: private:
DirtyFlag dirty_flag_; DirtyFlag dirty_flag_;
uint32_t line_count_; uint32_t line_count_;
uint32_t content_length_;
Size size_; Size size_;
BrushPtr default_fill_brush_; BrushPtr fill_brush_;
BrushPtr default_outline_brush_; BrushPtr outline_brush_;
StrokeStylePtr default_outline_stroke_; StrokeStylePtr outline_stroke_;
String content_;
}; };
/** @} */ /** @} */
@ -232,21 +166,6 @@ inline void TextLayout::Clear()
ResetNativePointer(); 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 inline TextLayout::DirtyFlag TextLayout::GetDirtyFlag() const
{ {
return dirty_flag_; return dirty_flag_;
@ -257,34 +176,34 @@ inline void TextLayout::SetDirtyFlag(TextLayout::DirtyFlag flag)
dirty_flag_ = flag; dirty_flag_ = flag;
} }
inline BrushPtr TextLayout::GetDefaultFillBrush() const inline BrushPtr TextLayout::GetFillBrush() const
{ {
return default_fill_brush_; return fill_brush_;
} }
inline BrushPtr TextLayout::GetDefaultOutlineBrush() const inline BrushPtr TextLayout::GetOutlineBrush() const
{ {
return default_outline_brush_; return outline_brush_;
} }
inline StrokeStylePtr TextLayout::GetDefaultOutlineStrokeStyle() const inline StrokeStylePtr TextLayout::GetOutlineStrokeStyle() const
{ {
return default_outline_stroke_; return outline_stroke_;
} }
inline void TextLayout::SetDefaultFillBrush(BrushPtr brush) inline void TextLayout::SetFillBrush(BrushPtr brush)
{ {
default_fill_brush_ = brush; fill_brush_ = brush;
} }
inline void TextLayout::SetDefaultOutlineBrush(BrushPtr brush) inline void TextLayout::SetOutlineBrush(BrushPtr brush)
{ {
default_outline_brush_ = brush; outline_brush_ = brush;
} }
inline void TextLayout::SetDefaultOutlineStrokeStyle(StrokeStylePtr stroke) inline void TextLayout::SetOutlineStrokeStyle(StrokeStylePtr stroke)
{ {
default_outline_stroke_ = stroke; outline_stroke_ = stroke;
} }
} // namespace kiwano } // namespace kiwano

View File

@ -24,33 +24,22 @@ namespace kiwano
{ {
TextStyle::TextStyle() TextStyle::TextStyle()
: TextStyle(String(), 18, FontWeight::Normal) : TextStyle(FontPtr(nullptr))
{
}
TextStyle::TextStyle(FontPtr font)
: font(font)
, alignment(TextAlign::Left)
, wrap_width(0)
, line_spacing(0)
, show_underline(false)
, show_strikethrough(false)
{ {
} }
TextStyle::TextStyle(const String& font_family, float font_size, uint32_t font_weight) TextStyle::TextStyle(const String& font_family, float font_size, uint32_t font_weight)
: font_size(font_size) : TextStyle(MakePtr<Font>(font_family, font_size, font_weight))
, font_weight(font_weight)
, italic(false)
, alignment(TextAlign::Left)
, wrap_width(0)
, line_spacing(0)
, show_underline(false)
, show_strikethrough(false)
{
font = MakePtr<Font>(font_family);
}
TextStyle::TextStyle(FontPtr font, float font_size, uint32_t font_weight)
: font(font)
, font_size(font_size)
, font_weight(font_weight)
, italic(false)
, alignment(TextAlign::Left)
, wrap_width(0)
, line_spacing(0)
, show_underline(false)
, show_strikethrough(false)
{ {
} }

View File

@ -43,26 +43,6 @@ enum class TextAlign
Justified ///< 两端对齐 Justified ///< 两端对齐
}; };
/**
* \~chinese
* @brief
*/
struct FontWeight
{
enum Value : uint32_t
{
Thin = 100U,
ExtraLight = 200U,
Light = 300U,
Normal = 400U, ///< 正常
Medium = 500U,
Bold = 700U,
ExtraBold = 800U,
Black = 900U,
ExtraBlack = 950U
};
};
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -71,9 +51,6 @@ class KGE_API TextStyle
{ {
public: public:
FontPtr font; ///< 字体 FontPtr font; ///< 字体
float font_size; ///< 字号
uint32_t font_weight; ///< 粗细值
bool italic; ///< 是否斜体
TextAlign alignment; ///< 对齐方式 TextAlign alignment; ///< 对齐方式
BrushPtr fill_brush; ///< 填充画刷 BrushPtr fill_brush; ///< 填充画刷
BrushPtr outline_brush; ///< 描边画刷 BrushPtr outline_brush; ///< 描边画刷
@ -90,6 +67,13 @@ public:
*/ */
TextStyle(); TextStyle();
/**
* \~chinese
* @brief
* @param font
*/
TextStyle(FontPtr font);
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -98,15 +82,6 @@ public:
* @param font_weight * @param font_weight
*/ */
TextStyle(const String& font_family, float font_size, uint32_t font_weight = FontWeight::Normal); TextStyle(const String& font_family, float font_size, uint32_t font_weight = FontWeight::Normal);
/**
* \~chinese
* @brief
* @param font
* @param font_size
* @param font_weight
*/
TextStyle(FontPtr font, float font_size, uint32_t font_weight = FontWeight::Normal);
}; };
/** @} */ /** @} */