add SpriteFrame & BinaryData & AnimationEventHandler

This commit is contained in:
Nomango 2020-10-11 03:45:42 +08:00
parent d9feebae31
commit e9c8ca63ad
31 changed files with 504 additions and 399 deletions

View File

@ -7,7 +7,6 @@
<ClInclude Include="..\..\src\kiwano\2d\animation\AnimationGroup.h" /> <ClInclude Include="..\..\src\kiwano\2d\animation\AnimationGroup.h" />
<ClInclude Include="..\..\src\kiwano\2d\animation\Animator.h" /> <ClInclude Include="..\..\src\kiwano\2d\animation\Animator.h" />
<ClInclude Include="..\..\src\kiwano\2d\animation\FrameSequence.h" /> <ClInclude Include="..\..\src\kiwano\2d\animation\FrameSequence.h" />
<ClInclude Include="..\..\src\kiwano\2d\animation\KeyFrame.h" />
<ClInclude Include="..\..\src\kiwano\2d\animation\TweenAnimation.h" /> <ClInclude Include="..\..\src\kiwano\2d\animation\TweenAnimation.h" />
<ClInclude Include="..\..\src\kiwano\2d\animation\PathAnimation.h" /> <ClInclude Include="..\..\src\kiwano\2d\animation\PathAnimation.h" />
<ClInclude Include="..\..\src\kiwano\2d\animation\AnimationWrapper.h" /> <ClInclude Include="..\..\src\kiwano\2d\animation\AnimationWrapper.h" />
@ -15,6 +14,7 @@
<ClInclude Include="..\..\src\kiwano\2d\animation\FrameAnimation.h" /> <ClInclude Include="..\..\src\kiwano\2d\animation\FrameAnimation.h" />
<ClInclude Include="..\..\src\kiwano\2d\animation\EaseFunc.h" /> <ClInclude Include="..\..\src\kiwano\2d\animation\EaseFunc.h" />
<ClInclude Include="..\..\src\kiwano\2d\GifSprite.h" /> <ClInclude Include="..\..\src\kiwano\2d\GifSprite.h" />
<ClInclude Include="..\..\src\kiwano\2d\SpriteFrame.h" />
<ClInclude Include="..\..\src\kiwano\base\component\Button.h" /> <ClInclude Include="..\..\src\kiwano\base\component\Button.h" />
<ClInclude Include="..\..\src\kiwano\base\component\Component.h" /> <ClInclude Include="..\..\src\kiwano\base\component\Component.h" />
<ClInclude Include="..\..\src\kiwano\base\component\ComponentManager.h" /> <ClInclude Include="..\..\src\kiwano\base\component\ComponentManager.h" />
@ -25,6 +25,7 @@
<ClInclude Include="..\..\src\kiwano\base\RefPtr.h" /> <ClInclude Include="..\..\src\kiwano\base\RefPtr.h" />
<ClInclude Include="..\..\src\kiwano\core\Allocator.h" /> <ClInclude Include="..\..\src\kiwano\core\Allocator.h" />
<ClInclude Include="..\..\src\kiwano\core\Any.h" /> <ClInclude Include="..\..\src\kiwano\core\Any.h" />
<ClInclude Include="..\..\src\kiwano\core\BinaryData.h" />
<ClInclude Include="..\..\src\kiwano\core\BitOperator.h" /> <ClInclude Include="..\..\src\kiwano\core\BitOperator.h" />
<ClInclude Include="..\..\src\kiwano\core\Cloneable.h" /> <ClInclude Include="..\..\src\kiwano\core\Cloneable.h" />
<ClInclude Include="..\..\src\kiwano\core\Common.h" /> <ClInclude Include="..\..\src\kiwano\core\Common.h" />
@ -124,7 +125,6 @@
<ClCompile Include="..\..\src\kiwano\2d\animation\AnimationGroup.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\animation\AnimationGroup.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\animation\Animator.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\animation\Animator.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\animation\FrameSequence.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\animation\FrameSequence.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\animation\KeyFrame.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\animation\TweenAnimation.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\animation\TweenAnimation.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\animation\PathAnimation.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\animation\PathAnimation.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\animation\CustomAnimation.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\animation\CustomAnimation.cpp" />
@ -135,6 +135,7 @@
<ClCompile Include="..\..\src\kiwano\2d\ShapeActor.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\ShapeActor.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\GifSprite.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\GifSprite.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\LayerActor.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\LayerActor.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\SpriteFrame.h.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Stage.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\Stage.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\Sprite.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\Sprite.cpp" />
<ClCompile Include="..\..\src\kiwano\2d\TextActor.cpp" /> <ClCompile Include="..\..\src\kiwano\2d\TextActor.cpp" />

View File

