Update Font & TextLayout & TextActor
This commit is contained in:
parent
f057b3b737
commit
8629d65797
|
|
@ -28,7 +28,6 @@
|
|||
<ClInclude Include="..\..\src\kiwano\2d\Stage.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\2d\Sprite.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\2d\TextActor.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\2d\TextStyle.hpp" />
|
||||
<ClInclude Include="..\..\src\kiwano\2d\Transform.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\2d\Transition.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\AsyncTask.h" />
|
||||
|
|
@ -61,10 +60,10 @@
|
|||
<ClInclude Include="..\..\src\kiwano\renderer\Brush.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\Color.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\Font.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\FontCollection.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\Geometry.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\GifImage.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\StrokeStyle.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\TextStyle.hpp" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\Texture.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\TextureCache.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\LayerArea.h" />
|
||||
|
|
@ -126,7 +125,6 @@
|
|||
<ClCompile Include="..\..\src\kiwano\renderer\Brush.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\renderer\Color.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\renderer\Font.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\renderer\FontCollection.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\renderer\Geometry.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\renderer\GifImage.cpp" />
|
||||
<ClCompile Include="..\..\src\kiwano\renderer\Texture.cpp" />
|
||||
|
|
|
|||
|
|
@ -48,9 +48,6 @@
|
|||
<ClInclude Include="..\..\src\kiwano\2d\Sprite.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\2d\TextStyle.hpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\2d\Transition.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -201,9 +198,6 @@
|
|||
<ClInclude Include="..\..\src\kiwano\renderer\RenderTarget.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\FontCollection.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\2d\Transform.h">
|
||||
<Filter>2d</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -270,6 +264,9 @@
|
|||
<ClInclude Include="..\..\src\kiwano\core\RefCounter.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\TextStyle.hpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\kiwano\ui\Button.cpp">
|
||||
|
|
@ -407,9 +404,6 @@
|
|||
<ClCompile Include="..\..\src\kiwano\renderer\RenderTarget.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\kiwano\renderer\FontCollection.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\kiwano\2d\Transform.cpp">
|
||||
<Filter>2d</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace kiwano
|
|||
PrepareRender(rt);
|
||||
|
||||
Rect bitmap_rect(0.f, 0.f, texture_cached_->GetWidth(), texture_cached_->GetHeight());
|
||||
rt->DrawTexture(texture_cached_, bitmap_rect, bitmap_rect);
|
||||
rt->DrawTexture(*texture_cached_, bitmap_rect, bitmap_rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -82,11 +82,6 @@ namespace kiwano
|
|||
stroke_style_ = stroke_style;
|
||||
}
|
||||
|
||||
void Canvas::SetTextFont(Font const& font)
|
||||
{
|
||||
text_font_ = font;
|
||||
}
|
||||
|
||||
void Canvas::SetTextStyle(TextStyle const & text_style)
|
||||
{
|
||||
text_style_ = text_style;
|
||||
|
|
@ -249,7 +244,7 @@ namespace kiwano
|
|||
{
|
||||
if (texture)
|
||||
{
|
||||
rt_.DrawTexture(texture, src_rect, dest_rect);
|
||||
rt_.DrawTexture(*texture, src_rect, dest_rect);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -259,7 +254,9 @@ namespace kiwano
|
|||
if (text.empty())
|
||||
return;
|
||||
|
||||
TextLayout layout(text, text_font_, text_style_);
|
||||
TextLayout layout;
|
||||
layout.SetStyle(text_style_);
|
||||
layout.SetText(text);
|
||||
DrawTextLayout(layout, point);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,11 +198,6 @@ namespace kiwano
|
|||
/// @param stroke_style 轮廓样式
|
||||
void SetStrokeStyle(StrokeStyle stroke_style);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文字字体
|
||||
/// @param font 文字字体
|
||||
void SetTextFont(Font const& font);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文字画刷样式
|
||||
/// @param text_style 文字画刷样式
|
||||
|
|
@ -270,7 +265,6 @@ namespace kiwano
|
|||
float stroke_width_;
|
||||
Color fill_color_;
|
||||
Color stroke_color_;
|
||||
Font text_font_;
|
||||
TextStyle text_style_;
|
||||
StrokeStyle stroke_style_;
|
||||
GeometrySink geo_sink_;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <kiwano/2d/DebugActor.h>
|
||||
#include <kiwano/renderer/Renderer.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <psapi.h>
|
||||
|
||||
#pragma comment(lib, "psapi.lib")
|
||||
|
|
@ -57,13 +58,10 @@ namespace kiwano
|
|||
debug_text_->SetPosition(Point{ 10, 10 });
|
||||
this->AddChild(debug_text_);
|
||||
|
||||
Font font;
|
||||
font.family = L"Arial";
|
||||
font.size = 16.f;
|
||||
font.weight = FontWeight::Normal;
|
||||
debug_text_->SetFont(font);
|
||||
|
||||
TextStyle style;
|
||||
style.font_family = L"Arial";
|
||||
style.font_size = 16.f;
|
||||
style.font_weight = FontWeight::Normal;
|
||||
style.line_spacing = 20.f;
|
||||
debug_text_->SetStyle(style);
|
||||
|
||||
|
|
|
|||
|
|
@ -89,11 +89,11 @@ namespace kiwano
|
|||
|
||||
void GifSprite::OnRender(RenderTarget* rt)
|
||||
{
|
||||
if (frame_.raw && frame_.raw->IsValid() && CheckVisibilty(rt))
|
||||
if (frame_to_render_ && CheckVisibilty(rt))
|
||||
{
|
||||
PrepareRender(rt);
|
||||
|
||||
rt->DrawTexture(frame_.raw, &frame_.rect, nullptr);
|
||||
rt->DrawTexture(*frame_to_render_, &frame_.rect, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,13 +188,16 @@ namespace kiwano
|
|||
loop_count_++;
|
||||
}
|
||||
|
||||
frame_rt_.DrawTexture(frame_.raw, nullptr, &frame_.rect);
|
||||
if (frame_.raw)
|
||||
{
|
||||
frame_rt_.DrawTexture(*frame_.raw, nullptr, &frame_.rect);
|
||||
}
|
||||
|
||||
frame_rt_.EndDraw();
|
||||
|
||||
TexturePtr frame_to_render = frame_rt_.GetOutput();
|
||||
if (frame_to_render)
|
||||
frame_to_render_ = frame_rt_.GetOutput();
|
||||
if (frame_to_render_)
|
||||
{
|
||||
frame_.raw = frame_to_render;
|
||||
next_index_ = (++next_index_) % gif_->GetFramesCount();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ namespace kiwano
|
|||
GifImagePtr gif_;
|
||||
GifImage::Frame frame_;
|
||||
TexturePtr saved_frame_;
|
||||
TexturePtr frame_to_render_;
|
||||
TextureRenderTarget frame_rt_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ namespace kiwano
|
|||
{
|
||||
PrepareRender(rt);
|
||||
|
||||
rt->DrawTexture(frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds());
|
||||
rt->DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,186 +26,39 @@ namespace kiwano
|
|||
{
|
||||
namespace
|
||||
{
|
||||
Font text_default_font;
|
||||
TextStyle text_default_style;
|
||||
}
|
||||
|
||||
void kiwano::TextActor::SetDefaultFont(Font const & font)
|
||||
{
|
||||
text_default_font = font;
|
||||
}
|
||||
|
||||
void kiwano::TextActor::SetDefaultStyle(TextStyle const & style)
|
||||
void TextActor::SetDefaultStyle(TextStyle const & style)
|
||||
{
|
||||
text_default_style = style;
|
||||
}
|
||||
|
||||
TextActor::TextActor()
|
||||
: font_(text_default_font)
|
||||
, layout_dirty_(false)
|
||||
, format_dirty_(false)
|
||||
: TextActor(String())
|
||||
{
|
||||
text_layout_.SetTextStyle(text_default_style);
|
||||
}
|
||||
|
||||
TextActor::TextActor(String const& text)
|
||||
: TextActor(text, text_default_font, text_default_style)
|
||||
{
|
||||
}
|
||||
|
||||
TextActor::TextActor(String const& text, const Font & font)
|
||||
: TextActor(text, font, text_default_style)
|
||||
: TextActor(text, text_default_style)
|
||||
{
|
||||
}
|
||||
|
||||
TextActor::TextActor(String const& text, const TextStyle & style)
|
||||
: TextActor(text, text_default_font, style)
|
||||
{
|
||||
}
|
||||
|
||||
TextActor::TextActor(String const& text, const Font & font, const TextStyle & style)
|
||||
: font_(font)
|
||||
, text_(text)
|
||||
, layout_dirty_(true)
|
||||
, format_dirty_(true)
|
||||
{
|
||||
text_layout_.SetTextStyle(style);
|
||||
SetText(text);
|
||||
SetStyle(style);
|
||||
}
|
||||
|
||||
TextActor::~TextActor()
|
||||
{
|
||||
}
|
||||
|
||||
void TextActor::SetText(String const& text)
|
||||
{
|
||||
text_ = text;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
|
||||
void TextActor::SetStyle(const TextStyle& style)
|
||||
{
|
||||
text_layout_.SetTextStyle(style);
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
|
||||
void TextActor::SetFont(const Font & font)
|
||||
{
|
||||
font_ = font;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
|
||||
void TextActor::SetFontFamily(String const& family)
|
||||
{
|
||||
if (font_.family != family)
|
||||
{
|
||||
font_.family = family;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextActor::SetFontSize(float size)
|
||||
{
|
||||
if (font_.size != size)
|
||||
{
|
||||
font_.size = size;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextActor::SetFontWeight(uint32_t weight)
|
||||
{
|
||||
if (font_.weight != weight)
|
||||
{
|
||||
font_.weight = weight;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextActor::SetItalic(bool italic)
|
||||
{
|
||||
if (font_.italic != italic)
|
||||
{
|
||||
font_.italic = italic;
|
||||
format_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextActor::SetWrapWidth(float wrap_width)
|
||||
{
|
||||
if (text_layout_.GetTextStyle().wrap_width != wrap_width)
|
||||
{
|
||||
text_layout_.GetTextStyle().wrap_width = wrap_width;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextActor::SetLineSpacing(float line_spacing)
|
||||
{
|
||||
if (text_layout_.GetTextStyle().line_spacing != line_spacing)
|
||||
{
|
||||
text_layout_.GetTextStyle().line_spacing = line_spacing;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextActor::SetAlignment(TextAlign align)
|
||||
{
|
||||
if (text_layout_.GetTextStyle().alignment != align)
|
||||
{
|
||||
text_layout_.GetTextStyle().alignment = align;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextActor::SetUnderline(bool underline)
|
||||
{
|
||||
if (text_layout_.GetTextStyle().underline != underline)
|
||||
{
|
||||
text_layout_.GetTextStyle().underline = underline;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextActor::SetStrikethrough(bool strikethrough)
|
||||
{
|
||||
if (text_layout_.GetTextStyle().strikethrough != strikethrough)
|
||||
{
|
||||
text_layout_.GetTextStyle().strikethrough = strikethrough;
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextActor::SetColor(Color const& color)
|
||||
{
|
||||
text_layout_.GetTextStyle().color = color;
|
||||
text_layout_.GetTextStyle().color = color;
|
||||
}
|
||||
|
||||
void TextActor::SetOutline(bool outline)
|
||||
{
|
||||
text_layout_.GetTextStyle().outline = outline;
|
||||
}
|
||||
|
||||
void TextActor::SetOutlineColor(Color const&outline_color)
|
||||
{
|
||||
text_layout_.GetTextStyle().outline_color = outline_color;
|
||||
}
|
||||
|
||||
void TextActor::SetOutlineWidth(float outline_width)
|
||||
{
|
||||
text_layout_.GetTextStyle().outline_width = outline_width;
|
||||
}
|
||||
|
||||
void TextActor::SetOutlineStroke(StrokeStyle outline_stroke)
|
||||
{
|
||||
text_layout_.GetTextStyle().outline_stroke = outline_stroke;
|
||||
}
|
||||
|
||||
void TextActor::OnRender(RenderTarget* rt)
|
||||
{
|
||||
UpdateLayout();
|
||||
|
||||
if (text_layout_ && CheckVisibilty(rt))
|
||||
if (text_layout_.IsValid() && CheckVisibilty(rt))
|
||||
{
|
||||
PrepareRender(rt);
|
||||
rt->DrawTextLayout(text_layout_);
|
||||
|
|
@ -214,16 +67,9 @@ namespace kiwano
|
|||
|
||||
void TextActor::UpdateLayout()
|
||||
{
|
||||
if (format_dirty_)
|
||||
if (text_layout_.IsDirty())
|
||||
{
|
||||
format_dirty_ = false;
|
||||
text_layout_.UpdateFont(font_);
|
||||
}
|
||||
|
||||
if (layout_dirty_)
|
||||
{
|
||||
layout_dirty_ = false;
|
||||
text_layout_.UpdateLayout(text_);
|
||||
text_layout_.Update();
|
||||
SetSize(text_layout_.GetLayoutSize());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,46 +45,33 @@ namespace kiwano
|
|||
TextActor();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 构建空的文本角色
|
||||
/// @brief 构建文本角色
|
||||
/// @param text 文字内容
|
||||
explicit TextActor(const String& text);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 构建空的文本角色
|
||||
/// @param text 文字内容
|
||||
/// @param font 字体
|
||||
TextActor(const String& text, const Font& font);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 构建空的文本角色
|
||||
/// @brief 构建文本角色
|
||||
/// @param text 文字内容
|
||||
/// @param style 文本样式
|
||||
TextActor(const String& text, const TextStyle& style);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 构建空的文本角色
|
||||
/// @param text 文字内容
|
||||
/// @param font 字体
|
||||
/// @param style 文本样式
|
||||
TextActor(const String& text, const Font& font, const TextStyle& style);
|
||||
|
||||
virtual ~TextActor();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取文本
|
||||
String const& GetText() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取字体
|
||||
Font GetFont() const;
|
||||
const String& GetText() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取文本样式
|
||||
TextStyle GetStyle() const;
|
||||
const TextStyle& GetStyle() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取文本布局
|
||||
TextLayout GetLayout() const;
|
||||
const TextLayout& GetLayout() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取字体
|
||||
FontPtr GetFont() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文本
|
||||
|
|
@ -96,7 +83,7 @@ namespace kiwano
|
|||
|
||||
/// \~chinese
|
||||
/// @brief 设置字体
|
||||
void SetFont(const Font& font);
|
||||
void SetFont(FontPtr font);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置字体族
|
||||
|
|
@ -104,9 +91,7 @@ namespace kiwano
|
|||
|
||||
/// \~chinese
|
||||
/// @brief 设置字号(默认值为 18)
|
||||
void SetFontSize(
|
||||
float size
|
||||
);
|
||||
void SetFontSize(float size);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置字体粗细值(默认值为 FontWeight::Normal)
|
||||
|
|
@ -132,17 +117,9 @@ namespace kiwano
|
|||
/// @brief 设置对齐方式(默认为 TextAlign::Left)
|
||||
void SetAlignment(TextAlign align);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置下划线(默认值为 false)
|
||||
void SetUnderline(bool underline);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置删除线(默认值为 false)
|
||||
void SetStrikethrough(bool strikethrough);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置是否显示描边
|
||||
void SetOutline(bool outline);
|
||||
void SetOutline(bool enable);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置描边颜色
|
||||
|
|
@ -157,12 +134,16 @@ namespace kiwano
|
|||
void SetOutlineStroke(StrokeStyle outline_stroke);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 更新文本布局
|
||||
void UpdateLayout();
|
||||
/// @brief 设置是否显示下划线(默认值为 false)
|
||||
void SetUnderline(bool enable);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置默认字体
|
||||
static void SetDefaultFont(Font const& font);
|
||||
/// @brief 设置是否显示删除线(默认值为 false)
|
||||
void SetStrikethrough(bool enable);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 更新文本布局
|
||||
void UpdateLayout();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置默认文字样式
|
||||
|
|
@ -171,21 +152,114 @@ namespace kiwano
|
|||
void OnRender(RenderTarget* rt) override;
|
||||
|
||||
private:
|
||||
bool format_dirty_;
|
||||
bool layout_dirty_;
|
||||
TextLayout text_layout_;
|
||||
String text_;
|
||||
Font font_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline String const& TextActor::GetText() const { return text_; }
|
||||
inline const String& TextActor::GetText() const
|
||||
{
|
||||
return text_layout_.GetText();
|
||||
}
|
||||
|
||||
inline Font TextActor::GetFont() const { return font_; }
|
||||
inline FontPtr TextActor::GetFont() const
|
||||
{
|
||||
return text_layout_.GetStyle().font;
|
||||
}
|
||||
|
||||
inline TextStyle TextActor::GetStyle() const { return text_layout_.GetTextStyle(); }
|
||||
inline const TextStyle& TextActor::GetStyle() const
|
||||
{
|
||||
return text_layout_.GetStyle();
|
||||
}
|
||||
|
||||
inline TextLayout TextActor::GetLayout() const { return text_layout_; }
|
||||
inline const TextLayout& TextActor::GetLayout() const
|
||||
{
|
||||
return text_layout_;
|
||||
}
|
||||
|
||||
inline void TextActor::SetText(String const& text)
|
||||
{
|
||||
text_layout_.SetText(text);
|
||||
}
|
||||
|
||||
inline void TextActor::SetStyle(const TextStyle& style)
|
||||
{
|
||||
text_layout_.SetStyle(style);
|
||||
}
|
||||
|
||||
inline void TextActor::SetFont(FontPtr font)
|
||||
{
|
||||
text_layout_.SetFont(font);
|
||||
}
|
||||
|
||||
inline void TextActor::SetFontFamily(String const& family)
|
||||
{
|
||||
text_layout_.SetFontFamily(family);
|
||||
}
|
||||
|
||||
inline void TextActor::SetFontSize(float size)
|
||||
{
|
||||
text_layout_.SetFontSize(size);
|
||||
}
|
||||
|
||||
inline void TextActor::SetFontWeight(uint32_t weight)
|
||||
{
|
||||
text_layout_.SetFontWeight(weight);
|
||||
}
|
||||
|
||||
inline void TextActor::SetItalic(bool italic)
|
||||
{
|
||||
text_layout_.SetItalic(italic);
|
||||
}
|
||||
|
||||
inline void TextActor::SetWrapWidth(float wrap_width)
|
||||
{
|
||||
text_layout_.SetWrapWidth(wrap_width);
|
||||
}
|
||||
|
||||
inline void TextActor::SetLineSpacing(float line_spacing)
|
||||
{
|
||||
text_layout_.SetLineSpacing(line_spacing);
|
||||
}
|
||||
|
||||
inline void TextActor::SetAlignment(TextAlign align)
|
||||
{
|
||||
text_layout_.SetAlignment(align);
|
||||
}
|
||||
|
||||
inline void TextActor::SetUnderline(bool enable)
|
||||
{
|
||||
text_layout_.SetUnderline(enable, 0, text_layout_.GetText().length());
|
||||
}
|
||||
|
||||
inline void TextActor::SetStrikethrough(bool enable)
|
||||
{
|
||||
text_layout_.SetStrikethrough(enable, 0, text_layout_.GetText().length());
|
||||
}
|
||||
|
||||
inline void TextActor::SetColor(Color const& color)
|
||||
{
|
||||
text_layout_.SetColor(color);
|
||||
}
|
||||
|
||||
inline void TextActor::SetOutline(bool enable)
|
||||
{
|
||||
text_layout_.SetOutline(enable);
|
||||
}
|
||||
|
||||
inline void TextActor::SetOutlineColor(Color const& outline_color)
|
||||
{
|
||||
text_layout_.SetOutlineColor(outline_color);
|
||||
}
|
||||
|
||||
inline void TextActor::SetOutlineWidth(float outline_width)
|
||||
{
|
||||
text_layout_.SetOutlineWidth(outline_width);
|
||||
}
|
||||
|
||||
inline void TextActor::SetOutlineStroke(StrokeStyle outline_stroke)
|
||||
{
|
||||
text_layout_.SetOutlineStroke(outline_stroke);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ namespace kiwano
|
|||
{
|
||||
next = listener->next_item();
|
||||
|
||||
if (listener->IsRunning() && listener->type_ == evt.GetType())
|
||||
if (listener->IsRunning())
|
||||
{
|
||||
listener->callback_(evt);
|
||||
listener->Receive(evt);
|
||||
}
|
||||
|
||||
if (listener->IsRemoveable())
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ namespace kiwano
|
|||
: type_(type)
|
||||
, callback_(callback)
|
||||
, running_(true)
|
||||
, removeable_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,6 +140,10 @@ namespace kiwano
|
|||
SetEventType(KGE_EVENT(_EventTy));
|
||||
}
|
||||
|
||||
/// \~chinese
|
||||
/// @brief ½ÓÊÕÏûÏ¢
|
||||
void Receive(Event& evt);
|
||||
|
||||
private:
|
||||
bool running_;
|
||||
bool removeable_;
|
||||
|
|
@ -193,4 +197,12 @@ namespace kiwano
|
|||
type_ = type;
|
||||
}
|
||||
|
||||
inline void EventListener::Receive(Event& evt)
|
||||
{
|
||||
if (type_ == evt.GetType() && callback_)
|
||||
{
|
||||
callback_(evt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ namespace kiwano
|
|||
{
|
||||
if (FAILED(hr))
|
||||
{
|
||||
KGE_ERROR(L"Fatal error with HRESULT of %08X", hr);
|
||||
KGE_ERROR(L"Failed with HRESULT of %08X", hr);
|
||||
|
||||
StackWalker{}.ShowCallstack();
|
||||
|
||||
static char buffer[1024 + 1];
|
||||
sprintf_s(buffer, "Fatal error with HRESULT of %08X", hr);
|
||||
sprintf_s(buffer, "Failed with HRESULT of %08X", hr);
|
||||
throw std::runtime_error(buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,11 +79,8 @@
|
|||
|
||||
|
||||
#include <kiwano/2d/Transform.h>
|
||||
#include <kiwano/2d/TextStyle.hpp>
|
||||
|
||||
#include <kiwano/2d/Frame.h>
|
||||
#include <kiwano/2d/FrameSequence.h>
|
||||
|
||||
#include <kiwano/2d/action/Action.h>
|
||||
#include <kiwano/2d/action/ActionGroup.h>
|
||||
#include <kiwano/2d/action/ActionTween.h>
|
||||
|
|
@ -92,9 +89,7 @@
|
|||
#include <kiwano/2d/action/Animation.h>
|
||||
#include <kiwano/2d/action/ActionHelper.h>
|
||||
#include <kiwano/2d/action/ActionManager.h>
|
||||
|
||||
#include <kiwano/2d/Transition.h>
|
||||
|
||||
#include <kiwano/2d/Actor.h>
|
||||
#include <kiwano/2d/Stage.h>
|
||||
#include <kiwano/2d/Layer.h>
|
||||
|
|
|
|||
|
|
@ -19,25 +19,48 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include <kiwano/renderer/Font.h>
|
||||
#include <kiwano/renderer/Renderer.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
Font::Font(String const& family, float size, uint32_t weight, bool italic)
|
||||
: family(family)
|
||||
, size(size)
|
||||
, weight(weight)
|
||||
, italic(italic)
|
||||
, collection()
|
||||
Font::Font()
|
||||
{
|
||||
}
|
||||
|
||||
Font::Font(FontCollection collection, String const& family, float size, uint32_t weight, bool italic)
|
||||
: family(family)
|
||||
, size(size)
|
||||
, weight(weight)
|
||||
, italic(italic)
|
||||
, collection(collection)
|
||||
Font::Font(String const& font_file)
|
||||
{
|
||||
Load(font_file);
|
||||
}
|
||||
|
||||
Font::Font(Resource const& font_resource)
|
||||
{
|
||||
Load(font_resource);
|
||||
}
|
||||
|
||||
bool Font::Load(String const& font_file)
|
||||
{
|
||||
try
|
||||
{
|
||||
Renderer::instance().CreateFontCollection(*this, { font_file });
|
||||
}
|
||||
catch (std::runtime_error&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Font::Load(Resource const& font_resource)
|
||||
{
|
||||
try
|
||||
{
|
||||
Renderer::instance().CreateFontCollection(*this, { font_resource });
|
||||
}
|
||||
catch (std::runtime_error&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,51 +19,50 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <kiwano/renderer/FontCollection.h>
|
||||
#include <kiwano/core/ObjectBase.h>
|
||||
#include <kiwano/core/win32/ComPtr.hpp>
|
||||
#include <kiwano/core/Resource.h>
|
||||
#include <dwrite.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
// 字体粗细值
|
||||
struct FontWeight
|
||||
{
|
||||
enum Value : uint32_t
|
||||
{
|
||||
Thin = 100U,
|
||||
ExtraLight = 200U,
|
||||
Light = 300U,
|
||||
Normal = 400U,
|
||||
Medium = 500U,
|
||||
Bold = 700U,
|
||||
ExtraBold = 800U,
|
||||
Black = 900U,
|
||||
ExtraBlack = 950U
|
||||
};
|
||||
};
|
||||
KGE_DECLARE_SMART_PTR(Font);
|
||||
|
||||
class Renderer;
|
||||
|
||||
// ×ÖÌå
|
||||
class Font
|
||||
: public ObjectBase
|
||||
{
|
||||
public:
|
||||
String family; // 字体族
|
||||
float size; // 字号
|
||||
uint32_t weight; // 粗细值
|
||||
bool italic; // 是否斜体
|
||||
FontCollection collection; // 字体集
|
||||
friend class Renderer;
|
||||
|
||||
public:
|
||||
Font(
|
||||
String const& family = L"",
|
||||
float size = 18,
|
||||
uint32_t weight = FontWeight::Normal,
|
||||
bool italic = false
|
||||
);
|
||||
Font();
|
||||
|
||||
Font(
|
||||
FontCollection collection,
|
||||
String const& family = L"",
|
||||
float size = 18,
|
||||
uint32_t weight = FontWeight::Normal,
|
||||
bool italic = false
|
||||
);
|
||||
Font(String const& font_file);
|
||||
|
||||
Font(Resource const& font_resource);
|
||||
|
||||
bool Load(String const& font_file);
|
||||
|
||||
bool Load(Resource const& font_resource);
|
||||
|
||||
private:
|
||||
ComPtr<IDWriteFontCollection> GetCollection() const;
|
||||
|
||||
void SetCollection(ComPtr<IDWriteFontCollection> collection);
|
||||
|
||||
private:
|
||||
ComPtr<IDWriteFontCollection> collection_;
|
||||
};
|
||||
|
||||
inline ComPtr<IDWriteFontCollection> Font::GetCollection() const
|
||||
{
|
||||
return collection_;
|
||||
}
|
||||
|
||||
inline void Font::SetCollection(ComPtr<IDWriteFontCollection> collection)
|
||||
{
|
||||
collection_ = collection;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Kiwano - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <kiwano/renderer/FontCollection.h>
|
||||
#include <kiwano/renderer/Renderer.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
FontCollection::FontCollection()
|
||||
{
|
||||
}
|
||||
|
||||
FontCollection::FontCollection(String const& file)
|
||||
{
|
||||
Load(file);
|
||||
}
|
||||
|
||||
FontCollection::FontCollection(Vector<String> const& files)
|
||||
{
|
||||
Load(files);
|
||||
}
|
||||
|
||||
FontCollection::FontCollection(Resource const& res)
|
||||
{
|
||||
Load(res);
|
||||
}
|
||||
|
||||
FontCollection::FontCollection(Vector<Resource> const& res_arr)
|
||||
{
|
||||
Load(res_arr);
|
||||
}
|
||||
|
||||
bool FontCollection::Load(String const& file)
|
||||
{
|
||||
Renderer::instance().CreateFontCollection(*this, { file });
|
||||
return IsValid();
|
||||
}
|
||||
|
||||
bool FontCollection::Load(Vector<String> const& files)
|
||||
{
|
||||
Renderer::instance().CreateFontCollection(*this, files);
|
||||
return IsValid();
|
||||
}
|
||||
|
||||
bool FontCollection::Load(Resource const& res)
|
||||
{
|
||||
Renderer::instance().CreateFontCollection(*this, { res });
|
||||
return IsValid();
|
||||
}
|
||||
|
||||
bool FontCollection::Load(Vector<Resource> const& res_arr)
|
||||
{
|
||||
Renderer::instance().CreateFontCollection(*this, res_arr);
|
||||
return IsValid();
|
||||
}
|
||||
|
||||
bool FontCollection::IsValid() const
|
||||
{
|
||||
return collection_ != nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Kiwano - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <kiwano/core/Resource.h>
|
||||
#include <kiwano/core/win32/ComPtr.hpp>
|
||||
#include <dwrite.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
// 字体集
|
||||
class FontCollection
|
||||
{
|
||||
public:
|
||||
FontCollection();
|
||||
|
||||
FontCollection(String const& file);
|
||||
|
||||
FontCollection(Vector<String> const& files);
|
||||
|
||||
FontCollection(Resource const& res);
|
||||
|
||||
FontCollection(Vector<Resource> const& res_arr);
|
||||
|
||||
// 从本地文件加载字体
|
||||
bool Load(String const& file);
|
||||
|
||||
// 从多个本地文件加载字体
|
||||
bool Load(Vector<String> const& files);
|
||||
|
||||
// 从资源加载字体
|
||||
bool Load(Resource const& res);
|
||||
|
||||
// 从多个资源加载字体
|
||||
bool Load(Vector<Resource> const& res_arr);
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
public:
|
||||
inline ComPtr<IDWriteFontCollection> GetFontCollection() const { return collection_; }
|
||||
|
||||
inline void SetFontCollection(ComPtr<IDWriteFontCollection> collection) { collection_ = collection; }
|
||||
|
||||
private:
|
||||
ComPtr<IDWriteFontCollection> collection_;
|
||||
};
|
||||
}
|
||||
|
|
@ -333,12 +333,12 @@ namespace kiwano
|
|||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void RenderTarget::DrawTexture(TexturePtr texture, Rect const& src_rect, Rect const& dest_rect)
|
||||
void RenderTarget::DrawTexture(Texture const& texture, Rect const& src_rect, Rect const& dest_rect)
|
||||
{
|
||||
DrawTexture(texture, &src_rect, &dest_rect);
|
||||
}
|
||||
|
||||
void RenderTarget::DrawTexture(TexturePtr texture, const Rect* src_rect, const Rect* dest_rect)
|
||||
void RenderTarget::DrawTexture(Texture const& texture, const Rect* src_rect, const Rect* dest_rect)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!render_target_)
|
||||
|
|
@ -346,19 +346,14 @@ namespace kiwano
|
|||
hr = E_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (!texture)
|
||||
if (SUCCEEDED(hr) && texture.IsValid())
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) && texture->IsValid())
|
||||
{
|
||||
auto mode = (texture->GetBitmapInterpolationMode() == InterpolationMode::Linear)
|
||||
auto mode = (texture.GetBitmapInterpolationMode() == InterpolationMode::Linear)
|
||||
? D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
|
||||
: D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
|
||||
|
||||
render_target_->DrawBitmap(
|
||||
texture->GetBitmap().get(),
|
||||
texture.GetBitmap().get(),
|
||||
dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr,
|
||||
opacity_,
|
||||
mode,
|
||||
|
|
@ -381,13 +376,14 @@ namespace kiwano
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
const TextStyle& style = layout.GetStyle();
|
||||
text_renderer_->SetTextStyle(
|
||||
opacity_,
|
||||
DX::ConvertToColorF(layout.GetTextStyle().color),
|
||||
layout.GetTextStyle().outline,
|
||||
DX::ConvertToColorF(layout.GetTextStyle().outline_color),
|
||||
layout.GetTextStyle().outline_width,
|
||||
GetStrokeStyle(layout.GetTextStyle().outline_stroke).get()
|
||||
DX::ConvertToColorF(style.color),
|
||||
style.outline,
|
||||
DX::ConvertToColorF(style.outline_color),
|
||||
style.outline_width,
|
||||
GetStrokeStyle(style.outline_stroke).get()
|
||||
);
|
||||
|
||||
hr = layout.GetTextLayout()->Draw(nullptr, text_renderer_.get(), offset.x, offset.y);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#pragma once
|
||||
#include <kiwano/core/time.h>
|
||||
#include <kiwano/core/win32/ComPtr.hpp>
|
||||
#include <kiwano/renderer/Brush.h>
|
||||
#include <kiwano/renderer/Texture.h>
|
||||
#include <kiwano/renderer/Geometry.h>
|
||||
|
|
@ -106,13 +107,13 @@ namespace kiwano
|
|||
);
|
||||
|
||||
void DrawTexture(
|
||||
TexturePtr texture,
|
||||
Texture const& texture,
|
||||
Rect const& src_rect,
|
||||
Rect const& dest_rect
|
||||
);
|
||||
|
||||
void DrawTexture(
|
||||
TexturePtr texture,
|
||||
Texture const& texture,
|
||||
const Rect* src_rect = nullptr,
|
||||
const Rect* dest_rect = nullptr
|
||||
);
|
||||
|
|
|
|||
|
|
@ -577,7 +577,7 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
void Renderer::CreateFontCollection(FontCollection& collection, Vector<String> const& file_paths)
|
||||
void Renderer::CreateFontCollection(Font& font, Vector<String> const& file_paths)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!d2d_res_)
|
||||
|
|
@ -620,18 +620,15 @@ namespace kiwano
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
collection.SetFontCollection(font_collection);
|
||||
font.SetCollection(font_collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
KGE_WARN(L"Load font failed with HRESULT of %08X!", hr);
|
||||
}
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Renderer::CreateFontCollection(FontCollection& collection, Vector<Resource> const& res_arr)
|
||||
void Renderer::CreateFontCollection(Font& font, Vector<Resource> const& res_arr)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!d2d_res_)
|
||||
|
|
@ -658,18 +655,15 @@ namespace kiwano
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
collection.SetFontCollection(font_collection);
|
||||
font.SetCollection(font_collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
KGE_WARN(L"Load font failed with HRESULT of %08X!", hr);
|
||||
}
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Renderer::CreateTextFormat(TextFormat& format, Font const& font)
|
||||
void Renderer::CreateTextFormat(TextLayout& layout)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!d2d_res_)
|
||||
|
|
@ -680,18 +674,28 @@ namespace kiwano
|
|||
ComPtr<IDWriteTextFormat> output;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d2d_res_->CreateTextFormat(output, font);
|
||||
const TextStyle& style = layout.GetStyle();
|
||||
|
||||
hr = d2d_res_->CreateTextFormat(
|
||||
output,
|
||||
style.font_family,
|
||||
style.font ? style.font->GetCollection() : nullptr,
|
||||
DWRITE_FONT_WEIGHT(style.font_weight),
|
||||
style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
style.font_size
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
format.SetTextFormat(output);
|
||||
layout.SetTextFormat(output);
|
||||
}
|
||||
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Renderer::CreateTextLayout(TextLayout& layout, String const& text, TextFormat const& format)
|
||||
void Renderer::CreateTextLayout(TextLayout& layout)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!d2d_res_)
|
||||
|
|
@ -704,8 +708,8 @@ namespace kiwano
|
|||
{
|
||||
hr = d2d_res_->CreateTextLayout(
|
||||
output,
|
||||
text,
|
||||
format.GetTextFormat()
|
||||
layout.GetText(),
|
||||
layout.GetTextFormat()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include <kiwano/renderer/win32/FontCollectionLoader.h>
|
||||
#include <kiwano/renderer/RenderTarget.h>
|
||||
#include <kiwano/renderer/GifImage.h>
|
||||
#include <kiwano/renderer/Font.h>
|
||||
#include <kiwano/renderer/TextStyle.hpp>
|
||||
|
||||
#if defined(KGE_USE_DIRECTX10)
|
||||
# include "win32/D3D10DeviceResources.h"
|
||||
|
|
@ -99,24 +101,21 @@ namespace kiwano
|
|||
);
|
||||
|
||||
void CreateFontCollection(
|
||||
FontCollection& collection,
|
||||
Font& font,
|
||||
Vector<String> const& file_paths
|
||||
);
|
||||
|
||||
void CreateFontCollection(
|
||||
FontCollection& collection,
|
||||
Font& font,
|
||||
Vector<Resource> const& res_arr
|
||||
);
|
||||
|
||||
void CreateTextFormat(
|
||||
TextFormat& format,
|
||||
Font const& font
|
||||
TextLayout& layout
|
||||
);
|
||||
|
||||
void CreateTextLayout(
|
||||
TextLayout& layout,
|
||||
String const& text,
|
||||
TextFormat const& format
|
||||
TextLayout& layout
|
||||
);
|
||||
|
||||
void CreateLineGeometry(
|
||||
|
|
|
|||
|
|
@ -24,109 +24,151 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
//
|
||||
// TextFormat
|
||||
//
|
||||
|
||||
TextFormat::TextFormat()
|
||||
{
|
||||
}
|
||||
|
||||
TextFormat::TextFormat(Font const& font)
|
||||
{
|
||||
Update(font);
|
||||
}
|
||||
|
||||
void TextFormat::Update(Font const& font)
|
||||
{
|
||||
Renderer::instance().CreateTextFormat(*this, font);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TextLayout
|
||||
//
|
||||
|
||||
TextLayout::TextLayout()
|
||||
: dirty_flag_(DirtyFlag::Clean)
|
||||
{
|
||||
}
|
||||
|
||||
TextLayout::TextLayout(String const& text, Font const& font, TextStyle const& style)
|
||||
void TextLayout::Update()
|
||||
{
|
||||
UpdateFont(font);
|
||||
SetTextStyle(style);
|
||||
UpdateLayout(text);
|
||||
}
|
||||
if (!IsDirty())
|
||||
return;
|
||||
|
||||
void TextLayout::UpdateFont(Font const& font)
|
||||
if (text_.empty())
|
||||
{
|
||||
text_format_.Update(font);
|
||||
}
|
||||
|
||||
void TextLayout::UpdateLayout(String const& text)
|
||||
{
|
||||
if (text.empty())
|
||||
{
|
||||
text_format_.SetTextFormat(nullptr);
|
||||
SetTextLayout(nullptr);
|
||||
text_format_.reset();
|
||||
text_layout_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
Renderer::instance().CreateTextLayout(
|
||||
*this,
|
||||
text,
|
||||
text_format_
|
||||
);
|
||||
if (!text_format_ || (dirty_flag_ & DirtyFlag::DirtyFormat))
|
||||
{
|
||||
Renderer::instance().CreateTextFormat(*this);
|
||||
}
|
||||
|
||||
HRESULT hr = text_layout_ ? S_OK : E_FAIL;
|
||||
if (dirty_flag_ & DirtyFlag::DirtyLayout)
|
||||
{
|
||||
Renderer::instance().CreateTextLayout(*this);
|
||||
|
||||
if (text_layout_)
|
||||
{
|
||||
SetAlignment(style_.alignment);
|
||||
SetWrapWidth(style_.wrap_width);
|
||||
SetLineSpacing(style_.line_spacing);
|
||||
}
|
||||
}
|
||||
|
||||
dirty_flag_ = DirtyFlag::Clean;
|
||||
}
|
||||
|
||||
void TextLayout::SetText(const String& text)
|
||||
{
|
||||
text_ = text;
|
||||
dirty_flag_ |= DirtyFlag::DirtyLayout;
|
||||
}
|
||||
|
||||
void TextLayout::SetStyle(const TextStyle& style)
|
||||
{
|
||||
style_ = style;
|
||||
dirty_flag_ |= DirtyFlag::DirtyLayout;
|
||||
}
|
||||
|
||||
void TextLayout::SetFont(FontPtr font)
|
||||
{
|
||||
if (style_.font != font)
|
||||
{
|
||||
style_.font = font;
|
||||
dirty_flag_ |= DirtyFlag::DirtyFormat;
|
||||
}
|
||||
}
|
||||
|
||||
void TextLayout::SetFontFamily(String const& family)
|
||||
{
|
||||
if (style_.font_family != family)
|
||||
{
|
||||
style_.font_family = family;
|
||||
dirty_flag_ |= DirtyFlag::DirtyFormat;
|
||||
}
|
||||
}
|
||||
|
||||
void TextLayout::SetFontSize(float size)
|
||||
{
|
||||
if (style_.font_size != size)
|
||||
{
|
||||
style_.font_size = size;
|
||||
dirty_flag_ |= DirtyFlag::DirtyFormat;
|
||||
}
|
||||
}
|
||||
|
||||
void TextLayout::SetFontWeight(uint32_t weight)
|
||||
{
|
||||
if (style_.font_weight != weight)
|
||||
{
|
||||
style_.font_weight = weight;
|
||||
dirty_flag_ |= DirtyFlag::DirtyFormat;
|
||||
}
|
||||
}
|
||||
|
||||
void TextLayout::SetItalic(bool italic)
|
||||
{
|
||||
if (style_.italic != italic)
|
||||
{
|
||||
style_.italic = italic;
|
||||
dirty_flag_ |= DirtyFlag::DirtyFormat;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t TextLayout::GetLineCount() const
|
||||
{
|
||||
// Force to update layout
|
||||
const_cast<TextLayout*>(this)->Update();
|
||||
|
||||
if (text_layout_)
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
if (SUCCEEDED(GetTextLayout()->GetMetrics(&metrics)))
|
||||
{
|
||||
return metrics.lineCount;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Size TextLayout::GetLayoutSize() const
|
||||
{
|
||||
// Force to update layout
|
||||
const_cast<TextLayout*>(this)->Update();
|
||||
|
||||
if (text_layout_)
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
if (SUCCEEDED(GetTextLayout()->GetMetrics(&metrics)))
|
||||
{
|
||||
return (metrics.layoutWidth > 0) ? Size(metrics.layoutWidth, metrics.height) : Size(metrics.width, metrics.height);
|
||||
}
|
||||
}
|
||||
return Size();
|
||||
}
|
||||
|
||||
void TextLayout::SetWrapWidth(float wrap_width)
|
||||
{
|
||||
style_.wrap_width = wrap_width;
|
||||
|
||||
if (text_layout_)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
bool enable_wrapping = (wrap_width > 0);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (style_.line_spacing == 0.f)
|
||||
{
|
||||
hr = text_layout_->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = text_layout_->SetLineSpacing(
|
||||
DWRITE_LINE_SPACING_METHOD_UNIFORM,
|
||||
style_.line_spacing,
|
||||
style_.line_spacing * 0.8f
|
||||
);
|
||||
}
|
||||
hr = text_layout_->SetWordWrapping(enable_wrapping ? DWRITE_WORD_WRAPPING_WRAP : DWRITE_WORD_WRAPPING_NO_WRAP);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = text_layout_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(style_.alignment));
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
if (enable_wrapping)
|
||||
{
|
||||
hr = text_layout_->SetWordWrapping((style_.wrap_width > 0) ? DWRITE_WORD_WRAPPING_WRAP : DWRITE_WORD_WRAPPING_NO_WRAP);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (style_.underline)
|
||||
{
|
||||
hr = text_layout_->SetUnderline(true, { 0, UINT32(text.length()) });
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (style_.strikethrough)
|
||||
{
|
||||
text_layout_->SetStrikethrough(true, { 0, UINT32(text.length()) });
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (style_.wrap_width > 0)
|
||||
{
|
||||
hr = text_layout_->SetMaxWidth(style_.wrap_width);
|
||||
hr = text_layout_->SetMaxWidth(wrap_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -140,34 +182,66 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
}
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
}
|
||||
|
||||
void TextLayout::SetLineSpacing(float line_spacing)
|
||||
{
|
||||
style_.line_spacing = line_spacing;
|
||||
|
||||
if (text_layout_)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (line_spacing == 0.f)
|
||||
{
|
||||
hr = text_layout_->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = text_layout_->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_UNIFORM, line_spacing, line_spacing * 0.8f);
|
||||
}
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
}
|
||||
|
||||
void TextLayout::SetAlignment(TextAlign align)
|
||||
{
|
||||
style_.alignment = align;
|
||||
|
||||
if (text_layout_)
|
||||
{
|
||||
HRESULT hr = text_layout_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(align));
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
}
|
||||
|
||||
void TextLayout::SetUnderline(bool enable, uint32_t start, uint32_t length)
|
||||
{
|
||||
// Force to update layout
|
||||
Update();
|
||||
|
||||
HRESULT hr = text_layout_ ? S_OK : E_FAIL;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = text_layout_->SetUnderline(enable, { start, length });
|
||||
}
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
uint32_t TextLayout::GetLineCount()
|
||||
void TextLayout::SetStrikethrough(bool enable, uint32_t start, uint32_t length)
|
||||
{
|
||||
if (text_layout_)
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
if (SUCCEEDED(text_layout_->GetMetrics(&metrics)))
|
||||
{
|
||||
return metrics.lineCount;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// Force to update layout
|
||||
Update();
|
||||
|
||||
Size TextLayout::GetLayoutSize() const
|
||||
HRESULT hr = text_layout_ ? S_OK : E_FAIL;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (text_layout_)
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
if (SUCCEEDED(text_layout_->GetMetrics(&metrics)))
|
||||
{
|
||||
return (metrics.layoutWidth > 0) ? Size(metrics.layoutWidth, metrics.height) : Size(metrics.width, metrics.height);
|
||||
hr = text_layout_->SetStrikethrough(enable, { start, length });
|
||||
}
|
||||
}
|
||||
return Size();
|
||||
ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,63 +20,209 @@
|
|||
|
||||
#pragma once
|
||||
#include <kiwano/math/math.h>
|
||||
#include <kiwano/renderer/Font.h>
|
||||
#include <kiwano/2d/TextStyle.hpp>
|
||||
#include <kiwano/renderer/TextStyle.hpp>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
// Îı¾¸ñʽ»¯
|
||||
class KGE_API TextFormat
|
||||
{
|
||||
public:
|
||||
TextFormat();
|
||||
|
||||
TextFormat(Font const& font);
|
||||
|
||||
void Update(Font const& font);
|
||||
|
||||
public:
|
||||
inline ComPtr<IDWriteTextFormat> GetTextFormat() const { return text_format_; }
|
||||
|
||||
inline void SetTextFormat(ComPtr<IDWriteTextFormat> format) { text_format_ = format; }
|
||||
|
||||
private:
|
||||
ComPtr<IDWriteTextFormat> text_format_;
|
||||
};
|
||||
|
||||
|
||||
// Îı¾²¼¾Ö
|
||||
/// \~chinese
|
||||
/// @brief 文本布局
|
||||
class KGE_API TextLayout
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 构造空的文本布局
|
||||
TextLayout();
|
||||
|
||||
TextLayout(String const& text, Font const& font, TextStyle const& style);
|
||||
/// \~chinese
|
||||
/// @brief 文本布局是否有效
|
||||
bool IsValid() const;
|
||||
|
||||
void UpdateFont(Font const& font);
|
||||
/// \~chinese
|
||||
/// @brief 文本布局是否陈旧
|
||||
bool IsDirty() const;
|
||||
|
||||
void UpdateLayout(String const& text);
|
||||
/// \~chinese
|
||||
/// @brief 更新文本布局
|
||||
/// @note 文本布局是懒更新的,在修改文本布局的属性后需要手动更新
|
||||
void Update();
|
||||
|
||||
uint32_t GetLineCount();
|
||||
/// \~chinese
|
||||
/// @brief 获取文本
|
||||
const String& GetText() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取文本样式
|
||||
const TextStyle& GetStyle() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取文本行数
|
||||
uint32_t GetLineCount() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取文本布局大小
|
||||
Size GetLayoutSize() const;
|
||||
|
||||
inline TextStyle& GetTextStyle() { return style_; }
|
||||
inline TextStyle const& GetTextStyle() const { return style_; }
|
||||
inline void SetTextStyle(TextStyle const& style) { style_ = style; }
|
||||
/// \~chinese
|
||||
/// @brief 设置文本
|
||||
void SetText(const String& text);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文本样式
|
||||
void SetStyle(const TextStyle& style);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置字体
|
||||
void SetFont(FontPtr font);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置字体族
|
||||
void SetFontFamily(String const& family);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置字号(默认值为 18)
|
||||
void SetFontSize(float size);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置字体粗细值(默认值为 FontWeight::Normal)
|
||||
void SetFontWeight(uint32_t weight);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文字颜色(默认值为 Color::White)
|
||||
void SetColor(Color const& color);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文字斜体(默认值为 false)
|
||||
void SetItalic(bool italic);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置文本自动换行的宽度
|
||||
void SetWrapWidth(float wrap_width);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置行间距(默认为 0)
|
||||
void SetLineSpacing(float line_spacing);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置对齐方式
|
||||
void SetAlignment(TextAlign align);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置是否显示描边
|
||||
void SetOutline(bool enable);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置描边颜色
|
||||
void SetOutlineColor(Color const& outline_color);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置描边线宽
|
||||
void SetOutlineWidth(float outline_width);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置描边线相交样式
|
||||
void SetOutlineStroke(StrokeStyle outline_stroke);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置下划线
|
||||
/// @param enable 是否显示下划线
|
||||
/// @param start 起始位置
|
||||
/// @param length 长度
|
||||
void SetUnderline(bool enable, uint32_t start, uint32_t length);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置删除线
|
||||
/// @param enable 是否显示删除线
|
||||
/// @param start 起始位置
|
||||
/// @param length 长度
|
||||
void SetStrikethrough(bool enable, uint32_t start, uint32_t length);
|
||||
|
||||
public:
|
||||
inline TextFormat GetTextFormat() const { return text_format_; }
|
||||
ComPtr<IDWriteTextFormat> GetTextFormat() const;
|
||||
|
||||
inline ComPtr<IDWriteTextLayout> GetTextLayout() const { return text_layout_; }
|
||||
void SetTextFormat(ComPtr<IDWriteTextFormat> format);
|
||||
|
||||
inline void SetTextLayout(ComPtr<IDWriteTextLayout> layout) { text_layout_ = layout; }
|
||||
ComPtr<IDWriteTextLayout> GetTextLayout() const;
|
||||
|
||||
inline operator bool() const { return static_cast<bool>(text_layout_); }
|
||||
void SetTextLayout(ComPtr<IDWriteTextLayout> layout);
|
||||
|
||||
private:
|
||||
TextStyle style_;
|
||||
TextFormat text_format_;
|
||||
mutable ComPtr<IDWriteTextLayout> text_layout_;
|
||||
enum DirtyFlag : uint8_t
|
||||
{
|
||||
Clean = 0,
|
||||
DirtyFormat = 1,
|
||||
DirtyLayout = 1 << 1,
|
||||
};
|
||||
uint8_t dirty_flag_;
|
||||
|
||||
ComPtr<IDWriteTextFormat> text_format_;
|
||||
ComPtr<IDWriteTextLayout> text_layout_;
|
||||
|
||||
String text_;
|
||||
TextStyle style_;
|
||||
};
|
||||
|
||||
inline bool TextLayout::IsValid() const
|
||||
{
|
||||
return !!text_layout_;
|
||||
}
|
||||
|
||||
inline bool TextLayout::IsDirty() const
|
||||
{
|
||||
return dirty_flag_ != DirtyFlag::Clean;
|
||||
}
|
||||
|
||||
inline const String& TextLayout::GetText() const
|
||||
{
|
||||
return text_;
|
||||
}
|
||||
|
||||
inline const TextStyle& TextLayout::GetStyle() const
|
||||
{
|
||||
return style_;
|
||||
}
|
||||
|
||||
inline ComPtr<IDWriteTextFormat> TextLayout::GetTextFormat() const
|
||||
{
|
||||
return text_format_;
|
||||
}
|
||||
|
||||
inline ComPtr<IDWriteTextLayout> TextLayout::GetTextLayout() const
|
||||
{
|
||||
return text_layout_;
|
||||
}
|
||||
|
||||
inline void TextLayout::SetColor(Color const& color)
|
||||
{
|
||||
style_.color = color;
|
||||
}
|
||||
|
||||
inline void TextLayout::SetTextFormat(ComPtr<IDWriteTextFormat> format)
|
||||
{
|
||||
text_format_ = format;
|
||||
}
|
||||
|
||||
inline void TextLayout::SetTextLayout(ComPtr<IDWriteTextLayout> layout)
|
||||
{
|
||||
text_layout_ = layout;
|
||||
}
|
||||
|
||||
inline void TextLayout::SetOutline(bool enable)
|
||||
{
|
||||
style_.outline = enable;
|
||||
}
|
||||
|
||||
inline void TextLayout::SetOutlineColor(Color const& outline_color)
|
||||
{
|
||||
style_.outline_color = outline_color;
|
||||
}
|
||||
|
||||
inline void TextLayout::SetOutlineWidth(float outline_width)
|
||||
{
|
||||
style_.outline_width = outline_width;
|
||||
}
|
||||
|
||||
inline void TextLayout::SetOutlineStroke(StrokeStyle outline_stroke)
|
||||
{
|
||||
style_.outline_stroke = outline_stroke;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#pragma once
|
||||
#include <kiwano/renderer/Color.h>
|
||||
#include <kiwano/renderer/StrokeStyle.h>
|
||||
#include <kiwano/renderer/Font.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
|
|
@ -35,6 +36,26 @@ namespace kiwano
|
|||
Center ///< 居中对齐
|
||||
};
|
||||
|
||||
/**
|
||||
* \~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 文本样式
|
||||
|
|
@ -42,12 +63,15 @@ namespace kiwano
|
|||
class KGE_API TextStyle
|
||||
{
|
||||
public:
|
||||
FontPtr font; ///< 字体
|
||||
String font_family; ///< 字体族
|
||||
float font_size; ///< 字号
|
||||
uint32_t font_weight; ///< 粗细值
|
||||
bool italic; ///< 是否斜体
|
||||
Color color; ///< 颜色
|
||||
TextAlign alignment; ///< 对齐方式
|
||||
float wrap_width; ///< 自动换行宽度
|
||||
float line_spacing; ///< 行间距
|
||||
bool underline; ///< 下划线
|
||||
bool strikethrough; ///< 删除线
|
||||
bool outline; ///< 描边
|
||||
Color outline_color; ///< 描边颜色
|
||||
float outline_width; ///< 描边线宽
|
||||
|
|
@ -57,35 +81,44 @@ namespace kiwano
|
|||
/**
|
||||
* \~chinese
|
||||
* @brief 构建文本样式
|
||||
* @param font 字体
|
||||
* @param font_family 字体族
|
||||
* @param font_size 字体大小
|
||||
* @param font_weight 字体粗细
|
||||
* @param italic 斜体
|
||||
* @param color 颜色
|
||||
* @param alignment 对齐方式
|
||||
* @param wrap_width 自动换行宽度
|
||||
* @param line_spacing 行间距
|
||||
* @param underline 下划线
|
||||
* @param strikethrough 删除线
|
||||
* @param outline 描边
|
||||
* @param outline_color 描边颜色
|
||||
* @param outline_width 描边线宽
|
||||
* @param outline_stroke 描边线相交样式
|
||||
*/
|
||||
TextStyle(
|
||||
FontPtr font = nullptr,
|
||||
const String& font_family = String(),
|
||||
float font_size = 18,
|
||||
uint32_t font_weight = FontWeight::Normal,
|
||||
bool italic = false,
|
||||
Color color = Color::White,
|
||||
TextAlign alignment = TextAlign::Left,
|
||||
float wrap_width = 0.f,
|
||||
float line_spacing = 0.f,
|
||||
bool underline = false,
|
||||
bool strikethrough = false,
|
||||
bool outline = false,
|
||||
Color outline_color = Color(Color::Black, 0.5),
|
||||
float outline_width = 1.f,
|
||||
StrokeStyle outline_stroke = StrokeStyle::Round
|
||||
)
|
||||
: color(color)
|
||||
: font(nullptr)
|
||||
, font_family(font_family)
|
||||
, font_size(font_size)
|
||||
, font_weight(font_weight)
|
||||
, italic(italic)
|
||||
, color(color)
|
||||
, alignment(alignment)
|
||||
, wrap_width(wrap_width)
|
||||
, line_spacing(line_spacing)
|
||||
, underline(underline)
|
||||
, strikethrough(strikethrough)
|
||||
, outline(outline)
|
||||
, outline_color(outline_color)
|
||||
, outline_width(outline_width)
|
||||
|
|
@ -65,7 +65,12 @@ namespace kiwano
|
|||
|
||||
HRESULT CreateTextFormat(
|
||||
_Out_ ComPtr<IDWriteTextFormat>& text_format,
|
||||
_In_ Font const& font
|
||||
_In_ String const& family,
|
||||
_In_ ComPtr<IDWriteFontCollection> collection,
|
||||
_In_ DWRITE_FONT_WEIGHT weight,
|
||||
_In_ DWRITE_FONT_STYLE style,
|
||||
_In_ DWRITE_FONT_STRETCH stretch,
|
||||
_In_ FLOAT font_size
|
||||
) override;
|
||||
|
||||
HRESULT CreateTextLayout(
|
||||
|
|
@ -435,19 +440,20 @@ namespace kiwano
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat> & text_format, _In_ Font const & font)
|
||||
HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat> & text_format, _In_ String const& family, _In_ ComPtr<IDWriteFontCollection> collection,
|
||||
_In_ DWRITE_FONT_WEIGHT weight, _In_ DWRITE_FONT_STYLE style, _In_ DWRITE_FONT_STRETCH stretch, _In_ FLOAT font_size)
|
||||
{
|
||||
if (!dwrite_factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
ComPtr<IDWriteTextFormat> output;
|
||||
HRESULT hr = dwrite_factory_->CreateTextFormat(
|
||||
font.family.c_str(),
|
||||
font.collection.GetFontCollection().get(),
|
||||
DWRITE_FONT_WEIGHT(font.weight),
|
||||
font.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
font.size,
|
||||
family.c_str(),
|
||||
collection.get(),
|
||||
weight,
|
||||
style,
|
||||
stretch,
|
||||
font_size,
|
||||
L"",
|
||||
&output
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <kiwano/renderer/Font.h>
|
||||
#include <kiwano/renderer/Color.h>
|
||||
#include <kiwano/math/math.h>
|
||||
#include <kiwano/core/Resource.h>
|
||||
#include <kiwano/core/win32/ComPtr.hpp>
|
||||
#include <kiwano/renderer/Color.h>
|
||||
#include <dwrite.h>
|
||||
#include <d2d1.h>
|
||||
#include <d2d1_1.h>
|
||||
|
|
@ -216,7 +216,12 @@ namespace kiwano
|
|||
|
||||
virtual HRESULT CreateTextFormat(
|
||||
_Out_ ComPtr<IDWriteTextFormat>& text_format,
|
||||
_In_ Font const& font
|
||||
_In_ String const& family,
|
||||
_In_ ComPtr<IDWriteFontCollection> collection,
|
||||
_In_ DWRITE_FONT_WEIGHT weight,
|
||||
_In_ DWRITE_FONT_STYLE style,
|
||||
_In_ DWRITE_FONT_STRETCH stretch,
|
||||
_In_ FLOAT font_size
|
||||
) = 0;
|
||||
|
||||
virtual HRESULT CreateTextLayout(
|
||||
|
|
|
|||
|
|
@ -22,9 +22,6 @@
|
|||
#include <kiwano/utils/ResourceCache.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <kiwano/platform/FileSystem.h>
|
||||
#include <kiwano/renderer/GifImage.h>
|
||||
#include <kiwano/renderer/FontCollection.h>
|
||||
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
|
|
@ -187,29 +184,6 @@ namespace kiwano
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ResourceCache::AddFrame(String const& id, String const& file_path)
|
||||
{
|
||||
FramePtr ptr = new (std::nothrow) Frame;
|
||||
if (ptr)
|
||||
{
|
||||
if (ptr->Load(file_path))
|
||||
{
|
||||
return AddFrame(id, ptr);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ResourceCache::AddFrame(String const & id, FramePtr frame)
|
||||
{
|
||||
if (frame)
|
||||
{
|
||||
object_cache_.insert(std::make_pair(id, frame));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t ResourceCache::AddFrameSequence(String const& id, Vector<String> const& files)
|
||||
{
|
||||
if (files.empty())
|
||||
|
|
@ -233,7 +207,7 @@ namespace kiwano
|
|||
if (!frames.empty())
|
||||
{
|
||||
FrameSequencePtr fs = new (std::nothrow) FrameSequence(frames);
|
||||
return AddFrameSequence(id, fs);
|
||||
return AddObject(id, fs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -273,20 +247,10 @@ namespace kiwano
|
|||
}
|
||||
|
||||
FrameSequencePtr fs = new (std::nothrow) FrameSequence(frames);
|
||||
return AddFrameSequence(id, fs);
|
||||
return AddObject(id, fs);
|
||||
}
|
||||
|
||||
size_t ResourceCache::AddFrameSequence(String const & id, FrameSequencePtr frames)
|
||||
{
|
||||
if (frames)
|
||||
{
|
||||
object_cache_.insert(std::make_pair(id, frames));
|
||||
return frames->GetFrames().size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ResourceCache::AddObjectBase(String const& id, ObjectBasePtr obj)
|
||||
bool ResourceCache::AddObject(String const& id, ObjectBasePtr obj)
|
||||
{
|
||||
if (obj)
|
||||
{
|
||||
|
|
@ -296,59 +260,6 @@ namespace kiwano
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ResourceCache::AddGifImage(String const& id, GifImagePtr gif)
|
||||
{
|
||||
if (gif && gif->IsValid())
|
||||
{
|
||||
object_cache_.insert(std::make_pair(id, gif));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ResourceCache::AddGifImage(String const& id, String const& file_path)
|
||||
{
|
||||
GifImagePtr gif = new (std::nothrow) GifImage;
|
||||
if (gif && gif->Load(file_path))
|
||||
{
|
||||
return AddGifImage(id, gif);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ResourceCache::AddFontCollection(String const& id, FontCollection const& collection)
|
||||
{
|
||||
if (collection.IsValid())
|
||||
{
|
||||
font_collection_cache_.insert(std::make_pair(id, collection));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FramePtr ResourceCache::GetFrame(String const & id) const
|
||||
{
|
||||
return Get<Frame>(id);
|
||||
}
|
||||
|
||||
FrameSequencePtr ResourceCache::GetFrameSequence(String const & id) const
|
||||
{
|
||||
return Get<FrameSequence>(id);
|
||||
}
|
||||
|
||||
GifImagePtr ResourceCache::GetGifImage(String const& id) const
|
||||
{
|
||||
return Get<GifImage>(id);
|
||||
}
|
||||
|
||||
FontCollection ResourceCache::GetFontCollection(String const& id) const
|
||||
{
|
||||
auto iter = font_collection_cache_.find(id);
|
||||
if (iter != font_collection_cache_.end())
|
||||
return iter->second;
|
||||
return FontCollection();
|
||||
}
|
||||
|
||||
void ResourceCache::Remove(String const & id)
|
||||
{
|
||||
object_cache_.erase(id);
|
||||
|
|
@ -357,7 +268,14 @@ namespace kiwano
|
|||
void ResourceCache::Clear()
|
||||
{
|
||||
object_cache_.clear();
|
||||
font_collection_cache_.clear();
|
||||
}
|
||||
|
||||
ObjectBasePtr ResourceCache::Get(String const& id) const
|
||||
{
|
||||
auto iter = object_cache_.find(id);
|
||||
if (iter == object_cache_.end())
|
||||
return nullptr;
|
||||
return (*iter).second;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -378,13 +296,21 @@ namespace kiwano
|
|||
if (type && (*type) == L"gif")
|
||||
{
|
||||
// GIF image
|
||||
return loader->AddGifImage(*id, gdata->path + (*file));
|
||||
GifImagePtr gif = new (std::nothrow) GifImage;
|
||||
if (gif && gif->Load(gdata->path + (*file)))
|
||||
{
|
||||
return loader->AddObject(*id, gif);
|
||||
}
|
||||
}
|
||||
|
||||
if (file && !(*file).empty())
|
||||
{
|
||||
// Simple image
|
||||
return loader->AddFrame(*id, gdata->path + (*file));
|
||||
FramePtr frame = new (std::nothrow) Frame;
|
||||
if (frame && frame->Load(gdata->path + (*file)))
|
||||
{
|
||||
return loader->AddObject(*id, frame);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -407,7 +333,7 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
FrameSequencePtr frame_seq = new FrameSequence(frames);
|
||||
return !!loader->AddFrameSequence(*id, frame_seq);
|
||||
return !!loader->AddObject(*id, frame_seq);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -429,30 +355,27 @@ namespace kiwano
|
|||
else
|
||||
{
|
||||
// Simple image
|
||||
return loader->AddFrame(*id, gdata->path + (*file));
|
||||
FramePtr frame = new (std::nothrow) Frame;
|
||||
if (frame && frame->Load(gdata->path + (*file)))
|
||||
{
|
||||
return loader->AddObject(*id, frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoadFontsFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const Vector<String>* files)
|
||||
bool LoadFontsFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* file)
|
||||
{
|
||||
if (!gdata || !id) return false;
|
||||
|
||||
// Font Collection
|
||||
if (files)
|
||||
if (file)
|
||||
{
|
||||
Vector<String> files_copy(*files);
|
||||
for (auto& file : files_copy)
|
||||
FontPtr font = new (std::nothrow) Font;
|
||||
if (font && font->Load(gdata->path + (*file)))
|
||||
{
|
||||
file = gdata->path + file;
|
||||
}
|
||||
|
||||
FontCollection collection;
|
||||
if (collection.Load(files_copy))
|
||||
{
|
||||
return loader->AddFontCollection(*id, collection);
|
||||
return loader->AddObject(*id, font);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
@ -512,22 +435,15 @@ namespace kiwano
|
|||
{
|
||||
for (const auto& font : json_data[L"fonts"])
|
||||
{
|
||||
String id;
|
||||
const String *id = nullptr, *file = nullptr;
|
||||
|
||||
if (font.count(L"id")) id = font[L"id"].as_string();
|
||||
if (font.count(L"files"))
|
||||
{
|
||||
Vector<String> files;
|
||||
files.reserve(font[L"files"].size());
|
||||
for (const auto& file : font[L"files"])
|
||||
{
|
||||
files.push_back(file.as_string());
|
||||
}
|
||||
if (!LoadFontsFromData(loader, &global_data, &id, &files))
|
||||
if (font.count(L"id")) id = &font[L"id"].as_string();
|
||||
if (font.count(L"file")) file = &font[L"file"].as_string();
|
||||
|
||||
if (!LoadFontsFromData(loader, &global_data, id, file))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -587,18 +503,11 @@ namespace kiwano
|
|||
{
|
||||
for (auto font = fonts->FirstChildElement(); font; font = font->NextSiblingElement())
|
||||
{
|
||||
String id;
|
||||
String id, file;
|
||||
if (auto attr = font->Attribute(L"id")) id.assign(attr);
|
||||
if (auto attr = font->Attribute(L"file")) file.assign(attr);
|
||||
|
||||
Vector<String> files_arr;
|
||||
for (auto file = font->FirstChildElement(); file; file = file->NextSiblingElement())
|
||||
{
|
||||
if (auto path = file->Attribute(L"path"))
|
||||
{
|
||||
files_arr.push_back(path);
|
||||
}
|
||||
}
|
||||
if (!LoadFontsFromData(loader, &global_data, &id, &files_arr))
|
||||
if (!LoadFontsFromData(loader, &global_data, &id, &file))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <kiwano/2d/Frame.h>
|
||||
#include <kiwano/2d/FrameSequence.h>
|
||||
#include <kiwano/renderer/GifImage.h>
|
||||
#include <kiwano/renderer/Font.h>
|
||||
#include <3rd-party/tinyxml2/tinyxml2.h>
|
||||
|
||||
namespace kiwano
|
||||
|
|
@ -46,11 +47,8 @@ namespace kiwano
|
|||
// 从 XML 文档对象加载资源信息
|
||||
bool LoadFromXml(const tinyxml2::XMLDocument* doc);
|
||||
|
||||
// Ìí¼Ó֡ͼÏñ
|
||||
bool AddFrame(String const& id, String const& file_path);
|
||||
|
||||
// Ìí¼Ó֡ͼÏñ
|
||||
bool AddFrame(String const& id, FramePtr frame);
|
||||
// 添加对象
|
||||
bool AddObject(String const& id, ObjectBasePtr obj);
|
||||
|
||||
// 添加序列帧
|
||||
size_t AddFrameSequence(String const& id, Vector<String> const& files);
|
||||
|
|
@ -59,46 +57,18 @@ namespace kiwano
|
|||
// 按行列数裁剪图片
|
||||
size_t AddFrameSequence(String const& id, String const& file_path, int cols, int rows = 1, float padding_x = 0, float padding_y = 0);
|
||||
|
||||
// Ìí¼ÓÐòÁÐÖ¡
|
||||
size_t AddFrameSequence(String const& id, FrameSequencePtr frames);
|
||||
|
||||
// Ìí¼Ó¶ÔÏó
|
||||
bool AddObjectBase(String const& id, ObjectBasePtr obj);
|
||||
|
||||
// Ìí¼Ó GIF ͼÏñ
|
||||
bool AddGifImage(String const& id, GifImagePtr gif);
|
||||
|
||||
// Ìí¼Ó GIF ͼÏñ
|
||||
bool AddGifImage(String const& id, String const& file_path);
|
||||
|
||||
// Ìí¼Ó×ÖÌ弯
|
||||
bool AddFontCollection(String const& id, FontCollection const& collection);
|
||||
|
||||
// »ñȡ֡ͼÏñ
|
||||
FramePtr GetFrame(String const& id) const;
|
||||
|
||||
// »ñÈ¡ÐòÁÐÖ¡
|
||||
FrameSequencePtr GetFrameSequence(String const& id) const;
|
||||
|
||||
// »ñÈ¡ GIF ͼÏñ
|
||||
GifImagePtr GetGifImage(String const& id) const;
|
||||
|
||||
// »ñÈ¡×ÖÌ弯
|
||||
FontCollection GetFontCollection(String const& id) const;
|
||||
|
||||
// 删除指定资源
|
||||
void Remove(String const& id);
|
||||
|
||||
// 清空所有资源
|
||||
void Clear();
|
||||
|
||||
ObjectBasePtr Get(String const& id) const;
|
||||
|
||||
template<typename _Ty>
|
||||
_Ty* Get(String const& id) const
|
||||
SmartPtr<_Ty> Get(String const& id) const
|
||||
{
|
||||
auto iter = object_cache_.find(id);
|
||||
if (iter == object_cache_.end())
|
||||
return nullptr;
|
||||
return const_cast<_Ty*>(dynamic_cast<const _Ty*>((*iter).second.get()));
|
||||
return dynamic_cast<_Ty*>(Get(id).get());
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -108,6 +78,5 @@ namespace kiwano
|
|||
|
||||
private:
|
||||
UnorderedMap<String, ObjectBasePtr> object_cache_;
|
||||
UnorderedMap<String, FontCollection> font_collection_cache_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue