update Font
This commit is contained in:
parent
0e5f0a5be9
commit
4eb5dd007d
|
|
@ -60,9 +60,7 @@ DebugActor::DebugActor()
|
|||
BrushPtr fill_brush = MakePtr<Brush>();
|
||||
fill_brush->SetColor(Color::White);
|
||||
|
||||
debug_text_style_.font = new Font("Arial");
|
||||
debug_text_style_.font_size = 16.f;
|
||||
debug_text_style_.font_weight = FontWeight::Normal;
|
||||
debug_text_style_.font = new Font("Arial", 16.0f, FontWeight::Normal);
|
||||
debug_text_style_.line_spacing = 20.f;
|
||||
debug_text_style_.fill_brush = fill_brush;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ void TextActor::SetText(const String& text)
|
|||
try
|
||||
{
|
||||
layout_->Reset(text, style_);
|
||||
content_ = text;
|
||||
}
|
||||
catch (SystemError& e)
|
||||
{
|
||||
|
|
@ -75,7 +76,7 @@ void TextActor::SetStyle(const TextStyle& style)
|
|||
{
|
||||
style_ = style;
|
||||
if (layout_)
|
||||
layout_->Reset(style);
|
||||
layout_->Reset(content_, style);
|
||||
}
|
||||
|
||||
void TextActor::SetFont(FontPtr font)
|
||||
|
|
@ -84,37 +85,7 @@ void TextActor::SetFont(FontPtr font)
|
|||
{
|
||||
style_.font = font;
|
||||
if (layout_)
|
||||
layout_->SetFont(font, { 0, layout_->GetContentLength() });
|
||||
}
|
||||
}
|
||||
|
||||
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() });
|
||||
layout_->SetFont(font);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +95,7 @@ void TextActor::SetUnderline(bool enable)
|
|||
{
|
||||
style_.show_underline = enable;
|
||||
if (layout_)
|
||||
layout_->SetUnderline(enable, { 0, layout_->GetContentLength() });
|
||||
layout_->SetUnderline(enable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +105,7 @@ void TextActor::SetStrikethrough(bool enable)
|
|||
{
|
||||
style_.show_strikethrough = enable;
|
||||
if (layout_)
|
||||
layout_->SetStrikethrough(enable, { 0, layout_->GetContentLength() });
|
||||
layout_->SetStrikethrough(enable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +145,7 @@ void TextActor::SetFillBrush(BrushPtr brush)
|
|||
{
|
||||
style_.fill_brush = brush;
|
||||
if (layout_)
|
||||
layout_->SetDefaultFillBrush(brush);
|
||||
layout_->SetFillBrush(brush);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +155,7 @@ void TextActor::SetOutlineBrush(BrushPtr brush)
|
|||
{
|
||||
style_.outline_brush = brush;
|
||||
if (layout_)
|
||||
layout_->SetDefaultOutlineBrush(brush);
|
||||
layout_->SetOutlineBrush(brush);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,7 +165,7 @@ void TextActor::SetOutlineStrokeStyle(StrokeStylePtr stroke)
|
|||
{
|
||||
style_.outline_stroke = stroke;
|
||||
if (layout_)
|
||||
layout_->SetDefaultOutlineStrokeStyle(stroke);
|
||||
layout_->SetOutlineStrokeStyle(stroke);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +215,7 @@ bool TextActor::CheckVisibility(RenderContext& ctx) const
|
|||
|
||||
void TextActor::UpdateDirtyLayout()
|
||||
{
|
||||
if (layout_ && layout_->UpdateWhenDirty())
|
||||
if (layout_ && layout_->UpdateIfDirty())
|
||||
{
|
||||
ForceUpdateLayout();
|
||||
}
|
||||
|
|
@ -254,7 +225,7 @@ void TextActor::ForceUpdateLayout()
|
|||
{
|
||||
if (layout_)
|
||||
{
|
||||
layout_->UpdateWhenDirty();
|
||||
layout_->UpdateIfDirty();
|
||||
SetSize(layout_->GetSize());
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -98,14 +98,6 @@ public:
|
|||
/// @brief 设置字体
|
||||
void SetFont(FontPtr font);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置字号(默认值为 18)
|
||||
void SetFontSize(float size);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置字体粗细值(默认值为 FontWeight::Normal)
|
||||
void SetFontWeight(uint32_t weight);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文字填充画刷
|
||||
void SetFillBrush(BrushPtr brush);
|
||||
|
|
@ -114,10 +106,6 @@ public:
|
|||
/// @brief 设置文字填充颜色(默认值为 Color::White)
|
||||
void SetFillColor(const Color& color);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文字斜体(默认值为 false)
|
||||
void SetItalic(bool italic);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文本自动换行的宽度(默认为 0)
|
||||
void SetWrapWidth(float wrap_width);
|
||||
|
|
@ -172,6 +160,7 @@ protected:
|
|||
bool CheckVisibility(RenderContext& ctx) const override;
|
||||
|
||||
private:
|
||||
String content_;
|
||||
TextStyle style_;
|
||||
TextLayoutPtr layout_;
|
||||
};
|
||||
|
|
@ -180,11 +169,7 @@ private:
|
|||
|
||||
inline String TextActor::GetText() const
|
||||
{
|
||||
if (layout_)
|
||||
{
|
||||
return layout_->GetContent();
|
||||
}
|
||||
return String();
|
||||
return content_;
|
||||
}
|
||||
|
||||
inline FontPtr TextActor::GetFont() const
|
||||
|
|
|
|||
|
|
@ -126,9 +126,9 @@ void RenderContextImpl::DrawTextLayout(const TextLayout& layout, const Point& of
|
|||
if (layout.IsValid())
|
||||
{
|
||||
auto native = NativePtr::Get<IDWriteTextLayout>(layout);
|
||||
auto fill_brush = NativePtr::Get<ID2D1Brush>(layout.GetDefaultFillBrush());
|
||||
auto outline_brush = NativePtr::Get<ID2D1Brush>(layout.GetDefaultOutlineBrush());
|
||||
auto outline_stroke = NativePtr::Get<ID2D1StrokeStyle>(layout.GetDefaultOutlineStrokeStyle());
|
||||
auto fill_brush = NativePtr::Get<ID2D1Brush>(layout.GetFillBrush());
|
||||
auto outline_brush = NativePtr::Get<ID2D1Brush>(layout.GetOutlineBrush());
|
||||
auto outline_stroke = NativePtr::Get<ID2D1StrokeStyle>(layout.GetOutlineStrokeStyle());
|
||||
float outline_width = 1.0f;
|
||||
|
||||
if (fill_brush)
|
||||
|
|
@ -141,9 +141,9 @@ void RenderContextImpl::DrawTextLayout(const TextLayout& layout, const Point& of
|
|||
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(),
|
||||
|
|
|
|||
|
|
@ -599,23 +599,29 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
auto font_weight = DWRITE_FONT_WEIGHT(style.font_weight);
|
||||
auto font_style = style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
|
||||
auto collection = NativePtr::Get<IDWriteFontCollection>(style.font);
|
||||
FontPtr font = style.font;
|
||||
if (!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;
|
||||
if (style.font)
|
||||
|
||||
String name = font->GetFamilyName();
|
||||
if (!name.empty())
|
||||
{
|
||||
String name = style.font->GetFamilyName();
|
||||
if (!name.empty())
|
||||
{
|
||||
font_family = strings::NarrowToWide(name);
|
||||
}
|
||||
font_family = strings::NarrowToWide(name);
|
||||
}
|
||||
|
||||
ComPtr<IDWriteTextFormat> format;
|
||||
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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -84,26 +84,31 @@ FontPtr Font::Preload(const Resource& resource)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
Font::Font() {}
|
||||
|
||||
Font::Font(const String& family_name)
|
||||
Font::Font()
|
||||
: size_(18.0f)
|
||||
, 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())
|
||||
return true;
|
||||
return;
|
||||
|
||||
if (FontPtr font = FontCache::GetInstance().GetFontByFamily(family_name))
|
||||
FontPtr found = FontCache::GetInstance().GetFontByFamily(family_name);
|
||||
if (found)
|
||||
{
|
||||
ResetNativePointer(font->GetNativePointer());
|
||||
SetFamilyName(family_name);
|
||||
return true;
|
||||
this->ResetNativePointer(found->GetNativePointer());
|
||||
this->SetFamilyName(family_name);
|
||||
}
|
||||
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() {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* @brief 字体
|
||||
|
|
@ -50,29 +80,45 @@ public:
|
|||
/// @param resource 字体资源
|
||||
static FontPtr Preload(const Resource& resource);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 创建系统默认字体
|
||||
Font();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 通过字体族创建字体
|
||||
/// @param family_name 字体族
|
||||
Font(const String& family_name);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief ¼ÓÔØ×ÖÌå×å
|
||||
/// @param family_name ×ÖÌå×å
|
||||
bool Load(const String& family_name);
|
||||
/// @param size 字号
|
||||
/// @param weight 字体粗细
|
||||
/// @param posture 字体形态
|
||||
Font(const String& family_name, float size, uint32_t weight = FontWeight::Normal,
|
||||
FontPosture posture = FontPosture::Regular);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取字体族
|
||||
String GetFamilyName() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取字号
|
||||
float GetSize() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取字体粗细值
|
||||
uint32_t GetWeight() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取字体形态
|
||||
FontPosture GetPosture() const;
|
||||
|
||||
protected:
|
||||
/// \~chinese
|
||||
/// @brief 获取字体族
|
||||
void SetFamilyName(const String& name);
|
||||
|
||||
protected:
|
||||
String family_name_;
|
||||
float size_;
|
||||
uint32_t weight_;
|
||||
FontPosture posture_;
|
||||
String family_name_;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -134,6 +180,21 @@ inline String Font::GetFamilyName() const
|
|||
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)
|
||||
{
|
||||
family_name_ = name;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ namespace kiwano
|
|||
TextLayout::TextLayout()
|
||||
: dirty_flag_(DirtyFlag::Clean)
|
||||
, 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)
|
||||
{
|
||||
content_ = content;
|
||||
if (!content_.empty())
|
||||
content_length_ = (uint32_t)content.length();
|
||||
if (content_length_)
|
||||
{
|
||||
Renderer::GetInstance().CreateTextLayout(*this, content_, style);
|
||||
Renderer::GetInstance().CreateTextLayout(*this, content, style);
|
||||
|
||||
SetAlignment(style.alignment);
|
||||
SetWrapWidth(style.wrap_width);
|
||||
SetLineSpacing(style.line_spacing);
|
||||
|
||||
SetDefaultFillBrush(style.fill_brush);
|
||||
SetDefaultOutlineBrush(style.outline_brush);
|
||||
SetDefaultOutlineStrokeStyle(style.outline_stroke);
|
||||
SetFillBrush(style.fill_brush);
|
||||
SetOutlineBrush(style.outline_brush);
|
||||
SetOutlineStrokeStyle(style.outline_stroke);
|
||||
|
||||
if (style.show_underline)
|
||||
SetUnderline(style.show_underline, { 0, content_.length() });
|
||||
SetUnderline(style.show_underline);
|
||||
|
||||
if (style.show_strikethrough)
|
||||
SetStrikethrough(style.show_strikethrough, { 0, content_.length() });
|
||||
SetStrikethrough(style.show_strikethrough);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -71,20 +72,19 @@ void TextLayout::Reset(const String& content, const TextStyle& style)
|
|||
|
||||
Size TextLayout::GetSize() const
|
||||
{
|
||||
const_cast<TextLayout*>(this)->UpdateWhenDirty();
|
||||
const_cast<TextLayout*>(this)->UpdateIfDirty();
|
||||
return size_;
|
||||
}
|
||||
|
||||
uint32_t TextLayout::GetLineCount() const
|
||||
{
|
||||
const_cast<TextLayout*>(this)->UpdateWhenDirty();
|
||||
const_cast<TextLayout*>(this)->UpdateIfDirty();
|
||||
return line_count_;
|
||||
}
|
||||
|
||||
void TextLayout::SetFont(FontPtr font, TextRange range)
|
||||
void TextLayout::SetFont(FontPtr font)
|
||||
{
|
||||
KGE_ASSERT(content_.size() >= (range.start + range.length));
|
||||
if (range.length == 0)
|
||||
if (!font)
|
||||
return;
|
||||
|
||||
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
|
||||
|
|
@ -93,10 +93,47 @@ void TextLayout::SetFont(FontPtr font, TextRange range)
|
|||
|
||||
if (native)
|
||||
{
|
||||
auto collection = NativePtr::Get<IDWriteFontCollection>(font);
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
HRESULT hr = native->SetFontCollection(collection.Get(), { range.start, range.length });
|
||||
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontCollection failed");
|
||||
// reset font collection
|
||||
{
|
||||
auto collection = NativePtr::Get<IDWriteFontCollection>(font);
|
||||
|
||||
hr = native->SetFontCollection(collection.Get(), { 0, content_length_ });
|
||||
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontCollection failed");
|
||||
}
|
||||
|
||||
// reset font family
|
||||
{
|
||||
String family = font->GetFamilyName();
|
||||
WideString font_family = family.empty() ? L"" : strings::NarrowToWide(family);
|
||||
|
||||
hr = native->SetFontFamilyName(font_family.c_str(), { 0, content_length_ });
|
||||
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontFamilyName failed");
|
||||
}
|
||||
|
||||
// reset font size
|
||||
{
|
||||
hr = native->SetFontSize(font->GetSize(), { 0, content_length_ });
|
||||
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontSize failed");
|
||||
}
|
||||
|
||||
// reset font weight
|
||||
{
|
||||
auto font_weight = DWRITE_FONT_WEIGHT(font->GetWeight());
|
||||
|
||||
hr = native->SetFontWeight(font_weight, { 0, content_length_ });
|
||||
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
|
||||
// not supported
|
||||
|
|
@ -105,113 +142,15 @@ void TextLayout::SetFont(FontPtr font, TextRange range)
|
|||
SetDirtyFlag(DirtyFlag::Dirty);
|
||||
}
|
||||
|
||||
void TextLayout::SetFontFamily(const String& family, 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
|
||||
auto native = NativePtr::Get<IDWriteTextLayout>(this);
|
||||
KGE_ASSERT(native);
|
||||
|
||||
if (native)
|
||||
{
|
||||
WideString font_family = family.empty() ? L"" : strings::NarrowToWide(family);
|
||||
|
||||
HRESULT hr = native->SetFontFamilyName(font_family.c_str(), { range.start, range.length });
|
||||
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontFamilyName failed");
|
||||
}
|
||||
#else
|
||||
// not supported
|
||||
#endif
|
||||
|
||||
SetDirtyFlag(DirtyFlag::Dirty);
|
||||
}
|
||||
|
||||
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 });
|
||||
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontSize failed");
|
||||
}
|
||||
#else
|
||||
// not supported
|
||||
#endif
|
||||
|
||||
SetDirtyFlag(DirtyFlag::Dirty);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
HRESULT hr = native->SetFontWeight(font_weight, { range.start, range.length });
|
||||
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontWeight failed");
|
||||
}
|
||||
#else
|
||||
// not supported
|
||||
#endif
|
||||
|
||||
SetDirtyFlag(DirtyFlag::Dirty);
|
||||
}
|
||||
|
||||
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);
|
||||
KGE_ASSERT(native);
|
||||
|
||||
if (native)
|
||||
{
|
||||
DWRITE_FONT_STYLE font_style = italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL;
|
||||
|
||||
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 });
|
||||
HRESULT hr = native->SetUnderline(enable, { 0, content_length_ });
|
||||
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetUnderline failed");
|
||||
}
|
||||
#else
|
||||
|
|
@ -221,19 +160,15 @@ void TextLayout::SetUnderline(bool enable, TextRange range)
|
|||
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
|
||||
auto native = NativePtr::Get<IDWriteTextLayout>(this);
|
||||
KGE_ASSERT(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");
|
||||
}
|
||||
#else
|
||||
|
|
@ -243,59 +178,6 @@ void TextLayout::SetStrikethrough(bool enable, TextRange range)
|
|||
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)
|
||||
{
|
||||
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
|
||||
|
|
@ -389,7 +271,7 @@ void TextLayout::SetLineSpacing(float line_spacing)
|
|||
SetDirtyFlag(DirtyFlag::Dirty);
|
||||
}
|
||||
|
||||
bool TextLayout::UpdateWhenDirty()
|
||||
bool TextLayout::UpdateIfDirty()
|
||||
{
|
||||
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
|
||||
if (dirty_flag_ == DirtyFlag::Dirty)
|
||||
|
|
@ -400,7 +282,7 @@ bool TextLayout::UpdateWhenDirty()
|
|||
size_ = Size();
|
||||
|
||||
auto native = NativePtr::Get<IDWriteTextLayout>(this);
|
||||
if (content_.empty() || !native)
|
||||
if (content_length_ == 0 || !native)
|
||||
return true;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
|
|
|||
|
|
@ -54,25 +54,12 @@ 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;
|
||||
|
|
@ -83,83 +70,45 @@ public:
|
|||
|
||||
/// \~chinese
|
||||
/// @brief 获取默认填充画刷
|
||||
BrushPtr GetDefaultFillBrush() const;
|
||||
BrushPtr GetFillBrush() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取默认描边画刷
|
||||
BrushPtr GetDefaultOutlineBrush() const;
|
||||
BrushPtr GetOutlineBrush() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取默认描边线条样式
|
||||
StrokeStylePtr GetDefaultOutlineStrokeStyle() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 文字范围
|
||||
struct TextRange
|
||||
{
|
||||
uint32_t start; ///< 起始位置
|
||||
uint32_t length; ///< 长度
|
||||
};
|
||||
StrokeStylePtr GetOutlineStrokeStyle() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置字体
|
||||
/// @param font 字体
|
||||
/// @param range 文字范围
|
||||
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);
|
||||
void SetFont(FontPtr font);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置下划线
|
||||
/// @param enable 是否显示下划线
|
||||
/// @param range 文字范围
|
||||
void SetUnderline(bool enable, TextRange range);
|
||||
void SetUnderline(bool enable);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置删除线
|
||||
/// @param enable 是否显示删除线
|
||||
/// @param range 文字范围
|
||||
void SetStrikethrough(bool enable, TextRange range);
|
||||
void SetStrikethrough(bool enable);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文字填充画刷,描边画刷和描边线宽
|
||||
/// @param brush 画刷
|
||||
/// @param range 文字范围
|
||||
void SetFillBrush(BrushPtr brush, TextRange range);
|
||||
void SetFillBrush(BrushPtr brush);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文字描边画刷
|
||||
/// @param brush 画刷
|
||||
/// @param range 文字范围
|
||||
void SetOutlineBrush(BrushPtr brush, TextRange range);
|
||||
void SetOutlineBrush(BrushPtr brush);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置描边线条样式
|
||||
/// @param stroke 线条样式
|
||||
/// @param range 文字范围
|
||||
void SetOutlineStrokeStyle(StrokeStylePtr stroke, TextRange range);
|
||||
void SetOutlineStrokeStyle(StrokeStylePtr stroke);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置对齐方式
|
||||
|
|
@ -174,21 +123,6 @@ public:
|
|||
/// @brief 设置行间距(默认为 0)
|
||||
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
|
||||
/// @brief 脏布局标志
|
||||
enum class DirtyFlag : uint8_t
|
||||
|
|
@ -208,16 +142,16 @@ public:
|
|||
/// \~chinese
|
||||
/// @brief 更新脏布局
|
||||
/// @return 是否需要更新
|
||||
bool UpdateWhenDirty();
|
||||
bool UpdateIfDirty();
|
||||
|
||||
private:
|
||||
DirtyFlag dirty_flag_;
|
||||
uint32_t line_count_;
|
||||
uint32_t content_length_;
|
||||
Size size_;
|
||||
BrushPtr default_fill_brush_;
|
||||
BrushPtr default_outline_brush_;
|
||||
StrokeStylePtr default_outline_stroke_;
|
||||
String content_;
|
||||
BrushPtr fill_brush_;
|
||||
BrushPtr outline_brush_;
|
||||
StrokeStylePtr outline_stroke_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
|
@ -232,21 +166,6 @@ 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_;
|
||||
|
|
@ -257,34 +176,34 @@ inline void TextLayout::SetDirtyFlag(TextLayout::DirtyFlag 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
|
||||
|
|
|
|||
|
|
@ -24,33 +24,22 @@ namespace kiwano
|
|||
{
|
||||
|
||||
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)
|
||||
: 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)
|
||||
{
|
||||
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)
|
||||
: TextStyle(MakePtr<Font>(font_family, font_size, font_weight))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,26 +43,6 @@ enum class TextAlign
|
|||
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
|
||||
* @brief 文本样式
|
||||
|
|
@ -71,9 +51,6 @@ class KGE_API TextStyle
|
|||
{
|
||||
public:
|
||||
FontPtr font; ///< 字体
|
||||
float font_size; ///< 字号
|
||||
uint32_t font_weight; ///< 粗细值
|
||||
bool italic; ///< 是否斜体
|
||||
TextAlign alignment; ///< 对齐方式
|
||||
BrushPtr fill_brush; ///< 填充画刷
|
||||
BrushPtr outline_brush; ///< 描边画刷
|
||||
|
|
@ -90,6 +67,13 @@ public:
|
|||
*/
|
||||
TextStyle();
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 构建文本样式
|
||||
* @param font 字体
|
||||
*/
|
||||
TextStyle(FontPtr font);
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 构建文本样式
|
||||
|
|
@ -98,15 +82,6 @@ public:
|
|||
* @param font_weight 字体粗细
|
||||
*/
|
||||
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);
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
|
|
|||
Loading…
Reference in New Issue