@ -372,12 +372,15 @@
<ClInclude Include="..\..\src\kiwano\2d\animation\FrameSequence.h"> <ClInclude Include="..\..\src\kiwano\2d\animation\FrameSequence.h">
<Filter>2d\animation</Filter> <Filter>2d\animation</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\animation\KeyFrame.h">
<Filter>2d\animation</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\animation\AnimationWrapper.h"> <ClInclude Include="..\..\src\kiwano\2d\animation\AnimationWrapper.h">
<Filter>2d\animation</Filter> <Filter>2d\animation</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\core\BinaryData.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\2d\SpriteFrame.h">
<Filter>2d</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp"> <ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
@ -617,8 +620,8 @@
<ClCompile Include="..\..\src\kiwano\2d\animation\FrameSequence.cpp"> <ClCompile Include="..\..\src\kiwano\2d\animation\FrameSequence.cpp">
<Filter>2d\animation</Filter> <Filter>2d\animation</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\2d\animation\KeyFrame.cpp"> <ClCompile Include="..\..\src\kiwano\2d\SpriteFrame.h.cpp">
<Filter>2d\animation</Filter> <Filter>2d</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -94,7 +94,7 @@ HRESULT Transcoder::LoadMediaResource(const Resource& res)
ComPtr<IMFByteStream> byte_stream; ComPtr<IMFByteStream> byte_stream;
ComPtr<IMFSourceReader> reader; ComPtr<IMFSourceReader> reader;
Resource::Data data = res.GetData(); BinaryData data = res.GetData();
if (!data.IsValid()) if (!data.IsValid())
{ {
return E_FAIL; return E_FAIL;

View File

@ -20,7 +20,7 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/animation/KeyFrame.h> #include <kiwano/2d/SpriteFrame.h>
#include <kiwano/render/ShapeMaker.h> #include <kiwano/render/ShapeMaker.h>
#include <kiwano/render/RenderContext.h> #include <kiwano/render/RenderContext.h>
@ -164,6 +164,19 @@ public:
/// @param crop_rect 纹理裁剪矩形 /// @param crop_rect 纹理裁剪矩形
void DrawTexture(TexturePtr texture, const Point& pos, const Size& size, const Rect* crop_rect = nullptr); void DrawTexture(TexturePtr texture, const Point& pos, const Size& size, const Rect* crop_rect = nullptr);
/// \~chinese
/// @brief 绘制精灵帧
/// @param frame 精灵帧
/// @param pos 绘制的目标位置
void DrawSpriteFrame(const SpriteFrame& frame, const Point& pos);
/// \~chinese
/// @brief 绘制精灵帧
/// @param frame 精灵帧
/// @param pos 绘制的目标位置
/// @param size 绘制的目标大小
void DrawSpriteFrame(const SpriteFrame& frame, const Point& pos, const Size& size);
/// \~chinese /// \~chinese
/// @brief 绘制文字布局 /// @brief 绘制文字布局
/// @param text 文字 /// @param text 文字
@ -402,6 +415,16 @@ inline void CanvasRenderContext::DrawTexture(TexturePtr texture, const Point& po
} }
} }
inline void CanvasRenderContext::DrawSpriteFrame(const SpriteFrame& frame, const Point& pos)
{
this->DrawSpriteFrame(frame, pos, frame.GetCropRect().GetSize());
}
inline void CanvasRenderContext::DrawSpriteFrame(const SpriteFrame& frame, const Point& pos, const Size& size)
{
this->DrawTexture(frame.GetTexture(), pos, size, &frame.GetCropRect());
}
inline void CanvasRenderContext::DrawTextLayout(const String& text, const TextStyle& style, const Point& point) inline void CanvasRenderContext::DrawTextLayout(const String& text, const TextStyle& style, const Point& point)
{ {
TextLayoutPtr layout = MakePtr<TextLayout>(text, style); TextLayoutPtr layout = MakePtr<TextLayout>(text, style);

View File

@ -38,35 +38,37 @@ Sprite::Sprite(const Resource& res)
Sprite::Sprite(TexturePtr texture) Sprite::Sprite(TexturePtr texture)
{ {
SetTexture(texture); SetFrame(SpriteFrame(texture));
} }
Sprite::Sprite(const String& file_path, const Rect& crop_rect) Sprite::Sprite(const String& file_path, const Rect& crop_rect)
: Sprite(file_path)
{ {
SetCropRect(crop_rect); SetFrame(SpriteFrame(file_path, crop_rect));
} }
Sprite::Sprite(const Resource& res, const Rect& crop_rect) Sprite::Sprite(const Resource& res, const Rect& crop_rect)
: Sprite(res)
{ {
SetCropRect(crop_rect); SetFrame(SpriteFrame(res, crop_rect));
} }
Sprite::Sprite(TexturePtr texture, const Rect& crop_rect) Sprite::Sprite(TexturePtr texture, const Rect& crop_rect)
{ {
SetTexture(texture); SetFrame(SpriteFrame(texture, crop_rect));
SetCropRect(crop_rect); }
Sprite::Sprite(const SpriteFrame& frame)
{
SetFrame(frame);
} }
Sprite::~Sprite() {} Sprite::~Sprite() {}
bool Sprite::Load(const String& file_path) bool Sprite::Load(const String& file_path)
{ {
TexturePtr texture = MakePtr<Texture>(file_path); SpriteFrame frame(file_path);
if (texture && texture->IsValid()) if (frame.IsValid())
{ {
SetTexture(texture); SetFrame(frame);
return true; return true;
} }
Fail("Sprite::Load failed"); Fail("Sprite::Load failed");
@ -75,39 +77,38 @@ bool Sprite::Load(const String& file_path)
bool Sprite::Load(const Resource& res) bool Sprite::Load(const Resource& res)
{ {
TexturePtr texture = MakePtr<Texture>(res); SpriteFrame frame(res);
if (texture && texture->IsValid()) if (frame.IsValid())
{ {
SetTexture(texture); SetFrame(frame);
return true; return true;
} }
Fail("Sprite::Load failed"); Fail("Sprite::Load failed");
return false; return false;
} }
void Sprite::SetTexture(TexturePtr texture) void Sprite::SetFrame(const SpriteFrame& frame)
{ {
texture_ = texture; frame_ = frame;
SetSize(frame_.GetSize());
Size texture_size; if (!frame_.IsValid())
if (texture_)
{ {
texture_size = texture_->GetSize(); Fail("Sprite::SetFrame failed");
} }
// ÖØÖòüô¾ØÐÎ
SetCropRect(Rect(Point(), texture_size));
} }
void Sprite::OnRender(RenderContext& ctx) void Sprite::OnRender(RenderContext& ctx)
{ {
if (texture_ && texture_->IsValid()) if (frame_.IsValid())
{ {
ctx.DrawTexture(*texture_, &crop_rect_, &GetBounds()); ctx.DrawTexture(*frame_.GetTexture(), &frame_.GetCropRect(), &GetBounds());
} }
} }
bool Sprite::CheckVisibility(RenderContext& ctx) const bool Sprite::CheckVisibility(RenderContext& ctx) const
{ {
return texture_ && texture_->IsValid() && Actor::CheckVisibility(ctx); return frame_.IsValid() && Actor::CheckVisibility(ctx);
} }
} // namespace kiwano } // namespace kiwano

View File

@ -20,7 +20,7 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/animation/KeyFrame.h> #include <kiwano/2d/SpriteFrame.h>
namespace kiwano namespace kiwano
{ {
@ -74,6 +74,11 @@ public:
/// @param crop_rect 裁剪矩形 /// @param crop_rect 裁剪矩形
Sprite(TexturePtr texture, const Rect& crop_rect); Sprite(TexturePtr texture, const Rect& crop_rect);
/// \~chinese
/// @brief ´´½¨¾«Áé
/// @param frame ¾«ÁéÖ¡
Sprite(const SpriteFrame& frame);
virtual ~Sprite(); virtual ~Sprite();
/// \~chinese /// \~chinese
@ -95,9 +100,8 @@ public:
Rect GetCropRect() const; Rect GetCropRect() const;
/// \~chinese /// \~chinese
/// @brief 设置图像并重置裁剪矩形 /// @brief »ñÈ¡¾«ÁéÖ¡
/// @param[in] texture 图像 SpriteFrame GetFrame() const;
void SetTexture(TexturePtr texture);
/// \~chinese /// \~chinese
/// @brief 使用矩形区域裁剪精灵 /// @brief 使用矩形区域裁剪精灵
@ -105,9 +109,9 @@ public:
void SetCropRect(const Rect& crop_rect); void SetCropRect(const Rect& crop_rect);
/// \~chinese /// \~chinese
/// @brief 设置关键帧 /// @brief ÉèÖþ«ÁéÖ¡
/// @param[in] frame 关键帧 /// @param[in] frame ¾«ÁéÖ¡
void SetKeyFrame(KeyFramePtr frame); void SetFrame(const SpriteFrame& frame);
void OnRender(RenderContext& ctx) override; void OnRender(RenderContext& ctx) override;
@ -115,35 +119,29 @@ protected:
bool CheckVisibility(RenderContext& ctx) const override; bool CheckVisibility(RenderContext& ctx) const override;
private: private:
TexturePtr texture_; SpriteFrame frame_;
Rect crop_rect_;
}; };
/** @} */ /** @} */
inline TexturePtr Sprite::GetTexture() const inline TexturePtr Sprite::GetTexture() const
{ {
return texture_; return frame_.GetTexture();
} }
inline Rect Sprite::GetCropRect() const inline Rect Sprite::GetCropRect() const
{ {
return crop_rect_; return frame_.GetCropRect();
}
inline SpriteFrame Sprite::GetFrame() const
{
return frame_;
} }
inline void Sprite::SetCropRect(const Rect& crop_rect) inline void Sprite::SetCropRect(const Rect& crop_rect)
{ {
crop_rect_ = crop_rect; frame_.SetCropRect(crop_rect);
SetSize(crop_rect.GetSize());
}
inline void Sprite::SetKeyFrame(KeyFramePtr frame)
{
if (frame)
{
SetTexture(frame->GetTexture());
SetCropRect(frame->GetCropRect());
}
} }
} // namespace kiwano } // namespace kiwano

View File

@ -19,53 +19,54 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/Common.h>
#include <kiwano/math/Math.h>
#include <kiwano/render/Texture.h> #include <kiwano/render/Texture.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(KeyFrame);
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API KeyFrame : public ObjectBase class KGE_API SpriteFrame
{ {
public: public:
KeyFrame(); SpriteFrame();
/// \~chinese /// \~chinese
/// @brief 创建关键 /// @brief 创建精灵
/// @param file_path 图像路径 /// @param file_path 图像路径
KeyFrame(const String& file_path); SpriteFrame(const String& file_path);
/// \~chinese /// \~chinese
/// @brief 创建关键 /// @brief 创建精灵
/// @param res 图像资源 /// @param res 图像资源
KeyFrame(const Resource& res); SpriteFrame(const Resource& res);
/// \~chinese /// \~chinese
/// @brief 创建关键 /// @brief 创建精灵
/// @param texture 纹理 /// @param texture 纹理
KeyFrame(TexturePtr texture); SpriteFrame(TexturePtr texture);
/// \~chinese /// \~chinese
/// @brief 创建关键 /// @brief 创建精灵
/// @param file_path 图像路径 /// @param file_path 图像路径
/// @param crop_rect 裁剪矩形 /// @param crop_rect 裁剪矩形
KeyFrame(const String& file_path, const Rect& crop_rect); SpriteFrame(const String& file_path, const Rect& crop_rect);
/// \~chinese /// \~chinese
/// @brief 创建关键 /// @brief 创建精灵
/// @param res 图像资源 /// @param res 图像资源
/// @param crop_rect 裁剪矩形 /// @param crop_rect 裁剪矩形
KeyFrame(const Resource& res, const Rect& crop_rect); SpriteFrame(const Resource& res, const Rect& crop_rect);
/// \~chinese /// \~chinese
/// @brief 创建关键 /// @brief 创建精灵
/// @param texture 纹理 /// @param texture 纹理
/// @param crop_rect 裁剪矩形 /// @param crop_rect 裁剪矩形
KeyFrame(TexturePtr texture, const Rect& crop_rect); SpriteFrame(TexturePtr texture, const Rect& crop_rect);
/// \~chinese /// \~chinese
/// @brief 加载图像 /// @brief 加载图像
@ -81,16 +82,6 @@ public:
/// @brief 是否有效 /// @brief 是否有效
bool IsValid() const; bool IsValid() const;
/// \~chinese
/// @brief 裁剪关键帧为矩形
/// @param crop_rect 裁剪矩形
void SetCropRect(const Rect& crop_rect);
/// \~chinese
/// @brief 设置纹理
/// @param texture 纹理
void SetTexture(TexturePtr texture);
/// \~chinese /// \~chinese
/// @brief 获取裁剪矩形 /// @brief 获取裁剪矩形
const Rect& GetCropRect() const; const Rect& GetCropRect() const;
@ -99,24 +90,52 @@ public:
/// @brief 获取纹理 /// @brief 获取纹理
TexturePtr GetTexture() const; TexturePtr GetTexture() const;
/// \~chinese
/// @brief 获取精灵帧大小
Size GetSize() const;
/// \~chinese
/// @brief 裁剪精灵帧为矩形
/// @param crop_rect 裁剪矩形
void SetCropRect(const Rect& crop_rect);
/// \~chinese
/// @brief 设置纹理并重置裁剪矩形
/// @param texture 纹理
void SetTexture(TexturePtr texture);
/// \~chinese
/// @brief 按行列分割精灵帧
/// @param cols 列数
/// @param rows 行数
/// @param max_num 最大帧数量,设-1为将分割后的图像全部作为序列帧
/// @param padding_x X方向间隔
/// @param padding_y Y方向间隔
Vector<SpriteFrame> Split(int cols, int rows, int max_num = -1, float padding_x = 0, float padding_y = 0);
private: private:
TexturePtr texture_; TexturePtr texture_;
Rect crop_rect_; Rect crop_rect_;
}; };
inline bool KeyFrame::IsValid() const inline bool SpriteFrame::IsValid() const
{ {
return texture_ && texture_->IsValid(); return texture_ && texture_->IsValid();
} }
inline const Rect& KeyFrame::GetCropRect() const inline const Rect& SpriteFrame::GetCropRect() const
{ {
return crop_rect_; return crop_rect_;
} }
inline TexturePtr KeyFrame::GetTexture() const inline TexturePtr SpriteFrame::GetTexture() const
{ {
return texture_; return texture_;
} }
inline Size SpriteFrame::GetSize() const
{
return crop_rect_.GetSize();
}
} // namespace kiwano } // namespace kiwano

View File

@ -0,0 +1,138 @@
// 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/2d/SpriteFrame.h>
namespace kiwano
{
SpriteFrame::SpriteFrame() {}
SpriteFrame::SpriteFrame(const String& file_path)
{
Load(file_path);
}
SpriteFrame::SpriteFrame(const Resource& res)
{
Load(res);
}
SpriteFrame::SpriteFrame(TexturePtr texture)
{
SetTexture(texture);
}
SpriteFrame::SpriteFrame(const String& file_path, const Rect& crop_rect)
: SpriteFrame(file_path)
{
SetCropRect(crop_rect);
}
SpriteFrame::SpriteFrame(const Resource& res, const Rect& crop_rect)
: SpriteFrame(res)
{
SetCropRect(crop_rect);
}
SpriteFrame::SpriteFrame(TexturePtr texture, const Rect& crop_rect)
: SpriteFrame(texture)
{
SetCropRect(crop_rect);
}
bool SpriteFrame::Load(const String& file_path)
{
TexturePtr texture = Texture::Preload(file_path);
if (texture->IsValid())
{
SetTexture(texture);
return true;
}
return false;
}
bool SpriteFrame::Load(const Resource& res)
{
TexturePtr texture = Texture::Preload(res);
if (texture->IsValid())
{
SetTexture(texture);
return true;
}
return false;
}
void SpriteFrame::SetCropRect(const Rect& crop_rect)
{
crop_rect_ = crop_rect;
}
void SpriteFrame::SetTexture(TexturePtr texture)
{
texture_ = texture;
Size texture_size;
if (texture_)
{
texture_size = texture_->GetSize();
}
SetCropRect(Rect(Point(), texture_size));
}
Vector<SpriteFrame> SpriteFrame::Split(int cols, int rows, int max_num, float padding_x, float padding_y)
{
if (cols <= 0 || rows <= 0 || max_num == 0)
return {};
if (!IsValid())
return {};
float raw_width = crop_rect_.GetWidth();
float raw_height = crop_rect_.GetHeight();
float width = (raw_width - (cols - 1) * padding_x) / cols;
float height = (raw_height - (rows - 1) * padding_y) / rows;
Vector<SpriteFrame> frames;
frames.reserve((max_num > 0) ? max_num : (rows * cols));
int current_num = 0;
float dty = crop_rect_.GetTop();
for (int i = 0; i < rows; i++)
{
float dtx = crop_rect_.GetLeft();
for (int j = 0; j < cols; j++)
{
frames.emplace_back(texture_, Rect{ dtx, dty, dtx + width, dty + height });
++current_num;
dtx += (width + padding_x);
}
dty += (height + padding_y);
if (max_num > 0 && current_num == max_num)
break;
}
return frames;
}
} // namespace kiwano

View File

@ -124,4 +124,71 @@ void Animation::DoClone(Animation* to) const
} }
} }
AnimationEventHandlerPtr AnimationEventHandler::Create(const Function<void(Animation*, Actor*, AnimationEvent)>& handler)
{
class CallbackAnimationEventHandler : public AnimationEventHandler
{
public:
typedef Function<void(Animation*, Actor*, AnimationEvent)> Callback;
Callback handler;
CallbackAnimationEventHandler(const Callback& handler) : handler(handler) {}
void Handle(Animation* anim, Actor* target, AnimationEvent evt) override
{
if (handler)
{
handler(anim, target, evt);
}
}
};
return AnimationEventHandlerPtr(new CallbackAnimationEventHandler(handler));
}
AnimationEventHandlerPtr AnimationEventHandler::Create(AnimationEvent evt, const Function<void(Animation*, Actor*)>& handler)
{
class OneEventAnimationEventHandler : public AnimationEventHandler
{
public:
typedef Function<void(Animation*, Actor*)> Callback;
AnimationEvent evt;
Callback handler;
OneEventAnimationEventHandler(AnimationEvent evt, const Callback& handler)
: handler(handler)
, evt(evt)
{
}
void Handle(Animation* anim, Actor* target, AnimationEvent evt) override
{
if (this->evt != evt)
return;
if (handler)
{
handler(anim, target);
}
}
};
return AnimationEventHandlerPtr(new OneEventAnimationEventHandler(evt, handler));
}
AnimationEventHandlerPtr AnimationEventHandler::HandleStarted(const Function<void(Animation*, Actor*)>& handler)
{
return AnimationEventHandler::Create(AnimationEvent::Started, handler);
}
AnimationEventHandlerPtr AnimationEventHandler::HandleLoopDone(const Function<void(Animation*, Actor*)>& handler)
{
return AnimationEventHandler::Create(AnimationEvent::LoopDone, handler);
}
AnimationEventHandlerPtr AnimationEventHandler::HandleDone(const Function<void(Animation*, Actor*)>& handler)
{
return AnimationEventHandler::Create(AnimationEvent::Done, handler);
}
} // namespace kiwano } // namespace kiwano

View File

@ -51,12 +51,11 @@ enum class AnimationEvent
Started, ///< 动画开始 Started, ///< 动画开始
LoopDone, ///< 动画一次循环结束 LoopDone, ///< 动画一次循环结束
Done, ///< 动画结束 Done, ///< 动画结束
Removed, ///< 动画被移除
}; };
/// \~chinese /// \~chinese
/// @brief 动画事件处理器 /// @brief 动画事件处理器
class KGE_API AnimationEventHandler : public ObjectBase class KGE_API AnimationEventHandler : public RefObject
{ {
public: public:
/// \~chinese /// \~chinese
@ -65,6 +64,32 @@ public:
/// @param target 执行动画的对象 /// @param target 执行动画的对象
/// @param evt 动画事件 /// @param evt 动画事件
virtual void Handle(Animation* anim, Actor* target, AnimationEvent evt) = 0; virtual void Handle(Animation* anim, Actor* target, AnimationEvent evt) = 0;
/// \~chinese
/// @brief 创建动画事件处理器
/// @param handler 处理动画事件回调函数
static AnimationEventHandlerPtr Create(const Function<void(Animation*, Actor*, AnimationEvent)>& handler);
/// \~chinese
/// @brief 创建动画事件处理器
/// @param evt 处理的动画事件
/// @param handler 处理动画事件回调函数
static AnimationEventHandlerPtr Create(AnimationEvent evt, const Function<void(Animation*, Actor*)>& handler);
/// \~chinese
/// @brief 创建Started动画事件处理器
/// @param handler 处理动画事件回调函数
static AnimationEventHandlerPtr HandleStarted(const Function<void(Animation*, Actor*)>& handler);
/// \~chinese
/// @brief 创建LoopDone动画事件处理器
/// @param handler 处理动画事件回调函数
static AnimationEventHandlerPtr HandleLoopDone(const Function<void(Animation*, Actor*)>& handler);
/// \~chinese
/// @brief 创建Done动画事件处理器
/// @param handler 处理动画事件回调函数
static AnimationEventHandlerPtr HandleDone(const Function<void(Animation*, Actor*)>& handler);
}; };
/// \~chinese /// \~chinese

View File

@ -26,12 +26,14 @@ namespace kiwano
FrameAnimation::FrameAnimation() FrameAnimation::FrameAnimation()
: frame_seq_(nullptr) : frame_seq_(nullptr)
, current_index_(0)
{ {
} }
FrameAnimation::FrameAnimation(Duration dur, FrameSequencePtr frame_seq) FrameAnimation::FrameAnimation(Duration dur, FrameSequencePtr frame_seq)
: TweenAnimation(dur) : TweenAnimation(dur)
, frame_seq_(frame_seq) , frame_seq_(frame_seq)
, current_index_(0)
{ {
} }
@ -61,7 +63,7 @@ void FrameAnimation::Init(Actor* target)
if (sprite_target && frame_seq_) if (sprite_target && frame_seq_)
{ {
sprite_target->SetKeyFrame(frame_seq_->GetFrames()[0]); sprite_target->SetFrame(frame_seq_->GetFrames()[0]);
current_index_ = 0; current_index_ = 0;
} }
} }
@ -79,7 +81,7 @@ void FrameAnimation::UpdateTween(Actor* target, float percent)
if (index != current_index_) if (index != current_index_)
{ {
current_index_ = index; current_index_ = index;
sprite_target->SetKeyFrame(frames[index]); sprite_target->SetFrame(frames[index]);
} }
} }
} }

View File

@ -28,24 +28,24 @@ FrameSequence::FrameSequence() {}
FrameSequence::~FrameSequence() {} FrameSequence::~FrameSequence() {}
FrameSequence::FrameSequence(const Vector<KeyFramePtr>& frames) FrameSequence::FrameSequence(const Vector<SpriteFrame>& frames)
{ {
AddFrames(frames); AddFrames(frames);
} }
void FrameSequence::AddFrame(KeyFramePtr frame) void FrameSequence::AddFrame(const SpriteFrame& frame)
{ {
if (frame) if (frame.IsValid())
{ {
frames_.push_back(frame); frames_.push_back(frame);
} }
else else
{ {
Fail("FrameSequence::Add failed, NULL pointer exception"); Fail("FrameSequence::AddFrame failed, frame is invalid");
} }
} }
void FrameSequence::AddFrames(const Vector<KeyFramePtr>& frames) void FrameSequence::AddFrames(const Vector<SpriteFrame>& frames)
{ {
if (frames_.empty()) if (frames_.empty())
frames_ = frames; frames_ = frames;
@ -57,13 +57,13 @@ void FrameSequence::AddFrames(const Vector<KeyFramePtr>& frames)
} }
} }
KeyFramePtr FrameSequence::GetFrame(size_t index) const const SpriteFrame& FrameSequence::GetFrame(size_t index) const
{ {
KGE_ASSERT(index < frames_.size()); KGE_ASSERT(index < frames_.size());
return frames_[index]; return frames_[index];
} }
const Vector<KeyFramePtr>& FrameSequence::GetFrames() const const Vector<SpriteFrame>& FrameSequence::GetFrames() const
{ {
return frames_; return frames_;
} }
@ -96,62 +96,4 @@ FrameSequencePtr FrameSequence::Reverse() const
return frame_seq; return frame_seq;
} }
KeyFrameSpliter::KeyFrameSpliter(TexturePtr texture)
: texture(texture)
{
if (texture)
{
crop_rect = Rect(Point(), texture->GetSize());
}
}
KeyFrameSpliter::KeyFrameSpliter(TexturePtr texture, const Rect& crop_rect)
: texture(texture)
, crop_rect(crop_rect)
{
}
Vector<KeyFramePtr> KeyFrameSpliter::Split(int cols, int rows, int max_num, float padding_x, float padding_y)
{
if (cols <= 0 || rows <= 0 || max_num == 0)
return {};
if (!texture)
return {};
float raw_width = crop_rect.GetWidth();
float raw_height = crop_rect.GetHeight();
float width = (raw_width - (cols - 1) * padding_x) / cols;
float height = (raw_height - (rows - 1) * padding_y) / rows;
Vector<KeyFramePtr> frames;
frames.reserve((max_num > 0) ? max_num : (rows * cols));
int current_num = 0;
float dty = crop_rect.GetTop();
for (int i = 0; i < rows; i++)
{
float dtx = crop_rect.GetLeft();
for (int j = 0; j < cols; j++)
{
KeyFramePtr ptr = MakePtr<KeyFrame>();
if (ptr)
{
ptr->SetTexture(texture);
ptr->SetCropRect(Rect{ dtx, dty, dtx + width, dty + height });
frames.push_back(ptr);
++current_num;
}
dtx += (width + padding_x);
}
dty += (height + padding_y);
if (max_num > 0 && current_num == max_num)
break;
}
return frames;
}
} // namespace kiwano } // namespace kiwano

View File

@ -19,9 +19,9 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/2d/animation/KeyFrame.h>
#include <kiwano/core/Common.h> #include <kiwano/core/Common.h>
#include <kiwano/core/Time.h> #include <kiwano/core/Time.h>
#include <kiwano/2d/SpriteFrame.h>
namespace kiwano namespace kiwano
{ {
@ -36,8 +36,8 @@ class KGE_API FrameSequence : public ObjectBase
public: public:
/// \~chinese /// \~chinese
/// @brief ´´½¨ÐòÁÐÖ¡ /// @brief ´´½¨ÐòÁÐÖ¡
/// @param frames 关键帧集合 /// @param frames 精灵帧集合
FrameSequence(const Vector<KeyFramePtr>& frames); FrameSequence(const Vector<SpriteFrame>& frames);
/// \~chinese /// \~chinese
/// @brief ¹¹½¨¿ÕÐòÁÐÖ¡ /// @brief ¹¹½¨¿ÕÐòÁÐÖ¡
@ -46,26 +46,26 @@ public:
virtual ~FrameSequence(); virtual ~FrameSequence();
/// \~chinese /// \~chinese
/// @brief 添加关键 /// @brief 添加精灵
/// @param frame 关键 /// @param frame 精灵
void AddFrame(KeyFramePtr frame); void AddFrame(const SpriteFrame& frame);
/// \~chinese /// \~chinese
/// @brief 添加多个关键 /// @brief 添加多个精灵
/// @param frames 关键帧集合 /// @param frames 精灵帧集合
void AddFrames(const Vector<KeyFramePtr>& frames); void AddFrames(const Vector<SpriteFrame>& frames);
/// \~chinese /// \~chinese
/// @brief 获取关键 /// @brief 获取精灵
/// @param index 关键帧下标 /// @param index 精灵帧下标
KeyFramePtr GetFrame(size_t index) const; const SpriteFrame& GetFrame(size_t index) const;
/// \~chinese /// \~chinese
/// @brief 获取所有关键 /// @brief 获取所有精灵
const Vector<KeyFramePtr>& GetFrames() const; const Vector<SpriteFrame>& GetFrames() const;
/// \~chinese /// \~chinese
/// @brief 获取关键帧数量 /// @brief 获取精灵帧数量
size_t GetFramesCount() const; size_t GetFramesCount() const;
/// \~chinese /// \~chinese
@ -77,37 +77,7 @@ public:
FrameSequencePtr Reverse() const; FrameSequencePtr Reverse() const;
private: private:
Vector<KeyFramePtr> frames_; Vector<SpriteFrame> frames_;
};
/// \~chinese
/// @brief 序列帧图像分割器
struct KGE_API KeyFrameSpliter
{
TexturePtr texture;
Rect crop_rect;
KeyFrameSpliter() = default;
/// \~chinese
/// @brief 创建序列帧图像分割器
/// @param texture 图像
KeyFrameSpliter(TexturePtr texture);
/// \~chinese
/// @brief 创建序列帧图像分割器
/// @param texture 图像
/// @param crop_rect 裁剪矩形
KeyFrameSpliter(TexturePtr texture, const Rect& crop_rect);
/// \~chinese
/// @brief 按行列分割图像并创建序列帧
/// @param cols 列数
/// @param rows 行数
/// @param max_num 最大帧数量,设-1为将分割后的图像全部作为序列帧
/// @param padding_x X方向间隔
/// @param padding_y Y方向间隔
Vector<KeyFramePtr> Split(int cols, int rows = 1, int max_num = -1, float padding_x = 0, float padding_y = 0);
}; };
} // namespace kiwano } // namespace kiwano

View File

@ -1,105 +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/2d/animation/KeyFrame.h>
namespace kiwano
{
KeyFrame::KeyFrame() {}
KeyFrame::KeyFrame(const String& file_path)
{
Load(file_path);
}
KeyFrame::KeyFrame(const Resource& res)
{
Load(res);
}
KeyFrame::KeyFrame(TexturePtr texture)
{
SetTexture(texture);
}
KeyFrame::KeyFrame(const String& file_path, const Rect& crop_rect)
: KeyFrame(file_path)
{
SetCropRect(crop_rect);
}
KeyFrame::KeyFrame(const Resource& res, const Rect& crop_rect)
: KeyFrame(res)
{
SetCropRect(crop_rect);
}
KeyFrame::KeyFrame(TexturePtr texture, const Rect& crop_rect)
: KeyFrame(texture)
{
SetCropRect(crop_rect);
}
bool KeyFrame::Load(const String& file_path)
{
TexturePtr texture = Texture::Preload(file_path);
if (texture->IsValid())
{
SetTexture(texture);
return true;
}
return false;
}
bool KeyFrame::Load(const Resource& res)
{
TexturePtr texture = Texture::Preload(res);
if (texture->IsValid())
{
SetTexture(texture);
return true;
}
return false;
}
void KeyFrame::SetCropRect(const Rect& crop_rect)
{
if (texture_->IsValid())
{
auto bitmap_size = texture_->GetSize();
crop_rect_.left_top.x = std::min(std::max(crop_rect.left_top.x, 0.f), bitmap_size.x);
crop_rect_.left_top.y = std::min(std::max(crop_rect.left_top.y, 0.f), bitmap_size.y);
crop_rect_.right_bottom.x = std::min(std::max(crop_rect.right_bottom.x, 0.f), bitmap_size.x);
crop_rect_.right_bottom.y = std::min(std::max(crop_rect.right_bottom.y, 0.f), bitmap_size.y);
}
}
void KeyFrame::SetTexture(TexturePtr texture)
{
texture_ = texture;
if (texture_->IsValid())
{
crop_rect_.left_top.x = crop_rect_.left_top.y = 0;
crop_rect_.right_bottom.x = texture_->GetWidth();
crop_rect_.right_bottom.y = texture_->GetHeight();
}
}
} // namespace kiwano

View File

@ -0,0 +1,50 @@
// 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/Common.h>
namespace kiwano
{
/// \~chinese
/// @brief 二进制数据
struct KGE_API BinaryData
{
void* buffer; ///< 数据
uint32_t size; ///< 数据大小
BinaryData();
bool IsValid() const;
};
inline BinaryData::BinaryData()
: buffer(nullptr)
, size(0)
{
}
inline bool BinaryData::IsValid() const
{
return buffer != nullptr && size != 0;
}
} // namespace kiwano

View File

@ -36,7 +36,7 @@ Resource::Resource(uint32_t id, const String& type)
{ {
} }
Resource::Data Resource::GetData() const BinaryData Resource::GetData() const
{ {
do do
{ {

View File

@ -19,11 +19,11 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/Common.h> #include <kiwano/core/BinaryData.h>
#include <kiwano/macros.h>
namespace kiwano namespace kiwano
{ {
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -40,17 +40,6 @@ namespace kiwano
class KGE_API Resource class KGE_API Resource
{ {
public: public:
/// \~chinese
/// @brief 资源的二进制数据
struct Data
{
void* buffer; ///< 资源数据
uint32_t size; ///< 资源数据大小
Data();
bool IsValid() const;
};
/// \~chinese /// \~chinese
/// @brief 构造资源 /// @brief 构造资源
@ -65,7 +54,7 @@ public:
/// \~chinese /// \~chinese
/// @brief 获取资源的二进制数据 /// @brief 获取资源的二进制数据
/// @return 资源数据 /// @return 资源数据
Resource::Data GetData() const; BinaryData GetData() const;
/// \~chinese /// \~chinese
/// @brief 获取资源 ID /// @brief 获取资源 ID
@ -79,20 +68,9 @@ private:
uint32_t id_; uint32_t id_;
String type_; String type_;
mutable Resource::Data data_; mutable BinaryData data_;
}; };
inline Resource::Data::Data()
: buffer(nullptr)
, size(0)
{
}
inline bool Resource::Data::IsValid() const
{
return buffer != nullptr && size;
}
inline uint32_t Resource::GetId() const inline uint32_t Resource::GetId() const
{ {
return id_; return id_;

View File

@ -98,6 +98,7 @@
#include <kiwano/2d/GifSprite.h> #include <kiwano/2d/GifSprite.h>
#include <kiwano/2d/LayerActor.h> #include <kiwano/2d/LayerActor.h>
#include <kiwano/2d/ShapeActor.h> #include <kiwano/2d/ShapeActor.h>
#include <kiwano/2d/SpriteFrame.h>
#include <kiwano/2d/Sprite.h> #include <kiwano/2d/Sprite.h>
#include <kiwano/2d/Stage.h> #include <kiwano/2d/Stage.h>
#include <kiwano/2d/TextActor.h> #include <kiwano/2d/TextActor.h>
@ -112,7 +113,6 @@
#include <kiwano/2d/animation/AnimationGroup.h> #include <kiwano/2d/animation/AnimationGroup.h>
#include <kiwano/2d/animation/TweenAnimation.h> #include <kiwano/2d/animation/TweenAnimation.h>
#include <kiwano/2d/animation/PathAnimation.h> #include <kiwano/2d/animation/PathAnimation.h>
#include <kiwano/2d/animation/KeyFrame.h>
#include <kiwano/2d/animation/FrameSequence.h> #include <kiwano/2d/animation/FrameSequence.h>
#include <kiwano/2d/animation/FrameAnimation.h> #include <kiwano/2d/animation/FrameAnimation.h>
#include <kiwano/2d/animation/Animator.h> #include <kiwano/2d/animation/Animator.h>

View File

@ -176,7 +176,7 @@ bool FileSystem::ExtractResourceToFile(const Resource& res, const String& dest_f
if (file_handle == INVALID_HANDLE_VALUE) if (file_handle == INVALID_HANDLE_VALUE)
return false; return false;
Resource::Data data = res.GetData(); BinaryData data = res.GetData();
if (data.IsValid()) if (data.IsValid())
{ {
DWORD written_bytes = 0; DWORD written_bytes = 0;

View File

@ -72,8 +72,8 @@ public:
HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr<IDWriteFontCollection>& font_collection, HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr<IDWriteFontCollection>& font_collection,
const Vector<String>& file_paths) override; const Vector<String>& file_paths) override;
HRESULT CreateFontCollectionFromResources(_Out_ ComPtr<IDWriteFontCollection>& font_collection, HRESULT CreateFontCollectionFromBinaryData(_Out_ ComPtr<IDWriteFontCollection>& font_collection,
const Vector<Resource>& resources) override; const Vector<BinaryData>& data) override;
HRESULT GetFontFamilyNames(_Out_ Vector<String>& family_names, HRESULT GetFontFamilyNames(_Out_ Vector<String>& family_names,
_In_ ComPtr<IDWriteFontCollection> font_collection) override; _In_ ComPtr<IDWriteFontCollection> font_collection) override;
@ -548,8 +548,8 @@ HRESULT D2DDeviceResources::CreateFontCollectionFromFiles(ComPtr<IDWriteFontColl
return hr; return hr;
} }
HRESULT D2DDeviceResources::CreateFontCollectionFromResources(ComPtr<IDWriteFontCollection>& font_collection, HRESULT D2DDeviceResources::CreateFontCollectionFromBinaryData(ComPtr<IDWriteFontCollection>& font_collection,
const Vector<Resource>& resources) const Vector<BinaryData>& data)
{ {
if (!dwrite_factory_ || !res_font_collection_loader_) if (!dwrite_factory_ || !res_font_collection_loader_)
return E_UNEXPECTED; return E_UNEXPECTED;
@ -557,7 +557,7 @@ HRESULT D2DDeviceResources::CreateFontCollectionFromResources(ComPtr<IDWriteFont
LPVOID key = nullptr; LPVOID key = nullptr;
uint32_t key_size = 0; uint32_t key_size = 0;
HRESULT hr = res_font_collection_loader_->AddResources(resources, &key, &key_size); HRESULT hr = res_font_collection_loader_->AddResources(data, &key, &key_size);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {

View File

@ -59,8 +59,8 @@ public:
virtual HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr<IDWriteFontCollection> & font_collection, virtual HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr<IDWriteFontCollection> & font_collection,
const Vector<String>& file_paths) = 0; const Vector<String>& file_paths) = 0;
virtual HRESULT CreateFontCollectionFromResources(_Out_ ComPtr<IDWriteFontCollection> & font_collection, virtual HRESULT CreateFontCollectionFromBinaryData(_Out_ ComPtr<IDWriteFontCollection> & font_collection,
const Vector<Resource>& resources) = 0; const Vector<BinaryData>& data) = 0;
virtual HRESULT GetFontFamilyNames(_Out_ Vector<String> & family_names, virtual HRESULT GetFontFamilyNames(_Out_ Vector<String> & family_names,
_In_ ComPtr<IDWriteFontCollection> font_collection) = 0; _In_ ComPtr<IDWriteFontCollection> font_collection) = 0;

View File

@ -344,7 +344,7 @@ public:
} }
STDMETHOD(AddResources) STDMETHOD(AddResources)
(const Vector<Resource>& resources, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize); (const Vector<BinaryData>& data, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize);
// IDWriteFontCollectionLoader methods // IDWriteFontCollectionLoader methods
virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey,
@ -360,7 +360,7 @@ private:
ULONG refCount_; ULONG refCount_;
IDWriteFontFileLoader* pFileLoader_; IDWriteFontFileLoader* pFileLoader_;
typedef Vector<Resource> ResourceCollection; typedef Vector<BinaryData> ResourceCollection;
Vector<ResourceCollection> resources_; Vector<ResourceCollection> resources_;
Vector<size_t> collectionKeys_; Vector<size_t> collectionKeys_;
}; };
@ -389,7 +389,8 @@ HRESULT IResourceFontCollectionLoader::Create(_Out_ IResourceFontCollectionLoade
return hr; return hr;
} }
STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector<Resource>& resources, _Out_ LPVOID* pCollectionKey, STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector<BinaryData>& data,
_Out_ LPVOID* pCollectionKey,
_Out_ uint32_t* pCollectionKeySize) _Out_ uint32_t* pCollectionKeySize)
{ {
if (!pCollectionKey || !pCollectionKeySize) if (!pCollectionKey || !pCollectionKeySize)
@ -401,7 +402,7 @@ STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector<Resource>&
{ {
size_t collectionKey = resources_.size(); size_t collectionKey = resources_.size();
collectionKeys_.push_back(collectionKey); collectionKeys_.push_back(collectionKey);
resources_.push_back(resources); resources_.push_back(data);
*pCollectionKey = reinterpret_cast<LPVOID>(&collectionKeys_.back()); *pCollectionKey = reinterpret_cast<LPVOID>(&collectionKeys_.back());
*pCollectionKeySize = sizeof(collectionKey); *pCollectionKeySize = sizeof(collectionKey);
@ -423,7 +424,7 @@ HRESULT STDMETHODCALLTYPE ResourceFontCollectionLoader::CreateEnumeratorFromKey(
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (collectionKey == NULL || collectionKeySize % sizeof(Resource*) != 0) if (collectionKey == NULL || collectionKeySize % sizeof(BinaryData*) != 0)
hr = E_INVALIDARG; hr = E_INVALIDARG;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -533,14 +534,14 @@ HRESULT STDMETHODCALLTYPE ResourceFontFileLoader::CreateStreamFromKey(void const
HRESULT hr = S_OK; HRESULT hr = S_OK;
// Make sure the key is the right size. // Make sure the key is the right size.
if (fontFileReferenceKeySize != sizeof(Resource)) if (fontFileReferenceKeySize != sizeof(BinaryData))
hr = E_INVALIDARG; hr = E_INVALIDARG;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
// Create the pFileStream object. // Create the pFileStream object.
IResourceFontFileStream* pFileStream = NULL; IResourceFontFileStream* pFileStream = NULL;
Resource resource = *static_cast<Resource const*>(fontFileReferenceKey); BinaryData resource = *static_cast<BinaryData const*>(fontFileReferenceKey);
hr = IResourceFontFileStream::Create(&pFileStream, resource); hr = IResourceFontFileStream::Create(&pFileStream, resource);
@ -601,7 +602,7 @@ public:
STDMETHOD(Initialize)(IDWriteFactory* pFactory, IDWriteFontFileLoader* pLoader); STDMETHOD(Initialize)(IDWriteFactory* pFactory, IDWriteFontFileLoader* pLoader);
STDMETHOD(SetResources)(const Vector<Resource>& resources); STDMETHOD(SetResources)(const Vector<BinaryData>& data);
// IDWriteFontFileEnumerator methods // IDWriteFontFileEnumerator methods
virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ BOOL* hasCurrentFile); virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ BOOL* hasCurrentFile);
@ -618,7 +619,7 @@ private:
IDWriteFactory* pFactory_; IDWriteFactory* pFactory_;
IDWriteFontFile* currentFile_; IDWriteFontFile* currentFile_;
IDWriteFontFileLoader* pLoader_; IDWriteFontFileLoader* pLoader_;
Vector<Resource> resources_; Vector<BinaryData> resources_;
uint32_t nextIndex_; uint32_t nextIndex_;
}; };
@ -671,11 +672,11 @@ STDMETHODIMP ResourceFontFileEnumerator::Initialize(IDWriteFactory* pFactory, ID
return E_INVALIDARG; return E_INVALIDARG;
} }
STDMETHODIMP ResourceFontFileEnumerator::SetResources(const Vector<Resource>& resources) STDMETHODIMP ResourceFontFileEnumerator::SetResources(const Vector<BinaryData>& data)
{ {
try try
{ {
resources_.assign(resources.begin(), resources.end()); resources_.assign(data.begin(), data.end());
} }
catch (std::bad_alloc&) catch (std::bad_alloc&)
{ {
@ -697,7 +698,7 @@ HRESULT STDMETHODCALLTYPE ResourceFontFileEnumerator::MoveNext(_Out_ BOOL* hasCu
if (nextIndex_ < resources_.size()) if (nextIndex_ < resources_.size())
{ {
hr = pFactory_->CreateCustomFontFileReference(&resources_[nextIndex_], sizeof(Resource), pLoader_, hr = pFactory_->CreateCustomFontFileReference(&resources_[nextIndex_], sizeof(BinaryData), pLoader_,
&currentFile_); &currentFile_);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -758,7 +759,7 @@ class ResourceFontFileStream : public IResourceFontFileStream
public: public:
ResourceFontFileStream(); ResourceFontFileStream();
STDMETHOD(Initialize)(Resource const resources); STDMETHOD(Initialize)(const BinaryData& data);
// IDWriteFontFileStream methods // IDWriteFontFileStream methods
virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset,
@ -781,7 +782,7 @@ private:
DWORD resourceSize_; DWORD resourceSize_;
}; };
HRESULT IResourceFontFileStream::Create(_Out_ IResourceFontFileStream** ppStream, const Resource resource) HRESULT IResourceFontFileStream::Create(_Out_ IResourceFontFileStream** ppStream, const BinaryData& data)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -797,7 +798,7 @@ HRESULT IResourceFontFileStream::Create(_Out_ IResourceFontFileStream** ppStream
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = pFileStream->Initialize(resource); hr = pFileStream->Initialize(data);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -816,10 +817,9 @@ ResourceFontFileStream::ResourceFontFileStream()
{ {
} }
STDMETHODIMP ResourceFontFileStream::Initialize(const Resource resource) STDMETHODIMP ResourceFontFileStream::Initialize(const BinaryData& data)
{ {
Resource::Data data = resource.GetData(); HRESULT hr = data.IsValid() ? S_OK : E_FAIL;
HRESULT hr = data.IsValid() ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {

View File

@ -19,7 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/Resource.h> #include <kiwano/core/BinaryData.h>
#include <kiwano/render/DirectX/helper.h> #include <kiwano/render/DirectX/helper.h>
#include <dwrite.h> #include <dwrite.h>
@ -52,7 +52,7 @@ public:
IDWriteFontFileLoader * pFileLoader); IDWriteFontFileLoader * pFileLoader);
STDMETHOD(AddResources) STDMETHOD(AddResources)
(const Vector<Resource>& resources, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize) PURE; (const Vector<BinaryData>& data, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize) PURE;
}; };
interface DWRITE_DECLARE_INTERFACE("08D21408-6FC1-4E36-A4EB-4DA16BE3399E") IResourceFontFileLoader interface DWRITE_DECLARE_INTERFACE("08D21408-6FC1-4E36-A4EB-4DA16BE3399E") IResourceFontFileLoader
@ -69,13 +69,14 @@ public:
static HRESULT Create(_Out_ IResourceFontFileEnumerator * *ppEnumerator, IDWriteFactory * pFactory, static HRESULT Create(_Out_ IResourceFontFileEnumerator * *ppEnumerator, IDWriteFactory * pFactory,
IDWriteFontFileLoader * pFileLoader); IDWriteFontFileLoader * pFileLoader);
STDMETHOD(SetResources)(const Vector<Resource>& resources) PURE; STDMETHOD(SetResources)(const Vector<BinaryData>& data) PURE;
}; };
interface DWRITE_DECLARE_INTERFACE("A6267450-27F3-4948-995F-FF8345A72F88") IResourceFontFileStream interface DWRITE_DECLARE_INTERFACE("A6267450-27F3-4948-995F-FF8345A72F88") IResourceFontFileStream
: public IDWriteFontFileStream : public IDWriteFontFileStream
{ {
public: public:
static HRESULT Create(_Out_ IResourceFontFileStream * *ppStream, const Resource resource); static HRESULT Create(_Out_ IResourceFontFileStream * *ppStream, const BinaryData& data);
}; };
} // namespace kiwano } // namespace kiwano

View File

@ -250,7 +250,7 @@ void RendererImpl::CreateTexture(Texture& texture, const String& file_path)
KGE_SET_STATUS_IF_FAILED(hr, texture, "Load texture failed"); KGE_SET_STATUS_IF_FAILED(hr, texture, "Load texture failed");
} }
void RendererImpl::CreateTexture(Texture& texture, const Resource& resource) void RendererImpl::CreateTexture(Texture& texture, const BinaryData& data)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!d2d_res_) if (!d2d_res_)
@ -260,8 +260,6 @@ void RendererImpl::CreateTexture(Texture& texture, const Resource& resource)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
Resource::Data data = resource.GetData();
hr = data.IsValid() ? S_OK : E_FAIL; hr = data.IsValid() ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -334,7 +332,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const String& file_path)
KGE_SET_STATUS_IF_FAILED(hr, gif, "Load GIF texture failed"); KGE_SET_STATUS_IF_FAILED(hr, gif, "Load GIF texture failed");
} }
void RendererImpl::CreateGifImage(GifImage& gif, const Resource& resource) void RendererImpl::CreateGifImage(GifImage& gif, const BinaryData& data)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!d2d_res_) if (!d2d_res_)
@ -344,8 +342,6 @@ void RendererImpl::CreateGifImage(GifImage& gif, const Resource& resource)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
Resource::Data data = resource.GetData();
hr = data.IsValid() ? S_OK : E_FAIL; hr = data.IsValid() ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -559,7 +555,7 @@ void RendererImpl::CreateFontCollection(Font& font, Vector<String>& family_names
KGE_SET_STATUS_IF_FAILED(hr, font, "Create font collection failed"); KGE_SET_STATUS_IF_FAILED(hr, font, "Create font collection failed");
} }
void RendererImpl::CreateFontCollection(Font& font, Vector<String>& family_names, const Resource& res) void RendererImpl::CreateFontCollection(Font& font, Vector<String>& family_names, const BinaryData& data)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!d2d_res_) if (!d2d_res_)
@ -570,7 +566,7 @@ void RendererImpl::CreateFontCollection(Font& font, Vector<String>& family_names
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<IDWriteFontCollection> font_collection; ComPtr<IDWriteFontCollection> font_collection;
hr = d2d_res_->CreateFontCollectionFromResources(font_collection, Vector<Resource>{ res }); hr = d2d_res_->CreateFontCollectionFromBinaryData(font_collection, Vector<BinaryData>{ data });
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {

View File

@ -34,17 +34,17 @@ public:
void CreateTexture(Texture& texture, const String& file_path) override; void CreateTexture(Texture& texture, const String& file_path) override;
void CreateTexture(Texture& texture, const Resource& resource) override; void CreateTexture(Texture& texture, const BinaryData& data) override;
void CreateGifImage(GifImage& gif, const String& file_path) override; void CreateGifImage(GifImage& gif, const String& file_path) override;
void CreateGifImage(GifImage& gif, const Resource& resource) override; void CreateGifImage(GifImage& gif, const BinaryData& data) override;
void CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index) override; void CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index) override;
void CreateFontCollection(Font& font, Vector<String>& family_names, const String& file_path) override; void CreateFontCollection(Font& font, Vector<String>& family_names, const String& file_path) override;
void CreateFontCollection(Font& font, Vector<String>& family_names, const Resource& res) override; void CreateFontCollection(Font& font, Vector<String>& family_names, const BinaryData& data) override;
void CreateTextLayout(TextLayout& layout, const String& content, const TextStyle& style) override; void CreateTextLayout(TextLayout& layout, const String& content, const TextStyle& style) override;

View File

@ -67,7 +67,7 @@ FontPtr Font::Preload(const Resource& resource)
if (ptr) if (ptr)
{ {
Vector<String> family_names; Vector<String> family_names;
Renderer::GetInstance().CreateFontCollection(*ptr, family_names, resource); Renderer::GetInstance().CreateFontCollection(*ptr, family_names, resource.GetData());
if (ptr->IsValid()) if (ptr->IsValid())
{ {
FontCache::GetInstance().AddFont(hash_code, ptr); FontCache::GetInstance().AddFont(hash_code, ptr);

View File

@ -92,7 +92,7 @@ bool GifImage::Load(const String& file_path)
bool GifImage::Load(const Resource& res) bool GifImage::Load(const Resource& res)
{ {
Renderer::GetInstance().CreateGifImage(*this, res); Renderer::GetInstance().CreateGifImage(*this, res.GetData());
if (IsValid()) if (IsValid())
{ {

View File

@ -37,7 +37,7 @@ KGE_DECLARE_SMART_PTR(NativeObject);
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API NativeObjectBase : public ObjectBase class KGE_API NativeObjectBase : public ObjectBase
{ {

View File

@ -88,8 +88,8 @@ public:
/// \~chinese /// \~chinese
/// @brief 创建纹理内部资源 /// @brief 创建纹理内部资源
/// @param[out] texture 纹理 /// @param[out] texture 纹理
/// @param[in] resource ͼƬ×ÊÔ´ /// @param[in] data 图片二进制数据
virtual void CreateTexture(Texture& texture, const Resource& resource) = 0; virtual void CreateTexture(Texture& texture, const BinaryData& data) = 0;
/// \~chinese /// \~chinese
/// @brief 创建GIF图像内部资源 /// @brief 创建GIF图像内部资源
@ -100,8 +100,8 @@ public:
/// \~chinese /// \~chinese
/// @brief 创建GIF图像内部资源 /// @brief 创建GIF图像内部资源
/// @param[out] gif GIF图像 /// @param[out] gif GIF图像
/// @param[in] resource ͼƬ×ÊÔ´ /// @param[in] data 图片二进制数据
virtual void CreateGifImage(GifImage& gif, const Resource& resource) = 0; virtual void CreateGifImage(GifImage& gif, const BinaryData& data) = 0;
/// \~chinese /// \~chinese
/// @brief 创建GIF关键帧内部资源 /// @brief 创建GIF关键帧内部资源
@ -121,8 +121,8 @@ public:
/// @brief 创建字体集内部资源 /// @brief 创建字体集内部资源
/// @param[out] font 字体 /// @param[out] font 字体
/// @param[out] family_names 字体包含的字体族 /// @param[out] family_names 字体包含的字体族
/// @param[in] res_arr ×ÖÌå×ÊÔ´ /// @param[in] data 字体二进制资源
virtual void CreateFontCollection(Font& font, Vector<String>& family_names, const Resource& res) = 0; virtual void CreateFontCollection(Font& font, Vector<String>& family_names, const BinaryData& data) = 0;
/// \~chinese /// \~chinese
/// @brief 创建文字布局内部资源 /// @brief 创建文字布局内部资源

View File

@ -89,7 +89,7 @@ bool Texture::Load(const String& file_path)
bool Texture::Load(const Resource& res) bool Texture::Load(const Resource& res)
{ {
Renderer::GetInstance().CreateTexture(*this, res); Renderer::GetInstance().CreateTexture(*this, res.GetData());
return IsValid(); return IsValid();
} }

View File

@ -23,10 +23,9 @@
#include <kiwano/utils/Logger.h> #include <kiwano/utils/Logger.h>
#include <kiwano/utils/ResourceLoader.h> #include <kiwano/utils/ResourceLoader.h>
#include <kiwano/utils/ResourceCache.h> #include <kiwano/utils/ResourceCache.h>
#include <kiwano/render/Font.h> #include <kiwano/render/Font.h>
#include <kiwano/render/GifImage.h> #include <kiwano/render/GifImage.h>
#include <kiwano/2d/animation/KeyFrame.h> #include <kiwano/2d/SpriteFrame.h>
#include <kiwano/2d/animation/FrameSequence.h> #include <kiwano/2d/animation/FrameSequence.h>
namespace kiwano namespace kiwano
@ -200,10 +199,10 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String&
else if (!file.empty()) else if (!file.empty())
{ {
// Simple image // Simple image
KeyFramePtr frame = MakePtr<KeyFrame>(); TexturePtr texture = MakePtr<Texture>();
if (frame && frame->Load(gdata->path + file)) if (texture && texture->Load(gdata->path + file))
{ {
cache->AddObject(id, frame); cache->AddObject(id, texture);
return; return;
} }
} }
@ -217,12 +216,12 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String&
return; return;
// Frames // Frames
Vector<KeyFramePtr> frames; Vector<SpriteFrame> frames;
frames.reserve(files.size()); frames.reserve(files.size());
for (const auto& file : files) for (const auto& file : files)
{ {
KeyFramePtr frame = MakePtr<KeyFrame>(); SpriteFrame frame;
if (frame->Load(gdata->path + file)) if (frame.Load(gdata->path + file))
{ {
frames.push_back(frame); frames.push_back(frame);
} }
@ -249,16 +248,13 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String&
if (rows || cols) if (rows || cols)
{ {
// KeyFrame slices // KeyFrame slices
TexturePtr texture = MakePtr<Texture>(); SpriteFrame frame;
if (texture && texture->Load(gdata->path + file)) if (frame.Load(gdata->path + file))
{ {
FrameSequencePtr frame_seq = MakePtr<FrameSequence>(); FrameSequencePtr frame_seq = MakePtr<FrameSequence>();
if (frame_seq) if (frame_seq)
{ {
KeyFrameSpliter spliter(texture); frame_seq->AddFrames(frame.Split(cols, rows, max_num, padding_x, padding_y));
auto frames = spliter.Split(cols, rows, max_num, padding_x, padding_y);
frame_seq->AddFrames(frames);
cache->AddObject(id, frame_seq); cache->AddObject(id, frame_seq);
return; return;
} }
@ -267,10 +263,10 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String&
else else
{ {
// Simple image // Simple image
KeyFramePtr frame = MakePtr<KeyFrame>(); TexturePtr texture = MakePtr<Texture>();
if (frame && frame->Load(gdata->path + file)) if (texture && texture->Load(gdata->path + file))
{ {
cache->AddObject(id, frame); cache->AddObject(id, texture);
return; return;
} }
} }